Large tables
The following example shows how you can add to a table little by little, in order to keep the memory footprint low.
Limitations
The use of large tables is not recommended in the following use cases:
- Tables with complex content: For example, the use of form fields. This is because if the page is flushed too early, we can no longer update the needed data structures.
Extra Considerations:
- PDF/A, PDF/UA: To ensure documents conform to these standards, flushing is disabled since we need to check a lot of things upon closing the document. For example, does all text actually use embedded fonts etc. Therefore, we must retain all the pages in memory to perform these conformance checks. This will generate a warning informing you page flushing could not be performed. However, using the large tables feature still benefits from general speed and memory improvements, because we return unused objects to the garbage collector.
See https://stackoverflow.com/questions/78707405/itext7-large-table-pdf-a for more details on a real-world example.
incompletetable
JAVA
JAVA
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2023 Apryse Group NV
Authors: Apryse Software.
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
package com.itextpdf.samples.sandbox.tables;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.UnitValue;
import java.io.File;
public class IncompleteTable {
public static final String DEST = "./target/sandbox/tables/incomplete_table.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
file.getParentFile().mkdirs();
new IncompleteTable().manipulatePdf(DEST);
}
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
// The second argument determines 'large table' functionality is used
// It defines whether parts of the table will be written before all data is added.
Table table = new Table(UnitValue.createPercentArray(5), true);
for (int i = 0; i < 5; i++) {
table.addHeaderCell(new Cell().setKeepTogether(true).add(new Paragraph("Header " + i)));
}
// For the "large tables" they shall be added to the document before its child elements are populated
doc.add(table);
for (int i = 0; i < 500; i++) {
if (i % 5 == 0) {
// Flushes the current content, e.g. places it on the document.
// Please bear in mind that the method (alongside complete()) make sense only for 'large tables'
table.flush();
}
table.addCell(new Cell().setKeepTogether(true).add(new Paragraph("Test " + i)
.setMargins(0, 0, 0, 0)));
}
// Flushes the rest of the content and indicates that no more content will be added to the table
table.complete();
doc.close();
}
}
C#
C#
using System;
using System.IO;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace iText.Samples.Sandbox.Tables
{
public class IncompleteTable
{
public static readonly string DEST = "results/sandbox/tables/incomplete_table.pdf";
public static void Main(String[] args)
{
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
new IncompleteTable().ManipulatePdf(DEST);
}
private void ManipulatePdf(string dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
// The second argument determines 'large table' functionality is used
// It defines whether parts of the table will be written before all data is added.
Table table = new Table(UnitValue.CreatePercentArray(5), true);
for (int i = 0; i < 5; i++)
{
table.AddHeaderCell(new Cell().SetKeepTogether(true).Add(new Paragraph("Header " + i)));
}
// For the "large tables" they shall be added to the document before its child elements are populated
doc.Add(table);
for (int i = 0; i < 500; i++)
{
if (i % 5 == 0)
{
// Flushes the current content, e.g. places it on the document.
// Please bear in mind that the method (alongside complete()) make sense only for 'large tables'
table.Flush();
}
table.AddCell(new Cell().SetKeepTogether(true).Add(new Paragraph("Test " + i)
.SetMargins(0, 0, 0, 0)));
}
// Flushes the rest of the content and indicates that no more content will be added to the table
table.Complete();
doc.Close();
}
}
}