繁体   English   中英

使用 Microsoft.Office.Interop.Excel 加快性能导出到 Excel 文件

[英]speed performance exporting to excel file using Microsoft.Office.Interop.Excel

我正在使用 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();
        }
    }

如果您死心塌地使用互操作,那么最好先创建一个值数组,然后在一次犯规中将其写出,而不是在行之间循环 - 众所周知,互操作在这方面很慢

就个人而言,我建议放弃互操作并使用开放的 xml 库(例如EPPlus)来完成此类任务。 我发现它更易于使用并且通常性能更高。 作为奖励,它摆脱了所有令人讨厌的混乱释放 com object marshal 的东西;-)

这将用以下内容替换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;
}

作为替代方案,您可以使用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);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM