提问人:Lucy82 提问时间:10/13/2023 更新时间:10/13/2023 访问量:46
OpenXML - 在不消耗内存的情况下编辑大型 Excel 文件
OpenXML - Edit large Excel file without memory drain
问:
我正在使用 SAX 方法直接使用 DataReader(无内存中)写入 .xlsx 文件,这效果很好。但我也希望 Excel 文件中的列是自动调整的。
使用 SAX 方法意味着直接使用 OpenXmlWriter 编写 .xlsx 文件,不幸的是,仅在一个方向上(在 xml 树上)。由于 xml 顺序,列必须在实际数据之前写入,这意味着我无法计算它们的宽度,因为 DataReader 尚未打开。
过去,我通过执行两次DataReader来实现自动调整 - 第一次用于搜索最长的字符串以计算列宽,然后用于将实际数据写入.xlsx文件。这在编写大文件时很耗时,所以我对此不满意。
我看到的唯一选项是编辑 .xlsx 文件,但我找不到任何 SAX 方法。
我设法使用下面的方法进行自动调整,但是当 Linq 参与其中时,它会消耗巨大的内存(2Mb 文件需要 300GB 内存,大约 1 mio 行):
private void Autofit(string _filename)
{
using (SpreadsheetDocument Excel = SpreadsheetDocument.Open(_filename, true))
{
foreach (var wp in Excel.WorkbookPart.WorksheetParts)
{
//This line drains 2GB memory, tested on 1 mio rows for .xlsx file
var sd = wp.Worksheet.Descendants<SheetData>().First();
var cs = new Columns();
uint Col_index = 1;
//MaxText is List<string>, containing longest strings of each column
foreach (var longest_string in MaxText)
{
//CalculateWidth is a method for calculating column width
double cell_width = CalculateWidth(new System.Drawing.Font("Arial", 10), longest_string) + 1.5;
Column c = new Column { Min = Col_index, Max = Col_index, Width = cell_width, CustomWidth = true };
cs.Append(c);
Col_index++;
}
wp.Worksheet.InsertAfter(cs, sd);
}
}
}
我还有什么可以尝试使用 OpenXml 的吗?或者也许是 xlst 转换,XStreamingElement ?或者我可以修复上层 Linq 方法以不消耗此类内存? 任何示例或链接将不胜感激。
答: 暂无答案
评论
DataReader