Microsoft.Bureau de.Interop.Excel vraiment lent
Je suis de l'exportation d'un 1200 X 800 matrice (indexMatrix) à un fichier excel en utilisant le standard de Microsoft.Bureau de.Interop.Excel. L'application fonctionne, c'est juste que c'est vraiment vraiment vraiment lent( même pour l'100 x 100 de la matrice) . J'ai également exporter dans un fichier texte par le biais d'un TextWriter un il fonctionne presque instantanément . Est-il possible d'exporter le fichier excel plus vite?
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 devez vous connecter pour publier un commentaire.
Vous êtes à la mise à jour des cellules individuelles. Ça va être très lent. Si vous pensez à ce sujet, à chaque fois que vous mettez à jour une cellule, un appel RPC sera convoquée pour le processus Excel.
Il sera beaucoup plus vite si vous assignez votre tableau à deux dimensions des valeurs d'une Plage Excel de mêmes dimensions en une seule instruction (un processus d'appel) à la place de votre 1200 x 800 = 960,000 de la croix-traiter les appels.
Quelque chose comme:
En fait, pour être pédant, il y a trois croix-traiter les appels dans le code ci-dessus (.Les cellules, .get_Resize et .set_Value), et il y a deux appels par itération dans votre code (.Les cellules sont et implicite .set_Value) pour un total de 1200 x 800 x 2 = 1,920,000.
Note
range.get_Resize
etrange.set_Value
ont été nécessaires pour une ancienne version d'Excel bibliothèque d'interopérabilité j'ai été en utilisant lors de ce post a été rédigé. Ces jours, vous pouvez utiliserrange.Resize
etrange.Value
comme indiqué dans le commentaire de @The1nk.get_Resize
ouset_Value
. Il vous suffit d'utilisercell.Resize
etcell.Value
comme d'habitude.Excel interopérabilité n'est jamais va être rapide. Vous avez en gros de commander à distance une instance de l'application Excel. Vous pourriez avoir plus de succès par la création d'un fichier CSV, puis à l'aide d'Excel interop convertir cette .xls ou .fichier xlsx
TextWriter
classe peut s'en occuper.J'ai eu des problèmes similaires lors de la lecture d'un très gros fichier excel et il a fallu plus de 2 heures à l'aide d'interop.
J'ai essayé d'utiliser ClosedXml et le processus a pris moins de 10 secondes.
ClosedXml
Aussi garder à l'esprit l'interopérabilité ne fonctionnera pas sur votre serveur, sauf si vous avez excel installé. ClosedXml n'a pas besoin d'excel est installé.
Désactiver
ScreenUpdating
avant d'écrire,Application.ScreenUpdating = FALSE
puis allumez à la fin du code= TRUE
Utilisation Valeur2 pour le faire rapidement;
Montrer excel avant de les remplir de données
ClosedXML est un miracle, c'est beaucoup plus rapide et plus facile à utiliser.
Vous installer à l'aide d'un nu pour faire passer un paquet.
https://www.nuget.org/packages/ClosedXML
Il y a trois façons de le faire, 2 sont cités dans les différentes réponses données par les autres:
Toutes 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 de l'ordre de 6 secondes.
P. S. Ils n'ont cependant pas de résoudre mon problème de mise en forme les données pour les bordures, les styles de polices, les couleurs, les cellules de la fusion etc.