使用 oleDbCommand 在 C# 中将行插入 Excel 电子表格的更快方法?

Faster way to insert rows into Excel spreadsheet in C# using oleDbCommand?

所以我正在寻找一种更快的插入服务器电子表格的方法。现在它取决于所使用的数据,但将 100 行插入到单个电子表格中大约需要 20 秒。我理解它为什么这样做,因为插入电子表格会导致 excel 每次插入新行时移动行。因此,添加到单个电子表格的行越多,所需的时间就越长。我测试了这个理论,它是正确的,我创建了大约 100 个电子表格,并随机插入了 1000 行分布在所有电子表格中。这需要大约 60 秒才能完成。将相同的 1000 行插入到单个电子表格中需要 5 多分钟才能完成。下面是我的代码:

 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();
                    }
                }
            }

嗯,如果您需要将数据从某些数据源(例如 DataTable、Arrays、List 等)导入 MS Excel 工作表或从工作表导出数据以填充 DataTable 或数组等。一次性尝试相关的 Aspose.Cells API(高效)来完成任务。您应该根据您的要求检查 Cells class 的特定方法(例如 Cells.ImportDataTable、Cells.ExportDataTable 等 - 还有一些其他有用的方法。)。此外,您的数据table 将以这样的方式插入,即其他内容将相应地转移到table 下。

1) 查看将数据 table 导入工作表的代码行:

//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) 同样,请参阅有关从工作表导出数据以填充数据表的示例代码段:

//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);

我在 Aspose 工作developer/Evangelist。

我想出了如何极大地减少它。正如我之前所说,insert into 函数在处理大型数据集时会导致拥塞。因此,针对每个单元格并使用 putvalue 函数。例如:

                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]);  

}

有点草率,但你明白了。 60 多秒下降到稳定的 40 秒,25 秒下降到 15 秒。虽然仍然不是快如闪电,但插入电子表格永远不会超快。

我发现另一个将 运行 时间减少到个位数的问题是保存功能。我从 foreach 循环中删除了保存并将其放在外面,它仍然正确保存。