Мне нужно экспортировать большое количество данных в Excel. Данные происходят из списка объектов. Данные различаются по размеру, но это может быть до 7000 столбцов и 20000 строк.
Я использую WPF в Visual Studio 2017 на ноутбуке с 24 гигабайтами оперативной памяти.
Приведенный ниже код генерирует исключение системы из памяти. Как я могу изменить приведенный ниже код для обработки экспорта больших данных в Excel?
public static void LargeExportTest(List<ExcelData> arrExport, string sDefaultPath)
{
string filename = sDefaultPath + "\\" + Path.GetRandomFileName() + ".xlsx";
UInt32 sheetId = 1;
try
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
//this list of attributes will be used when writing a start element
List<OpenXmlAttribute> attributes;
OpenXmlWriter writer;
document.AddWorkbookPart();
WorksheetPart workSheetPart = document.WorkbookPart.AddNewPart<WorksheetPart>();
writer = OpenXmlWriter.Create(workSheetPart);
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.Worksheet());
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.SheetData());
int batchCount = 0;
for (int rowNum = 0; rowNum <= arrExport.Count-1; ++rowNum)
{
int u = Convert.ToInt32(rowNum.ToString());
batchCount++;
//create a new list of attributes
attributes = new List<OpenXmlAttribute>();
// add the row index attribute to the list
attributes.Add(new OpenXmlAttribute("r", null, (rowNum + 1).ToString()));
//write the row start element with the row index attribute
writer.WriteStartElement(new Row(), attributes);
var MaxCol = arrExport[u].ColumnData.Max(x => x.ColumnNumber);
attributes = new List<OpenXmlAttribute>();
// add data type attribute - in this case inline string (you might want to look at the shared strings table)
attributes.Add(new OpenXmlAttribute("t", null, "str"));
//add the cell reference attribute
attributes.Add(new OpenXmlAttribute("r", "", string.Format(arrExport[u].Name)));
//write the cell start element with the type and reference attributes
writer.WriteStartElement(new Cell(), attributes);
//write the cell value
writer.WriteElement(new CellValue(string.Format(arrExport[u].Name)));
// write the end cell element
writer.WriteEndElement();
foreach (var col in arrExport[u].ColumnData)
{
//reset the list of attributes
attributes = new List<OpenXmlAttribute>();
// add data type attribute - in this case inline string (you might want to look at the shared strings table)
attributes.Add(new OpenXmlAttribute("t", null, "str"));
//add the cell reference attribute
attributes.Add(new OpenXmlAttribute("r", "", string.Format("{0}{1}", GetColumnName(col.ColumnNumber + 1), (rowNum + 1))));
//write the cell start element with the type and reference attributes
writer.WriteStartElement(new Cell(), attributes);
//write the cell value
writer.WriteElement(new CellValue(col.ColumnData.ToString()));
// write the end cell element
writer.WriteEndElement();
}
// write the end row element
writer.WriteEndElement();
if(batchCount > 150)
{
// write the end SheetData element
writer.WriteEndElement();
// write the end Worksheet element
writer.WriteEndElement();
// writer.Close();
//writer.WriteElement(new Sheet()
//{
// Name = "Large Sheet" + sheetId.ToString(),
// SheetId = sheetId,
// Id = document.WorkbookPart.GetIdOfPart(workSheetPart)
//});
sheetId++;
//////////////////////////////////////
writer = OpenXmlWriter.Create(workSheetPart);
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.Worksheet());
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.SheetData());
batchCount = 0;
}
}
// write the end SheetData element
writer.WriteEndElement();
// write the end Worksheet element
writer.WriteEndElement();
writer.Close();
writer = OpenXmlWriter.Create(document.WorkbookPart);
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.Workbook());
writer.WriteStartElement(new DocumentFormat.OpenXml.Spreadsheet.Sheets());
writer.WriteElement(new Sheet()
{
Name = "Large Sheet" + sheetId.ToString(),
SheetId = sheetId,
Id = document.WorkbookPart.GetIdOfPart(workSheetPart)
});
// End Sheets
writer.WriteEndElement();
// End Workbook
writer.WriteEndElement();
writer.Close();
document.Close();
}
}
catch (Exception ex)
{
throw ex;
}
}
Я ожидаю, что файл Excel будет сгенерирован без ошибок, но исключение из памяти
РЕДАКТИРОВАТЬ: я изменил код в попытке создать новый лист, если было обработано более 150 строк. Он не создает новую рабочую таблицу, поэтому код не работает. Новичок в OpenXml и не совсем уверен, как добавить новый лист. Предложения?