使用PDFBox从生成的PDF中复制粘贴文本会导致垃圾

时间:2017-12-07 16:36:54

标签: java pdf fonts copy-paste pdfbox

我有一些代码,它采用模板PDF,创建一个新的PDF,将新PDF覆盖在模板PDF上,并将结果写入流。所有这些都使用PDFBox 2.0.4。

问题在于,将生成的PDF中的文本复制粘贴到文本编辑器会导致垃圾文本。

仅在我的代码添加的文本中发生这种情况,原始模板中的文本仍能正常工作。我添加的文本使用自定义字体添加。

如何修复生成的PDF以便可以复制粘贴文本?

SSCCE:

public class PDFTest {

    private static final String FONT = "/fonts/font.ttf";

    public static void main(final String... args) throws IOException, FontFormatException {
        final Overlay overlay = new Overlay();
        overlay.setInputPDF(newDocument("Input text", 400));
        overlay.setAllPagesOverlayPDF(newDocument("Test text", 200));

        try (final PDDocument document = overlay.overlay(new HashMap<>())) {
            document.save("example.pdf");
        }
    }

    private static PDDocument newDocument(final String text, final int offsetY) throws IOException, FontFormatException {
        final PDDocument document = new PDDocument();
        document.addPage(insertTextInPage(document, text, offsetY));
        return document;
    }

    private static PDPage insertTextInPage(final PDDocument document, final String text, final int offsetY) throws IOException, FontFormatException {
        try (final InputStream fontStream = PDFTest.class.getResourceAsStream(FONT)) {
            final PDFont normalFont = PDType0Font.load(document, fontStream);

            final PDPage page = new PDPage();
            try (final PDPageContentStream contentStream = new PDPageContentStream(document, page, APPEND, false)) {
                addTextBlock(contentStream, normalFont, text, offsetY);
            }
            return page;
        }
    }

    private static void addTextBlock(final PDPageContentStream contentStream, final PDFont font, final String text, final int offsetY)
            throws IOException {
        contentStream.beginText();
        contentStream.setFont(font, 16);
        contentStream.newLineAtOffset(20, offsetY);
        contentStream.showText(text);
        contentStream.endText();
    }
}

1 个答案:

答案 0 :(得分:0)

这是一个已知问题(PDFBOX-3243),使用子集化字体构建的文件(您使用的PDType0Font.load()非常有效)处于中间状态,直到它们被保存为止,这是时间子集化发生。

您的解决方案:保存和重新加载,或保存到假人。在Windows中我像这样更改了newDocument并且它有效:

private static PDDocument newDocument(final String text, final int offsetY) throws IOException, FontFormatException
{
    final PDDocument document = new PDDocument();
    document.addPage(insertTextInPage(document, text, offsetY));
    document.save("nul"); // NEW!
    return document;
}