Search code examples
pdfitextitext7

Itext7 null exception error when removing pages from the PDF


I'm trying to keep the range of pages in the PDF with 12 pages total and remove the rest

PdfReader pdfReader = new PdfReader("src/main/sample/test_doc2.pdf");
pdfReader.setUnethicalReading(true);
PdfDocument inputPDF = new PdfDocument(pdfReader);
PdfDocument outputPDF = new PdfDocument(new PdfWriter("src/main/sample/output.pdf").setSmartMode(true));
inputPDF.copyPagesTo(1, inputPDF.getNumberOfPages(), outputPDF, new PdfPageFormCopier());

Integer pages[] = {
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    // 10,
    // 11,
    12
};
ListIterator<Integer> pagesList = Arrays.asList(pages).listIterator(pages.length);


while (pagesList.hasPrevious()) {
    outputPDF.removePage(pagesList.previous());
}

outputPDF.close();

This works for most ranges, but for certain ones (ie, if I want to keep only pages 10 and 11) I'm getting a null pointer exception in PDFPagesTree.class::generate_tree() itext method on line 303:

assert current != null;
current.addPages(pages);

I tried with different documents, and consistently getting the null pointer exception for ranges 10-11.


Solution

  • This is indeed a bug in iText. As a workaround you can try calculating which pages you want to leave in the end instead of copying them first and removing some of them afterwards.

    Alternatively, you can use an intermediate PDF for your result after copying pages from the source document, and then you can create another PdfDocument for removing some of the pages from the intermediate PDF and producing the final result.

    Here is the example of such approach:

    PdfReader pdfReader = new PdfReader(inputPdf);
    pdfReader.setUnethicalReading(true);
    PdfDocument inputPDF = new PdfDocument(pdfReader);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfDocument tempPDF = new PdfDocument(new PdfWriter(baos));
    inputPDF.copyPagesTo(1, inputPDF.getNumberOfPages(), tempPDF, new PdfPageFormCopier());
    tempPDF.close();
    
    PdfDocument outPDF = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())),
            new PdfWriter(outputPdf));
    
    Integer pages[] = {
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            // 10,
            // 11,
            12
    };
    ListIterator<Integer> pagesList = Arrays.asList(pages).listIterator(pages.length);
    
    while (pagesList.hasPrevious()) {
        outPDF.removePage(pagesList.previous());
    }
    
    outPDF.close();