如何在Open XML SDK中有效地caching和刷新stream

我使用OpenXML SDK 2.0生成大量数据的Excel文件,appox。 1000000行,我需要优化内存使用,因为我的机器速度非常快。

我想通过在运行时将部分生成的DOM树清空到文件来解决这个问题。 我做我自己的数据缓冲。 例如,我有100000条logging要写入,并且当我向Excel工作表中添加1000行时,我想要刷新到文件stream。 我通过使用方法worksheetPart.Worksheet.Save()来做到这一点。 Documantation说这个方法是Save():“把DOM树中的数据保存回部分,也可以多次调用,每次调用时,都会刷新stream。

foreach (Record m in dataList) { Row contentRow = CreateContentRow(index, m); // my own method to create row content //Append new row to sheet data. sheetData.AppendChild(contentRow); if (index % BufferSize == 0) { worksheetPart.Worksheet.Save(); } index++; } 

这种方法的工作原理是内存使用graphics看起来很不舒服,内存隐约增长。

有没有人有任何想法如何解决这个问题?

SpreadsheetGear for .NET可以在74秒内创build一个具有1,000,000行,40列随机数(即4000万个单元格)的xlsx工作簿(包括在随机数字的内存中创build工作簿,并通过超频的Intel QX 6850和Windows Vista 32)。

您使用Open XML SDK看到了什么样的性能?

您可以在这里下载SpreadsheetGear的免费试用版,并自行试用。

我将通过代码生成下面的4000万个单元工作簿。

免责声明:我自己的SpreadsheetGear LLC

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using SpreadsheetGear; namespace ConsoleApplication10 { class Program { static void Main(string[] args) { try { // Run once with 100 rows and then run forever with 1,000,000 rows. for (int rows = 100; rows <= 1000000; rows = 1000000) { Console.Write("rows={0}, ", rows); var startMemory = System.GC.GetTotalMemory(true); var timer = System.Diagnostics.Stopwatch.StartNew(); var workbook = BuildWorkbook(rows); var usedMemory = System.GC.GetTotalMemory(true) - startMemory; Console.WriteLine("usedMemory={0}, time={1} seconds, workbook.Name={2}", usedMemory, timer.Elapsed.TotalSeconds, workbook.Name); workbook = null; } } catch (Exception e) { Console.WriteLine("got exception={0}", e.Message); } } static IWorkbook BuildWorkbook(int rows) { var workbook = Factory.GetWorkbook(); var worksheet = workbook.Worksheets[0]; var values = (SpreadsheetGear.Advanced.Cells.IValues)worksheet; Random rand = new Random(); int cols = 40; for (int col = 0; col < cols; col++) { for (int row = 0; row <= rows; row++) { values.SetNumber(row, col, rand.NextDouble()); } } workbook.SaveAs(string.Format(@"c:\tmp\Rows{0}.xlsx", rows), FileFormat.OpenXMLWorkbook); return workbook; } } } 

对于编写大型Excel文件的任务,“缓冲区和刷新”有相反的方法。 该方法基于使用OpenXmlWriter类,并使用顺序写入,而不是缓冲和刷新。 一个典型的解决scheme还使用replace部分和OpenXmlReader来从模板中获取不变的内容。 查看“使用Open XML SDK编写大型Excel文件” (附带一些代码示例)和“编写大型OpenXML文档” (完整的代码示例)。