如何减少许多单元格的PdfPTable的内存消耗

我正在使用ITextSharp创建一个PDF,它由一个PdfTable组成。 不幸的是,对于特定的数据集,由于创建了大量的PdfPCell,我得到了Out of memory Exception(我已经分析了内存使用情况 – 我已经有近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有一个非常酷的接口叫做ILargeElementPdfPTable实现了它。 根据文件:

 /** * 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。 在你的内循环中做一些forms的计数器,每隔一段时间就会添加表,从而清除内存。 然后在循环结束时将Complete设置为true并再次添加它。

下面是显示此关闭的示例代码。 没有计数器检查,此代码在我的机器上使用大约500MB的RAM。 通过计数器检查每1,000个项目,它下降到16MB的RAM。 您需要为计数器找到自己的最佳位置,这取决于您平均每个单元格添加的文本数量。

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