Best approach to use PdfStamper in for loop

后端 未结 1 1451
灰色年华
灰色年华 2021-01-25 04:10

I have below iText code to read files and adding it into master PDF file, so it is basically adding PDF page in the existing PDF at absolute position. Absolute posi

1条回答
  •  囚心锁ツ
    2021-01-25 04:26

    As explained in my answer to Extract pdf page and insert into existing pdf, using PdfStamper is only one way to meet your requirement. PdfStamper is probably your best choice if you need to manipulate a single PDF document and it's possible to add a single page from another PDF as my previous answer demonstrates.

    However, you now indicate that you have to concatenate multiple PDF files. In that case, using PdfStamper isn't the best choice. You should consider switching to PdfCopy:

    Suppose that you have the following files.

    String[] paths = new String[]{
        "resources/to_be_inserted_1.pdf",
        "resources/to_be_inserted_2.pdf",
        "resources/to_be_inserted_3.pdf"
    };
    

    You need to insert the first page (and only the first page) of each of these documents at the start of an existing PDF with path "resources/main_document.pdf", then you could do something like this:

    Document document = new Document();
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest));
    document.open();
    PdfReader reader;
    for (String path : paths) {
        reader = new PdfReader(path);
        copy.addPage(copy.getImportedPage(reader, 1));
        reader.close();
    }
    reader = new PdfReader("resources/main_document.pdf");
    copy.addDocument(reader);
    reader.close();
    document.close();
    

    As you can see, the addPage() method adds a single page, whereas the addDocument() method adds all the pages of a document.

    Update

    It seems that you don't want to insert new pages, but that you want to superimpose pages: you want to add pages on top of or under existing content.

    In that case, you indeed need PdfStamper, but you're making two crucial errors.

    1. You close the stamper inside the loop. Once the stamper is closed, it is closed: you can't add any more content to it. You need to move stamper.close() outside the loop.
    2. You close the reader inside the loop, but stamper hasn't released the reader yet. You should free the reader first.

    This is shown in the SuperImpose example:

    public static final String SRC = "resources/pdfs/primes.pdf";
    public static final String[] EXTRA =
        {"resources/pdfs/hello.pdf", "resources/pdfs/base_url.pdf", "resources/pdfs/state.pdf"};
    public static final String DEST = "results/stamper/primes_superimpose.pdf";
    
    PdfReader reader = new PdfReader(SRC);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
    PdfContentByte canvas = stamper.getUnderContent(1);
    PdfReader r;
    PdfImportedPage page;
    for (String path : EXTRA) {
        r = new PdfReader(path);
        page = stamper.getImportedPage(r, 1);
        canvas.addTemplate(page, 0, 0);
        stamper.getWriter().freeReader(r);
        r.close();
    }
    stamper.close();
    

    In this case, I always add the imported pages to page 1 of the main document. If you want to add the imported pages to different pages, you need to create the canvas object inside the loop.

    0 讨论(0)
提交回复
热议问题