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



所选视图行数据->Excel->PDF

工具:Excel com interop

以下是我的程序的要点,

  1. 它从90000行的海量数据库中读取数据,或者大约是这个估计值。(尽管目标是批量转换,但仅限于从数据网格视图中选择的行)

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

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

不幸的是,我的程序只处理700个项目大约需要一个小时,尽管我不确定这是不是我的机器,一个i3,2GB的ram笔记本电脑。下面的代码只转换datagridview中的选定记录,我将其用作测试大型数据集的临时权宜之计。

我的问题是,我该如何提高它的性能?我写的代码已经相对简单了,而且它很有效,我不知道从哪里看是什么减缓了它的速度,以及如何提高写速度。以下是性能打击的嫌疑人:

  1. 数据是从数据网格视图中读取的,尽管该视图由Access数据库支持,但单独读取数据网格视图不会对性能造成影响
  2. 写Excel可能需要一些时间,我剪掉了一块代码来缩短StackOverflow的代码输入。单元写入可能会使用一些资源
  3. Excel到pdf本质上是一行代码,所以我不确定是否有命中,或者这里是否有任何改进
  4. 当通过datagridview循环到下面代码块中for循环的当前索引时,可能会遇到问题
  5. 我的资源监视器似乎检测到EXCEL.exe的几个签名正在处理和终止,但根据代码,这应该是正常的,因为它们都没有停留超过应有的时间

非常感谢对此事的协助!


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);
}
}
}

这是时间签名,我不知道这些加载的模块是什么,也不知道它们做什么。也不记得以前包含过它们/注意过它们。

新线程链接:

如何在EPPLUS语法中编写此Excel Interop语法

我看到从第一次保存到最终创建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很可能是罪魁祸首。不确定是否有大容量插入数据的方法。

嗯,有一种方法可以批量插入,但您的代码赢得了"年度最不可管理代码">奖。所以,我不确定您将如何实现它,但您希望使用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。如果您真的只使用字符串,也可以用Text替换Value

最新更新