簡體   English   中英

在 pdfbox 中使用 PDType0Font 時出現 PDFTextStripper().getText 問題

[英]Problem with PDFTextStripper().getText when using PDType0Font in pdfbox

我最近開始使用 PDType0Font(我們使用了 PDType1Font.HELVETICA 但需要 unicode 支持)並且我面臨一個錯誤,我使用 PDPageContentStream 向文件添加行但 PDFTextStripper.getText 沒有得到更新文件內容。

我正在加載字體:

PDType0Font.load(document, fontFile)

並按如下方式創建 contentStream:

PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.PREPEND, false)

我將內容添加到 pdf 的功能是:

  private fun addTextToContents(contentStream: PDPageContentStream, txtLines: List<String>, x: Float, y: Float, pdfFont: PDFont, fontSize: Float, maxWidth: Float) {
     contentStream.beginText()
     contentStream.setFont(pdfFont, fontSize)
     contentStream.newLineAtOffset(x, y)
     txtLines.forEach { txt ->
       contentStream.showText(txt)
       contentStream.newLineAtOffset(0.0F, -fontSize)
     }
     contentStream.endText()
     contentStream.close()

當我嘗試使用 PDFTextStripper.getText 讀取文件內容時,我會在更改之前獲取文件。 但是,如果我在閱讀 PDFTextStripper 之前添加 document.save,它會起作用。

      val txt: String = PDFTextStripper().getText(doc) //not working

      doc.save(//File)
      val txt: String = PDFTextStripper().getText(doc) //working

如果我在使用 PDType1Font.HELVETICA

contentStream.setFont(pdfFont, fontSize)

一切正常,沒有任何問題,並且在閱讀文本之前無需保存文檔。

我懷疑問題出在 PDPageContentStream.showTextInternal() 中的代碼上:

        // Unicode code points to keep when subsetting
    if (font.willBeSubset())
    {
        int offset = 0;
        while (offset < text.length())
        {
            int codePoint = text.codePointAt(offset);
            font.addToSubset(codePoint);
            offset += Character.charCount(codePoint);
        }
    }

這是將 PDType0Font 與 embedsubsets 和 PDType1Font 一起使用時唯一不同的地方。

有人可以幫忙嗎? 我究竟做錯了什么?

您的問題,特別是引用的代碼,已經暗示了您問題的答案:

當使用子集字體( font.willBeSubset() == true )時,關聯的 PDF 對象在保存文件之前未完成。 另一方面,文本提取需要完成的 PDF 對象才能正常工作。 因此,不要將文本提取應用於仍在創建的文檔並使用將是子集的字體。

您將您的用例描述為

對於我們的單元測試,我們將文本(對我們來說是強制性文本)添加到文檔中,然后使用 PDFTextStripper 驗證文件是否具有正確的字段。

正如 Tilman 所建議的那樣:那么保存 PDF 然后重新加載會更有意義。 那將是一個更現實的測試。 恕我直言,不儲蓄就是偷工減料。

實際上,在單元測試中,您應該首先生成最終的 PDF,因為它將被發送(即,將其保存到文件系統或內存中),然后重新加載該文件,並僅測試這個重新加載的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM