把大量的数据写入excel c#

我需要从数据库表中导出大量的数据到excel(xls / xlsx)文件。 它可能很容易1000万行和更多。

我需要不需要安装Office的开源解决scheme(SpreadsheetGear和Interop解决scheme不适用于我)。

我正在检查两个库: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 memoryexception。 我需要batch oriented方法,并能够append数据append到Excel文档的末尾。 不幸的是,我没有find如何使用OpenXML SDK追加行。

另外,我用LoadFromCollection方法检查了EPPlus soluion 。 它确实支持与LoadFromDataReader IDataReader ,但我没有在代码中的数据读取器。

问题是有没有办法将数据附加到现有的工作表xls / xlsx文件与作家的types? 像OpenXML SDK OpenXMLWrite一样。

UPD。 Excel显然不支持1000万行。 让我们坚持1m行,丢失的列没有内存不足的例外。

UPD。 添加了EPPlus示例。 在6分钟内输出200k行,并占用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文件用于1000万行

假设CSV是不够的,我最喜欢导出到Excel的方式是使用Open XML SDK。 下面的解决scheme链接到文森特汤姆伟大的文章,如何实现一个大的数据导出,只是他的样本稍微清理新用户。

将大数据查询(60k +行)导出到Excel

当我自己做这件事的时候,我基本上使用了一个Open XML Writer和一个IQueryable上的每个循环。 永远不要调用ToList(),否则你将不得不填充一个包含内存中所有数据的列表,这将破坏整个点。

例如,我使用这种技术导出了Excel文件,其中190,000个logging和87个列,其中我试过的其他Excel库都失败了。