Open xml 使用具有 24 列的模板几乎在 8 分钟内将 24k 行写入 excel 文件。我必须提高这种性能,所以我必须找到错误的东西。模板文件会导致性能不佳。但它没有任何宏。导致性能不佳将是一个错误。但我还没有看到任何关于这个的错误。我需要你的帮助。如何使用 Open XMl 提高性能,或者您有任何建议,什么是将大数据写入 excel 的最佳库。
- 开放XML 2.5 .网络框架 4.5
工作表Part.Worksheet.Save();需要7分钟。
Stopwatch sw = new Stopwatch();
sw.Start();
FileInfo temp_excel_file = new FileInfo(Path.Combine(ConfigFile.ConfigsPaths["ExcelRaporFolder"], "temp", "Monitoring.xlsm"));
rapor_file = new FileInfo(Path.Combine(ConfigFile.ConfigsPaths["ExcelRaporFolder"], "excel", FileName + ".xlsm"));
File.Copy(temp_excel_file.FullName, rapor_file.FullName);
Log.LogYaz(rapor_file.Name + "-Excell Açılıyor..");
SpreadsheetDocument myDoc = SpreadsheetDocument.Open(rapor_file.FullName, true);
IEnumerable<Sheet> sheets = myDoc.WorkbookPart.Workbook.Descendants<Sheet>();
WorksheetPart worksheetPart = (WorksheetPart)myDoc.WorkbookPart.GetPartById(sheets.Skip(1).First().Id);
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
foreach (var row_index in filtered_data)
{
...
sheetData.AppendChild(Utils.CreateRow(row, 0, cell_data));
}
worksheetPart.Worksheet.Save();
myDoc.Close();
myDoc = null;
sw.Stop();
Open XML 有一个错误!Openxml 在超出缓冲容量时使用静态内存流。缓冲区BG容量是10 MB,我猜。所以当你在多线程中使用openxml时,会发生死锁。我不再在多线程中使用 open xml。
这可能有助于使用 Open XML 文件编写大型 Excel 文件,同时避免性能或内存不足异常。
尝试使用 OpenXML Writer。 它比简单的 foreach 语句更好。请看这里
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(filename, true))
{
//For Diagonostice Only
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
WorkbookPart workbookPart = spreadSheet.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
string origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);
WorksheetPart replacementPart = workbookPart.AddNewPart<WorksheetPart>();
string replacementPartId = workbookPart.GetIdOfPart(replacementPart);
OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
OpenXmlWriter writer = OpenXmlWriter.Create(replacementPart);
int rec = 0;
#region Looping through data
while (reader.Read())
{
if (reader.ElementType == typeof(SheetData))
{
if (reader.IsEndElement)
continue;
writer.WriteStartElement(new SheetData());
for (int row = 0; row < listData.Count; row++)
{
if (!string.IsNullOrEmpty(listData[row].WorkOrder))
{
Row newRow = new Row();
writer.WriteStartElement(newRow);
for (int col = 0; col < 5; col++)
{
Cell newCell = new Cell();
CellValue cellValue = new CellValue();
//assigning value
cellValue.Text = row.ToString();
//appending the value to cell
newCell.Append(cellValue);
writer.WriteElement(newCell);
}
writer.WriteEndElement();
}
}
writer.WriteEndElement();
}
else
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
#endregion
reader.Close();
writer.Close();
//replace the templateSheet with DataSheet.
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>()
.Where(s => s.Id.Value.Equals(origninalSheetId)).First();
sheet.Id.Value = replacementPartId;
workbookPart.DeletePart(worksheetPart);
}
尝试加载文件内容并将其写入内存流中,寻找开头并使用此内存流打开文档。保存操作后,您可以将内存流的内容写回文件。
我不确定它是否会对您有所帮助,但我自己正在打开 Word 中使用此序列。
检查 foreach 循环和 Utils.CreateRow(row, 0, cell_data) 函数所花费的时间。基于此,使用 Linq 优化代码。
谢谢!