java - 线程 "main"org.pdfclown.util.parsers.ParseException : 'name' table does NOT exist 中的异常

标签 java parsing pdf importerror pdfclown

我正在尝试运行 Stefano Chizzolini(很棒的人:PDFClown 的创建者)编写的 Java 代码,以使用 PDF Clown 库解析 PDF。我收到此错误,但我不知道该如何解决。

Exception in thread "main" org.pdfclown.util.parsers.ParseException: 'name' table does NOT exist.
at org.pdfclown.documents.contents.fonts.OpenFontParser.getName(OpenFontParser.java:570)
at org.pdfclown.documents.contents.fonts.OpenFontParser.load(OpenFontParser.java:221)
at org.pdfclown.documents.contents.fonts.OpenFontParser.<init>(OpenFontParser.java:205)
at org.pdfclown.documents.contents.fonts.TrueTypeFont.loadEncoding(TrueTypeFont.java:91)
at org.pdfclown.documents.contents.fonts.SimpleFont.onLoad(SimpleFont.java:118)
at org.pdfclown.documents.contents.fonts.Font.load(Font.java:738)
at org.pdfclown.documents.contents.fonts.Font.<init>(Font.java:351)
at org.pdfclown.documents.contents.fonts.SimpleFont.<init>(SimpleFont.java:62)
at org.pdfclown.documents.contents.fonts.TrueTypeFont.<init>(TrueTypeFont.java:68)
at org.pdfclown.documents.contents.fonts.Font.wrap(Font.java:253)
at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:72)
at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:1)
at org.pdfclown.documents.contents.ResourceItems.get(ResourceItems.java:119)
at org.pdfclown.documents.contents.objects.SetFont.getResource(SetFont.java:119)
at org.pdfclown.documents.contents.objects.SetFont.getFont(SetFont.java:83)
at org.pdfclown.documents.contents.objects.SetFont.scan(SetFont.java:97)
at org.pdfclown.documents.contents.ContentScanner.moveNext(ContentScanner.java:1330)
at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:626)
at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:296)
at PDFReader.FullExtract.run(FullExtract.java:71)
at PDFReader.FullExtract.main(FullExtract.java:142)

我知道库包中的类 OpenFontParser 会引发此错误。我能做些什么来解决这个问题吗?

此代码适用于大多数 PDF。我有一个无法解析的 PDF。我猜这是因为 this symbol在 pdf 下方。

public class PDFReader extends Sample {

@Override
public void run()
{
    String filePath = new String("C:\\Users\\XYZ\\Desktop\\SomeSamplePDF.pdf");

    // 1. Open the PDF file!
    File file;
    try
    {file = new File(filePath);}
    catch(Exception e)
    {throw new RuntimeException(filePath + " file access error.",e);}

    // 2. Get the PDF document!
    Document document = file.getDocument();

    // 3. Extracting text from the document pages...
    for(Page page : document.getPages())
    {
    extract(new ContentScanner(page)); // Wraps the page contents into a scanner.

    }
    close(file);
}

private void close(File file) {
    // TODO Auto-generated method stub

}

/**
Scans a content level looking for text.
 */
/*
NOTE: Page contents are represented by a sequence of content objects,
possibly nested into multiple levels.
 */
private void extract(
        ContentScanner level
        )
{
    if(level == null)
        return;

    while(level.moveNext())
    {
        ContentObject content = level.getCurrent();
        if(content instanceof ShowText)
        {
            Font font = level.getState().getFont();
            // Extract the current text chunk, decoding it!
            System.out.println(font.decode(((ShowText)content).getText()));
        }
        else if(content instanceof Text
                || content instanceof ContainerObject)
        {
            // Scan the inner level!
            extract(level.getChildLevel());
        }
    }
}

private boolean prompt(Page page)
{
    int pageIndex = page.getIndex();
    if(pageIndex > 0)
    {
        Map<String,String> options = new HashMap<String,String>();
        options.put("", "Scan next page");
        options.put("Q", "End scanning");
        if(!promptChoice(options).equals(""))
            return false;
    }

    System.out.println("\nScanning page " + (pageIndex+1) + "...\n");
    return true;
}

public static void main(String args[])
{
    new PDFReader().run();
    }

}

