Font Color on PdfPCell increases the size of PDF file

Viewed 583

I have created a Font in this way.

Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);

and then using it inside PdfPCell with Phrase.

PdfPCell hcell = new PdfPCell(new Phrase("Column A", tableHeaderFont));

I am showing table header on every page.

Now if I drop the Font Color, it generates the PDF file of size 10 MB but when Color is provided it generates PDF file of size 24 MB. There are around 1400 page in PDF document.

Is there any better way to specify Font Color on PdfPCell level?

In addition to this, when I try to merge these pdf documents using PdfSmartCopy it takes around 4 GB memory usage.

I have tried both iText & OpenPDF.

Update:

iText 5.5:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>

When I use the BaseColor class of iText 5+ then I am getting the same size of pdf file with or without Font Color.

Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, BaseColor.WHITE);

OpenPDF 1.3.20

<dependency>
    <groupId>com.github.librepdf</groupId>
    <artifactId>openpdf</artifactId>
    <version>1.3.20</version>
</dependency>

But OpenPDF doesn't come with BaseColor class so I have to use Color.WHITE here.

Font tableHeaderFont = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.WHITE);

Do we have any alternative of BaseColor class in OpenPDF or iText4?

Update 2: Sample Use Case to reproduce the issue.

OpenPDF Impl: PDF File Size is around 15 MB

import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class TestOpenPDF {

    public static void main(String[] args) throws FileNotFoundException {
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        Document.compress = false;
        try {
            PdfWriter.getInstance(document,
                    new FileOutputStream("AddBigTable_OpenPDF.pdf"));
            document.open();
            String[] bogusData = {"M0065920"};
            int NumColumns = 1;

            PdfPTable datatable = new PdfPTable(NumColumns);
            datatable.getDefaultCell().setPadding(3);
            datatable.getDefaultCell().setBorderWidth(2);
            datatable.getDefaultCell().setHorizontalAlignment(
                    Element.ALIGN_CENTER);
            Font tableHeaderFont = new Font(Font.HELVETICA, 20, Font.NORMAL, Color.WHITE);
            PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
            header.setBackgroundColor(Color.GRAY);
            header.setPadding(3);
            header.setBorderWidth(2);
            header.setHorizontalAlignment(Element.ALIGN_CENTER);
            datatable.addCell(header);

            datatable.setHeaderRows(1); // this is the end of the table header

            datatable.getDefaultCell().setBorderWidth(1);
            for (int i = 1; i < 75000; i++) {
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(0.9f);
                }
                for (int x = 0; x < NumColumns; x++) {
                    datatable.addCell(bogusData[x]);
                }
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(1);
                }
            }
            document.add(datatable);
        } catch (Exception de) {
            de.printStackTrace();
        }
        document.close();
    }
}

iText Impl: PDF File Size is around 8.5 MB

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class TestIText {

    public static void main(String[] args) throws FileNotFoundException {
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        Document.compress = false;
        try {
            PdfWriter.getInstance(document,
                    new FileOutputStream("AddBigTable_iText.pdf"));
            document.open();
            String[] bogusData = {"M0065920"};
            int NumColumns = 1;

            PdfPTable datatable = new PdfPTable(NumColumns);
            datatable.getDefaultCell().setPadding(3);
            datatable.getDefaultCell().setBorderWidth(2);
            datatable.getDefaultCell().setHorizontalAlignment(
                    Element.ALIGN_CENTER);

            Font tableHeaderFont = FontFactory.getFont(FontFactory.HELVETICA, 20, Font.NORMAL, BaseColor.WHITE);
            PdfPCell header = new PdfPCell(new Phrase("Clock #", tableHeaderFont));
            header.setBackgroundColor(BaseColor.GRAY);
            header.setPadding(3);
            header.setBorderWidth(2);
            header.setHorizontalAlignment(Element.ALIGN_CENTER);
            datatable.addCell(header);

            datatable.setHeaderRows(1); // this is the end of the table header

            datatable.getDefaultCell().setBorderWidth(1);
            for (int i = 1; i < 75000; i++) {
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(0.9f);
                }
                for (int x = 0; x < NumColumns; x++) {
                    datatable.addCell(bogusData[x]);
                }
                if (i % 2 == 1) {
                    datatable.getDefaultCell().setGrayFill(1);
                }
            }
            document.add(datatable);
        } catch (Exception de) {
            de.printStackTrace();
        }
        document.close();
    }
}
2 Answers

From the snippets which are shared, I can grasp that iText 2 is used. If it is possible, it is better to reconsider such a choice, since iText 2 is more than 10 years old, potentially has a lot of functional and security issues and no longer maintained.

I recommend updating to iText 7. Although I do not have your code and thus could not prove that in your case setting color would not make the size of the PDF much bigger, I have created the following sample to demonstrate that there should no issue:

    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
    Document doc = new Document(pdfDoc);

    for (int i = 0; i < 10000; i++) {
        doc.add(new Paragraph("Hello World")/*.setFontColor(ColorConstants.RED)*/);
    }

    doc.close();

The size of the resultant PDF, in which font color is enabled, is 161Kb; the size of the resultant PDF, in which font color is disabled, is 160Kb (that is fully expected, because enabling a color means writing the corresponding instruction to the PDF: there are 10k instructions there, hence 1Kb difference).

The issue has been fixed with latest version of OpenPDF 1.3.25. I was using the older version.

Related