我使用Microsoft.Office.Interop.Excel将本地数据库表导出到excel文件。有五列。
如果行为400则需要大约20秒,
如果行是1200,则大约需要45秒,
如果行为5000则需要250-300秒。
有没有办法减少出口时间?或者这是最大的表现?如果您可以建议在速度方面改进我的代码或建议一些替代方案,我将不胜感激。由于它在后台工作,因此调用是必要的。我的代码是
int rowCount = oLXTableDataGridView.RowCount;
if (rowCount == 1)
{
MessageBox.Show("No data to export.");
return;
}
this.Invoke((MethodInvoker)delegate
{
this.ExportFilepictureBox.Image = Properties.Resources.Animation;
labelexpoertolx.Text = "Preparing to export...";
});
object misValue = System.Reflection.Missing.Value;
conn = new SqlCeConnection(@"Data Source=|DataDirectory|\dontdelete.sdf");
String selectgroup = "SELECT * FROM OLXTable";
int namecol = 1;
int cellcol = 2;
int emailcol = 3;
int citycol = 4;
int categorycol = 5;
try
{
Excel.Application xlApp1;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
xlApp1 = new Excel.Application();
xlWorkBook = xlApp1.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
// MessageBox.Show("this is file");
xlWorkSheet.Cells[1, namecol].Value2 = "Name";
xlWorkSheet.Cells[1, cellcol].Value2 = "Cell No";
xlWorkSheet.Cells[1, emailcol].Value2 = "Email";
xlWorkSheet.Cells[1, citycol].Value2 = "City";
xlWorkSheet.Cells[1, categorycol].Value2 = "Category";
SqlCeDataReader reader = null;
//conn = new SqlCeConnection(selectnumbers);
conn.Open(); //open the connection
SqlCeCommand selecectnumberscmd = new SqlCeCommand(selectgroup, conn);
reader = selecectnumberscmd.ExecuteReader();
int i = 1;
while (reader.Read())
{
xlWorkSheet.Cells[i, namecol].Value2 = reader.GetString(1);
xlWorkSheet.Cells[i, cellcol].Value2 = reader.GetInt64(2);
xlWorkSheet.Cells[i, emailcol].Value2 = reader.GetString(3); ;
xlWorkSheet.Cells[i, citycol].Value2 = reader.GetString(4);
xlWorkSheet.Cells[i, categorycol].Value2 = reader.GetString(5);
i++;
}
conn.Close();
xlWorkBook.Close(true, misValue, misValue);
xlApp1.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp1);
this.Invoke((MethodInvoker)delegate
{
this.ExportFilepictureBox.Image = null;
labelexpoertolx.Text = "";
});
}
catch (Exception e13)
{
MessageBox.Show("Error Exporting data" + e13.Message);
conn.Close();
}
Cursor.Current = Cursors.Default;
和
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
答案 0 :(得分:1)
如果你已经开始使用互操作,那么最好首先创建一个值数组然后一次性写出来而不是循环遍历行 - 互操作在这方面是非常慢的
就个人而言,我建议抛弃互操作并使用开放式xml库(例如EPPlus)来完成此类任务。我发现它更容易使用,通常更高效。作为奖励,它摆脱了所有令人厌烦的凌乱释放com对象编组的东西; - )
这将替换try
块中的所有内容,如下所示:
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add("Data");
ws.Cells[1, namecol].Value = "Name";
ws.Cells[1, cellcol].Value = "Cell No";
ws.Cells[1, emailcol].Value = "Email";
ws.Cells[1, citycol].Value = "City";
ws.Cells[1, categorycol].Value = "Category";
SqlCeDataReader reader = null;
conn.Open(); //open the connection
SqlCeCommand selecectnumberscmd = new SqlCeCommand(selectgroup, conn);
reader = selecectnumberscmd.ExecuteReader();
int i = 1;
while (reader.Read())
{
ws.Cells[i, namecol].Value = reader.GetString(1);
ws.Cells[i, cellcol].Value = reader.GetInt64(2);
ws.Cells[i, emailcol].Value = reader.GetString(3); ;
ws.Cells[i, citycol].Value = reader.GetString(4);
ws.Cells[i, categorycol].Value = reader.GetString(5);
i++;
}
conn.Close();
//Now you have options to export the file - just save someplace, get a byte array or get a reference to the output stream etc with some of the following:
package.SaveAs(someFilePathString);
someByteArrayVariable = package.GetAsByteArray();
package.Stream;
}
答案 1 :(得分:-1)
作为替代方案,您可以使用SwiftExcel库(免责声明:我写了该库),就像EPPlus一样,它不使用互操作,但由于将数据直接流到文件中而具有更好的性能,该速度更快并且没有任何内存都会影响大批量。
以下是Nuget命令,可将其添加到您的项目中:
PM> Install-Package SwiftExcel
这是使用方法:
using (var ew = new ExcelWriter("C:\\temp\\test.xlsx"))
{
for (var row = 1; row <= 100; row++)
{
for (var col = 1; col <= 10; col++)
{
ew.Write($"row:{row}-col:{col}", col, row);
}
}
}