使用PDFBox后的编码问题

问题描述 投票:1回答:1

我必须

  1. 从pdf提取文本,我在这里粗略地使用它

    f = IOUtility.getFileForPath(filePath);
    RandomAccessFile randomAccessFile = new RandomAccessFile(f, "r");
    PDFParser parser = new PDFParser(randomAccessFile);
    parser.parse();
    cosDoc = parser.getDocument();
    pdfStripper = new PDFTextStripper();
    pdDoc = new PDDocument(cosDoc);
    pdfStripper.setStartPage(1);
    pdfStripper.setEndPage(pdDoc.getNumberOfPages());
    String parsedText = pdfStripper.getText(pdDoc);
    
  2. 缩放PDF

    File PDFFile = IOUtility.getFileForPath(scaleConfig.getFilePath());
    document = PDDocument.load(PDFFile);
    
    for (PDPage page : document.getPages()) {
        PDRectangle cropBox = page.getCropBox();
        float tx = ((cropBox.getLowerLeftX() + cropBox.getUpperRightX()) * 0.03f) / 2;
        float ty = ((cropBox.getLowerLeftY() + cropBox.getUpperRightY()) * 0.03f) / 2;
        PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false);
        cs.transform(Matrix.getScaleInstance(0.97f, 0.97f));
        cs.transform(Matrix.getTranslateInstance(tx, ty));
        cs.close();
    }
    document.save(scaleConfig.getTargetFilePath());
    
  3. ,最后在pdf的每一页上写点东西。我使用这里提到的14种受支持的字体之一https://pdfbox.apache.org/1.8/cookbook/workingwithfonts.html。在这种情况下为Times New Roman。

    File PDFFile = IOUtility.getFileForPath(writeConfig.getFilePath());
    document = PDDocument.load(PDFFile);
    for (PDPage page : document.getPages()) {
        PDFBoxHelper.fixRotation(document, page);
        writeStringOnPage(document, page, writeConfig);
    }
    document.save(writeConfig.getTargetFilePath());
    

    [writeStringOnPage正在执行

    contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false, true);
    WriteCoordinates writeCoordinates = WriteCoordinateFactory.buildCoordinates(writeConfig, page.getMediaBox());
    contentStream.beginText();
    // lower left x and lower left y are different after rotation so use those for your calculation
    contentStream.newLineAtOffset(writeCoordinates.getX(), writeCoordinates.getY());
    contentStream.setFont(writeConfig.getFont(), writeConfig.getFontSize());
    contentStream.setNonStrokingColor(writeConfig.getFontColor());
    contentStream.showText(writeConfig.getToWrite());
    contentStream.endText();
    

由于公司原因,我省略了签名和识别块。我总是关闭内容流。

大多数情况下,处理过的PDF在Chrome PDF-Viewer,Acrobat Reader中以及将它们导入BMD后看起来都很好。但是在某些特定情况下,我似乎有编码问题,某些部分无法正确显示。我添加到PDF上的所有文本始终正确显示。

我意识到在PDF中仅粗体显示了错误显示的文本,所以我使用Adobe Acrobat Reader查看所使用的字体。

eingebettete Schriften

Arial和Arial,Bold被嵌入并使用Identity-H进行编码。当一切都以粗体显示时,我得出结论,所有以Arial,Bold书写的文本均显示错误。处理pdf后,其他一切都还不错。我无法添加pdf,因为它具有客户数据,但以下是一些示例:

  1. Rechnungs-Nr:-> 5HFKQXQJV1U
  2. 60 Tage netto(27.12.2019)-> 7DJHQHWWR

如果PDF是在没有PDFBox操作的情况下以BMD导入的,则显示正确。

我试图仅通过缩放和仅写来缩小问题的范围,但是两次都出现了问题。

我正在使用PDFBox 2.017和Java 8。

因为当我仅缩放我使用的PDF时也会发生错误,因此[比较原始PDF:

orignal PDF

和我缩放后的pdf:

scaled PDF

唯一看起来不同/不同的是目录条目。

当我打开缩放的PDF时,单击字体部分和Arial,Bold字体,我会收到很多有关unicode映射的警告。 PDF可以正确显示在PDFDebugger中。

warnings

我既不是PDFBox的专家,也不是字体和编码的专家,所以将不胜感激!

java pdf encoding pdfbox
1个回答
0
投票
简而言之

相关的区别是PDFBox对名称的序列化方式不同。但是根据PDF规范的不同输出是等效的,因此您显然已经发现了WPViewPDF错误。

写名字的区别

在原始PDF(raw.pdf)中,您找到名称

NOWFJV + Arial,Bold和NOWFJV + Arial,Bold-WinCharSetFFFF,在由PDFBox处理的所有文件中,所有这些名称的出现在内容流之外被NOWFJV + Arial#2CBoldNOWFJV + Arial#2CBold-WinCharSetFFFF代替。

WPViewPDF无法正确显示以这些更改的名称字体显示的文本。将PDF修补回以在这些名称中包含逗号代替“#2C”之后,WPViewPDF再次正确显示此类文本。

我以为WPViewPDF在内容流中找到了

NOWFJV + Arial,Bold

,并期望使用相同的书写名称在页面资源中找到匹配的字体定义,因此它无法使用名称 NOWFJV + Arial#2CBold是PDFBox错误吗?

根据PDF规范,>

名称中的任何常规字符(除NUMBER SIGN之外的字符均应以其本身或使用其2位数的十六进制代码并以NUMBER SIGN开头的形式编写。

(ISO 32000-2,第7.3.5节“名称对象”)

因此,用'#2C'序列替换名称中的逗号是写这些名称的完全有效的替代方法。

因此,不是,这不是PDFBox错误,但显然是WPViewPDF错误。

© www.soinside.com 2019 - 2024. All rights reserved.