如何减少具有多个单元格的 PdfPTable 的内存消耗

Tom*_*ter 2 c# itextsharp pdfptable pdf-writer

我正在使用由单个 PdfTable 组成的 ITextSharp 创建 PDF。不幸的是,对于特定数据集,由于创建了大量 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();
Run Code Online (Sandbox Code Playgroud)

Chr*_*aas 5

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
*/
Run Code Online (Sandbox Code Playgroud)

因此,您需要做的就是在创建您的 之后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();
Run Code Online (Sandbox Code Playgroud)

  • 这种方法适用于使用 IArgeElement 接口的 iTextSharp 4.1.2。有 table.ElementComplete 属性。 (2认同)