I am writing a routine to create and fill an Excel sheet in ASP.NET MVC. The object that I want to transfer to the sheet is a List, where T is a structure.
Do you know of any piece of code that does this?
The constructor that do this is:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
…
public byte[] ExcelContent;
public ExportExcel(List<OrdViewModel> ol)
{
MemoryStream memstream = new MemoryStream();
SpreadsheetDocument XlsxDoc = SpreadsheetDocument.Create(memstream, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = XlsxDoc.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = XlsxDoc.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = XlsxDoc.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
// code here…
XlsxDoc.Close();
ExcelContent = memstream.ToArray();
}
You can use my SwiftExcel library. It was designed to maximize performance and minimize memory usage when writing to Excel:
public ExportExcel(List<OrdViewModel> ol)
{
using (var ew = new ExcelWriter("C:\\temp\\test.xlsx"))
{
for (var row = 1; row <= ol.Count; row++)
{
var item = ol[row-1];
ew.Write(item.YourProperty1, 1, row);
ew.Write(item.YourProperty2, 2, row);
ew.Write(item.YourProperty3, 3, row);
ew.Write(item.YourProperty4, 4, row);
}
}
}
Related
I was trying to create an excel using Memory Stream. Here is the code I'm trying,
using (MemoryStream mem = new MemoryStream())
{
using (var sheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook))
{
//// Add a WorkbookPart to the document.
WorkbookPart workbookpart = sheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorkbookStylesPart workbookstyle = workbookpart.AddNewPart<WorkbookStylesPart>();
workbookstyle.Stylesheet = this.GenerateStyleSheet();
workbookstyle.Stylesheet.Save();
//// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Columns cols = new Columns();
Column col = new Column();
col.BestFit = true;
col.CustomWidth = true;
col.Width = 22.33;
col.Max = 13;
col.Min = 1;
cols.Append(col);
worksheetPart.Worksheet.Append(cols);
SheetData sheetData = new SheetData();
worksheetPart.Worksheet.Append(sheetData);
//// Add Sheets to the Workbook.
Sheets sheets = sheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
//// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = sheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
sheets.Append(sheet);
workbookpart.Workbook.Save();
List<string> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
}
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = this.CreateHeaderRow(columns);
sheetData.AppendChild(headerRow);
foreach (DataRow dataSetRow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = this.CreateDataRow(dataSetRow);
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
var result = mem.ToArray();
System.IO.File.WriteAllBytes(fileName, result);
}
An excel file is getting created, but when I try to open it, I'm getting an error as bellow
If I press yes, it says
The workbook cannot be opened or repaired by Microsoft Excel because
it is corrupt
How can I fix this?
Thanks to #zaikhan's comment, I was able to fix my issue. When I closed the sheetDocument it worked.
using (MemoryStream mem = new MemoryStream())
{
using (var sheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook))
{
//// Add a WorkbookPart to the document.
WorkbookPart workbookpart = sheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorkbookStylesPart workbookstyle = workbookpart.AddNewPart<WorkbookStylesPart>();
workbookstyle.Stylesheet = this.GenerateStyleSheet();
workbookstyle.Stylesheet.Save();
//// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Columns cols = new Columns();
Column col = new Column();
col.BestFit = true;
col.CustomWidth = true;
col.Width = 22.33;
col.Max = 13;
col.Min = 1;
cols.Append(col);
worksheetPart.Worksheet.Append(cols);
SheetData sheetData = new SheetData();
worksheetPart.Worksheet.Append(sheetData);
//// Add Sheets to the Workbook.
Sheets sheets = sheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
//// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = sheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
sheets.Append(sheet);
workbookpart.Workbook.Save();
List<string> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
}
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = this.CreateHeaderRow(columns);
sheetData.AppendChild(headerRow);
foreach (DataRow dataSetRow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = this.CreateDataRow(dataSetRow);
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
sheetDocument.Close();
}
var result = mem.ToArray();
System.IO.File.WriteAllBytes(fileName, result);
}
Given
I use
<PackageReference Include="DocumentFormat.OpenXml" Version="2.12.3" />
and set
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("sk");
When
I add a cell with decimal number
new Cell
{
DataType = CellValues.Number,
CellValue = new CellValue(1.2d)
}
Then
Invalid xlsx ids generated. I get following message when opening:
Can I explicitly tell what culture should the document use?
I would like to avoid setting CurrentCulture globally, because it might have side effects.
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("sk");
string fileFullname = #"c:\temp\test.xlsx";
using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileFullname, SpreadsheetDocumentType.Workbook))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = document.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = document.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
sheetData.AppendChild(new Row(new []
{
new Cell
{
DataType = CellValues.Number,
CellValue = new CellValue(1.2d)
}
}));
// Close the document.
document.Save();
document.Close();
}
Use DocumentFormat.Openxml 2.8.1.
I try to create Excel Sheet and create Table inside it.
But when i do it - and try to open excel file - excel says that can not open and try to restore this file.
So, i create excel file:
var fStream = new FileStream(tempPathName, FileMode.Open, FileAccess.ReadWrite, FileShare.None, 1048, FileOptions.DeleteOnClose);
SpreadsheetDocument ssDoc = SpreadsheetDocument.Create(inputStream,
SpreadsheetDocumentType.Workbook);
Then , create sheet:
var tempPathName = Path.GetTempFileName();
WorkbookPart workbookPart = ssDoc.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
Sheets sheets = ssDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
WorksheetPart worksheetPart4 = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart4.Worksheet = new Worksheet();
Worksheet workSheet4 = worksheetPart4.Worksheet;
var table = CreateTable1();
TableParts tableParts = new TableParts() { Count = (UInt32)1 };
TablePart tablePart = new TablePart() { Id = "rId" + 1 };
tableParts.Append(table);
tableParts.Append(tablePart);
workSheet4.AppendChild(tableParts);
Sheet sheet4 = new Sheet()
{
Id = ssDoc.WorkbookPart.GetIdOfPart(worksheetPart4),
SheetId = 4,
Name = "test"
};
sheets.Append(sheet4);
ssDoc.Close();
private Table CreateTable1()
{
// First, we create the table, its properties and we append it.
Table table = new Table();
TableProperties props = new TableProperties();
table.AppendChild<TableProperties>(props);
// Now we create a new layout and make it "fixed".
TableLayout tl = new TableLayout() { Type = TableLayoutValues.Fixed };
props.TableLayout = tl;
// Then we just create a new row and a few cells and we give them a width
var tr = new TableRow();
var tc1 = new TableCell();
var tc2 = new TableCell();
tc1.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
tc2.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2000" }));
table.Append(tr);
return table;
}
So, how to create table in Excel sheet and insert data in table?
Thank you.
TableStyle class is what you`re looking for.
You actually have to create TableStyle and add it to your spreadsheet.
In CreateTable1(), TableProperties, TableLayout, TableRow, and TableCell are WordProcessing elements.
Instead, you will want to use code similar to this:
private void CreateTable2(SheetData sheetData)
{
var row1 = new Row(){ RowIndex = 1 };
sheetData.Append(row1);
var cell1 = new Cell();
cell1.DataType = CellValues.InlineString;
cell1.InlineString = new InlineString() { Text = new Text("Hello") };
row1.InsertAt(cell1, 0);
var cell2 = new Cell();
cell2.DataType = CellValues.InlineString;
cell2.InlineString = new InlineString() { Text = new Text("World") };
row1.InsertAt(cell2, 1);
}
Slightly modify the rest of your code to look like the following (most of which I borrowed from here).
var fStream = new FileStream(tempPathName, FileMode.Create);
SpreadsheetDocument ssDoc = SpreadsheetDocument.Create(fStream, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
WorkbookPart workbookPart = ssDoc.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = ssDoc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = ssDoc.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheet"
};
sheets.Append(sheet);
// Get the sheetData cell table.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
CreateTable2(sheetData);
workbookPart.Workbook.Save();
ssDoc.Close();
fStream.Close();
I am trying to download the large excel file using open xml. I am able to download it. My excel file contains more than 100k records. When I double click on the file, I get below error message.
Below is my code.
public MemoryStream WriteExcelUsingOpenXML(IEnumerable<string> headers, IEnumerable<IEnumerable<string>> values, string worksheetName)
{
var stream = new MemoryStream();
var headersArray = headers.ToArray();
using (SpreadsheetDocument document = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = Constants.TimephaseWorksheet };
sheets.Append(sheet);
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
// Constructing header
Row row = new Row();
foreach (var data in headersArray)
{
row.Append(ConstructCell(headersArray[0], CellValues.SharedString));
}
// Insert the header row to the Sheet Data
sheetData.AppendChild(row);
// Inserting each employee
foreach (var valuesEnumeration in values)
{
row = new Row();
var flattend = valuesEnumeration.ToArray();
row.Append(
ConstructCell(flattend[0], CellValues.Number),
ConstructCell(flattend[1], CellValues.SharedString),
ConstructCell(flattend[2], CellValues.SharedString),
ConstructCell(flattend[3], CellValues.Number),
ConstructCell(flattend[4], CellValues.SharedString));
sheetData.AppendChild(row);
}
worksheetPart.Worksheet.Save();
}
return stream;
}
private Cell ConstructCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
};
}
Below is the sample data of excel file.
How to fix the error?
I have a problem in C# when i try to generate new excel file with 4 values. When i try to open file i receive an error telling me :
excel cannot open the file because the file format or file extension is not valid
When i try to debug it i have noticed that output is trowing :
System invalid operation exception and i don't know how to fix this. i just want to generate excel file that has some values inside (later i will fill insert my values). For now i am just trying to create excel file that isn't corrupted.
[HttpPost]
public HttpResponseMessage PrintDevices()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
using (MemoryStream output = new MemoryStream())
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(output, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Testing"
};
sheets.Append(sheet);
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
// Constructing header
Row row = new Row();
row.Append(
ConstructCell("Id", CellValues.String),
ConstructCell("Name", CellValues.String),
ConstructCell("Birth Date", CellValues.String),
ConstructCell("Salary", CellValues.String));
// Insert the header row to the Sheet Data
sheetData.AppendChild(row);
// Inserting each employee
worksheetPart.Worksheet.Save();
}
}
Cell ConstructCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
};
}
return response;
}