如何提高我编写的 Excel 到 PDF 转换器的性能?
How do I improve the performance of this Excel to PDF converter I wrote?
选定的视图行数据 -> Excel -> PDF
工具: Excel com interop
这是我的程序的要点,
它从 90,000 行或大约该估计值的 MASSIVE 数据库中读取数据。 (只有那些从数据网格视图中选择的行,虽然目标是批量转换)
将它们分配给变量,变量被写入预先格式化的excel文件的单元格中(因为它的单元格排列,字体大小,颜色等,不可避免)。
最后我将 excel 文件转换成 PDF,我的主要 objective.
不幸的是,我的程序只需要大约一个小时来处理 700 个项目,但我不确定它是否是我的机器,一个 i3、2GB ram 笔记本电脑单元。
下面的代码仅转换来自 datagridview 的选定记录,我将其用作测试大型数据集的临时权宜之计。
我的问题是,如何提高它的性能?我写的代码已经相对简单并且可以运行,我不知道去哪里看看是什么在减慢它的速度以及如何提高写入速度。
这些是性能命中的嫌疑人:
- 数据是从 datagridview 读取的,尽管该视图由 Access 数据库支持,但单独读取 datagridview 应该不会影响性能。
- 写入Excel可能需要一些时间,我截断了一段代码以缩短我在 Whosebug 的代码输入。单元写入可能会占用一些资源。
- Excel 到 pdf 基本上是 1 行代码,所以我不确定是否有成功,或者这里是否有任何改进。
- 可能在下面的代码块中循环遍历 datagridview 到 for 循环的当前索引时命中。
- 我的资源监视器似乎检测到 EXCEL.exe 的多个签名正在处理和终止,根据代码这应该是正常的,但是因为 none 其中的逗留时间比他们应该的要长。
非常感谢在此问题上提供的帮助!
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 Whosebug
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 Whosebug!
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);
}
}
}
这是拍号,我不知道这些加载的模块是什么或它们做了什么。不记得之前包括 them/noticing 它们。
新话题link:
我看到从第一次保存到最终创建 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 Whosebug!
如TaW所述:
Moving data to Excel is most likely the culprit. Not sure if there is a way to bulk insert the data.
好吧,有一种方法可以批量插入,但是您的代码赢得了 "Most Unmanageable Code of the Year" 奖。所以,我不确定您将如何实现它,但您会希望使用 Range
和 Value
而不是 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
。
选定的视图行数据 -> Excel -> PDF
工具: Excel com interop
这是我的程序的要点,
它从 90,000 行或大约该估计值的 MASSIVE 数据库中读取数据。 (只有那些从数据网格视图中选择的行,虽然目标是批量转换)
将它们分配给变量,变量被写入预先格式化的excel文件的单元格中(因为它的单元格排列,字体大小,颜色等,不可避免)。
最后我将 excel 文件转换成 PDF,我的主要 objective.
不幸的是,我的程序只需要大约一个小时来处理 700 个项目,但我不确定它是否是我的机器,一个 i3、2GB ram 笔记本电脑单元。 下面的代码仅转换来自 datagridview 的选定记录,我将其用作测试大型数据集的临时权宜之计。
我的问题是,如何提高它的性能?我写的代码已经相对简单并且可以运行,我不知道去哪里看看是什么在减慢它的速度以及如何提高写入速度。 这些是性能命中的嫌疑人:
- 数据是从 datagridview 读取的,尽管该视图由 Access 数据库支持,但单独读取 datagridview 应该不会影响性能。
- 写入Excel可能需要一些时间,我截断了一段代码以缩短我在 Whosebug 的代码输入。单元写入可能会占用一些资源。
- Excel 到 pdf 基本上是 1 行代码,所以我不确定是否有成功,或者这里是否有任何改进。
- 可能在下面的代码块中循环遍历 datagridview 到 for 循环的当前索引时命中。
- 我的资源监视器似乎检测到 EXCEL.exe 的多个签名正在处理和终止,根据代码这应该是正常的,但是因为 none 其中的逗留时间比他们应该的要长。
非常感谢在此问题上提供的帮助!
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 Whosebug
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 Whosebug!
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);
}
}
}
这是拍号,我不知道这些加载的模块是什么或它们做了什么。不记得之前包括 them/noticing 它们。
新话题link:
我看到从第一次保存到最终创建 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 Whosebug!
如TaW所述:
Moving data to Excel is most likely the culprit. Not sure if there is a way to bulk insert the data.
好吧,有一种方法可以批量插入,但是您的代码赢得了 "Most Unmanageable Code of the Year" 奖。所以,我不确定您将如何实现它,但您会希望使用 Range
和 Value
而不是 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
。