我正在使用 ITextSharp 创建一个 PDF,它由单个 PdfTable 组成。不幸的是,对于特定的数据集,由于创建了大量 PdfPCell,我遇到了内存不足异常(我已经分析了内存使用情况 - 我有近百万个单元格的 1/2!)
在这种情况下有什么办法可以减少内存使用吗?
我尝试过在各个点(每行之后)冲洗并完全压缩
PdfWriter 基于 FileStream
代码看起来很像这样:
Document document = Document();
FileStream stream = new FileStream(fileName,FileMode.Create);
pdfWriter = PdfWriter.GetInstance(document, stream);
document.Open();
PdfPTable table = new PdfPTable(nbColumnToDisplay);
foreach (GridViewRow row in gridView.Rows)
{
j = 0;
for (int i = 0; i < gridView.HeaderRow.Cells.Count; i++)
{
PdfPCell cell = new PdfPCell( new Phrase( text) );
table.AddCell(cell);
}
}
document.Add(table);
document.Close();
iTextSharp 有一个非常酷的界面,称为ILargeElement http://sourceforge.net/p/itextsharp/code/532/tree/trunk/src/core/iTextSharp/text/ILargeElement.cs认为PdfPTable
实施。根据文档:
/**
* Interface implemented by Element objects that can potentially consume
* a lot of memory. Objects implementing the LargeElement interface can
* be added to a Document more than once. If you have invoked setCompleted(false),
* they will be added partially and the content that was added will be
* removed until you've invoked setCompleted(true);
* @since iText 2.0.8
*/
所以你需要做的就是在创建你的PdfPTable
,设置Complete
属性为 false。在您的内部循环中执行某种形式的计数器,每隔一段时间就会添加表,从而清除内存。然后在循环结束时设置Complete
为 true 并再添加一次。
下面的示例代码展示了这一点。如果没有计数器检查,此代码在我的机器上使用大约 500MB 的 RAM。每检查 1,000 个项目,RAM 就会减少到 16MB。您需要找到自己的计数器最佳位置,这取决于您平均向每个单元格添加的文本量。
string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "table.pdf");
Document document = new Document();
FileStream stream = new FileStream(fileName, FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(document, stream);
document.Open();
PdfPTable table = new PdfPTable(4);
table.Complete = false;
for (int i = 0; i < 1000000; i++) {
PdfPCell cell = new PdfPCell(new Phrase(i.ToString()));
table.AddCell(cell);
if (i > 0 && i % 1000 == 0) {
Console.WriteLine(i);
document.Add(table);
}
}
table.Complete = true;
document.Add(table);
document.Close();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)