如何使用iText生成兼容PDF / UA的PDF?

时间:2015-01-29 18:49:02

标签: itext accessibility jaws-screen-reader

我们网站上有许多动态生成的可打印表格文件,使用iText 4.2.0。但是,我们也有大量具有阅读障碍的用户,并使用屏幕阅读器(如JAWS)来呈现我们的PDF。我们使用.setTagged()方法标记PDF,但PDF的某些元素不按顺序显示。有些人甚至在打电话给setTagged后变得更加混乱!

我在2013年与Bruno Lowagie关于iText的采访中读到了关于PDF / UA的内容,这似乎可能对我们的问题有所帮助。但是,我还没有找到如何生成PDF / UA文档的好例子。你能提供一个例子吗?另外,我们需要生成符合PDF / UA标准的PDF文档的iText的最低版本是什么?

1 个答案:

答案 0 :(得分:4)

请查看PdfUA示例。它逐步解释了符合PDF / UA所需的内容。 2014年iText峰会和JavaOne上也提供了类似的例子。观看iText Summit video tutorial

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document(PageSize.A4.rotate());
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    writer.setPdfVersion(PdfWriter.VERSION_1_7);
    //TAGGED PDF
    //Make document tagged
    writer.setTagged();
    //===============
    //PDF/UA
    //Set document metadata
    writer.setViewerPreferences(PdfWriter.DisplayDocTitle);
    document.addLanguage("en-US");
    document.addTitle("English pangram");
    writer.createXmpMetadata();
    //=====================
    document.open();

    Paragraph p = new Paragraph();
    //PDF/UA
    //Embed font
    Font font = FontFactory.getFont(FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 20);
    p.setFont(font);
    //==================
    Chunk c = new Chunk("The quick brown ");
    p.add(c);
    Image i = Image.getInstance(FOX);
    c = new Chunk(i, 0, -24);
    //PDF/UA
    //Set alt text
    c.setAccessibleAttribute(PdfName.ALT, new PdfString("Fox"));
    //==============
    p.add(c);
    p.add(new Chunk(" jumps over the lazy "));
    i = Image.getInstance(DOG);
    c = new Chunk(i, 0, -24);
    //PDF/UA
    //Set alt text
    c.setAccessibleAttribute(PdfName.ALT, new PdfString("Dog"));
    //==================
    p.add(c);
    document.add(p);

    p = new Paragraph("\n\n\n\n\n\n\n\n\n\n\n\n", font);
    document.add(p);
    List list = new List(true);
    list.add(new ListItem("quick", font));
    list.add(new ListItem("brown", font));
    list.add(new ListItem("fox", font));
    list.add(new ListItem("jumps", font));
    list.add(new ListItem("over", font));
    list.add(new ListItem("the", font));
    list.add(new ListItem("lazy", font));
    list.add(new ListItem("dog", font));
    document.add(list);
    document.close();
}

您使用setTagged文档标记了文档,但这还不够。您还需要设置文档数据:需要显示文档标题,并且需要指明文档中使用的语言。 XMP元数据是必需的。

此外,您需要嵌入所有字体。有图像时,需要备用说明。在示例中,我们用图像替换“dog”和“fox”。为确保正确“大声读出”这些图像,我们需要使用setAccessibleAttribute()方法。

在示例的最后,我添加了编号列表。在您的重复问题https://stackoverflow.com/questions/28222490/numbered-list-across-a-page-break-causes-jaws-to-read-numbers-out-of-order-in-it中,您声称JAWS无法正确读取列表。如果您检查使用上面的示例创建的PDF文件,更具体地说是pdfua.pdf,您将发现JAWS按预期读取文档,数字和文本的顺序正确。

尝试此操作时“它不起作用”的原因很简单。您声称自己使用的是iText,但事实并非如此。你正在使用iText的“gork”。 “gork”是一个非正式的“叉子”,上帝只知道里面有什么。您需要最新的iText版本来实现您的目标,因为PDF / UA是一个可以追溯到2012年的标准,您使用的是从2009年开始的iText版本。

我建议您删除其他问题,因为:

  • 这是这个问题的重复(如果你不同意,请阅读我的答案:不是完全你在这两个问题中提出的问题?),
  • 这听起来像是“我正在使用一台古老的DVD播放器并且它不想播放我的蓝光光盘。”(我知道你是downvoted)我的正确答案是因为你不相信这是真的。所以就这样吧。其他人会觉得这个答案很有价值,并且明白你的投票是不公平的。)

请阅读The Best iText Questions on StackOverflow中的最后一个问题,了解我对使用非官方,流氓,过时的iText版本的人的看法。 另请参阅https://stackoverflow.com/questions/25696851/can-itext-2-1-7-or-earlier-can-be-used-commercially