J'utilise microsoft.office.interop.excel pour lire une feuille de calcul ouverte en mémoire.
gXlWs = (Microsoft.Office.Interop.Excel.Worksheet)gXlApp.ActiveWorkbook.ActiveSheet; int NumCols = 7; string[] Fields = new string[NumCols]; string input = null; int NumRow = 2; while (Convert.ToString(((Microsoft.Office.Interop.Excel.Range)gXlWs.Cells[NumRow, 1]).Value2) != null) { for (int c = 1; c <= NumCols; c++) { Fields[c-1] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)gXlWs.Cells[NumRow, c]).Value2); } NumRow++; //Do my other processing }
6 Réponses :
Il existe plusieurs options - toutes impliquent une bibliothèque supplémentaire:
P>
OpenXML 2.0 (bibliothèque libre de MS ) Peut être utilisé pour lire / modifier le contenu d'un fichier .xlsx afin de pouvoir le faire avec ce que vous voulez p> li>
Certaines bibliothèques 3RD-Parties sont livrées avec des contrôles de réseau vous permettant de faire beaucoup plus encore avec des fichiers Excel de votre application (IT WinForms / WPF / ASP.NET ...) comme tableur
, aspossible.cells etc. p> li>
ul>
Mais est-ce qu'il est probable d'être plus rapide?
Oui, c'est pourquoi je l'ai proposé, il accède au fichier sans utiliser Excel et sans les frais généraux de COM / Interop
Mais je veux accéder à une feuille de calcul ouverte en mémoire. Pour que je puisse le changer de manière interactive puis exécuter mon code à nouveau. Je pense que ce que vous suggère de lire le fichier sauvegardé de disque - ou je me trompe?
@Maninmoon - Vous devrez alors accepter que la lecture du fichier ouvert en mémoire va avoir des problèmes de performance. Vous n'avez pas indiqué combien de temps il faut pour lire 180 000 enregistrements.
Je suppose que ce n'est pas la source de "ralentissement" ...
En réalité, la récupération des valeurs de cellules est très lente. P>
Je pense que cette conversion n'est pas nécessaire: P> < Pré> xxx pré>
Ça devrait fonctionner sans cela. p>
et vous pouvez demander directement: p> Essayez de déplacer toute la plage Ou, au moins, la ligne entière à une matrice d'objet et travaille avec elle au lieu de la gamme elle-même. p> p>
Pendant que vous faites de bons points, rien de tout cela augmenterait la vitesse de son code. La conversion ne ralentit pas son code.
Louerait toute la gamme dans (une matrice de 180 000,7) être plus rapide? J'ai vu une référence à cela avec .get_range mais je ne suis pas sûr de la façon dont vous l'utiliseriez - des indices seraient formidables.
@Maninmoon - Ce ne serait pas plus rapide, cela aurait plus de sens, vous allez toujours être limité par la façon dont vous lisez le fichier.
Cela pourrait être plus rapide. S'il y a des frais généraux à chaque "lecture" du classeur ouvert. Je ne sais tout simplement pas comment l'utiliser.
Eh bien, la solution que vous avez montrée ci-dessus semble être ce que j'ai suggéré. Êtes-vous d'accord?
Je ne suis pas sûr que "Convertir" est efficace. Y a-t-il de toute façon je pourrais faire ce plus rapide? p> blockQuote>
Qu'est-ce qui vous fait croire cela? Je vous promets que
convert.tostring () strong> est la méthode la plus efficace dans le code que vous avez affiché. Votre problème est que votre boucle à travers 180 000 enregistrements dans un document Excel ... P> Vous pourriez diviser l'opération depuis que vous connaissez le nombre de lignes c'est un trival à faire. P>
Pourquoi couvrez-vous la valeur2 à une chaîne exactement? p>
@Maninmoon - Expliquez ce que vous entendez par cette déclaration. Vous comprenez que votre chaîne [] ne peut que 7 cordes juste? Votre code n'a donc pas beaucoup de sens si votre lecture de 180 000 enregistrements.
Où j'ai mis "// faire mon autre procèses" je traite avec chaque "rangée" séparément
Bonjour, j'ai trouvé un moyen très plus rapide.
Il est préférable de lire les données complètes en une fois à l'aide de "get_range". Ceci charge les données en mémoire et je peux boucler à travers cela comme un tableau normal. P>
Microsoft.Office.Interop.Excel.Range range = gXlWs.get_Range("A1", "F188000"); object[,] values = (object[,])range.Value2; int NumRow=1; while (NumRow < values.GetLength(0)) { for (int c = 1; c <= NumCols; c++) { Fields[c - 1] = Convert.ToString(values[NumRow, c]); } NumRow++; }
Qu'est-ce que Numrow ++ signifie?
Numrow ++ est identique à numrow = numrow + 1;
Vous avez utilisé "F188000". Dans mon cas, je ne sais pas combien de rangées seraient là. Que dois-je faire?
Vous pouvez accélérer la conversion à l'aide de array.copy () code>. Voir Stackoverflow.com/a/5083690/380384 . Bien sûr, cela dépend de ce que sont les contenus cellulaires. Sont-ils des chiffres ou des cordes?
Notez que le tableau 2-D résultant est (bizarrement) 1 à base de 1 à 0, malgré le fait qu'il ressemble à une matrice C # standard. Mais oui, c'est des ordres de grandeur plus rapidement que d'itération à travers les cellules sous-jacentes - merci.
Absolument fantastique ... sérieusement, le code qui a pris des minutes est fait en un clin d'œil.
@ user728630 Une autre méthode d'obtention de la plage de données est la suivante: Excel.excel.Range Datarange = Excelworksheet.ReçuRange; objet [] ExcelRangeValues = (objet []) Datarange.value2; var rowcount = datarange.rows.count + 1; var colonnecount = Datarange.columns.Count + 1; code>
Utilisez la méthode OLEDB code>. C'est le plus rapide comme suit;
J'ai trouvé un moyen vraiment rapide de lire Excel de ma manière spécifique. J'ai besoin de l'obtenir comme une éventail de chaîne en deux dimensions. Avec vraiment grand Excel, il a fallu environ une heure de vieille. De cette façon, je reçois mes valeurs en 20sec.
J'utilise cette nugget: https://reposhub.com/dotnet/office/exceldatareader-exceldatareader-exceldatareader.html p>
et voici mon code: p>
Savez-vous si vous êtes io lié ou cpu lié? Vous pouvez probablement paralleraliser ce code sur une machine multi-noyau / cpu.
Vous pouvez également faire une demande SQL sur une feuille de calcul Excel à l'aide de Ado.net. De cette façon, vous pouvez éviter de faire la boucle de temps. Voir Stackoverflow.com/questions/6789648/...