如何提高我写的Excel到PDF转换器的性能?

时间:2017-02-07 09:29:10

标签: c# performance pdf datagridview excel-interop

选定的视图行数据 - > Excel - > PDF

工具: Excel com interop

以下是我的计划的主旨,

  1. 它从大约90,000行的MASSIVE数据库中读取数据,或者在该估计值附近。 (只有那些从数据网格视图中选择的行,但目标是转换批发)

  2. 将它们分配给变量,将变量写入预先格式化的excel文件的单元格(用于其单元格排列,字体大小,颜色等,不可避免)。

  3. 最后我将excel文件转换为PDF,这是我的主要目标。

  4. 不幸的是,我的程序只需要一个小时来处理700件物品,但我不确定它是不是我的机器,i3,2GB内存笔记本电脑。 下面的代码只转换来自datagridview的选定记录,我用它作为临时的间隙测量来测试大量数据。

    我的问题是,如何改善其表现?我写的代码已经相对简单了,它可以工作,我不知道在哪里查看什么会减慢它以及如何提高写入速度。 这些是性能命中的嫌疑人:

    1. 从datagridview读取数据,虽然视图由Access数据库支持,但单独读取datagridview不应该有性能损失。
    2. 写入Excel可能需要一些时间,我切断了一段代码来缩短我的StackOverflow代码条目。单元格写入可能会使用一些资源。
    3. Excel到pdf基本上是一行代码,所以我不确定是否有点击,或者这里是否有任何改进。
    4. 在将数据网格视图循环到下面代码块中for循环的当前索引时,可能存在命中。
    5. 我的资源监视器似乎检测到正在处理和终止的EXCEL.exe的几个签名,但是根据代码这应该是正常的,因为它们都没有留下比它们应该更长的时间。
    6. 非常感谢协助此事!

      if (DGVmain.RowCount > 0)
      {
          if (DGVmain.SelectedCells.Count <= 0)
          {
              return;
          }
          //Source
          OpenFileDialog openFileDialog = new OpenFileDialog();
          openFileDialog.Filter = "Excel Files|*.xls;*.xlsx";
          openFileDialog.ShowDialog();
          lblSuccess.Text = openFileDialog.FileName;
          lblPathings = Path.ChangeExtension(openFileDialog.FileName, null);
          int count = DGVmain.SelectedRows.Count;
          int ballast = 0;
          foreach (DataGridViewRow selectedRow in DGVmain.SelectedRows)
          {
              //Drag
              if (lblSuccess.Text == null)
                  return;
              //Drag
              if (lblSuccess.Text == null)
                  return;
              string drags = Convert.ToString(selectedRow.Cells[0].Value);
              string dragsy = Convert.ToString(selectedRow.Cells[1].Value);
              string drag = Convert.ToString(selectedRow.Cells[2].Value);
              string drag2 = Convert.ToString(selectedRow.Cells[3].Value);
              string drag3 = Convert.ToString(selectedRow.Cells[4].Value);
              string drag4 = Convert.ToString(selectedRow.Cells[5].Value);
              string drag5 = Convert.ToString(selectedRow.Cells[6].Value);
              string drag6 = Convert.ToString(selectedRow.Cells[7].Value);
              string drag7 = Convert.ToString(selectedRow.Cells[8].Value);
              \\trimmed this part down for Stackoverflow
              Persona = drag;
              generateID();
              //Initialize the Excel File
              try
              {
                  ballast++;
                  lblItem.Text = "Item #" + ballast;
                  Xls = new Excel.Application();
                  WBs = Xls.Workbooks;
                  WB = WBs.Open(lblSuccess.Text, 0, false, 5, "", "", true,
                      XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
                  if (WB == null)
                  {
                      Xls.Quit();
                      Xls = null;
                      WB = null;
                      return;
                  }
                  SS = WB.Worksheets;
                  WS = SS.get_Item(1);
                  //Tin Algorithm
                  string input = drag23;
                  string digit1 = "0";
                  string digit2 = "0";
                  string digit3 = "0";
                  string digit4 = "0";
                  StringBuilder sb = new StringBuilder();
                  StringBuilder partBuilder = new StringBuilder();
                  int partsSplitted = 0;
                  for (int i = 1; i <= input.Length; i++)
                  {
                      partBuilder.Append(input[i - 1]);
                      if (i % 3 == 0 && partsSplitted <= 3)
                      {
                          sb.Append(' ');
                          sb.Append(partBuilder.ToString());
                          partBuilder = new StringBuilder();
                          partsSplitted++;
                      }
                  }
                  sb.Append(partBuilder.ToString());
                  string formatted = sb.ToString().TrimStart();
                  string[] formatCollection = formatted.Split(' ');
                  digit1 = formatCollection[0];
                  digit2 = formatCollection[1];
                  digit3 = formatCollection[2];
                  digit4 = formatCollection[3];
                  //Names
                  WS.Cells[14, 2] = dragsy + ",  " + drag + drag2;
                  // Write to cells here
                  WS.Cells[8, 8] = "2016";
                  WS.Cells[8, 29] = drag24;
                  WS.Cells[8, 34] = drag25;
                  WS.Cells[11, 9] = digit1;
                  WS.Cells[11, 12] = digit2;
      
                  //Trimmed for StackOverflow!
      
                  WB.Save();
                  try
                  {
                      WB.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, finalformat);
      
                  }
                  catch (System.Exception ex)
                  {
                      MessageBox.Show("Error occurred: " + ex, "General error exception");
                  }
              }
              catch (Exception ex)
              {
                  MessageBox.Show("Write Excel: " + ex.Message);
              }
              finally
              {
                  GC.Collect();
                  GC.WaitForPendingFinalizers();
                  WB.Close();
                  Xls.Quit();
                  releaseObject(SS);
                  releaseObject(WS);
                  releaseObject(WBs);
                  releaseObject(WB);
                  releaseObject(Xls);
              }
          }
      }
      

      以下是时间签名,我不知道这些加载的模块是什么或它们做什么。不要记得在它们之前包括它们/注意它们。

      新线程链接:

      How do I write this Excel Interop syntax in EPPLUS syntax

1 个答案:

答案 0 :(得分:2)

我看到从第一次保存到最终的PDF创建需要大约60秒。如果您要保存和导出4次,这似乎是合理的时间跨度。如果您的性能问题是从foreach循环开始到第一次保存的约80秒,我猜你的问题出在以下几行:

WS.Cells[14, 2] = dragsy + ",  " + drag + drag2;
// Write to cells here
WS.Cells[8, 8] = "2016";
WS.Cells[8, 29] = drag24;
WS.Cells[8, 34] = drag25;
WS.Cells[11, 9] = digit1;
WS.Cells[11, 12] = digit2;

//Trimmed for StackOverflow!

正如TaW所述:

  

将数据移动到Excel很可能是罪魁祸首。不确定是否有批量插入数据的方法。

嗯,有一种批量插入的方法,但您的代码会赢得&#34;年度最难以管理的代码&#34; 奖励。因此,我不确定您将如何实施它,但您希望使用RangeValue代替Cell。在你的情况下,它可能看起来像......

string[,] values = new string[15, 35];  //or objects
values[7, 7] = "2016";
values[7, 28] = drag24;
values[7, 33] = drag25;
values[10, 8] = digit1;
values[10, 11] = digit2;
// etc.

Range range = WS.Range[WS.Cells[1, 1], WS.Cells[15, 35]];
range.Value = values;

如果您想使用数字,也可以使用object代替string。如果您真的只使用字符串,也可以将Value替换为Text