当前位置: 首页 > 知识库问答 >
问题:

在PDFBox中使用覆盖后,adobe中字体的PDF问题

阚小云
2023-03-14

我们在其中一个应用程序中使用pdfbox。一些叠加的PDF会导致输出和字体“损坏”。

下面是我用来覆盖pdf的示例代码。pdf有时具有不同的页数。我们将顶角变平,并将注释设置为只读。pdf页面旋转和bbox大小有时设置不同(尤其是扫描仪),所以我们试图纠正这一点。

    PDDocument baseDocument = PDDocument.load(new File("base.pdf"));
    PDDocument overlayDocument = PDDocument.load(new File("overlay.pdf"));
    Iterator<PDPage> baseDocumentIterator = baseDocument.getPages().iterator();
    Iterator<PDPage> overlayIterator = overlayDocument.getPages().iterator();
    PDDocument finalOverlayDoc = new PDDocument();
    while(baseDocumentIterator.hasNext() && overlayIterator.hasNext()) {
        PDPage backing = baseDocumentIterator.next();
        //locking annotations per page
        List<PDAnnotation> annotations = backing.getAnnotations();
        for (PDAnnotation a :annotations) {
            a.setLocked(true);
            a.setReadOnly(true);
        }
        // setting size so there's no weird overflow issues
        PDRectangle rect = new PDRectangle();
        rect.setLowerLeftX(0);
        rect.setLowerLeftY(0);
        rect.setUpperRightX(backing.getBBox().getWidth());
        rect.setUpperRightY(backing.getBBox().getHeight());
        backing.setCropBox(rect);
        backing.setMediaBox(rect);
        backing.setBleedBox(rect);
        PDPage pg = overlayIterator.next();
        //setting rotation if different. Some scanners cause issues.
        if(backing.getRotation()!= pg.getRotation())
        {
            pg.setRotation(-backing.getRotation());
        }
        finalOverlayDoc.addPage(pg);
    }
    finalOverlayDoc.close();
    //flatten acroform
    PDAcroForm acroForm = baseDocument.getDocumentCatalog().getAcroForm();
    if (acroForm != null) {
        acroForm.flatten();
        acroForm.setNeedAppearances(false);
    }
    Overlay overlay = new Overlay();
    overlay.setOverlayPosition(Overlay.Position.FOREGROUND);
    overlay.setInputPDF(baseDocument);
    overlay.setAllPagesOverlayPDF(finalOverlayDoc);

    Map<Integer, String> ovmap = new HashMap<Integer, String>();
    overlay.overlay(ovmap);
    PDPageTree allOverlayPages = overlayDocument.getPages();
    if(baseDocument.getPages().getCount() < overlayDocument.getPages().getCount()) //Additional pages in the overlay pdf need to be appended to the base pdf.
    {
        for(int i=baseDocument.getPages().getCount();i<allOverlayPages.getCount(); i++)
        {
            baseDocument.addPage(allOverlayPages.get(i));
        }
    }
    PDDocument finalDocument = new PDDocument();
    for(PDPage p: baseDocument.getPages()){
        finalDocument.addPage(p);
    }

    String filename = "examples/merge_pdf_examples/debug.pdf";
    filename = filename + new Date().getTime() + ".pdf";
    finalDocument.save(filename);
    finalDocument.close();
    baseDocument.close();
    overlayDocument.close();

共有1个答案

鲁浩渺
2023-03-14

您共享的PDF文件中没有与使用Overlay相关的错误。

它使用了一个很少使用的PDF功能,但是,页面从其父节点继承资源:PDF中的页面对象排列在树中,实际页面是叶子;此树中的页面对象本身通常携带定义它的所有信息,但许多页面属性也可以由内部节点携带并由后代页面继承,除非它们重写它们。

共享代码后,您的准备步骤会丢失所有继承的信息:当您从overlydocument生成finaleverlaydoc时,您基本上会:

java prettyprint-override">while(overlayIterator.hasNext()) {
    PDPage pg = overlayIterator.next();
    //setting rotation if different. Some scanners cause issues.
    finalOverlayDoc.addPage(pg);
}

说明:OverlayDocuments testtestOverlayPREationSuspleBroken

这里只传输页面对象本身,失去所有继承的属性。

对于手头的文档,可以通过将页面资源显式设置为继承的资源来解决此问题:

while(overlayIterator.hasNext()) {
    PDPage pg = overlayIterator.next();
    pg.setResources(pg.getResources());
    //setting rotation if different. Some scanners cause issues.
    finalOverlayDoc.addPage(pg);
}

(OverlayDocuments testtestOverlayPREationFixedCanpleBroken

不过要注意:这只是显式地设置页面资源,但还有其他可以继承的页面属性。

因此,我建议您根本不创建新的PDDocument;不要将overlydocument页面移动到finalOverlayDoc中,只在适当的位置更改它们。如果overlydocument的页面数超过baseDocument,您还必须从overlydocument中删除多余的页面。然后在叠加中使用overlydocument,而不是finalOverlayDoc

再往下看代码,我看到您一次又一次地重复将页面对象移动到其他文档的反模式,而不尊重继承的属性。我想你应该彻底修改代码,去掉反模式。

 类似资料:
  • 我正在阅读一个PDF文件,它有可编辑的字段,这些字段可以通过Adobe Reader打开它来编辑。我正在使用PDFBox API生成一个输出PDF,输入PDF中的可编辑字段填充了数据。可以使用Adobe Reader打开输出PDF,我可以看到字段值,但无法直接从Adobe Reader编辑这些字段。 这个问题还有一张JIRA票,根据本链接未解决: 每次打开使用pdfbox API编写的PDF文件时

  • 注意: Adobe Muse 不再添加新增功能,并将于 2020 年 3 月 26 日停止支持。有关详细信息和帮助,请参阅 Adobe Muse 服务结束页面。 注意:   Typekit 现已更名为 Adobe Fonts,包含在 Creative Cloud 和其他订阅中。了解详情。 使用 Adobe Muse 设计网页时,可以在三种不同的字体类型之间选择要应用到文本的字体。发布或导出页面时,

  • 请,我想知道从pdf中提取的字体是否嵌入,如何使用PDFBox实现这一点?

  • 我有一个pdf模板,我试图在新文档中重写它。我需要从模板PDF中获取一些字段,并在新的PDF中重写它们的值。我这样做: 但我发现了一个例外: iText。内核PDFEException:“没有用于生成间接项的关联PdfWriter。” 我做错了什么以及如何修复它?这是第七次。

  • 早上好 我有一个新手PDFbox的问题,我希望一些帮助... 我刚刚(上周)从github下载了最新的PDFbox源代码,正在尝试创建HelloWorldOTF。java,基于HelloWorldTTF。java示例,希望创建一个PDF文件,该文件使用OTF字体(本例中为Adobe Caslon Pro Regular)将文本添加到输出PDF中。 到目前为止,我有以下信息: 我可以使用以下代码加载

  • 问题内容: 是否可以覆盖移动Chrome中的字体增强功能?我在〜包括stackoverflow〜之前搜索了互联网。 我发现有人说这是不可能的,而且我还发现了元标记可以帮助文本,但同时也减小了文本的面积……这不好。 感谢您的帮助。 问题答案: 将以下行添加到我的reset.css对我有用