简体   繁体   中英

merge multiple pdfs in order


hey guys sorry for long post and bad language and if there is unnecessary details
i created multiple 1page pdfs from one pdf template using excel document
i have now
something like this
tempfile0.pdf
tempfile1.pdf
tempfile2.pdf
...
im trying to merge all files in one single pdf using itext5
but it semmes that the pages in the resulted pdf are not in the order i wanted per exemple
tempfile0.pdf in the first page
tempfile1. int the 2000 page
here is the code im using.
the procedure im using is:
1 filling a from from a hashmap
2 saving the filled form as one pdf
3 merging all the files in one single pdf

public void fillPdfitext(int debut,int fin) throws IOException, DocumentException {


    for (int i =debut; i < fin; i++) {
        HashMap<String, String> currentData = dataextracted[i];
        // textArea.appendText("\n"+pdfoutputname +" en cours de preparation\n ");
        PdfReader reader = new PdfReader(this.sourcePdfTemplateFile.toURI().getPath());
        String outputfolder = this.destinationOutputFolder.toURI().getPath();
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputfolder+"\\"+"tempcontrat"+debut+"-" +i+ "_.pdf"));
        // get the document catalog
        AcroFields acroForm = stamper.getAcroFields();
        // as there might not be an AcroForm entry a null check is necessary
        if (acroForm != null) {
            for (String key : currentData.keySet()) {
                try {

                    String fieldvalue=currentData.get(key);
                    if (key=="ADRESSE1"){
                        fieldvalue = currentData.get("ADRESSE1")+" "+currentData.get("ADRESSE2") ;
                        acroForm.setField("ADRESSE", fieldvalue);
                    }
                    if (key == "IMEI"){

                        acroForm.setField("NUM_SERIE_PACK", fieldvalue);

                    }
                    acroForm.setField(key, fieldvalue);
                    // textArea.appendText(key + ": "+fieldvalue+"\t\t");
                } catch (Exception e) {
                    // e.printStackTrace();
                }
            }
            stamper.setFormFlattening(true);
        }
        stamper.close();
    }

}

this is the code for merging

 public void Merge() throws IOException, DocumentException
{
     File[] documentPaths = Main.objetapp.destinationOutputFolder.listFiles((dir, name) -> name.matches( "tempcontrat.*\\.pdf" ));
    Arrays.sort(documentPaths, NameFileComparator.NAME_INSENSITIVE_COMPARATOR);

    byte[] mergedDocument;

    try (ByteArrayOutputStream memoryStream = new ByteArrayOutputStream())
    {
        Document document = new Document();
        PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document, memoryStream);
        document.open();

        for (File docPath : documentPaths)
        {
            PdfReader reader = new PdfReader(docPath.toURI().getPath());
            try
            {
                reader.consolidateNamedDestinations();

                    PdfImportedPage pdfImportedPage = pdfSmartCopy.getImportedPage(reader, 1);
                    pdfSmartCopy.addPage(pdfImportedPage);

            }
            finally
            {
                pdfSmartCopy.freeReader(reader);
                reader.close();
            }
        }

        document.close();
        mergedDocument = memoryStream.toByteArray();
    }



    FileOutputStream stream = new FileOutputStream(this.destinationOutputFolder.toURI().getPath()+"\\"+
            this.sourceDataFile.getName().replaceFirst("[.][^.]+$", "")+".pdf");
    try {
        stream.write(mergedDocument);
    } finally {
        stream.close();
    }

    documentPaths=null;
    Runtime r = Runtime.getRuntime();
    r.gc();
}

my question is how to keep the order of the files the same in the resulting pdf

It is because of naming of files. Your code new FileOutputStream(outputfolder + "\\\\" + "tempcontrat" + debut + "-" + i + "_.pdf") will produce:

  • tempcontrat0-0_.pdf
  • tempcontrat0-1_.pdf
  • ...
  • tempcontrat0-10_.pdf
  • tempcontrat0-11_.pdf
  • ...
  • tempcontrat0-1000_.pdf

Where tempcontrat0-1000_.pdf will be placed before tempcontrat0-11_.pdf , because you are sorting it alphabetically before merge.

It will be better to left pad file number with 0 character using leftPad() method of org.apache.commons.lang.StringUtils or java.text.DecimalFormat and have it like this tempcontrat0-000000.pdf , tempcontrat0-000001.pdf , ... tempcontrat0-9999999.pdf .


And you can also do it much simpler and skip writing into file and then reading from file steps and merge documents right after the form fill and it will be faster. But it depends how many and how big documents you are merging and how much memory do you have.

So you can save the filled document into ByteArrayOutputStream and after stamper.close() create new PdfReader for bytes from that stream and call pdfSmartCopy.getImportedPage() for that reader. In short cut it can look like:

// initialize

PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document, memoryStream);
for (int i = debut; i < fin; i++) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    // fill in the form here

    stamper.close();    
    PdfReader reader = new PdfReader(out.toByteArray());
    reader.consolidateNamedDestinations();
    PdfImportedPage pdfImportedPage = pdfSmartCopy.getImportedPage(reader, 1);
    pdfSmartCopy.addPage(pdfImportedPage);

    // other actions ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM