我正在编写一个 Java 函数,它以 String 作为参数并使用PDFBox生成 PDF 作为输出。
只要我使用拉丁字符,一切正常。但是,我事先不知道输入是什么,它可能是一些英文以及中文或日文字符。
在非拉丁字符的情况下,这是我得到的错误:
Exception in thread "main" java.lang.IllegalArgumentException: U+3053 ('kohiragana') is not available in this font Helvetica encoding: WinAnsiEncoding
at org.apache.pdfbox.pdmodel.font.PDType1Font.encode(PDType1Font.java:426)
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:324)
at org.apache.pdfbox.pdmodel.PDPageContentStream.showTextInternal(PDPageContentStream.java:509)
at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:471)
at com.mylib.pdf.PDFBuilder.generatePdfFromString(PDFBuilder.java:122)
at com.mylib.pdf.PDFBuilder.main(PDFBuilder.java:111)
如果我理解正确,我必须为日语使用一种特定的字体,为中文使用另一种字体等等,因为我正在使用的字体(Helvetiva)不能处理所有必需的 unicode 字符。
我还可以使用处理所有这些 unicode 字符的字体,例如Arial Unicode。但是这种字体是在特定的许可证下,所以我不能使用它,我还没有找到另一个。
我发现了一些想要克服这个问题的项目,比如Google NOTO 项目。但是,这个项目提供了多个字体文件。所以我必须在运行时根据我的输入选择要加载的正确文件。
所以我面临 2 个选项,其中一个我不知道如何正确实施:
继续寻找可以处理几乎所有 unicode 字符的字体(我正在拼命寻找的这个圣杯在哪里?!)
尝试检测使用哪种语言并根据它选择一种字体。尽管我不知道(还)如何做到这一点,但我认为它不是一个干净的实现,因为输入和字体文件之间的映射将被硬编码,这意味着我必须对所有内容进行硬编码可能的映射。
还有其他解决方案吗?
我完全偏离轨道了吗?
提前感谢您的帮助和指导!
这是我用来生成 PDF 的代码:
public static void main(String args[]) throws IOException {
String latinText = "This is latin text";
String japaneseText = "これは日本語です";
// This works good
generatePdfFromString(latinText);
// This generate an error
generatePdfFromString(japaneseText);
}
private static OutputStream generatePdfFromString(String content) throws IOException {
PDPage page = new PDPage();
try (PDDocument doc = new PDDocument();
PDPageContentStream contentStream = new PDPageContentStream(doc, page)) {
doc.addPage(page);
contentStream.setFont(PDType1Font.HELVETICA, 12);
// Or load a specific font from a file
// contentStream.setFont(PDType0Font.load(this.doc, new File("/fontPath.ttf")), 12);
contentStream.beginText();
contentStream.showText(content);
contentStream.endText();
contentStream.close();
OutputStream os = new ByteArrayOutputStream();
doc.save(os);
return os;
}
}