最佳答案

问题

如堆栈跟踪所示,问题在于 PDF 中嵌入的某些 TrueType 字体不包含 name 表,即使它是必需的表:

org.pdfclown.util.parsers.ParseException: 'name' table does NOT exist.
...
at org.pdfclown.documents.contents.fonts.TrueTypeFont.loadEncoding(TrueTypeFont.java:91)

因此,严格来说,嵌入的字体是无效的,因此嵌入的 PDF 也是如此。由于这个有效性问题,PDFClown 遇到了异常。

一些背景

A TrueType font file consists of a sequence of concatenated tables. ...

The first of the tables is the font directory, a special table that facilitates access to the other tables in the font. The directory is followed by a sequence of tables containing the font data. These tables can appear in any order. Certain tables are required for all fonts. Others are optional depending upon the functionality expected of a particular font.

Tables that are required must appear in any valid TrueType font file. The required tables and their tag names are shown in Table 2.

Table 2: The required tables

Tag     Table 
'cmap'  character to glyph mapping 
'glyf'  glyph data 
'head'  font header 
'hhea'  horizontal header 
'hmtx'  horizontal metrics 
'loca'  index to location 
'maxp'  maximum profile 
'name'  naming 
'post'  PostScript 

(Section TrueType Font files: an overview in chapter 6 The TrueType Font File in the TrueType Reference Manual)

另一方面,虽然有许多 PDF 生成器将嵌入式 TrueType 字体减少到 PDF 查看器(最重要的 Adob​​e Reader)所需的基本要素,并且 name 表似乎没有严格要求。

此外,表 name 在 PDFClown 中仅用于一个目的,即确定相关字体的名称,即使字体名称可以从 BaseFont 相关字体词典的条目也是如此。实际上后者是 PDF 规范必需的,而 name 表中的 PostScript 字体名称可选的 根据 TTF 手册。

因此,使用 PDF 字体字典中的 BaseFont 条目将是此 name 表访问的更好替代方案。

修复它

Is there anything I can do to fix this?

您可以通过向有问题的嵌入式 TTF 添加 name 表来修复不完全有效的 PDF,或者您可以修补 PDFClown 以忽略丢失的缺失表:在类 org.pdfclown.documents.contents.fonts.OpenFontParser 中编辑方法 getName:

private String getName(
  int id
  ) throws EOFException, UnsupportedEncodingException
{
  // Naming Table ('name' table).
  Integer tableOffset = tableOffsets.get("name");
  if(tableOffset == null)
    throw new ParseException("'name' table does NOT exist.");

throw new ParseException("'name' table does NOT exist.") 替换为 return null

附言

虽然可以仅使用 OP 提供的信息来分析问题,但 sample file@akarshad 提供在他现已删除的答案中,他更有动力开始分析。

关于java - 线程 "main"org.pdfclown.util.parsers.ParseException : 'name' table does NOT exist 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23544547/

相关文章:

javascript - 使用 Ajax 将 var 发送到查询

java - 如何在 Ubuntu 中将 Java 从 1.6.0 降级到 1.5.0?

javascript - 从剪贴板解析并添加 url

pdf - SSRS - 字体未嵌入到 pdf 文件中

java - Android挂起Intent和系统重启的行为?

java - Android 正确关闭进程

parsing - 编写一个可在 8 位嵌入式系统上使用的解析器,例如 Flex/Bison

python - 使用 python 和语法列表解析文本文件

java - 从 .docx 转换为 pdf 时图像显示效果不佳

mysql - 从 MySQL 数据库合并 PDF Blob 文件