【发布时间】:2016-02-21 21:51:59
【问题描述】:
我编写了一些代码,将 Azure 数据库中的数据复制到 Excel 文件中。这可以在这个问题的末尾找到。
问题是当我为其中一个表有 10k 行时,填充 Excel 工作表需要很长时间。显然,这对于 Excel 来说并不理想,但此时必须以这种方式完成。我想知道是否有更快的方法来编码。 当然,创建 excel 表是瓶颈,因为 C# 可以在几秒钟内获取数据集。如果我进入 Excel 并查看数据,然后右键单击并复制标题并将其粘贴到 Excel 表中,它也会在几秒钟内完成。
那么我可以以编程方式执行此操作吗?
private void createExcelFile()
{
string fileName = "FvGReport.xlsx";
string filePath = HttpContext.Current.Request.MapPath("~/App_Data/" + fileName); //check www.dotnetperls.com/mappath
string sqlQuery = "";
List<string> sheetNames = new List<string>();
foreach (ListItem item in ddlSummary_Supplier.Items)
{
string sqlSummary = "SELECT * FROM FvGSummaryAll WHERE Supplier_Code = '" + item.Text + "'; ";
sqlQuery = sqlQuery + sqlSummary;
sheetNames.Add("Summary " + item.Text);
string sqlPaymentsSummary = "SELECT * FROM FvGSummaryPayment WHERE Supplier_Code = '" + item.Text + "'; ";
sqlQuery = sqlQuery + sqlPaymentsSummary;
sheetNames.Add("PaymentSummary " + item.Text);
}
DataSet dataSet = new DataSet();
//string sqlQuery = @"SELECT * FROM FvGData WHERE Supplier_Code = 'SFF Pacific'; SELECT * FROM FvGSummaryPayment";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(sqlQuery, connection);
adapter.Fill(dataSet);
}
//this reference conflicts with System.Data as both have DataTable. So defining it here.
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook excelWorkBook = null;
Microsoft.Office.Interop.Excel.Worksheet excelWorkSheet = null;
ExcelApp.Visible = true;
excelWorkBook = ExcelApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
//excel rows start at 1 not 0
try
{
for (int i = 1; i < dataSet.Tables.Count; i++)
{
excelWorkBook.Worksheets.Add(); //Adds new sheet in Excel WorkBook
}
for (int i = 0; i < dataSet.Tables.Count; i++)
{
int dsRow = 1;
excelWorkSheet = excelWorkBook.Worksheets[i + 1];
//Writing Columns Name in Excel Sheet
for (int col = 1; col < dataSet.Tables[i].Columns.Count; col++)
{
excelWorkSheet.Cells[dsRow, col] = dataSet.Tables[i].Columns[col - 1].ColumnName;
}
dsRow++;
for (int xlRow = 0; xlRow < dataSet.Tables[i].Rows.Count; xlRow++)
{
//Excel row and col positions for writing row = 1, col = 1
for (int col = 1; col < dataSet.Tables[i].Columns.Count; col++)
{
excelWorkSheet.Cells[dsRow, col] = dataSet.Tables[i].Rows[xlRow][col - 1].ToString();
}
dsRow++;
}
excelWorkSheet.Name = sheetNames[i]; //Renaming ExcelSheets
}
excelWorkBook.SaveAs(filePath);
excelWorkBook.Close();
ExcelApp.Quit();
Marshal.ReleaseComObject(excelWorkSheet);
Marshal.ReleaseComObject(excelWorkBook);
Marshal.ReleaseComObject(ExcelApp);
}
catch (Exception ex)
{
lblNoData.Text = ex.ToString();
}
finally
{
foreach (Process process in Process.GetProcessesByName("Excel"))
{
process.Kill();
}
}
downloadExcel(filePath, fileName);
}
【问题讨论】:
-
不要使用 Excel 互操作 - 它速度慢且难以正确使用。试试 Open XML - msdn.microsoft.com/en-us/library/office/…。但是,如果您想尝试优化当前解决方案而不是查看单元格范围分配。抓住一个尽可能大的范围并根据需要填充它 - 这应该会加快速度。
-
我建议你看看使用类似
OpenXML or ClosedXML的东西,你也可以看看在Convert DataTable to Excel上进行谷歌搜索,你也可以编写自己的解析器并将数据写入逗号分隔的字段并将文件另存为 .csv -
还有你为什么要这样做
foreach (Process process in Process.GetProcessesByName("Excel")),而在 finally 块中你所要做的就是调用Marshal.ReleaseComObject,因为 finally 将始终运行..
标签: c# asp.net sql-server excel