ClosedXML how to set cell width for whole workbook? - c#

i'm using closedXml to export data to Excel. But my columns need to be adjusted to the content therefore i've tried to specify the colums width by hand:
var ws = workbook.Worksheets.Add("Column Settings");
col.Width = 50;
Wasn't working for me.I've also tried:
Columns().AdjustToContents();
But also no results. So looking for an solution that will pre set the cell width in the whole sheet or workbook.
This is my code:
//variables
XLWorkbook workbook = new XLWorkbook();
var wsDep = workbook.Worksheets.Add("MBR");
wsDep.Columns().AdjustToContents();
DataTable dt = new DataTable() { TableName = "MBR" };
DataSet ds = new DataSet();
TagRepo tr = new TagRepo();
List<string> tags = new List<string>();
tags.Add("TimeStamp");
//list min,max,avg.
foreach (var item in tr.getAllTagNames())
{
tags.Add(item.Trim()+"_Min");
tags.Add(item.Trim() + "_Max");
tags.Add(item.Trim() + "_Avg");
}
//input data
int l = tags.Count();
//Colum names
string[] columns = new string [l];
for (int i = 0; i < l; i++)
{
columns[i] = tags[i];
}
var rows = new object[][]
{
new object[] {"1", 2, false },
new object[] { "test", 10000, 19.9 },
};
//Add columns
dt.Columns.AddRange(columns.Select(c => new DataColumn(c.ToString())).ToArray());
//Add rows
foreach (var row in rows)
{
dt.Rows.Add(row);
}
//Convert datatable to dataset and add it to the workbook as worksheet
ds.Tables.Add(dt);
workbook.Worksheets.Add(ds);
//save
//string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string savePath = Path.Combine(#"\\nas\TreviMap\Pilootproeven en opvolging-IC\Export data", "toon.xlsx");
workbook.SaveAs(savePath, false);

You need to call Columns().AdjustToContents(); after you have filled the worksheet(s).

Related

Why does my WorkbookView sequence keep returning "null" value with OpenXml?

I have created a download button in C#/asp.net, which takes a GridView, converts it to a data table, and then stores it into a .xlsx file. What I want to do after is be able to change the active tab of the spreadsheet I created.
Here is the code below:
protected void downloadBtn_Click(object sender, EventArgs e)
{
using (var spreadSheet = SpreadsheetDocument.Create(Server.MapPath("~/Downloads/TestSheet.xlsx"), DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = spreadSheet.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
//Fine up to this point
spreadSheet.WorkbookPart.Workbook.Sheets = new Sheets();
DataTable table = new DataTable();
//Converts GridView into Data Table **
for (int i = 0; i < gvEmployee.HeaderRow.Cells.Count - 1; i++)
{
table.Columns.Add(gvEmployee.HeaderRow.Cells[i + 1].Text);
}
// fill rows
for (int i = 0; i < gvEmployee.Rows.Count; i++)
{
DataRow dr = table.NewRow();
for (int j = 0; j < gvEmployee.Columns.Count - 1; j++)
{
dr[j] = gvEmployee.Rows[i].Cells[j + 1].Text;
}
table.Rows.Add(dr);
}
var sheetPart = spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
sheetPart.Worksheet = new Worksheet(sheetData);
Sheets sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = spreadSheet.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = "TestSheet" };
sheets.Append(sheet);
Row headerRow = new Row();
List<String> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in table.Rows)
{
Row newRow = new Row();
foreach (String col in columns)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
Sheet sheet2 = new Sheet() { Id = spreadSheet.WorkbookPart.GetIdOfPart(sheetPart), SheetId = 2, Name = "AdditionalSheet" };
sheets.Append(sheet2);
var sheetIndex = workbookPart.Workbook.Descendants<Sheet>().ToList().IndexOf(sheet2);
WorkbookView workbookView = workbookPart.Workbook.Descendants<WorkbookView>().FirstOrDefault(); //new WorkbookView();
workbookView.ActiveTab = Convert.ToUInt32(sheetIndex);
workbookPart.Workbook.Save();
spreadSheet.Close();
}
}
When I try to run this code, it throws an error on the "workbookView.ActiveTab" at the last few lines stating
System.NullReferenceException: 'Object reference not set to an instance of an object.'
workbookView was null.
Any ideas as to why its doing this?
Okay, I just figured out what was wrong, there was no WorkbookView initialized, as I thought it thought it didn't need to be. But you have to actually make a WorkbookView of your workbook before you can change it. I just needed this one line:
workbookPart.Workbook.Append(new BookViews(new WorkbookView()));

