按顺序合并多个 PDF




嘿伙计们很抱歉长帖子和糟糕的语言,如果有不必要的细节
我使用 Excel 文档从一个 PDF 模板创建了多个 1 页 PDF
我现在有
像这样的东西
临时文件0.pdf
临时文件1.pdf
临时文件2.pdf

IM 尝试使用 itext5 将所有文件合并到一个 PDF 中
但它发现结果 PDF 中的页面不符合我想要的顺序 每个示例
tempfile0.pdf 在第一页
临时文件1. int the 2000 page
这是我使用的代码。
IM 使用的过程是:
1 从哈希图填充 a from
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 preparationn ");
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+"tt");
} 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 中保持文件的顺序相同

这是因为文件的命名。您的代码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之前,因为您在合并之前按字母顺序对其进行排序。

最好使用 leftPad(( 方法org.apache.commons.lang.StringUtilsjava.text.DecimalFormat将带有0字符的填充文件编号,并像这样使用它 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 ...
}

最新更新