在网站上生成一个xslx文件的最好方法是什么? 可能有数百万行?

我的任务是编写一个解决scheme来修复性能不佳的传统Excel文件生成器。

我需要生成的文件可能会变得非常大。 也许高达一百万行,40-50列。 我想如果可能的话,我会直接stream式传输给用户,但是我可能只需要先将文件保存到磁盘,然后为用户创build一个链接。

我的目标是做一个性能testing,testing是否可以生成一个包含1.500.000行和50列的xslx文件,每个单元格包含一个随机的10个字母的string…即使处理文件这么大,

注意事实上,大多数文件的生成绝不会超过300.000行,绝对最大值是大约950.000行,但是在压力testing时,我喜欢玩150M行。

你有什么build议,我应该如何去解决这个任务。 我应该注意哪些组件? excel的限制?

PS:如果我不必在服务器上安装Excel,我将不胜感激。

您可以在电子表格中使用的行数是有限制的( Office 2007为1M )。 我会生成一个CSV文件,这实际上只是一个格式化的文本文件,可以在Excel中打开。

Excel 2007支持1,048,576行16,384列的最大工作表大小,因此您的150万行的testing可能不可行。 资源

编辑:Excel 2003支持更less的行:65,536行乘256列。 资源

如果您能够要求您的用户能够以Excel 2007(xlsx)格式打开文档,那么这可能是您最好的select,因为它只是一个XML文档,可以在服务器上不需要任何Excel的情况下生成。

如果您需要支持“所有”版本的Excel /其他办公套件程序,您应该使用CSV或其他字符分隔的格式。

开放文档格式也可能是有趣的,但Excel用户需要ODF插件来使用文档。

编辑2:如果您正在使用CSV,您可能需要查看FileHelpers库。

尽pipe我无法回答Excel可以处理的最大数据量,但如果使用新的.xlsx格式,则使用MS的OpenXML格式。 .xlsx文件实际上是一个压缩文件,内部存储了所有文档数据。 XML可以像其他任何XML一样书写,但是您必须查看标准。 这里有一些商业组件的实现。 您不需要Excel来编写格式。

这里有一些有用的链接:

  • Office OpenXML – 维基百科
  • Office Open XML C#库 – 这看起来像一个用于读/写OpenXML的开源库
  • 读取和写入Open XML文件 – CodeProject – R / W库的另一个实现
  • GemBox.Spreadsheet – 用于读写Office电子表格的商业.NET组件。 有一个免费版本,你可以读写的行数有限制,如果你想尝试一下。
  • NPOI库 – 用于阅读和编写office文档的Java POI库的实现。
  • 简单的OOXML – “一套助手类,使Open Office XML文档的创build更容易,使用Open Office SDK 2.0,修改或创build任何.docx或.xlsx文档,无需Microsoft Word或Microsoft Excel。

确保您的testing代表实际数据。 Excel比简单的文本单元格更有效地处理简单的数字单元格 – 特别是当所有文本单元格都是唯一的时候。 所以,如果你的数据真的要由10个字符的唯一string组成,那么一定要用它作为你的testing用例。 如果它实际上主要是数字,确保你的testing反映了这个事实。

例如。 我使用SpreadsheetGear for .NET构build了一个简单的testing,通过50列Open XML(.xlsx)工作簿生成一个300,000行。 创build和保存到具有唯一编号的磁盘花了13.62秒,在我近乎两年的超频QX6850 CPU上创build和保存30万行50列.xlsx工作簿与10个字符的唯一string花费了78秒 – 文本长度的6倍数字。 我将粘贴下面的代码,你可以运行免费的SpreadsheetGear试用版,你可以在这里下载。

需要注意的是,Open XML(.xlsx)是压缩的,所以如果你的数据有很多的冗余,那么使用.xlsx的文件比.csv文件要小。 如果您要在networking服务器上生成工作簿,以便在networking上使用,这可能会对性能产生重大影响。

SpreadsheetGear与IWorkbook.SaveToStream方法以及大多数其他第三方Excel兼容库将允许您直接保存到ASP.NET应用程序中的响应stream中,这样您就可以避免保存到服务器上的磁盘上。

免责声明:我自己的SpreadsheetGear LLC

这里是testing代码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using SpreadsheetGear; namespace ConsoleApplication11 { class Program { static void Main(string[] args) { var timer = System.Diagnostics.Stopwatch.StartNew(); int rows = 300000; int sheets = 1; var workbook = Factory.GetWorkbook(); var sb = new System.Text.StringBuilder(); int counter = 0; bool numeric = true; for (int sheet = 0; sheet < sheets; sheet++) { // Use the SpreadsheetGear Advanced API which is faster than the IRange API. var worksheet = (sheet == 0) ? workbook.Worksheets[0] : workbook.Worksheets.Add(); var values = (SpreadsheetGear.Advanced.Cells.IValues)worksheet; for (int row = 0; row < rows; row++) { for (int col = 0; col < 50; col++) { if (numeric) values.SetNumber(row, col, ++counter); else { sb.Length = 0; // Make a 10 character unique string. sb.Append(++counter); System.Diagnostics.Debug.Assert(sb.Length <= 10); // Make it 10 characters long. while (sb.Length < 10) sb.Append((char)('A' + (char)sb.Length)); values.SetText(row, col, sb); } } } } Console.WriteLine("Created {0} cells in {1} seconds.", counter, timer.Elapsed.TotalSeconds); workbook.SaveAs(@"C:\tmp\BigWorkbook.xlsx", FileFormat.OpenXMLWorkbook); Console.WriteLine("Created and saved {0} cells in {1} seconds.", counter, timer.Elapsed.TotalSeconds); } } } 

您可能需要查看NPOI库,以便在http://npoi.codeplex.com/上阅读和编写excel文件&#x3002; 至于在服务器上存储是一个选项,但记住,你将不得不清理后,下载的文件。

看看Codeplex上的Simple OOXML项目。

这可能是你在找什么。

PS。 Excel主要是电子表格软件,没有数据库替代品。 您确定要将一百万行转储给最终用户吗?

Excel无法处理数百万行,请尝试创buildCSV输出文件,这可以通过Excel读取。

而且不build议在用户请求的excel中添加大量的数据。在下载文件之前,他需要等待很长时间。

假设您可以避免超出Excel 2007中的新行限制(通过拆分到其他工作表或文件),Excel 2007的xlsx格式应该可以正常工作。

由于XLSX是一种zip格式,而不是在内存中创build或写入磁盘,所以应该考虑直接写入内存中的zipstream。 压缩将保持内存使用率低,不写入文件系统将有助于性能。

另一个可能的解决scheme,根据您的情况:创build一个空白的Access模板,复制并写入,并发送它而不是Excel文件。 当然,这将是您的应用程序的转变,但Access不会有相同的行限制。