Faster creation of Excel (Interop)

I identified the code slowing down the process as this one (where I'm filling the cells):
What I'm doing here is basically loading some data from a database using a DataSet.
Microsoft.Office.Interop.Excel.Range range1 = null;
Microsoft.Office.Interop.Excel.Range cell1 = null;
Microsoft.Office.Interop.Excel.Borders border1 = null;
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
int s = i + 1;
for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
{
data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[s + 1, j + 1] = data;
range1 = xlWorkSheet.UsedRange;
cell1 = range1.Cells[s + 1, j + 1];
border1 = cell1.Borders;
if (((IList)terms).Contains(xlWorkSheet.Cells[1, j + 1].Value.ToString()))
{
cell1.Interior.Color = System.Drawing.Color.Red;
}
range1.Columns.AutoFit();
range1.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
border1.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
border1.Weight = 2d;
}
}
It's sometimes taking like more than 1 minute to load the whole thing. Is there is away to optimize it?.
Cell-by-cell is the slowest possible way to interact with Excel using Interop - look up how to add data to a sheet from an array in one operation.
E.g.
Write Array to Excel Range
shows this approach.
Interop libraries are extremely slow and spends huge source of system.
Instead of using Interop Libraries to create Excel files, you can simply use it OpenXML library.
I'm using it in production. And over 1 million rows it just takes about 10 seconds to export dataset to excel file.
Here is a sample code quoted from:
Export DataTable to Excel with Open Xml SDK in c#
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);
}
}
}
}

The excel file is created by using DocumentFormat.OpenXML but need to repairing when opeing in Excel

I am new for DocumentFormat program.I searched the web and found the example to export dataset to excel using OpenXML. Following the code, the excel file is generated. However when the file is open, there is an issue that the Excel indicated that "a problem with some content in report. Do you want us to try to recover as much as we can?.." when the user clicked yes, the data is fine. I searched the website and look like the string column type by using InlineString is ok. Am I wrong? I have no idea which code cause the problem. Would someone can tell me? Thanks in advance.
There is the code I found in the web:
namespace ExcelObject
{
public class ExcelStream
{
SpreadsheetDocument document = null;
public MemoryStream GetExcelStream(DataSet dataset)
{
DataSet ds = dataset;
using (var ms = new MemoryStream())
{
//Create workbook in memory
document = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
//Add workbook
var workbookpart = document.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
//add worksheet to wrokbook
var worksheet = workbookpart.AddNewPart<WorksheetPart>();
worksheet.Worksheet = new Worksheet(new SheetData());
var sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
//Add a new worksheet and associte it with the workbook.
var mainSheet = new Sheet()
{
Id = document.WorkbookPart.GetIdOfPart(worksheet),
SheetId = 1,
Name = "TestReport"
};
sheets.Append(mainSheet);
uint rowIndex = 0;
//Get sheet data
var sheetData = worksheet.Worksheet.GetFirstChild<SheetData>();
var row = new Row { RowIndex = ++rowIndex };
AddColumnHeaderRow(ds, row, sheetData);
AddDataRows(ds, rowIndex, sheetData);
workbookpart.Workbook.Save();
document.Close();
return ms;
}
}
private static void AddColumnHeaderRow(DataSet ds, Row row, SheetData sheetData)
{
for (var i = 0; i < ds.Tables[0].Columns.Count; i++)
{
var cell = new Cell { DataType = CellValues.InlineString, StyleIndex = 1 };
var inlineCell = new InlineString();
var cellText = new Text { Text = ds.Tables[0].Columns[i].ColumnName };
inlineCell.AppendChild<Text>(cellText);
cell.AppendChild<InlineString>(inlineCell);
row.AppendChild<Cell>(cell);
}
sheetData.AppendChild(row);
}
private static void AddDataRows(DataSet ds, uint rowIndex, SheetData sheetData)
{
for (var r = 0; r < ds.Tables[0].Rows.Count; r++)
{
var row = new Row { RowIndex = ++rowIndex };
for (var c = 0; c < ds.Tables[0].Columns.Count; c++)
{
var cell = new Cell { DataType = CellValues.InlineString };
var istring = new InlineString();
var t = new Text
{
Text = ds.Tables[0].Rows[r][c].ToString()
};
istring.AppendChild<Text>(t);
cell.AppendChild<InlineString>(istring);
row.AppendChild(cell);
}
//append each data row to sheet data
sheetData.AppendChild<Row>(row);
}
}
}
}
There is my code to generate the table and get the result:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim dt As New DataTable("Test")
dt.Columns.Add("Code", GetType(String))
dt.Columns.Add("Price", GetType(String))
Dim dr As DataRow = dt.NewRow()
dr("Code") = "ABC"
dr("Price") = "12"
dt.Rows.Add(dr)
Dim dr1 As DataRow = dt.NewRow()
dr1("Code") = "DEF"
dr1("Price") = "1"
dt.Rows.Add(dr1)
Dim ds As New DataSet
ds.Tables.Add(dt)
Dim t As ExcelStreamObject.ExcelStream = New ExcelStreamObject.ExcelStream
Dim ms As MemoryStream = t.GetExcelStream(ds)
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AppendHeader("Content-Disposition", "attachment; filename=TestReport.xlsx")
Response.BinaryWrite(ms.ToArray())
Response.Flush()
Response.Close()
Response.End()
End Sub
I found what is wrong of my code. The AddColumnHeaderRow having Style that I didn't have. So I changed the "var cell = new Cell { DataType = CellValues.InlineString, StyleIndex = 1 };" to be "var cell = new Cell { DataType = CellValues.InlineString };" The error message didn't show when opening the file.

