我有一个 500mb 的 excel (.xlsb/.xlsm) 文件。我需要一种使用 C# 读取/写入/修改大型 (.xlsb/.xlsm) 文件的方法,而无需将整个文件加载到内存中,而是以块的形式加载它,或者至少一次加载一张纸。
2 回答
Excel 文件本质上是包含 XML 文件的 zip 文件。如果您使用任何 zip 工具打开一个 excel 文件,您将看到该 excel 文档的内容。你需要修改的是:
xl/sharedStrings.xml - excel通过在这个文件中索引它们来优化字符串的使用(不是视觉上的,但你可以将它们迭代到最后并计数——第一个索引为0,第二个索引为1,依此类推。 ..)。使用这些索引来更改/添加工作表文件中的字符串,以免损坏文档。
xl/workbook.xml - 包含工作表的名称。例如,您可以在 Excel 中发现 sheet1 名为“This Months' Income”。如果愿意,可以使用它按名称查找工作表。
xl/worksheets/*.xml - 这是您的实际工作表。要更改/添加字符串,请使用共享字符串 XML 文件。要更改/添加数字,请直接执行。包含共享字符串值的单元格被标记为这样。
现在您只需要在逐行读取它们的同时解析/编辑这些 XML 文件,而不是将整个文件加载到内存中,您将能够以非常少的内存占用处理大量数据。
在 C# 中,我使用 ZipArchive 来临时提取我需要的文件,编辑它们,然后更新 zip。不要提取所有内容然后再次压缩,因为您会损坏文件。至少我不知道如何压缩它以使其再次可用。
我的基于 Mit 许可库编写 xlsb 的建议
c#代码:
using Sylvan.Data.Csv;
using SpreadSheetTasks;
using var csv = CsvDataReader.Create(@"C:\test\file.csv");
csv.Read();
using (XlsbWriter xlsb = new XlsbWriter(@"C:\test\file.xlsb"))
{
xlsb.AddSheet("sheetName");
xlsb.WriteSheet(csv);
}
disclimer - 我是 SpreadSheetTasks Link的创建者