6

我希望有人可以帮助我……看来我想做的事情应该很简单,但是我已经与这件事斗争了一天多,而且没有想法。我在 StackOverflow 和整个 Internet 上找到了很多信息,但没有什么能帮助我解决这个问题。

我正在尝试使用 itext-2.0.8 和 core-renderer-R8 来创建带有嵌入字体的 PDF。我正在尝试从有效的 XHTML 生成 PDF,并使用 @font-face 样式标签嵌入字体。我已通过在浏览器中打开文件确认 @font-face 标记包含字体。而且我总是小心地保持 TTF 字段与 XHTML/CSS 文档相关。

为了尝试解决这个问题,我创建了一个小的“Hello World”类型程序来尝试嵌入字体。我采取了两种不同的方法,但都未能产生预期的结果。我在http://christopherluft.com/FlyingSaucer.zip放置了这个小 Eclipse 程序的副本

该程序在这两种情况下都会生成 PDF,但都没有按预期嵌入 PDF。使用带有 setDocument 的文件的第一种方法不会产生错误,但也不会产生字体。第二种方法生成 PDF,但在调试输出中显示 java.net.MalformedURLException。

我尝试了各种路径和 URL 的多种排列方式;然而,没有一个不能产生预期的结果。我的怀疑是我无法理解 ITextRenderer.setDocument; 但是,我很难找到任何适合我的用例的文档。

我尝试的第一种方法是:

public static void main(String[] args) throws IOException, DocumentException {

    System.getProperties().setProperty("xr.util-logging.loggingEnabled",
            "true");
    XRLog.setLoggingEnabled(true);

    String inputFile = "sample.xhtml";
    String url = new File(inputFile).toURI().toURL().toString();
    String outputFile = "firstdoc.pdf";

    OutputStream os = new FileOutputStream(outputFile);

    ITextRenderer renderer = new ITextRenderer();
    renderer.setDocument(url);
    renderer.layout();
    renderer.createPDF(os);

    os.close();
}

我使用的第二种方法(更接近我们在应用程序中使用它的实际方式)是:

public static void main(String[] args)  throws IOException, DocumentException {

    System.getProperties().setProperty("xr.util-logging.loggingEnabled", "true");
    XRLog.setLoggingEnabled(true);

    String inputFile = "sample.xhtml";
    String url = new File(inputFile).toURI().toURL().toString();

    DocumentBuilder documentBuilder;
    org.w3c.dom.Document xhtmlContent;

    try 
    {
        documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        documentBuilder.setEntityResolver(new XhtmlEntityResolver(new SuppressingEntityResolver()));
        xhtmlContent = documentBuilder.parse(url);

        System.out.println(url);

        String outputFile = "firstdoc.pdf";
        OutputStream os = new FileOutputStream(outputFile);
        ITextRenderer renderer = new ITextRenderer();

        renderer.setDocument(xhtmlContent,".");
        renderer.layout();
        renderer.createPDF(os);

        System.out.println("Finishing up....");
        os.close();
    } 
    catch (SAXException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
    catch (ParserConfigurationException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}

XHTML 中的 @font-face 包含如下所示:

@font-face {

    font-family: 'MisoRegular';

    src: url("miso-regular-webfont.ttf");

    -fs-pdf-font-embed: embed;

    -fs-pdf-font-encoding: Identity-H;
}

现在我觉得这是一个非常常见的用例,我想我只是没有执行一个简单的步骤才能让它工作......问题是我已经有一段时间了,我认为我是无法透过树木看到森林。任何人可以为我提供的任何帮助将不胜感激。感谢您的时间。

4

3 回答 3

4

我在使用 Flying Saucer 时遇到过问题,字体似乎没有正确嵌入,最终导致我尝试嵌入的字体已损坏或至少不完整。缺少有关字体系列和描述的属性。当我尝试在 OS XI 上使用 FontBook 中的 Validate File 选项验证我的字体时,会立即出现警告说:

  • “名称”表可用性
  • “名称”表结构

然而,FlyingSaucer 默默地失败了,只是继续嵌入 Times-Roman 和 Times-Bold 作为默认字体。当我尝试使用通过 FontBook 验证的字体时,我发现该字体已正确嵌入。

我花了几个小时试图增加从 FlyingSaucer 记录的详细程度以获取更多信息,但直到我逐步完成整个渲染过程并碰巧注意到 FontFamily 在加载后在调试器中设置为“”时才发现这种情况字体并且它不包括我希望它注册的名称。

底线: 如果您在使用 FlyingSaucer 和字体时遇到问题,并且正在用头撞墙,请确保您的字体有效。

于 2012-04-27T02:10:21.353 回答
3

我遇到了像 tekrunt 一样的问题,但最后我得到了一个嵌入了自定义字体(现代计算机)的 PDF。我的经历:

  • 字体的 OTF 格式不起作用(在 iText 函数中崩溃)
  • 在我进行以下更改后,TTF 格式确实有效:在 CSS 中,使用与字体中编码的字体系列名称相同的字体系列名称。在中设置断点
    org.xhtmlrenderer.pdf.ITextFontResolver.addFontFaceFont()
    并找出变量“fontFamily”得到的值。如果这与 CSS 字体系列不同,我想它不会起作用。

当然这些问题应该由图书馆报告给用户。

于 2013-10-20T21:21:16.990 回答
2

我遇到了类似的问题,字体没有被应用到最终的 pdf 中,并且m4t关于调试的建议确实帮助我确定了这个问题。所以谢谢你!

就我而言,实际上有两个问题:

  1. 作为规则的一部分指定的src属性@font-face有 2 个值,即 url 和格式。它看起来像
@font-face {
   src: url("../../static/fonts/OpenSans-Regular.ttf") format("ttf");
}

由于第二个值format,CSSParser 中断,导致该src属性被完全无声地跳过。结果,在进一步处理中,渲染器不知道从哪里挑选字体。一旦我format从值中删除了部分,问题就得到了解决。

  1. 一旦 url 被 CSSParser 成功解析,它就无法正确解析,因为 css 中指定的 url 是相对的,并且在调用setDocumentAsString渲染器时没有明确指定 baseUrl(可选的第二个参数)。我通过使用类加载器在我的代码中显式加载静态资源的 uri,然后将其设置为基本 url,从而解决了这个问题。之后更改字体文件的路径成功解决并应用于我的pdf。

这里要注意的关键是,提供给的基本 url setDocumentAsString必须是一个 URI(文件:/文件夹/结构/静态/),并且必须以斜杠 ('/') 结尾。否则文件和 url 无法正确解析。

希望这可以帮助面临类似问题的人。

于 2020-09-15T11:22:26.207 回答