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

java中通过pdfbox阅读PDF

齐俊达
2023-03-14

我在使用pdfbox阅读pdf时遇到了一个问题。我的实际pdf部分不可读,所以当我在编辑器中复制和粘贴不可读的部分时,它会显示小方框符号,但当我试图通过pdfbox读取同一文件时,这些字符不会被读取(我也不希望它们被读取)。我希望我至少能得到一些符号或随机字符,而不是实际的字符。有没有办法做到这一点。该行已被选中,因此它不是图像。有人找到解决办法了吗?

有一个pdfbox示例,我们在pdfTextStripper类下重写writeString方法,以获得一些额外的字体属性。我使用这个方法来获取文本和一些字体属性。所以我的问题是为什么pdfbox不能读取每个字符(它可能会打印乱码)。但在我的例子中,我计算了方法被调用的次数(每个方法调用对应于每个字符),发现方法调用的数量与输出文本中的字符数量匹配,但与pdf中的字符总数不匹配。这是一个示例pdf,“利润”这个词是不可读的,pdf甚至没有显示这个词的胡言乱语,它只是完全跳过了它。这里是链接。https://drive.google.com/file/d/0B_Ke2amBgdpedUNwVTR3RVlRTFE/view?usp=sharing

共有1个答案

谭桐
2023-03-14

事实上,实际上整行“截至2014年3月31日的年度损益表”以及更多信息都无法提取;检查内容的原因变得显而易见:本文使用的是一种复合字体,既没有编码,也没有ToUnicode条目,以便识别所讨论的字符。

org.apache.pdfbox.text.PDFTextStreamEngine(派生自PDFTextStripper)方法show Glyph在调用Process TextPotion之前不久(PDFTextStripper实现并从中检索其文本信息)包含以下代码:

// use our additional glyph list for Unicode mapping
unicode = font.toUnicode(code, glyphList);

// when there is no Unicode mapping available, Acrobat simply coerces the character code
// into Unicode, so we do the same. Subclasses of PDFStreamEngine don't necessarily want
// this, which is why we leave it until this point in PDFTextStreamEngine.
if (unicode == null)
{
    if (font instanceof PDSimpleFont)
    {
        char c = (char) code;
        unicode = new String(new char[] { c });
    }
    else
    {
        // Acrobat doesn't seem to coerce composite font's character codes, instead it
        // skips them. See the "allah2.pdf" TestTextStripper file.
        return;
    }
}

所讨论的字体不能为文本提取提供任何线索。因此,unicode这里是null

此外,字体是复合的,而不是简单的。因此,执行else子句,甚至不调用processTextPosition

因此,PDFTextStripper根本不知道“截至2014年3月31日的年度损益表”这一行是否存在!

如果你换掉那个

    else
    {
        // Acrobat doesn't seem to coerce composite font's character codes, instead it
        // skips them. See the "allah2.pdf" TestTextStripper file.
        return;
    }

PDFTextStreamE中ngine.showGlyph通过一些代码设置Unicode,例如使用Unicode替换字符

    else
    {
        // Use the Unicode replacement character to indicate an unknown character
        unicode = "\uFFFD";
    }

你会得到

57
THIRTY SEVENTH ANNUAL REPORT 2013-14
STANDALONE FINANCIAL STATEMENTS
�������������������������������������������������������������
As per our report attached. Directors
For Deloitte Haskins & Sells LLP Deepak S. Parekh Nasser Munjee R. S. Tarneja
Chartered Accountants �������� B. S. Mehta J. J. Irani
D. N. Ghosh Bimal Jalan
Keki M. Mistry S. A. Dave D. M. Sukthankar
Sanjiv V. Pilgaonkar ���������������
Partner �����������������������
Renu Sud Karnad V. Srinivasa Rangan Girish V. Koliyote
������, May 6, 2014 Managing Director ������������������ �����������������
Notes Previous Year
� in Crore � in Crore
INCOME
����������������������� 23  23,894.03  20,796.95 
���������������������������� 24  248.98  315.55 
������������ 25  54.66  35.12 
Total Revenue  24,197.67  21,147.62 
EXPENSES
Finance Cost 26  16,029.37  13,890.89 
�������������� 27  279.18  246.19 
���������������������� 28  86.98  75.68 
�������������� 29  230.03  193.43 
������������������������������ 11 & 12  31.87  23.59 
Provision for Contingencies  100.00  145.00 
Total Expenses  16,757.43  14,574.78 

PROFIT BEFORE TAX  7,440.24  6,572.84 
�����������
�������������  1,973.00  1,727.68 
�������������� 14  27.00  (3.18)
PROFIT FOR THE YEAR 3  5,440.24  4,848.34 
EARNINGS PER SHARE��������������� 2) 31
- Basic 34.89 31.84
- Diluted 34.62 31.45
�������������������������������������������������������������

