Я написал код, который копирует данные из базы данных Azure в файл Excel. Это можно найти в конце этого вопроса.Копирование большого datatable в excel в ASP.Net
Проблема заключается в том, что для заполнения листа excel требуется навсегда, когда у меня есть 10k строк для одной из таблиц. Очевидно, что это не идеально для 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 Interop - это медленно и сложно использовать правильно. Попробуйте Open XML - https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx. Но если вы хотите попытаться оптимизировать текущее решение, чем посмотреть на распределение диапазона ячеек. Возьмите диапазон настолько большой, насколько вам нужно, и заполните его по своему усмотрению - это должно немного ускорить работу. –
Я бы порекомендовал вам использовать что-то вроде OpenXML или ClosedXML, также вы могли бы посмотреть на поиск google на 'Convert DataTable to Excel', также вы могли бы написать свой собственный Parser и записать данные в поля, разделенные запятыми, и сохранить файл как .csv – MethodMan
также почему вы делаете это 'foreach (процесс процесса в Process.GetProcessesByName (« Excel »)), когда все, что вам нужно сделать в блоке finally, вызывает вызов« Marshal.ReleaseComObject », поскольку, наконец, всегда бегать .. – MethodMan