使用 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 循环中删除了保存并将其放在外面,它仍然正确保存。
所以我正在寻找一种更快的插入服务器电子表格的方法。现在它取决于所使用的数据,但将 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 循环中删除了保存并将其放在外面,它仍然正确保存。