不幸的是,PDFTextStreamEngine。showGlyph方法使用一些私有类成员。因此,不能简单地在自己的PDFTextStripper类中使用具有上述更改的原始方法代码重写它。要么在自己的类中复制几乎所有PDFTextStreamEngine的功能,要么求助于Java反射,要么自己修补PDFBox类。

这种架构并不完全完美。

第二个文件的情况是由上面引用的同一段PDFBox代码引起的。不过,由于这次字体很简单,所以会执行另一个代码块:

    if (font instanceof PDSimpleFont)
    {
        char c = (char) code;
        unicode = new String(new char[] { c });
    }

这里发生的事情纯粹是猜测:如果没有将字形代码映射到Unicode的信息,让我们假设映射是拉丁-1,它简单地嵌入到char中。正如在OP的第二个文件中可见的那样,这个假设并不总是成立。

如果您不希望PDFBox在此处做出这样的假设,请将上面的if块替换为

    if (font instanceof PDSimpleFont)
    {
        // Use the Unicode replacement character to indicate an unknown character
        unicode = "\uFFFD";
    }

这导致

Aries Agro Care Private Limited
1118th Annual Report 2013-14
Balance Sheet as at 31st March, 2014
Particulars Note
No.
 As at 
31 March, 2014
Rupees
 As at
31 March, 2013
Rupees
I. EQUITY AND LIABILITIES
(1) Shareholder's Funds
(a) ������������� 3  100,000  100,000
(b) Reserves and Surplus 4  (2,673,971) ������������
 (2,573,971) ������������
(2) Current Liabilities
(a) Short Term Borrowings 5  5,805,535 �����������
(b) Trade Payables 6  159,400 ���������
(c) ������������������������� 7  2,500  22,743 
 5,967,435  5,934,756 
TOTAL  3,393,464 �����������
II. ASSETS
(1) Non-Current Assets
(a) �������������������� �  - -
 - -
(2) Current Assets
(a) ����������������������� 9  39,605 �������
(b) ����������������������������� 10  3,353,859 ����������
 3,393,464 ����������
TOTAL  3,393,464 ����������
��������������������������������
The Notes to Accounts 1 to 23 form part of these Financial Statements
As per our report of even date For and on behalf of the Board
For Kirti D. Shah & Associates 
��������������������� 
�����������������������������
Dr. Jimmy Mirchandani
Director
Kirti D. Shah 
Proprietor 
Membership No 32371
Dr. Rahul Mirchandani 
Director
Place : Mumbai. 
Date :- 26th May, 2014.
 类似资料:
  • 在问题[1]中,我了解到如果您想在Android下使用NFC标签,则不必采用NDEF格式。我想在Win 8.1 in. Net下执行此操作。我的情况是这样的: 我有一个RFID卡Mifare Classic 1K,其中存储了一个ID。(由制造商记录)该ID由我们的考勤系统通过通常的RFID读取器(例如Gigatek的PROMAG MFR120)读取。我们不在卡上写任何东西,我们只需要读取ID。但是

  • 问题内容: 我需要知道如何在运行时阅读Javadoc注释(可能是通过反射吗?) 说我有以下功能: 在运行时,我可以通过反射获得有关此函数的更多信息。但是无法阅读注释。所以问题是,如何在运行时阅读此 javadoc 注释。 问题答案: 考虑使用注释而不是Javadoc并编写注释处理器。

  • 问题内容: 我创建了具有3个虚拟机的应用程序,并使用Nagios监督所有这些计算机。 我使用nagios通过后缀将电子邮件发送到本地主机上的Outlook,然后使用Java EE应用程序获取了所有邮件,并将其放入数据库中。 如何使用Java EE从MS Outlook中提取所有电子邮件并将其放入数据库中? 我在后缀中使用IMAP将电子邮件发送到本地主机上的Outlook 我有Outlook版本20

  • 我想通过使用锁签署一个pdf文件。我正在使用PDFBox 2.0.9 我想实现的流量是: null 我可以签名,更改字段值,然后再次签名,签名就可以了。问题是当我在第二个签名之后更改字段的值时,签名仍然有效。我希望在上次更改后,第二个签名一定是无效的。

  • 问题内容: 我正在尝试从文本文件读取特定行,但是我不想将文件加载到内存中(它可能会变得很大)。 我一直在寻找,但是我发现的每个示例都要求读取每一行(这将使我的代码变慢,因为有超过100,000行)或将整个内容加载到数组中并获取正确的元素(文件将包含很多行)输入)。 我想做的一个例子: “代码不是实际的代码,它是为了显示我想要的原理而组成的” 有没有办法做到这一点? - - -编辑 - - - 我刚