C# 提高Excel文件创建的性能

C# 提高Excel文件创建的性能,c#,excel,winforms,performance,iteration,C#,Excel,Winforms,Performance,Iteration,我有一个带有TabControl的应用程序。它获取一些选项卡页,所有选项卡页都有一个DataGridView,其中填充了一个DataTable 填充选项卡控件后,我希望能够将所有数据网格视图(或者更确切地说,它们的数据源,都是数据表)导出到一个Excel文件中 我有下面的代码。它可以工作,但几乎需要一分钟。 单击按钮: private void exportBtn_Click(object sender, EventArgs e) { var result = new List<D

我有一个带有
TabControl
的应用程序。它获取一些
选项卡页
,所有选项卡页都有一个
DataGridView
,其中填充了一个
DataTable

填充
选项卡控件
后,我希望能够将所有
数据网格视图
(或者更确切地说,它们的
数据源
,都是
数据表
)导出到一个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);
}
private void exportBtn\u单击(对象发送方,事件参数e)
{
var result=新列表();
foreach(tabControl1.TabPages中的TabPage页)
{
var dgv=page.Controls[0]作为DataGridView;
如果(dgv==null)继续;
var dt=dgv.DataSource作为数据表;
如果(dt==null)继续;
dt.TableName=page.Text;
结果:添加(dt);
}
ExportServices.ToExcel(结果);
}
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;
    }
}
内部静态类导出服务
{
公共静态void ToExcel(列表表)
{
var excelApp=new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks.Add();
foreach(表中的var表)
{
表2.AddSheetoExcelApp(excelApp);
}
excelApp.Visible=true;
}
}
DataTable的扩展方法,取自:

public static void addsheetoExcelApp(此数据表Tbl,Microsoft.Office.Interop.Excel.Application excelApp)
{
尝试
{
if(Tbl==null | | Tbl.Columns.Count==0)
抛出新异常(“ExportToExcel:Null或空输入表!\n”);
//单一工作表
_工作表工作表=(_工作表)excelApp.Sheets.Add();
工作表.Name=Tbl.TableName.Remove(5,1);
//列标题
对于(int i=0;i
正如我所说,这个代码是有效的。但这需要永远的时间。在随机时间暂停程序的执行表明,大多数时间它都在下面的循环中工作
//rows

有没有办法加快这一进程?如果用户只为一个Excel文件等待一分钟,那将真的没有多大乐趣。


编辑:忘了提到除了我安装的库之外,我不能使用其他库。我们公司处理的是非常敏感的数据,因此我们不允许从“外部世界”运行任何代码。

使用COM dll来Excel是正常的,这样做需要时间

试试这个。你们不需要在机器上出类拔萃。我进行了测试,并使用这种方法将数据导出到Excel1000000行

如何使用它的完整示例:


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

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

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


3) 了解并使用OpenXmlWriter。这比任何其他选项都要灵活得多,但也有一个很好的学习曲线。您可以在不执行Excel应用程序的情况下生成Excel文件
你可以用。这是一个成熟的库,有很多功能

逐个设置单元格效率很低。我建议你立刻摆好整张桌子:

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;

或者,至少,使用较大的单元。

根据我使用
excel interop
的经验,使用单元格范围而不是单个单元格更快。我建议试着从链接的问题中找到这个答案;如果范围太大,请尝试为每行创建范围,例如谢谢,在寻找导出方法时,我也遇到了这个问题。但正如我在编辑中提到的,我不能使用第三方库。我后来看到了您的限制。在这种情况下,最好的解决方案是@AlexButenko。但我总是将行设置为选项卡分隔的字符串时间从56秒减少到
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;