объединить несколько PDF-файлов по порядку - PullRequest
0 голосов
/ 06 сентября 2018


Эй, ребята, извините за длинный пост и плохой язык, и если есть ненужные детали
Я создал несколько одностраничных PDF-файлов из одного шаблона PDF, используя документ Excel.
у меня сейчас
как то так
tempfile0.pdf
tempfile1.pdf
tempfile2.pdf
...
я пытаюсь объединить все файлы в один PDF-файл, используя itext5
но кажется, что страницы в полученном pdf находятся не в том порядке, который я хотел за пример
tempfile0.pdf на первой странице
tempfile1. на странице 2000
вот код, который я использую.
процедура, которую я использую:
1 заполнение от из hashmap
2 сохранение заполненной формы в формате pdf
3 объединение всех файлов в один 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();
    }

}

это код для слияния

 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();
}

мой вопрос, как сохранить порядок файлов в полученном pdf

1 Ответ

0 голосов
/ 06 сентября 2018

Это из-за именования файлов. Ваш код new FileOutputStream(outputfolder + "\\" + "tempcontrat" + debut + "-" + i + "_.pdf") будет производить:

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

Где tempcontrat0-1000_.pdf будет размещено перед tempcontrat0-11_.pdf , потому что вы сортируете его по алфавиту перед объединением.

Лучше будет оставить номер файла левой панели с символом 0, используя leftPad () метод org.apache.commons.lang.StringUtils или java.text.DecimalFormat, и иметь его так: tempcontrat0-000000.pdf , tempcontrat0-000001.pdf , ... tempcontrat0-9999999.pdf .


И вы также можете сделать это намного проще и пропустить запись в файл, а затем чтение из шагов файла и объединить документы сразу после заполнения формы, и это будет быстрее. Но это зависит от того, сколько и сколько документов вы объединяете и сколько у вас памяти.

Таким образом, вы можете сохранить заполненный документ в ByteArrayOutputStream и после stamper.close() создать новый PdfReader для байтов из этого потока и вызвать pdfSmartCopy.getImportedPage() для этого считывателя. Вкратце это может выглядеть так:

// 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 ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...