標準のMicrosoft.Office.Interop.Excelを使用して、1200 X 800マトリックス(indexMatrix)をExcelファイルにエクスポートしています。アプリは動作しますが、実際には本当に本当に遅いです(100 x 100マトリックスでも)。また、TextWriterを使用してテキストファイルをエクスポートすると、ほぼ瞬時に動作します。 Excelファイルにすばやくエクスポートする方法はありますか?
ここに私のコードがあります:
Excel.Application xlApp=new Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
//xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int i = 0; i < 800; i++) //h
for (int j = 0; j < 1200; j++)
xlWorkSheet.Cells[i+1,j+1] =indexMatrix[i][j];
xlWorkBook.SaveAs("C:\\a.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Excel file created , you can find the file c:\\csharp-Excel.xls");
個々のセルを更新しています。それは非常に遅くなります。考えてみると、セルを更新するたびに、RPC呼び出しがExcelプロセスにマーシャリングされます。
現在の1200 x 800 = 960,000のクロスではなく、単一のステートメント(1つのクロスプロセス呼び出し)で同じ次元のExcel範囲に値の2次元配列を割り当てると、muchより高速になります。プロセス呼び出し。
何かのようなもの:
// Get dimensions of the 2-d array
int rowCount = indexMatrix.GetLength(0);
int columnCount = indexMatrix.GetLength(1);
// Get an Excel Range of the same dimensions
Excel.Range range = (Excel.Range) xlWorkSheet.Cells[1,1];
range = range.get_Resize(rowCount, columnCount);
// Assign the 2-d array to the Excel Range
range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, indexMatrix);
実際には、上記のコードには3つのプロセス間呼び出し(.Cells、.get_Resizeおよび.set_Value)があり、コードの反復ごとに2つの呼び出し(.Cells getおよび暗黙的な.set_Value)があります。合計1200 x 800 x 2 = 1,920,000。
注range.get_Resize
およびrange.set_Value
は、この投稿が最初に作成されたときに使用していた古いバージョンのExcel相互運用ライブラリに必要でした。最近ではrange.Resize
およびrange.Value
@ The1nkのコメントに記載されているとおり。
Excelの相互運用が高速になることはありません。基本的に、Excelアプリケーションのインスタンスをリモート制御しています。 CSVファイルを作成し、Excel相互運用機能を使用してこれを.xlsまたは.xlsxファイルに変換すると、さらに成功する可能性があります。
非常に大きなExcelファイルを読み取るときに同様の問題が発生し、相互運用を使用して2時間以上かかりました。
ClosedXmlを使用してみましたが、処理に10秒もかかりませんでした。 ClosedXml
// To loop
Sheet.Row(y).Cell(x).Value
また、Excelがインストールされていない限り、サーバーで相互運用が機能しないことに注意してください。 ClosedXmlにはExcelをインストールする必要はありません。
データを書き込む前にScreenUpdating
をオフにします、Application.ScreenUpdating = FALSE
その後、コードの最後でオン= TRUE
Value2を使用して高速化します。データを入力する前にExcelを表示する
ClosedXMLは奇跡であり、非常に高速で使いやすいです。
var workbook = new XLWorkbook();//create the new book
var worksheet = workbook.Worksheets.Add("Computer Install");// Add a sheet
worksheet.Cell(1,1).Value = "PC Name";// (Row, column) write to a cell
workbook.SaveAs(@"LIC documents.xlsx");// Save the book
Nu Getパッケージを使用してインストールします。 https://www.nuget.org/packages/ClosedXML
これを行うには3つの方法があり、そのうち2つは他の人による異なる回答で言及されています。
上記の3つの方法はすべて非常に高速です。約6秒で90000行と100列のサイズのデータを書き込むことができました。
追伸ただし、境界線、フォントスタイル、色、セルマージなどのデータの書式設定に関する問題は解決しませんでした。