了解 PDFBox 2.0 中字体的加载 [英] Understanding loading of font in PDFBox 2.0

查看:248
本文介绍了了解 PDFBox 2.0 中字体的加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我终于成功地让 PDFBox 打印了我的 unicode.但是现在,我想了解我提出的解决方案.下面的代码有效并将 打印到页面.

I have finally succeeded in making PDFBox print my unicodes. But now, I would like to understand the solution that I have come up with. The code below works and prints a to the page.

有两件事不起作用:

  • 改变PDType0Font.load(documentMock, systemResourceAsStream, true);PDType0Font.load(documentMock, systemResourceAsStream, false);

改变final PDFont robotoLight = loadFontAlternative("Roboto-Light.ttf");final PDFont robotoLight = loadFont("Roboto-Light.ttf");

第一个更改打印两个点而不是字符.embedSubset 有什么作用,因为它在设置为 false 时不起作用?文档太少,我看不懂.

The first change prints two dots instead of the character. What does embedSubset do, since it does not work when set to false? The documentation is too sparse for me to understand.

第二个变化给出以下异常 Exception in thread "main" java.lang.IllegalArgumentException: U+2265 is not available in this font's encoding: WinAnsiEncoding在 PDFBox 2.0 之前的许多其他问题中已经涵盖了这个问题,其中在处理 unicode 时存在错误.所以,他们不直接回答这个问题.除此之外,问题很明显:我不应该将编码设置为 WinAnsiEncoding 而是不同的东西.但是编码应该是什么?以及为什么没有可用的 UTF-8 编码或类似的编码?COSName 中没有关于许多选项的文档.

The second change gives the following exception Exception in thread "main" java.lang.IllegalArgumentException: U+2265 is not available in this font's encoding: WinAnsiEncoding This problem has been covered in many other questions that pre-dates PDFBox 2.0 where there was a bug in handling unicodes. So, they do not answer the question directly. That aside, the problem is clear: I should not set the encoding to WinAnsiEncoding but something different. But what should the encoding be? and why is there no UTF-8 encoding or similar available? There is no documentation in COSName about the many options.

public class SimpleReportUnicode {
    public static void main(String[] args) throws IOException {
        PDDocument report = createReport();
        final String fileLocation = "c:/SimpleFormUnicode.pdf";
        report.save(fileLocation);
        report.close();
    }

    private static PDDocument createReport() throws IOException {
        PDDocument document = new PDDocument();
        PDPage page = new PDPage();
        document.addPage(page);

        PDPageContentStream contentStream = new PDPageContentStream(document, page);
        final PDFont robotoLight = loadFontAlternative("Roboto-Light.ttf");
        writeText(contentStream, robotoLight, 100, 650);

        contentStream.close();
        return document;
    }

    private static void writeText(PDPageContentStream contentStream, PDFont font, double x, double y) {
        try {
            contentStream.beginText();
            contentStream.setFont(font, 12);
            contentStream.moveTextPositionByAmount((float) x, (float) y);
            String unicode = "≥";
            contentStream.showText(unicode);
            contentStream.endText();
        }
        catch (IOException e) {
        }
    }

    private static PDFont loadFont(String location) {
        PDFont font;
        try {
            PDDocument documentMock = new PDDocument();
            InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream(location);
            Encoding encoding = Encoding.getInstance(COSName.WIN_ANSI_ENCODING);
            font = PDTrueTypeFont.load(documentMock, systemResourceAsStream, encoding);
        }
        catch (IOException e) {
            throw new RuntimeException("IO exception");
        }
        return font;
    }

    private static PDFont loadFontAlternative(String location) {
        PDDocument documentMock = new PDDocument();
        InputStream systemResourceAsStream = ClassLoader.getSystemResourceAsStream(location);
        PDFont font;
        try {
            font = PDType0Font.load(documentMock, systemResourceAsStream, true);
        }
        catch (IOException e) {
            throw new RuntimeException("IO exception");
        }
        return font;
    }
}

编辑如果您想使用与代码中相同的字体,可以在此处使用 Roboto:https://fonts.google.com/specimen/Roboto将 Roboto-Light.ttf 添加到您的类路径中,代码应该可以立即使用.

EDIT If you want to use the same font as in the code, Roboto is available here: https://fonts.google.com/specimen/Roboto Add Roboto-Light.ttf to your classpath and the code should work out of the box.

推荐答案

如评论中所述:

  • 使用 2.0.7 版后 embedSubsets 的问题消失了.(顺便说一句,今天发布了 2.0.8);
  • FAQ 和解决方案是使用 PDType0Font.load() 你已经在你的工作版本中使用过;
  • 字体没有 UTF-8 编码,因为它在 PDF 规范中不可用;
  • 使用 embedSubsets true 会生成一个 4KB 的文件,如果使用 false,则文件为 100KB,因为嵌入了完整字体,因此 false 通常是最好的.
  • The problem with embedSubsets went away by using version 2.0.7. (Btw 2.0.8 was released today);
  • The problem "U+2265 is not available in this font's encoding: WinAnsiEncoding" is explained in the FAQ and the solution is to use PDType0Font.load() which you already did in your working version;
  • There is no UTF-8 encoding for fonts because it isn't available in the PDF specification;
  • using embedSubsets true produces a 4KB file, with false the file is 100KB because the full font is embedded, so false is usually best.

这篇关于了解 PDFBox 2.0 中字体的加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