Varun Jaiswal
Varun Jaiswal

Reputation: 67

iText 7 - com.itextpdf.io.IOException: PDF startxref not found

We are trying to upgrade from iText 5 to iText 7 and saw few issues. I am getting an exception as "com.itextpdf.io.IOException: PDF startxref not found." inside PdfReader#readPdf() and finally in the caller method getting an exception as "com.itextpdf.kernel.PdfException: Trailer not found.".

My use case is creating a PdfReader instance using inputSream and then creating PdfDocument from the reader and passing PdfWriter as a constructor parameter. We are trying to modify existing PDF, and the sample code is as below

PdfReader pdfReader = new PdfReader(inputStream);
pdfReader.setUnethicalReading(true);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PdfDocument pdfDocument = new PdfDocument(pdfReader, new PdfWriter(os));

What am I doing wrong and how can we fix this issue?

We have a utility method that writes the output stream and creates a new PDF attachment.

Upvotes: 0

Views: 10849

Answers (2)

Jhonathan Correa
Jhonathan Correa

Reputation: 1

I had this exact same problem after add some elements to document (itextpdf 7.2.1), but the instance of PdfDocument was being closed (using a "try with resources"):

public static byte[] stampDocument(byte[] fileBytes, Integer startPageNumber) throws IOException {
    try (ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfDocument pdf = new PdfDocument(new PdfReader(bais), new PdfWriter(baos, new WriterProperties().setFullCompressionMode(true)))) {
        addStamps(pdf, startPageNumber);
        baos.flush();
        return baos.toByteArray();
    }
}

private static void addStamps(PdfDocument pdf, Integer startPageNumber) throws IOException {
    int iStartPageNumber = (startPageNumber == null ? 0 : startPageNumber - 1);

    for (int i = 1; i <= pdf.getNumberOfPages(); i++) {
        Rectangle rect = pdf.getPage(i).getPageSize();
        PdfCanvas canvas = new PdfCanvas(pdf.getPage(i).newContentStreamBefore(), pdf.getPage(i).getResources(), pdf);
        stampPage(canvas, iStartPageNumber + i, rect.getHeight(), rect.getWidth());
    }
}

private static void stampPage(PdfCanvas canvas, int pageNumber, float height, float width) throws IOException { 
    float x = width - 85;
    float y = height - 100;
    
    Rectangle recta = new Rectangle(x, y, 75, 75);
    try (Canvas ca = new Canvas(canvas, recta)) {
        ca.showTextAligned(new Paragraph(new Text(String.valueOf(pageNumber)).setFontSize(FONT_SIZE)), x + (recta.getWidth()/2), recta.getHeight()/2 - FONT_SIZE/2  + y, TextAlignment.CENTER);
    }
    canvas.rectangle(recta);
}

The solution was add a Document instance to be closed after add the new elements:

public static byte[] stampDocument(byte[] fileBytes, Integer startPageNumber) throws IOException {
    try (ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfDocument pdf = new PdfDocument(new PdfReader(bais), new PdfWriter(baos, new WriterProperties().setFullCompressionMode(true)))) {
        Document doc = new Document(pdf);
        addStamps(pdf, startPageNumber);
        doc.close();
        baos.flush();
        return baos.toByteArray();
    }
}

Upvotes: 0

Amedee Van Gasse
Amedee Van Gasse

Reputation: 7634

Copying the answer from the comments:

I got this issue fixed, I need to close pdfDocument before I am writing attachments from the output stream.

I was not closing the stream properly, I created the pdfDocument instance and reading from output stream before closing the pdfDocument. So I need to close pdfDocument stream first and then read from output stream to create attachments.

Upvotes: 5

Related Questions