J'exporte une matrice 1200 X 800 (indexMatrix) vers un fichier Excel à l'aide de la norme Microsoft.Office.Interop.Excel. L'application fonctionne, mais c'est vraiment très lente (même pour la matrice 100 x 100). J'exporte également dans un fichier texte via TextWriter et cela fonctionne presque instantanément. Est-il possible d'exporter le fichier Excel plus rapidement?
Voici mon code:
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");
Vous mettez à jour des cellules individuelles. Cela va être très lent. Si vous y réfléchissez, chaque fois que vous mettez à jour une cellule, un appel RPC est organisé dans le processus Excel.
Il sera beaucoup plus rapide si vous affectez votre tableau de valeurs à deux dimensions à une plage Excel de mêmes dimensions dans une seule instruction (un appel entre processus) à la place de vos 1 200 x 800 = 960 000 appels actuels entre processus. .
Quelque chose comme:
// 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);
En fait, pour être pédant, il existe trois appels inter-processus dans le code ci-dessus (.Cells, .get_Resize et .set_Value), et il y a deux appels par itération dans votre code (.Cells get et un .set_Value implicite) total de 1200 x 800 x 2 = 1 920 000.
Remarque range.get_Resize
et range.set_Value
étaient nécessaires pour une ancienne version de la bibliothèque d'interopérabilité Excel que j'utilisais au moment de la création de ce message. Ces jours-ci, vous pouvez utiliser range.Resize
et range.Value
comme indiqué dans le commentaire de @ The1nk.
L'interopérabilité Excel ne sera jamais rapide. Vous contrôlez à distance une instance de l'application Excel. Vous pouvez avoir plus de succès en créant un fichier CSV puis en utilisant Excel interop pour convertir ceci en un fichier .xls ou .xlsx
J'ai eu des problèmes similaires lors de la lecture d'un fichier Excel extrêmement volumineux et cela a pris plus de 2 heures avec interop.
J'ai essayé d'utiliser ClosedXml et le processus a pris moins de 10 secondes . ClosedXml
// To loop
Sheet.Row(y).Cell(x).Value
Gardez également à l'esprit que l'interopérabilité ne fonctionnera pas sur votre serveur si vous n'avez pas installé Excel. ClosedXml n'a pas besoin d'Excel installé.
Désactivez ScreenUpdating
avant d'écrire des données, Application.ScreenUpdating = FALSE
, puis activez-le à la fin du code = TRUE
Utilisez Value2 pour le rendre rapide; Afficher Excel avant de remplir les données
ClosedXML est un miracle, il est beaucoup plus rapide et facile à utiliser.
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
Vous installez en utilisant un package Get Get. https://www.nuget.org/packages/ClosedXML
Il y a trois façons de le faire, dont 2 sont mentionnées dans différentes réponses par d'autres:
Les trois méthodes ci-dessus sont très rapides. Je pourrais écrire des données avec une taille de 90000 lignes et 100 colonnes en environ 6 secondes.
P.S. Ils n'ont toutefois pas résolu mon problème de formatage des données pour les bordures, les styles de police, les couleurs, la fusion de cellules, etc.