2017-07-28 1 views
0

Je cherche donc une méthode d'insertion plus rapide dans des tableurs sur un serveur. À l'heure actuelle, cela dépend des données utilisées, mais il faut environ 20 secondes pour insérer 100 lignes dans une seule feuille de calcul. Je comprends pourquoi c'est le cas, car l'insertion dans une feuille de calcul entraîne Excel à déplacer les lignes chaque fois qu'une nouvelle ligne est insérée. Ainsi, plus il y a de lignes ajoutées à une feuille de calcul, plus cela prendra de temps. J'ai testé cette théorie et c'était correct, j'ai créé environ 100 feuilles de calcul et inséré aléatoirement 1000 lignes réparties entre eux. Cela a pris environ 60 secondes pour terminer. L'insertion des mêmes 1000 lignes dans une seule feuille de calcul prenait plus de 5 minutes à compléter. Voici mon code ci-dessous:Une méthode plus rapide pour insérer des lignes dans une feuille de calcul Excel en C# en utilisant oleDbCommand?

string connectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;" + 
          "Data Source={0};Extended Properties='Excel 12.0;HDR=YES'", file); 
      Aspose.Cells.Workbook wb = new Aspose.Cells.Workbook(fileTemplate); 
      Aspose.Cells.WorksheetCollection sheets = wb.Worksheets; 
      Aspose.Cells.Worksheet sheet = wb.Worksheets[0]; 

     wb.Save(file); 

      combinedCount = 0; 
      counter = 0; 
      foreach (DataRowView drv in view)//check each row in our simplified view for ebid 
      { 
       if (combinedList[combinedCount][1] == "") //if its empty it goes into brandies sheet 
       { 

        sheet.Cells.InsertRow(2); 
        using (OleDbConnection cn = new OleDbConnection(connectionString)) 
        { 
         cn.Open(); 
         OleDbCommand cmd1 = new OleDbCommand("INSERT INTO [" + combinedList[combinedCount][0] + "$] " + //"+sheetCnt+" 
          "([Reporting Retailer EBID],[Outlet BASF ID],[Retailer OT],[Mapped Grower ID],[Mapped Grower],[Ship To Grower],[Bill To Grower],[Transaction ID],[Product ID],[Product Description],[Quantity],[Invoice No],[Previously Sent],[Comments])" + 
          "VALUES(@value1,@value2,@value3,@value4,@value5,@value6,@value7,@value8,@value9,@value10,@value11,@value12,@value13,@value14)", cn); 
         cmd1.Parameters.AddWithValue("@value1", drv[0]);//retailer ebid 
         cmd1.Parameters.AddWithValue("@value2", drv[1]);//outlet basf 
         cmd1.Parameters.AddWithValue("@value3", drv[13]);//retailer ot 
         cmd1.Parameters.AddWithValue("@value4", drv[2]);//mapped g id 
         cmd1.Parameters.AddWithValue("@value5", drv[10]);//mapped g 
         cmd1.Parameters.AddWithValue("@value6", drv[11]);//ship to g 
         cmd1.Parameters.AddWithValue("@value7", drv[12]);//bill to g 
         cmd1.Parameters.AddWithValue("@value8", drv[3]);//trans id 
         cmd1.Parameters.AddWithValue("@value9", drv[4]);//prod id 
         cmd1.Parameters.AddWithValue("@value10", drv[5]);//prod desc 
         cmd1.Parameters.AddWithValue("@value11", drv[6]);//quantity 
         cmd1.Parameters.AddWithValue("@value12", drv[7]);//invoice no 
         cmd1.Parameters.AddWithValue("@value13", drv[8]);//prev sent 
         cmd1.Parameters.AddWithValue("@value14", drv[9]);//comments 
         cmd1.ExecuteNonQuery(); 
         cn.Close(); 
        } 
       } 
      } 
+1