How to Create Dropdownlist in Excel using Openxml in C#

There are some sheets which is created from a XML file.
There are some names in 2nd sheet .excel is created by reading XML file and change it to data-set and later created worksheet and all other rows and columns with the help of OPEN-XML .
So I want to create a list using names from 2nd sheet and show the list in sheet 1 as drop-down.Using OPEN-XML I want to create a drop-downlist with data taken from 2nd page. I browse many time but i did not find any solution Is it possible to create dropdown using openxml.
This is my whole code for creating excel from xml file so if it have solution please help me.
public void ExportDSToExcel(DataSet ds, string dest)
{
try
{
using (var workbook = SpreadsheetDocument.Create(dest, 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);
if(sheet.Name=="Customer")
{
PageMargins pageM = sheetPart.Worksheet.GetFirstChild<PageMargins>();
SheetProtection sheetProtection = new SheetProtection();
sheetProtection.Password = "admin";
sheetProtection.Sheet = true;
sheetProtection.Objects = true;
sheetProtection.Scenarios = true;
ProtectedRanges pRanges = new ProtectedRanges();
ProtectedRange pRange = new ProtectedRange();
ListValue<StringValue> lValue = new ListValue<StringValue>();
lValue.InnerText = ""; //set cell which you want to make it editable
pRange.SequenceOfReferences = lValue;
pRange.Name = "not allow editing";
pRanges.Append(pRange);
sheetPart.Worksheet.InsertBefore(sheetProtection, pageM);
sheetPart.Worksheet.InsertBefore(pRanges, pageM);
if (cell.CellReference == "B4")
{
CellFormula cellformula = new CellFormula();
cellformula.Text = "=INDEX(Sheet5!B:B,MATCH(A4,Sheet5!B:B,0))";
CellValue cellValue = new CellValue();
cellValue.Text = "0";
cell.Append(cellformula);
cell.Append(cellValue);
}
}
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
if (RadioButtonList1.SelectedItem.Text == "Yes")
{
PageMargins pageM = sheetPart.Worksheet.GetFirstChild<PageMargins>();
SheetProtection sheetProtection = new SheetProtection();
sheetProtection.Password = "admin";
sheetProtection.Sheet = true;
sheetProtection.Objects = true;
sheetProtection.Scenarios = true;
ProtectedRanges pRanges = new ProtectedRanges();
ProtectedRange pRange = new ProtectedRange();
ListValue<StringValue> lValue = new ListValue<StringValue>();
lValue.InnerText = ""; //set cell which you want to make it editable
pRange.SequenceOfReferences = lValue;
pRange.Name = "not allow editing";
pRanges.Append(pRange);
sheetPart.Worksheet.InsertBefore(sheetProtection, pageM);
sheetPart.Worksheet.InsertBefore(pRanges, pageM);
}
else
{
}
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);
}
}
}
}
catch
{
lblstatus.Text = "File Upload Not Succesfull ";
}
lblstatus.Text = "File Upload Succesfull ";
}
protected void Button1_Click(object sender, EventArgs e)
{
if(txtname.Text != null)
{
if (FileUpload1.HasFile == true)
{
string myXMLfile = "/uploads/" + FileUpload1.FileName;
FileUpload1.SaveAs(Server.MapPath(myXMLfile));
string dest = "D:/uploads/" + txtname.Text+".xlsx";
DataSet ds = new DataSet();
try
{
ds.ReadXml(Server.MapPath(myXMLfile));
}
catch (Exception ex)
{
lblstatus.Text=(ex.ToString());
}
ExportDSToExcel(ds, dest);
}
else
{
lblstatus.Text = "Please Upload the file ";
}
}
else {
lblstatus.Text = "Please enter the name ";
}
}
}
You need create a Validator
First Parameter is a worksheet where create a dropdown
Second parameter is worksheet to take data from
A1:A1048576 - is a cells to apply this Validator
public void CreateValidator(Worksheet ws, string dataContainingSheet)
{
/*** DATA VALIDATION CODE ***/
DataValidations dataValidations = new DataValidations();
DataValidation dataValidation = new DataValidation
{
Type = DataValidationValues.List,
AllowBlank = true,
SequenceOfReferences = new ListValue<StringValue> { InnerText = "A1:A1048576" }
};
dataValidation.Append(
//new Formula1 { Text = "\"FirstChoice,SecondChoice,ThirdChoice\"" }
new Formula1(string.Format("'{0}'!$A:$A", dataContainingSheet))
);
dataValidations.Append(dataValidation);
var wsp = ws.WorksheetPart;
wsp.Worksheet.AppendChild(dataValidations);
}

