【发布时间】:2016-01-22 11:49:10
【问题描述】:
我有一个带有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 文件真的不会很有趣。
编辑: 忘了提到我不能使用除了我已安装的库之外的任何其他库。我们公司正在处理非常敏感的数据,因此我们不允许运行来自“外部世界”的任何代码。
【问题讨论】:
-
根据我使用
excel interop的经验,使用单元格范围而不是单个单元格会更快。我建议从链接的问题中尝试这个答案stackoverflow.com/a/21079709/1506454;如果范围太大,请尝试为每一行创建范围,例如
标签: c# excel winforms performance iteration