Copie possible de [Quel est le moyen le plus rapide d'insérer 100 000 enregistrements dans un fichier MDB en C#] (https://stackoverflow.com/questions/21850137/what-is-the-fastest-way-to-insert -100-000-enregistrements-en-un-mdb-fichier-en-c-sharp) –

+1

N'a pas fait cela depuis un certain temps, mais je me souviens que le moyen le plus rapide que j'ai trouvé pour obtenir beaucoup de données dans Excel rapidement, était pour mettre en place une table de données dans une feuille contenant toutes les données, puis utiliser le tableau croisé dynamique dans d'autres feuilles pour extraire les données que je voulais. Cela a pris quelques secondes plutôt que des minutes –

+0

@JonathanWillcock Mon problème n'est pas avec les feuilles. Existe-t-il un moyen de spécifier la «prochaine rangée» dans un sens? Je cherchais à INSERT INTO ["+ combinedList [combinedCount] [0] +" $ a5: g] ou quelque chose comme ça – triswill227

Répondre

0

J'ai trouvé comment le réduire énormément. Comme je l'ai déjà dit, l'insertion dans la fonction provoque un encombrement lors du traitement de grands ensembles de données. Donc, ciblez chaque cellule et utilisez la fonction putvalue. Par exemple:

   combinedCount = 0; 
       counter = 0; 
       int testCount = 2; 
       foreach (DataRowView drv in view) 
        { 
         if (combinedCount != 0)//if its the first one, there is nothing to compare it to 
         { 
          if (combinedList[combinedCount - 1][0] == combinedList[combinedCount][0])//look at the previous one to check if its the same as the one before it, because we dont want to increment it everytime else it will increment on a different and empty page 
          { 
           testCount++; 
          } 
          else 
          { 
           testCount = 2; //2 is where our first row starts on each page 
          } 
         } 
         else { } 
          Aspose.Cells.Worksheet sheet = wb.Worksheets[combinedList[combinedCount][0]]; 
          Aspose.Cells.Cell cell1 = sheet.Cells["A" + testCount]; 
          Aspose.Cells.Cell cell2 = sheet.Cells["B" + testCount]; 
          Aspose.Cells.Cell cell3 = sheet.Cells["C" + testCount]; 
          Aspose.Cells.Cell cell4 = sheet.Cells["D" + testCount]; 
          Aspose.Cells.Cell cell5 = sheet.Cells["E" + testCount]; 
          Aspose.Cells.Cell cell6 = sheet.Cells["F" + testCount]; 
          Aspose.Cells.Cell cell7 = sheet.Cells["G" + testCount]; 
          Aspose.Cells.Cell cell14 = sheet.Cells["N" + testCount]; 
          Aspose.Cells.Cell cell15 = sheet.Cells["O" + testCount]; 
          Aspose.Cells.Cell cell16= sheet.Cells["P" + testCount]; 
          Aspose.Cells.Cell cell17 = sheet.Cells["Q" + testCount]; 
          Aspose.Cells.Cell cell18 = sheet.Cells["R" + testCount]; 
          Aspose.Cells.Cell cell19 = sheet.Cells["S" + testCount]; 
          Aspose.Cells.Cell cell20 = sheet.Cells["T" + testCount]; 

          cell1.PutValue(drv[0]); 
          cell2.PutValue(drv[1]); 
          cell3.PutValue(drv[13]); 
          cell4.PutValue(drv[2]); 
          cell5.PutValue(drv[10]); 
          cell6.PutValue(drv[11]); 
          cell7.PutValue(drv[12]); 
          cell14.PutValue(drv[3]); 
          cell15.PutValue(drv[4]); 
          cell16.PutValue(drv[5]); 
          cell17.PutValue(drv[6]); 
          cell18.PutValue(drv[7]); 
          cell19.PutValue(drv[8]); 
          cell20.PutValue(drv[9]); 

} 

C'est un peu bâclé mais vous obtenez le point. Plus de 60 secondes sont descendues à une solide 40 secondes, 25 secondes sont descendues à 15. Alors que toujours pas rapide comme l'éclair, l'insertion dans un tableur ne sera jamais super rapide.

Un autre problème que j'ai trouvé qui a réduit la durée d'exécution à un seul chiffre est la fonction de sauvegarde. J'ai enlevé l'enregistrement de la boucle foreach et l'ai mis dehors, il enregistre toujours correctement.

0

Eh bien, si vous avez besoin d'importer des données à partir d'une source de données (par exemple DataTable, tableaux, Liste, etc.) dans la feuille de calcul MS Excel ou exporter des données de feuille de calcul pour remplir un DataTable ou array, etc. en une seule fois, alors vous pouvez essayer les API Aspose.Cells pertinentes (qui sont efficaces) pour la tâche. Vous devriez vérifier les méthodes spécifiques de la classe Cells (par exemple Cells.ImportDataTable, Cells.ExportDataTable, etc. - il existe d'autres méthodes utiles.) Pour vos besoins. De plus, votre datatable serait inséré de manière à ce que les autres contenus soient décalés en conséquence.

1) Voir la ligne de code pour l'importation de tableau de données en feuille de calcul:

//Importing the contents of DataTable to the worksheet starting from "A1" cell, 
//where true specifies that the column names of the DataTable would be added to 
//the worksheet as a header row 
worksheet.Cells.ImportDataTable(dataTable, true, "A1"); 

2) voir même, le segment de code d'échantillon sur l'exportation de données de feuille de calcul pour remplir un DataTable:

//Exporting the contents of first 7 rows and 2 columns (A1:B7) starting from 1st cell to DataTable 
DataTable dataTable = worksheet.Cells.ExportDataTable(0, 0, 7, 2, true); 

Je travaille en tant que développeur/évangéliste chez Aspose.