Open XML Export datatable to excel directly on disk

I want to export datatable to xlsx directly to my disk instead of giving destination path and saving file on server.
I have following function :
private void ExportToCSVFileOpenXML(DataTable dt, string destination)
{
DataSet ds = new DataSet();
DataTable dtCopy = new DataTable();
dtCopy = dt.Copy();
ds.Tables.Add(dtCopy);
try
{
var workbook = SpreadsheetDocument.Create(Server.MapPath("~/" + destination.Replace("/","").Replace(":","")), 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);
}
}
}
}
catch (Exception)
{
throw;
}
}
How can I directly export this to disk instead of saving on server by giving destination path as :
var workbook = SpreadsheetDocument.Create(Server.MapPath("~/" + destination.Replace("/","").Replace(":","")), DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
Please help me.
SpreadsheetDocument.Create accepts a stream, string, or package as its first argument so we can just use a MemoryStream to create the workbook in memory and return a byte array.
It should be something like this:
public byte[] ExportToCSVFileOpenXML(DataTable dt)
{
byte[] returnBytes = null;
using (MemoryStream mem = new MemoryStream())
{
var workbook = SpreadsheetDocument.Create(mem, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
// your code
workbook.WorkbookPart.Workbook.Save();
workbook.Close();
returnBytes = mem.ToArray();
}
return returnBytes;
}
Once you have a byte array passing it as a file should be quite easy.
If you are using MVC it should be something like this in your controler:
return File(ExportToCSVFileOpenXML(aTable), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "export.xlsx");
Alex answer lead me to correct answer.
I did following thing :
private byte[] ExportToCSVFileOpenXML(DataTable dt)
{
DataSet ds = new DataSet();
DataTable dtCopy = new DataTable();
dtCopy = dt.Copy();
ds.Tables.Add(dtCopy);
try
{
byte[] returnBytes = null;
MemoryStream mem = new MemoryStream();
var workbook = SpreadsheetDocument.Create(mem, 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);
}
}
}
workbook.WorkbookPart.Workbook.Save();
workbook.Close();
returnBytes = mem.ToArray();
return returnBytes;
}
catch (Exception)
{
throw;
}
}
Called this function as:
protected void hlInCorrectRecords_Click(object sender, EventArgs e)
{
lblmsg.Text = "";
DataSet dsDtUploadedSummary = (DataSet)ViewState["dsDtUploadedSummary"];
if (dsDtUploadedSummary.Tables.Count > 0)
{
DataTable dtFreshRecords = dsDtUploadedSummary.Tables[4];
if (dtFreshRecords.Rows.Count > 0 && dtFreshRecords != null)
{
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
string filename = #"IncorrectRecordsUploaded_" + DateTime.Now.ToString();
Response.AddHeader("Content-Disposition", "inline;filename=" + filename.Replace("/", "").Replace(":", "")+".xlsx");
Response.BinaryWrite(ExportToCSVFileOpenXML(dtFreshRecords));
Response.Flush();
Response.End();
}
else
{
lblmsg.Text = "No Data To Export";
}
}
else
{
lblmsg.Text = "No Data To Export";
}
}
Thanks Alex. I am using plain ASP.NET not MVC

Categories