[英]Write large amount of data to excel c#
我需要將許多數據從數據庫表導出到excel(xls / xlsx)文件。 可能很容易有一千萬行甚至更多。
我需要不需要安裝Office的開源解決方案(SpreadsheetGear和interop解決方案對我來說不起作用)。
我正在檢查兩個庫:OpenXML SDK和EPPlus。
對於OpenXML SDK,我發現此方法:
private static void Write(string fileName, int numRows, int numCols)
{
using (var spreadsheetDocument = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
string origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);
WorksheetPart replacementPart = workbookPart.AddNewPart<WorksheetPart>();
string replacementPartId = workbookPart.GetIdOfPart(replacementPart);
using (OpenXmlReader reader = OpenXmlReader.Create(worksheetPart))
{
using (OpenXmlWriter writer = OpenXmlWriter.Create(replacementPart))
{
Row row = new Row();
Cell cell = new Cell();
//CellFormula cellFormula = new CellFormula();
//cellFormula.CalculateCell = true;
//cellFormula.Text = "RAND()";
//cell.Append(cellFormula);
CellValue cellValue = new CellValue("val val");
cell.Append(cellValue);
while (reader.Read())
{
if (reader.ElementType == typeof(SheetData))
{
if (reader.IsEndElement)
continue;
writer.WriteStartElement(new SheetData());
for (int rowNumber = 0; rowNumber < numRows; rowNumber++)
{
writer.WriteStartElement(row);
for (int col = 0; col < numCols; col++)
{
writer.WriteElement(cell);
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
else
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
}
}
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().First(s => s.Id.Value.Equals(origninalSheetId));
sheet.Id.Value = replacementPartId;
workbookPart.DeletePart(worksheetPart);
}
}
但是它拋出Out of memory
異常。 我需要batch oriented
方法,並且能夠append
數據append
到excel文檔的末尾。 不幸的是,我沒有找到如何使用OpenXML SDK
追加行。
另外,我用LoadFromCollection
方法檢查了EPPlus解決方案 。 它確實支持IDataReader
和LoadFromDataReader
但是我在代碼中沒有datareader。
問題:有沒有一種方法可以使用寫程序將數據附加到現有的工作表xls / xlsx文件中? 類似於OpenXML SDK
OpenXMLWrite
r。
UPD。 Excel顯然不支持1000萬行。 讓我們堅持1m行,並且列丟失而沒有內存不足異常。
UPD。 添加了EPPlus示例。 6分鍾內導出20萬行,最多占用1GB RAM。
private const string TempFile = @"C:\Users\vnechyp\Desktop\temp.xlsx";
private static void EPPlusExport()
{
var random = new Random();
var dt = new System.Data.DataTable();
for (int i = 0; i < 15; i++)
{
dt.Columns.Add($"column_{i}");
}
var values = Enumerable.Range(0, 15).Select(val => random.Next().ToString()).ToArray();
for (int i = 0; i < 10000; i++)
{
dt.Rows.Add(values);
}
using (ExcelPackage excelPackage = new ExcelPackage())
{
var workSheet = excelPackage.Workbook.Worksheets.Add("sheet");
workSheet.Cells[1, 1].LoadFromDataTable(dt, true);
excelPackage.SaveAs(new FileInfo(TempFile));
}
for (int i = 1; i < 50; i++)
{
Console.WriteLine($"Iteration: {i}");
var updateRow = i*10000;
Console.WriteLine($"Rows: {updateRow}");
FileInfo existingFile = new FileInfo(TempFile);
using (ExcelPackage excelPackage = new ExcelPackage(existingFile))
{
// get the first worksheet in the workbook
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
worksheet.Cells[updateRow, 1].LoadFromDataTable(dt, true);
excelPackage.SaveAs(new FileInfo(TempFile));
}
}
}
+-----------------+-----------+--------------+---------------------+
| | Max. Rows | Max. Columns | Max. Cols by letter |
+-----------------+-----------+--------------+---------------------+
| Excel 365* | 1,048,576 | 16,384 | XFD |
| Excel 2013 | 1,048,576 | 16,384 | XFD |
| Excel 2010 | 1,048,576 | 16,384 | XFD |
| Excel 2007 | 1,048,576 | 16,384 | XFD |
| Excel 2003 | 65,536 | 256 | IV |
| Excel 2002 (XP) | 65,536 | 256 | IV |
| Excel 2000 | 65,536 | 256 | IV |
| Excel 97 | 65,536 | 256 | IV |
| Excel 95 | 16,384 | 256 | IV |
| Excel 5 | 16,384 | 256 | IV |
+-----------------+-----------+--------------+---------------------+
您可以將csv文件用於一千萬行
假設CSV不夠,我最喜歡的導出到Excel的新方法是使用Open XML SDK。 下面的解決方案鏈接到Vincent Tom的一篇很棒的文章,內容涉及如何實現大數據導出,只是為新用戶提供了一些示例。
當我自己執行此操作時,基本上使用了Open XML Writer,並在IQueryable上為每個循環使用了一個。 永遠不要調用ToList(),否則您將不得不填充一個包含內存中所有數據的列表,這將使整個問題變得毫無用處。
例如,我已經使用這種技術導出了190,000多個記錄和87多個列的Excel文件,而我嘗試過的其他Excel庫都失敗了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.