如何减少多单元的PdfPTable的内存消耗
本文关键字:内存 PdfPTable 单元 何减少 | 更新日期: 2023-09-27 18:04:26
我正在使用ITextSharp创建一个PDF,它由单个PdfTable组成。不幸的是,对于一个特定的数据集,由于创建了大量的PdfPCells,我得到了内存不足的异常(我已经分析了内存使用情况-我有近50万个单元格!)
在这种情况下,有什么方法可以减少内存使用吗?我尝试过在不同的点(每行之后)刷新和完全压缩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
,由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。随着计数器每1000项检查一次,它的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();
PdfPTable pdftbale = new PdfPTable(gridview.HeaderRow.Cells.Count);
foreach (TableCell tabhead in gridview.HeaderRow.Cells)
{
PdfPCell pdfcell1 = new PdfPCell(new Phrase(tabhead.Text));
pdftbale.AddCell(pdfcell1);
}
foreach (GridViewRow gd in gridview.Rows)
{
foreach (TableCell tab in gd.Cells)
{
PdfPCell pdfcell = new PdfPCell(new Phrase(tab.Text));
pdftbale.AddCell(pdfcell);
}
}
iTextSharp.text.Document pdfDocument = new iTextSharp.text.Document(PageSize.A4, 10f, 10f, 10f, 10f);
PdfWriter.GetInstance(pdfDocument, new FileStream(Server.MapPath("~/pdf/" + DateTime.Now.ToString("ddMMyyyyhhmmss") + ".pdf"), FileMode.Create));
pdfDocument.Open();
pdfDocument.Add(pdftbale);
pdfDocument.Close();