提高Excel文件创建的性能

时间:2016-01-22 11:49:11

标签: c# excel winforms performance iteration

我有一个TabControl的应用程序。它得到一些TabPages,所有DataGridView都填充了DataTable 填充TabControl后,我希望能够将所有DataGridViews(或更确切地说是DataSources(全部为DataTables)导出到一个Excel文件中。
我有以下代码。它有效,但需要一分钟。

点击按钮:

private void exportBtn_Click(object sender, EventArgs e)
{
    var result = new List<DataTable>();
    foreach (TabPage page in tabControl1.TabPages)
    {
        var dgv = page.Controls[0] as DataGridView;
        if (dgv == null) continue;

        var dt = dgv.DataSource as DataTable;
        if (dt == null) continue;
        dt.TableName = page.Text;

        result.Add(dt);
    }

    ExportServices.ToExcel(result);
}

ExportServices看起来像这样:

internal static class ExportServices
{
    public static void ToExcel(List<DataTable> tables)
    {
        var excelApp = new Microsoft.Office.Interop.Excel.Application();
        excelApp.Workbooks.Add();

        foreach (var table in tables)
        {
            table.AddSheetToExcelApp(excelApp);
        }
        excelApp.Visible = true;
    }
}

DataTable的扩展方法,取自this question

public static void AddSheetToExcelApp(this DataTable Tbl, Microsoft.Office.Interop.Excel.Application excelApp)
{
    try
    {
        if (Tbl == null || Tbl.Columns.Count == 0)
            throw new Exception("ExportToExcel: Null or empty input table!\n");

        // single worksheet
        _Worksheet workSheet = (_Worksheet)excelApp.Sheets.Add();
        workSheet.Name = Tbl.TableName.Remove(5,1);

        // column headings
        for (int i = 0; i < Tbl.Columns.Count; i++)
        {
            workSheet.Cells[1, (i + 1)] = Tbl.Columns[i].ColumnName;
        }
        // rows
        for (int i = 0; i < Tbl.Rows.Count; i++)
        {
            for (int j = 0; j < Tbl.Columns.Count; j++)
            {
                workSheet.Cells[(i + 2), (j + 1)] = Tbl.Rows[i][j];
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("ExportToExcel: \n" + ex.Message);
    }
}

正如我所说,这段代码有效。但这需要永远这样做。在随机时间暂停程序的执行表明我大部分时间都在// rows下面的循环中工作。
有什么方法可以加速这个?对于一个Excel文件,等待一分钟的用户真的没有多大乐趣。

编辑:忘记提及我不能使用除我已安装的库之外的任何其他库。我们公司正在使用非常敏感的数据,因此我们不允许从外部世界运行任何代码&#34;。

4 个答案:

答案 0 :(得分:2)

逐个设置单元格效率非常低。我建议你立刻设置整个表格:

object[,] array = new object[Tbl.Rows.Count,Tbl.Columns.Count]
// Fill the array with values then

workSheet.Range[workSheet.Cells[1, 1], workSheet.Cells[Tbl.Rows.Count, Tbl.Columns.Count]].Value = array;

或者至少使用更大的碎片。

答案 1 :(得分:1)

使用COM dll进行Excel是正常的,这需要时间来执行此操作

试试这个。你不需要在机器上擅长。我测试过,我使用这种方法将数据导出到超过1 000 000行

https://github.com/jsegarra1971/SejExcelExport

完整示例如何使用它:

http://www.codeproject.com/Tips/829389/Fast-Excel-Import-and-Export

答案 2 :(得分:0)

我随着时间的推移使用了三种方法:

1)写出一个csv文件,然后将其导入excel表。

2)将数据放入剪贴板,用标签分隔值,然后将其粘贴到Excel中(可能使用粘贴特殊 - >无格式化)。您是否可以这样做显然在很大程度上取决于程序运行的环境。

3)了解并使用OpenXmlWriter。这比任何其他选项都要灵活得多,但也有很好的学习曲线才能做好。

答案 3 :(得分:0)

您可以在不执行Excel应用程序的情况下生成Excel文件 您可以使用EPPlus library。它是一个拥有大量功能的成熟库