Find Cell HeaderName in openXML - c#

I m using OfficeOpenXML to import Excel data into Database. here is the code sample that I am using for my task.But I want to have HeaderName while looping through each cell in row As I have to make some modifications to columns.
Any help suggestion appreciated. Thanks!
var ws = pck.Workbook.Worksheets.First();
var pck = new OfficeOpenXml.ExcelPackage();
for (var rowNum = 3; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, DtCommon.Tables[0].Columns.Count-1];
var row = tblResult.NewRow();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text; //Find HeaderName here based on cell index
}
tblResult.Rows.Add(row);
}

I've posted this suggestion in the comments, but as it helped, I'm posting it as an answer.
By looking at Your code, I suppose You're using ExcelPackage library.
If so, I suppose You may be able to get the first cell in each column by writing:
foreach (var cell in wsRow)
{
// code to get the header cell
var header = ws.Cell(1, cell.Column);
// rest of your code here
// ...
}

Related

Importing Excel to DataGrid using ClosedXML and OpenFileDialog

I want to load an Excel-file into my DataGrid, using ClosedXML.
I have this method:
public static DataTable ImportExceltoDataTable(string filePath, string sheetName) {
using (XLWorkbook wb = new(filePath)) {
IXLWorksheet ws = wb.Worksheet(1);
DataTable dt = new();
bool firstRow = true;
foreach (IXLRow row in ws.Rows()) {
if (firstRow) {
foreach (IXLCell cell in row.Cells()) {
dt.Columns.Add(cell.CachedValue.ToString());
}
firstRow = false;
} else {
dt.Rows.Add();
int i = 0;
foreach (IXLCell cell in row.Cells(row.FirstCellUsed().Address.ColumnNumber, row.LastCellUsed().Address.ColumnNumber)) {
dt.Rows[dt.Rows.Count - 1][i} = cell.CachedValue.ToString();
i++;
}
}
}
return dt;
}
}
And on a click-event, I am trying to pick my file using OpenFileDialog, see below:
OpenFileDialog of = new();
of.Filter = "Excel Files | *.xlsx;";
of.Title = "Import Excel file.";
if (of.ShowDialog()==true) {
dataGrid.ItemsSource = ImportExceltoDataTable("...", "...").DefaultView;
}
But I do not know how to notify the DataTable that I've chosen a file in my OpenFileDialog.
At the first line in the DataTable method, I get the following exception error:
System.ArgumentException: 'Empty extension is not supported'
Which makes sense... How can I tell it what file I've picked?
You may want to re-think your approach to reading the excel file. One possible issue is the if (firstRow) { … … statement, which is odd and makes a dangerous assumption. The code “assumes” that each column of data “has” a header cell. In other words, the number of columns added to the DataTable will be determined by the number of cells found (with some text in the cell) on the “FIRST” row. What if a column of data does NOT have a header cell?
Therefore, if there are any rows that have data to the right of the first row’s cells with headers, then the DataTable will not have the correct number of columns… and, when the code gets to these cells in the else portion below… the code will most likely crash when i goes beyond dt’s column count.
The code needs to guarantee that dt has the correct number of columns to avoid the problem described above. One way to help is to find the two cells that define the “top-left” cell where the data begins (as it may not necessarily always be the first cell in the worksheet) and “bottom-right” cell where the “last” cell with data is located.
Once we have these two cells (top-left and bottom-right)… then, we can determine how many columns are needed in the DataTable… and… we can almost guarantee that all the data in the worksheet will fit in the DataTable.
Below is one possible solution using the ideas described above. Note, the code below does not use a particular worksheet name and simply uses the first worksheet in the given workbook.
private void Button_Click(object sender, RoutedEventArgs e) {
OpenFileDialog of = new OpenFileDialog();
of.Filter = "Excel Files | *.xlsx;";
of.Title = "Import Excel file.";
if (of.ShowDialog() == true) {
dataGrid.ItemsSource = ImportExceltoDataTable(of.FileName).DefaultView;
}
}
public static DataTable ImportExceltoDataTable(string filePath) {
using (XLWorkbook wb = new XLWorkbook(filePath)) {
IXLWorksheet ws = wb.Worksheet(1);
int tl_Row = ws.FirstCellUsed().Address.RowNumber;
int tl_Col = ws.FirstCellUsed().Address.ColumnNumber;
int br_Row = ws.LastCellUsed().Address.RowNumber;
int br_Col = ws.LastCellUsed().Address.ColumnNumber;
DataTable dt = new DataTable();
// add dt columns using the first row of data
for (int i = tl_Col; i <= br_Col; i++) {
dt.Columns.Add(ws.Cell(tl_Row, i).CachedValue.ToString());
}
IXLRow currentRow;
// add data from the worksheet to dt - we already used the first row of data for the columns
for (int dtRow = 0; dtRow < br_Row - tl_Row; dtRow++) {
currentRow = ws.Row(tl_Row + dtRow + 1);
dt.Rows.Add();
for (int dtCol = 0; dtCol < br_Col - tl_Col + 1; dtCol++) {
dt.Rows[dtRow][dtCol] = currentRow.Cell(tl_Col + dtCol).CachedValue;
}
}
return dt;
}
}
I hope this makes sense and helps.

EPPlus not Inserting Formula Correcty

I'm using EPPlus to manipulate an Excel file. I need to insert a formula that references an entire column. I'm currently using:
currentWorksheet.Cells[2, 4].Formula = "QUARTILE(C:C,1)";
If I manually enter this formula into the Excel sheet it works, or if I insert it with a finite range in EPPlus like so:
=QUARTILE(C2:C1000,1)
But when it's inserted as a whole column range of C:C using EPPlus it results in the following:
=QUARTILE(#REF!,1)
Is there something special needed when referencing entire columns, or is this just a bug in EPPlus?
You can use following code
worksheet.Cells["A1"].Formula= "=QUARTILE(C2:C1000,1)";
Stewart is correct in that the formula should be valid. Try pasting in the rest of your code. I thought together a quick unit test and it worked fine:
[TestMethod]
public void Quartile_Range_Test()
{
//Throw in some data
var dtMain = new DataTable("tblData");
dtMain.Columns.Add(new DataColumn("Col1", typeof(int)));
for (var i = 0; i < 20; i++)
{
var row = dtMain.NewRow();
row["Col1"] = i * 100;
dtMain.Rows.Add(row);
}
//Clear the file
var newFile = new FileInfo(#"C:\Temp\Temp.xlsx");
if (newFile.Exists)
newFile.Delete();
using (var package = new ExcelPackage(newFile))
{
var currentWorksheet = package.Workbook.Worksheets.Add("Test");
currentWorksheet.Cells["C1"].LoadFromDataTable(dtMain, false);
currentWorksheet.Cells[2, 4].Formula = "QUARTILE(C:C,1)";
package.Save();
}
}

EPPlus - Named Range is not populated

I'm using EPPLus to open Excel Spreadsheets and trying to read from a named range. The Named Range is Empty.
Am I using this wrong, or is it a problem with EPPlus
Code
var package = new ExcelPackage();
using (var stream = File.OpenRead(tmpExcel))
{
package.Load(stream);
}
var worksheet = package.Workbook.Worksheets["Common-Lookup"];
using (ExcelNamedRange namedRange = worksheet.Names["LupVerticalSettings"])
{
for (var row = namedRange.Start.Row; row <= namedRange.End.Row; row++)
{
for (var col = namedRange.Start.Column; col <= namedRange.End.Column; col++)
{
_.Nv(worksheet.Cells[row, col].Address, worksheet.Cells[row, col].Text);
//worksheet.Cells[rowIndex, columnIndex].Value = "no more hair pulling";
}
}
}
The Excel looks like this
Empty Named Range
I solved my problem, I'll put answer here for anyone that may need it in the future
var package = new ExcelPackage();
using (var stream = File.OpenRead(tmpExcel))
{
package.Load(stream);
}
var worksheet = package.Workbook.Worksheets["Common-Lookup"];
// Access Named Ranges from the ExcelWorkbook instead of ExcelWorksheet
//using (ExcelNamedRange namedRange = worksheet.Names["LupVerticalSettings"])
// use package.Workbook.Names instead of worksheet.Names
using (ExcelNamedRange namedRange = package.Workbook.Names["LupVerticalSettings"])
{
for (var row = namedRange.Start.Row; row <= namedRange.End.Row; row++)
{
for (var col = namedRange.Start.Column; col <= namedRange.End.Column; col++)
{
_.Nv(worksheet.Cells[row, col].Address, worksheet.Cells[row, col].Text);
//worksheet.Cells[rowIndex, columnIndex].Value = "no more hair pulling";
}
}
}

OpenXML library save excel file

I have the following code and its not saving the values to cell and also in file. It shows value in cell.cellvalue field but its not writing it to excel. I have no idea how to save the file. I used OpenXml-SDK and I am writing datatable values to each cell/row of created spreadsheet document.
using (SpreadsheetDocument ssd=SpreadsheetDocument.Open(Server.MapPath(#"\ExcelPackageTemplate.xlsx"),true))
{
WorkbookPart wbPart = ssd.WorkbookPart;
WorksheetPart worksheetPart = wbPart.WorksheetParts.First();
SheetData sheetdata = worksheetPart.Worksheet.GetFirstChild<SheetData>();
string[] headerColumns = new string[] { dt.Columns[0].ColumnName, dt.Columns[1].ColumnName,dt.Columns[2].ColumnName };
DocumentFormat.OpenXml.Spreadsheet.Row r = new DocumentFormat.OpenXml.Spreadsheet.Row();
int RowIndexer = 1;
//int colInd=0;
r.RowIndex = (UInt32)RowIndexer;
string test = ColumnName(RowIndexer);
foreach (DataColumn dc in dt.Columns)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.CellReference = test+RowIndexer;
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new Text(dc.ColumnName.ToString()));
DocumentFormat.OpenXml.Spreadsheet.CellValue value = new DocumentFormat.OpenXml.Spreadsheet.CellValue();
r.AppendChild(cell);
// colInd++;
}
//r.RowIndex = (UInt32)RowIndexer;
RowIndexer = 2;
foreach (DataRow dr in dt.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row Row = new DocumentFormat.OpenXml.Spreadsheet.Row();
string Index = ColumnName(RowIndexer);
Row.RowIndex = (UInt32)RowIndexer;
foreach (object value in dr.ItemArray)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new Text(value.ToString()));
cell.CellReference = Index+RowIndexer;
// cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(value.ToString());
Row.AppendChild(cell);
}
RowIndexer++;
}
worksheetPart.Worksheet.Save();
wbPart.Workbook.Save();
ssd.Close();
Try this:
using (SpreadsheetDocument ssd = SpreadsheetDocument.Open(Server.MapPath(#"\ExcelPackageTemplate.xlsx"), true))
{
WorkbookPart wbPart = ssd.WorkbookPart;
WorksheetPart worksheetPart = wbPart.WorksheetParts.First();
SheetData sheetdata = worksheetPart.Worksheet.GetFirstChild<SheetData>();
string[] headerColumns = new string[] { dt.Columns[0].ColumnName, dt.Columns[1].ColumnName, dt.Columns[2].ColumnName };
DocumentFormat.OpenXml.Spreadsheet.Row r = new DocumentFormat.OpenXml.Spreadsheet.Row();
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
int RowIndexer = 1;
int ColumnIndexer = 1;
r.RowIndex = (UInt32)RowIndexer;
foreach (DataColumn dc in dt.Columns)
{
cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.CellReference = ColumnName(ColumnIndexer) + RowIndexer;
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new Text(dc.ColumnName.ToString()));
// consider using cell.CellValue. Then you don't need to use InlineString.
// Because it seems you're not using any rich text so you're just bloating up
// the XML.
r.AppendChild(cell);
ColumnIndexer++;
}
// here's the missing part you needed
sheetdata.Append(r);
RowIndexer = 2;
foreach (DataRow dr in dt.Rows)
{
r = new DocumentFormat.OpenXml.Spreadsheet.Row();
r.RowIndex = (UInt32)RowIndexer;
// this follows the same starting column index as your column header.
// I'm assuming you start with column 1. Change as you see fit.
ColumnIndexer = 1;
foreach (object value in dr.ItemArray)
{
cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
// I moved it here so it's consistent with the above part
// Also, the original code was using the row index to calculate
// the column name, which is weird.
cell.CellReference = ColumnName(ColumnIndexer) + RowIndexer;
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(new Text(value.ToString()));
r.AppendChild(cell);
ColumnIndexer++;
}
RowIndexer++;
// missing part
sheetdata.Append(r);
}
worksheetPart.Worksheet.Save();
wbPart.Workbook.Save();
ssd.Close();
}
Some comments:
The ColumnName() function is from here.
I'm assuming you wanted the column headers in a row, and data in subsequent rows (because the original code had the row index used for calculating the column name).
Cleaned up some parts of the code so it's easier to read and that the column header and data row parts are more consistent in writing style.
I suggest that you consider using CellValue instead of InlineString. Based on your code, you're importing a DataTable, and you don't seem to need rich text so InlineString's are a little overkill and might make the resulting file larger (bloated XML). Use one or the other, and remember to set DataType accordingly.
Also, the code only works for completely empty SheetData.
There are some possible issues here:
You create and add new Rows and Cells: it presumes the worksheet is totally blank when you open it (ie: no rows or cells with the same index/address).
Since you set the CellType to InlineString, you need to set the Cell.InlineString and not Cell.CellValue
cell.DataType = CellValues.InlineString;
cell.InlineString = new InlineString(New Text(value.TsString()));
Also, there is something wrong in your code concerning usage of
CellReference. These parts of code have no sense:
cell.CellReference = dc.ColumnName.ToString();
cell.CellReference = value.ToString();
Cell Address should be something like this "A1". You have to review your code to set the correct address. You already have the rowIndex. You need to get the column name. This Translate a column index into an Excel Column Name can help.

Export DataTable to Excel with Open Xml SDK in c#

My program have ability to export some data and DataTable to Excel file (template)
In the template I insert the data to some placeholders. It's works very good, but I need to insert a DataTable too...
My sample code:
using (Stream OutStream = new MemoryStream())
{
// read teamplate
using (var fileStream = File.OpenRead(templatePath))
fileStream.CopyTo(OutStream);
// exporting
Exporting(OutStream);
// to start
OutStream.Seek(0L, SeekOrigin.Begin);
// out
using (var resultFile = File.Create(resultPath))
OutStream.CopyTo(resultFile);
Next method to exporting
private void Exporting(Stream template)
{
using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings { AutoSave = true }))
{
// Replace shared strings
SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart;
IEnumerable<Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<Text>();
DoReplace(sharedStringTextElements);
// Replace inline strings
IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>();
foreach (var worksheet in worksheetParts)
{
DoReplace(worksheet.Worksheet.Descendants<Text>());
}
int z = 40;
foreach (System.Data.DataRow row in ExcelWorkXLSX.ToOut.Rows)
{
for (int i = 0; i < row.ItemArray.Count(); i++)
{
ExcelWorkXLSX.InsertText(workbook, row.ItemArray.ElementAt(i).ToString(), getColumnName(i), Convert.ToUInt32(z)); }
z++;
}
}
}
}
But this fragment to output DataTable slooooooooooooooooooooooowwwwwww...
How can I export DataTable to Excel fast and truly?
I wrote this quick example. It works for me. I only tested it with one dataset with one table inside, but I guess that may be enough for you.
Take into consideration that I treated all cells as String (not even SharedStrings). If you want to use SharedStrings you might need to tweak my sample a bit.
Edit: To make this work it is necessary to add WindowsBase and DocumentFormat.OpenXml references to project.
Enjoy,
private void ExportDataSet(DataSet ds, string destination)
{
using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
foreach (System.Data.DataTable table in ds.Tables) {
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
{
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (System.Data.DataColumn column in table.Columns) {
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (System.Data.DataRow dsrow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
}
}
}
eburgos, I've modified your code slightly because when you have multiple datatables in your dataset it was just overwriting them in the spreadsheet so you were only left with one sheet in the workbook. I basically just moved the part where the workbook is created out of the loop. Here is the updated code.
private void ExportDSToExcel(DataSet ds, string destination)
{
using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
uint sheetId = 1;
foreach (DataTable table in ds.Tables)
{
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
{
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
}
}
}
I also wrote a C#/VB.Net "Export to Excel" library, which uses OpenXML and (more importantly) also uses OpenXmlWriter, so you won't run out of memory when writing large files.
Full source code, and a demo, can be downloaded here:
Export to Excel
It's dead easy to use.
Just pass it the filename you want to write to, and a DataTable, DataSet or List<>.
CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx");
And if you're calling it from an ASP.Net application, pass it the HttpResponse to write the file out to.
CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response);
I wrote my own export to Excel writer because nothing else quite met my needs. It is fast and allows for substantial formatting of the cells. You can review it at
https://openxmlexporttoexcel.codeplex.com/
I hope it helps.
You could try taking a look at this libary. I've used it for one of my projects and found it very easy to work with, reliable and fast (I only used it for exporting data).
http://epplus.codeplex.com/
You can have a look at my library here. Under the documentation section, you will find how to import a data table.
You just have to write
using (var doc = new SpreadsheetDocument(#"C:\OpenXmlPackaging.xlsx")) {
Worksheet sheet1 = doc.Worksheets.Add("My Sheet");
sheet1.ImportDataTable(ds.Tables[0], "A1", true);
}
Hope it helps!
I tried accepted answer and got message saying generated excel file is corrupted when trying to open. I was able to fix it by doing few modifications like adding below line end of the code.
workbookPart.Workbook.Save();
I have posted full code # Export DataTable to Excel with Open XML in c#
I wanted to add this answer because I used the primary answer from this question as my basis for exporting from a datatable to Excel using OpenXML but then transitioned to OpenXMLWriter when I found it to be much faster than the above method.
You can find the full details in my answer in the link below. My code is in VB.NET though, so you'll have to convert it.
How to export DataTable to Excel

Categories

Resources