Java apache PDFBox-合并/标记PDF覆盖在覆盖和输入PDF上维护超链接?

Java apache PDFBox-合并/标记PDF覆盖在覆盖和输入PDF上维护超链接?,java,overlay,pdfbox,Java,Overlay,Pdfbox,我们正在尝试实现ApachePDFBoxOverlay。它工作得很好,但是,覆盖页上的超链接会丢失 在我们的案例中,客户上传一个覆盖图,上面有经常可点击的详细信息,如网站和电子邮件地址。前景PDF是发票,它还可以包含超链接,例如指向产品页面的超链接 基本上这是我们的代码: Overlay overlay = new Overlay(); //org.apache.pdfbox.multipdf.Overlay overlay.setInputPDF(inputDoc); //PDDDocume

我们正在尝试实现ApachePDFBoxOverlay。它工作得很好,但是,覆盖页上的超链接会丢失

在我们的案例中,客户上传一个覆盖图,上面有经常可点击的详细信息,如网站和电子邮件地址。前景PDF是发票,它还可以包含超链接,例如指向产品页面的超链接

基本上这是我们的代码:

Overlay overlay = new Overlay();  //org.apache.pdfbox.multipdf.Overlay
overlay.setInputPDF(inputDoc); //PDDDocument inputDoc with hyperlinks
overlay.setDefaultOverlayPDF(overlayDoc); //PDDDocument overlayDoc with hyperlinks
inputDoc上的超链接仍然有效,但OverlyDoc上的超链接无效。是否有另一种方法(使用PDFBox)在保持超链接等交互的同时,将覆盖PDF标记到inputDoc上


[更新]:可能的解决方案发布在下面。

解决方案

这是一个相当令人困惑的问题,令人惊讶的是,在这件事上几乎找不到什么信息。然而,最终它非常简单,我设法让它工作起来

基本上我所做的是(下面的代码示例):

  • 从覆盖PDF获取注释
  • 使用PDFBox overlay将输入文档与覆盖PDF覆盖
  • 保存新的覆盖文档
  • 遍历新文档页面:PDDocument.getPages()
  • 对于新文档中的每个页面,添加覆盖PDF中的注释
  • 就这些
看起来很好用。我唯一不确定的是我在下面的代码中执行annot.setPage(p)的部分。因为每次对于同一注释,我都会在新文档中设置不同的页面。它可以工作,但我认为创建一个新的注释实例并将新注释添加到文档中会更干净。但是,我还没有弄清楚如何将注释克隆到新实例中。欢迎对此提出意见:)

以下是我的(略带删节的)代码,供感兴趣的人参考:

//instantiate PDDocuments for input PDF and overlay PDF
PDDocument PDDDoc_inputDoc = PDDocument.load(...);
PDDocument PDDDoc_overlay = PDDocument.load(...);

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); 

//create PDFBox overlay
Overlay overlay = new Overlay();
overlay.setOverlayPosition(Overlay.Position.BACKGROUND);

//set inputDoc and overlayDoc PDFs
overlay.setInputPDF(PDDDoc_inputDoc);
overlay.setDefaultOverlayPDF(PDDDoc_overlay);

//execute overlay function
overlay.overlay(new HashMap<>()).save(baos);

//create new PDDocument from overlay
PDDocument PDD_newOverlaydDocument = PDDocument.load(new ByteArrayInputStream(baos.toByteArray()));

//for every page in the new (overlayed) document, add annotation from the source overlay PDF to the new PDF
PDPageTree pages = PDD_newOverlaydDocument.getPages();
for(PDPage p : pages){
    //get annotations from new document page
    List<PDAnnotation> pageAnnotations = p.getAnnotations();
                
    //add annotations from overlay page to the page
    for(PDAnnotation annot : overlayAnnotations) {
        annot.setPage(p);
        pageAnnotations.add(annot);
    }
}
        
//save new PDDDocument to outputstream or file and dow whatever you want with it        
PDD_newOverlaydDocument.save(...);

//close streams, cleanup, etc
....

//为输入PDF和覆盖PDF实例化PDDocuments
PDDocument PDDDoc_inputDoc=PDDocument.load(…);
PDDocument PDDDoc_overlay=PDDocument.load(…);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
ByteArrayOutputStream=newbytearrayoutputstream();
//创建PDFBox覆盖
覆盖层=新覆盖层();
覆盖。设置覆盖位置(覆盖。位置。背景);
//设置inputDoc和OverlyDoc PDF
overlay.setInputPDF(PDDDoc_inputDoc);
setDefaultOverlayPDF(PDDDoc_覆盖);
//执行覆盖函数
overlay.overlay(newhashmap()).save(baos);
//从覆盖创建新文档
PDDocument PDD_newoverlaydocument=PDDocument.load(new ByteArrayInputStream(baos.toByteArray());
//对于新(覆盖)文档中的每一页,将注释从源覆盖PDF添加到新PDF
PDPageTree pages=PDD_newoverlaydocument.getPages();
用于(PDP页:页){
//从新文档页面获取批注
List pageAnnotations=p.getAnnotations();
//将批注从覆盖页添加到该页
用于(PDAnnotation注释:叠加注释){
注释设置页(p);
pageAnnotations.add(annot);
}
}
//将新的PDD文档保存到outputstream或文件中,并根据需要添加任何内容
PDD_newoverlydocument.save(…);
//关闭溪流、清理等
....