2016-01-22 3 views
1

У меня есть приложение с TabControl. Он получает TabPages, все из которых имеют DataGridView, который заполняется DataTable.
Как только заполняется TabControl, я хочу, чтобы иметь возможность экспортировать все DataGridViews (или, скорее, их DataSources, которые все DataTables) в один файл Excel.
У меня для этого есть следующий код. Он работает, но занимает почти минута.
Улучшение производительности создания файла 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.

EDIT: Вспомните, что я не могу использовать какие-либо другие библиотеки, кроме тех, которые я установил. Наша компания работает с очень чувствительными данными, поэтому нам не разрешается запускать какой-либо код из «внешнего мира».

+0

Из моего опыта использования 'excel interop' быстрее работать с диапазонами ячеек вместо отдельных ячеек. Я предлагаю попробовать этот ответ http://stackoverflow.com/a/21079709/1506454 из связанного вопроса; если диапазон слишком велик, попробуйте создать диапазоны для каждой строки, например – ASh

ответ

1

Для установки ячеек один за другим очень неэффективно.Я советую вам установить всю таблицу сразу:

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; 

Или, по крайней мере, использовать большие миры.

+0

Время сокращалось с 56 секунд до <2 секунд. Благодарю. – Wilsu

1

Это нормально, что с помощью DLL COM для Excel это потребуется время, чтобы сделать это

Попробуйте это. Вы не подходите к машине. Я проверил, и я использовал этот подход для экспорта данных, чтобы преуспеть 1 000 000 строк

https://github.com/jsegarra1971/SejExcelExport

Полный пример того, как использовать его:

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

0

я использовал три метода с течением времени:

1) Выпишите файл csv, а затем импортируйте его в лист Excel.

2) помещаем данные в буфер обмена, разделяя значения с помощью вкладок, а затем вставляя их в Excel (возможно, с помощью специальной вставки -> без форматирования). Можете ли вы это сделать, очевидно, сильно зависит от среды, в которой работают программы.

3) узнать и использовать OpenXmlWriter. Это намного более гибко, чем любой другой вариант, но также имеет довольно кривую обучения, чтобы получить право.

0

Вы можете сгенерировать файл Excel без выполнения приложения Excel Вы можете использовать EPPlus library. Это зрелая библиотека с множеством функциональных возможностей.

+0

Спасибо, когда искали способ экспорта, я тоже наткнулся на это. Но, как я упоминал в своем редактировании, я не могу использовать сторонние библиотеки. – Wilsu

+0

Я видел позже ваше ограничение. В этом случае лучшим решением является @AlexButenko. Но я всегда устанавливал строки в виде строки, разделенной вкладкой – mnieto

Смежные вопросы