データベーステーブルからたくさんのデータをexcel(xls/xlsx)ファイルにエクスポートする必要があります。 簡単に10万行以上になる可能性があります。大量のデータを書き出してCをエクセルする#
私はOfficeをインストールする必要のないオープンソースのソリューションが必要です(SpreadsheetGearとinteropソリューションは私のためには機能しません)。
OpenXML SDKとEPPlusの2つのライブラリを確認しています。 OpenXMLのSDKについては
私はこの方法が見つかりました:
private static void Write(string fileName, int numRows, int numCols)
{
using (var spreadsheetDocument = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
string origninalSheetId = workbookPart.GetIdOfPart(worksheetPart);
WorksheetPart replacementPart = workbookPart.AddNewPart<WorksheetPart>();
string replacementPartId = workbookPart.GetIdOfPart(replacementPart);
using (OpenXmlReader reader = OpenXmlReader.Create(worksheetPart))
{
using (OpenXmlWriter writer = OpenXmlWriter.Create(replacementPart))
{
Row row = new Row();
Cell cell = new Cell();
//CellFormula cellFormula = new CellFormula();
//cellFormula.CalculateCell = true;
//cellFormula.Text = "RAND()";
//cell.Append(cellFormula);
CellValue cellValue = new CellValue("val val");
cell.Append(cellValue);
while (reader.Read())
{
if (reader.ElementType == typeof(SheetData))
{
if (reader.IsEndElement)
continue;
writer.WriteStartElement(new SheetData());
for (int rowNumber = 0; rowNumber < numRows; rowNumber++)
{
writer.WriteStartElement(row);
for (int col = 0; col < numCols; col++)
{
writer.WriteElement(cell);
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
else
{
if (reader.IsStartElement)
{
writer.WriteStartElement(reader);
}
else if (reader.IsEndElement)
{
writer.WriteEndElement();
}
}
}
}
}
Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().First(s => s.Id.Value.Equals(origninalSheetId));
sheet.Id.Value = replacementPartId;
workbookPart.DeletePart(worksheetPart);
}
}
をしかし、それはOut of memory
例外がスローされます。 私はbatch oriented
アプローチが必要であり、Excel文書の最後にappend
データを入力できるようにする必要があります。 残念ながら、OpenXML SDK
で行を追加する方法が見つかりませんでした。
また、EPPlus soluionをLoadFromCollection
の方法でチェックしました。 とIDataReader
をサポートしていますが、コードのその時点でdatareaderがありません。
質問:ライターのような既存のシートxls/xlsxファイルにデータを追加する方法はありますか? OpenXMLWrite
rのようにOpenXML SDK
にあります。
UPD。 Excelは明らかに1000万行をサポートしていません。メモリ不足の例外を除いて、1mの行と列を失いたくない。
UPD。 EPPlusサンプルが追加されました。 200k行は6分でエクスポートされ、最大1GBのRAMが必要です。
private const string TempFile = @"C:\Users\vnechyp\Desktop\temp.xlsx";
private static void EPPlusExport()
{
var random = new Random();
var dt = new System.Data.DataTable();
for (int i = 0; i < 15; i++)
{
dt.Columns.Add($"column_{i}");
}
var values = Enumerable.Range(0, 15).Select(val => random.Next().ToString()).ToArray();
for (int i = 0; i < 10000; i++)
{
dt.Rows.Add(values);
}
using (ExcelPackage excelPackage = new ExcelPackage())
{
var workSheet = excelPackage.Workbook.Worksheets.Add("sheet");
workSheet.Cells[1, 1].LoadFromDataTable(dt, true);
excelPackage.SaveAs(new FileInfo(TempFile));
}
for (int i = 1; i < 50; i++)
{
Console.WriteLine($"Iteration: {i}");
var updateRow = i*10000;
Console.WriteLine($"Rows: {updateRow}");
FileInfo existingFile = new FileInfo(TempFile);
using (ExcelPackage excelPackage = new ExcelPackage(existingFile))
{
// get the first worksheet in the workbook
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
worksheet.Cells[updateRow, 1].LoadFromDataTable(dt, true);
excelPackage.SaveAs(new FileInfo(TempFile));
}
}
}
私はこれを「チュートリアルを探しています」と票決しました。私はEPPlusをこのタイプの操作に数回使用しました。彼らのウェブサイトには、既存のワークシートへの書き込みを続ける例がたくさんあります。あなたの問題は、あまりにも多くのデータをメモリに保存して一度にダンプするということです。ドキュメントを見続けるだけです。 – krillgar
Excelは、そのサイズのデータセットに適したコンテナではありません。 –
@krillgarドキュメントを確認していただきありがとうございます。最後に私は何も見つけませんでした – makambi