Java PDFBox不支持多种语言
我正在尝试生成一份PDF报告,包含多种语言的句子。为此,我使用谷歌NOTO字体,但谷歌CJK字体不支持一些拉丁特殊字符,因为我的PDF框无法生成报告或有时显示奇怪的字符 谁有合适的解决方案?我尝试了多种方法,但找不到一个支持所有Unicode的TTF文件。我也试着回退到不同的字体文件,但这将是太多的工作 我支持的语言:-日语、德语、西班牙语、葡萄牙语、英语 注意:-由于许可问题,我不想使用arialuni.ttf文件Java PDFBox不支持多种语言,java,pdfbox,liferay-7,Java,Pdfbox,Liferay 7,我正在尝试生成一份PDF报告,包含多种语言的句子。为此,我使用谷歌NOTO字体,但谷歌CJK字体不支持一些拉丁特殊字符,因为我的PDF框无法生成报告或有时显示奇怪的字符 谁有合适的解决方案?我尝试了多种方法,但找不到一个支持所有Unicode的TTF文件。我也试着回退到不同的字体文件,但这将是太多的工作 我支持的语言:-日语、德语、西班牙语、葡萄牙语、英语 注意:-由于许可问题,我不想使用arialuni.ttf文件 任何人都可以提出任何建议。以下是示例子项目2.0.14版中的代码: /**
任何人都可以提出任何建议。以下是示例子项目2.0.14版中的代码:
/**
* Output a text without knowing which font is the right one. One use case is a worldwide
* address list. Only LTR languages are supported, RTL (e.g. Hebrew, Arabic) are not
* supported so they would appear in the wrong direction.
* Complex scripts (Thai, Arabic, some Indian languages) are also not supported, any output
* will look weird. There is an (unfinished) effort here:
* https://issues.apache.org/jira/browse/PDFBOX-4189
*
* @author Tilman Hausherr
*/
public class EmbeddedMultipleFonts
{
public static void main(String[] args) throws IOException
{
try (PDDocument document = new PDDocument())
{
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDFont font1 = PDType1Font.HELVETICA; // always have a simple font as first one
TrueTypeCollection ttc2 = new TrueTypeCollection(new File("c:/windows/fonts/batang.ttc"));
PDType0Font font2 = PDType0Font.load(document, ttc2.getFontByName("Batang"), true); // Korean
TrueTypeCollection ttc3 = new TrueTypeCollection(new File("c:/windows/fonts/mingliu.ttc"));
PDType0Font font3 = PDType0Font.load(document, ttc3.getFontByName("MingLiU"), true); // Chinese
PDType0Font font4 = PDType0Font.load(document, new File("c:/windows/fonts/mangal.ttf")); // Indian
PDType0Font font5 = PDType0Font.load(document, new File("c:/windows/fonts/ArialUni.ttf")); // Fallback
try (PDPageContentStream cs = new PDPageContentStream(document, page))
{
cs.beginText();
List<PDFont> fonts = new ArrayList<>();
fonts.add(font1);
fonts.add(font2);
fonts.add(font3);
fonts.add(font4);
fonts.add(font5);
cs.newLineAtOffset(20, 700);
showTextMultiple(cs, "abc 한국 中国 भारत 日本 abc", fonts, 20);
cs.endText();
}
document.save("example.pdf");
}
}
static void showTextMultiple(PDPageContentStream cs, String text, List<PDFont> fonts, float size)
throws IOException
{
try
{
// first try all at once
fonts.get(0).encode(text);
cs.setFont(fonts.get(0), size);
cs.showText(text);
return;
}
catch (IllegalArgumentException ex)
{
// do nothing
}
// now try separately
int i = 0;
while (i < text.length())
{
boolean found = false;
for (PDFont font : fonts)
{
try
{
String s = text.substring(i, i + 1);
font.encode(s);
// it works! Try more with this font
int j = i + 1;
for (; j < text.length(); ++j)
{
String s2 = text.substring(j, j + 1);
if (isWinAnsiEncoding(s2.codePointAt(0)) && font != fonts.get(0))
{
// Without this segment, the example would have a flaw:
// This code tries to keep the current font, so
// the second "abc" would appear in a different font
// than the first one, which would be weird.
// This segment assumes that the first font has WinAnsiEncoding.
// (all static PDType1Font Times / Helvetica / Courier fonts)
break;
}
try
{
font.encode(s2);
}
catch (IllegalArgumentException ex)
{
// it's over
break;
}
}
s = text.substring(i, j);
cs.setFont(font, size);
cs.showText(s);
i = j;
found = true;
break;
}
catch (IllegalArgumentException ex)
{
// didn't work, will try next font
}
}
if (!found)
{
throw new IllegalArgumentException("Could not show '" + text.substring(i, i + 1) +
"' with the fonts provided");
}
}
}
static boolean isWinAnsiEncoding(int unicode)
{
String name = GlyphList.getAdobeGlyphList().codePointToName(unicode);
if (".notdef".equals(name))
{
return false;
}
return WinAnsiEncoding.INSTANCE.contains(name);
}
}
/**
*在不知道哪种字体是正确的情况下输出文本。一个用例是全球范围的
*地址列表。仅支持LTR语言,不支持RTL(如希伯来语、阿拉伯语)
*支持,以便它们出现在错误的方向。
*也不支持复杂脚本(泰语、阿拉伯语、某些印度语言),不支持任何输出
*看起来会很奇怪。这里有一项(未完成的)工作:
* https://issues.apache.org/jira/browse/PDFBOX-4189
*
*@作者Tilman Hausherr
*/
公共类嵌入的多重元素
{
公共静态void main(字符串[]args)引发IOException
{
try(PDDocument document=new PDDocument())
{
PDPage page=新的PDPage(PD矩形.A4);
文件。添加页(第页);
PDFont font1=PDType1Font.HELVETICA;//始终使用简单字体作为第一个字体
TrueTypeCollection ttc2=新的TrueTypeCollection(新文件(“c:/windows/fonts/batang.ttc”);
PDType0Font font2=PDType0Font.load(文档,ttc2.getFontByName(“Batang”),true);//韩语
TrueTypeCollection ttc3=新的TrueTypeCollection(新文件(“c:/windows/fonts/mingliu.ttc”);
PDType0Font-font3=PDType0Font.load(document,ttc3.getFontByName(“MingLiU”),true);//中文
PDType0Font font4=PDType0Font.load(文档,新文件(“c:/windows/fonts/mangal.ttf”);//印度
PDType0Font font5=PDType0Font.load(文档,新文件(“c:/windows/fonts/ArialUni.ttf”);//回退
try(PDPageContentStream cs=newpdpagecontentstream(文档,页面))
{
cs.beginText();
列表字体=新建ArrayList();
字体。添加(font1);
字体。添加(font2);
字体。添加(font3);
字体。添加(font4);
字体。添加(font5);
cs.Newlineatofset(20700);
showTextMultiple(cs),abc한국 中国 भारत 日本 abc”,字体,20);
cs.endText();
}
document.save(“example.pdf”);
}
}
静态void showTextMultiple(PDPageContentStream cs、字符串文本、列表字体、浮动大小)
抛出IOException
{
尝试
{
//首先一次尝试所有方法
字体。获取(0)。编码(文本);
cs.setFont(字体.get(0),大小);
cs.showText(text);
返回;
}
捕获(IllegalArgumentException ex)
{
//无所事事
}
//现在分别尝试
int i=0;
而(i
arialuni的替代品可在此处找到: