Java iText输出缺少Unicode字符

Java iText输出缺少Unicode字符,java,pdf,unicode,fonts,itext,Java,Pdf,Unicode,Fonts,Itext,我正在使用iText从java.awt.print.Printables用java生成PDF。 这一切都很好,直到有一点: 可打印文件通常包含各种unicode字符(我猜它们只是:-),为此,我在lib/fonts/fallback中使用了一种复合字体和一种额外的回退字体。在Java中,使用此解决方案一切正常 将其导出为PDF时,我已经在使用自己的FontMapper实现: public class PdfFontMapper implements FontMapper { public Ba

我正在使用iText从java.awt.print.Printables用java生成PDF。 这一切都很好,直到有一点:

可打印文件通常包含各种unicode字符(我猜它们只是:-),为此,我在lib/fonts/fallback中使用了一种复合字体和一种额外的回退字体。在Java中,使用此解决方案一切正常

将其导出为PDF时,我已经在使用自己的FontMapper实现:

public class PdfFontMapper implements FontMapper {

public BaseFont awtToPdf(Font font) {

    try {
         if(!font.getFamily().equalsIgnoreCase("Trebuchet MS")) {
                return getBaseFontFromFile(SunFontManager.getInstance().getPlatformFontPath( true ), "ARIALUNI.ttf");
         }
         else {
                return getBaseFontFromFile(SunFontManager.getInstance().getPlatformFontPath( true ), "Trebuchet MS.ttf");
         }

    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

public Font pdfToAwt(BaseFont baseFont, int size) {

    throw new UnsupportedOperationException();
}

private BaseFont getBaseFontFromFile(String directory, String filename)
        throws Exception {

    InputStream is = null;
    try {

        final ClassLoader cl = Thread.currentThread()
                .getContextClassLoader();
        is = cl.getResourceAsStream(filename);
        // is = IMappingApplication.class.getResourceAsStream(directory +
        // filename);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        while (true) {
            int size = is.read(buf);
            if (size < 0) {
                break;
            }
            bos.write(buf, 0, size);
        }
        buf = bos.toByteArray();
        BaseFont bf = BaseFont.createFont(filename, BaseFont.IDENTITY_H,
                BaseFont.NOT_EMBEDDED, BaseFont.NOT_CACHED, buf, null);
        return bf;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (is != null) {
            is.close();
        }
    }
}
}
公共类PdfontMapper实现了FontMapper{
公共基础字体awtToPdf(字体){
试一试{
如果(!font.getFamily().equalsIgnoreCase(“投石机MS”)){
返回getBaseFontFromFile(SunFontManager.getInstance().getPlatformFontPath(true),“ARIALUNI.ttf”);
}
否则{
返回getBaseFontFromFile(SunFontManager.getInstance().getPlatformFontPath(true),“Trebuchet MS.ttf”);
}
}捕获(例外e){
抛出新的运行时异常(e);
}
}
公共字体pdfToAwt(BaseFont BaseFont,int size){
抛出新的UnsupportedOperationException();
}
专用BaseFont getBaseFontFromFile(字符串目录,字符串文件名)
抛出异常{
InputStream=null;
试一试{
最终类加载器cl=Thread.currentThread()
.getContextClassLoader();
is=cl.getResourceAsStream(文件名);
//is=IMappingApplication.class.getResourceAsStream(目录+
//文件名);
ByteArrayOutputStream bos=新建ByteArrayOutputStream();
字节[]buf=新字节[1024];
while(true){
int size=is.read(buf);
如果(尺寸<0){
打破
}
bos.write(buf,0,大小);
}
buf=bos.toByteArray();
BaseFont bf=BaseFont.createFont(文件名,BaseFont.IDENTITY\u H,
BaseFont.NOT_EMBEDDED,BaseFont.NOT_CACHED,buf,null);
返回高炉;
}捕获(例外e){
e、 printStackTrace();
返回null;
}最后{
如果(is!=null){
is.close();
}
}
}
}
,特别感谢G.J.Schouten

但不幸的是,我的基本字体“Trebuchet MS”中没有包含的字符无法导出,它们只是丢失了。有趣的是,如果我只在映射器中添加一种字体,“Arial Unicode”,它的效果相当不错。 那我当然可以只用一种字体。但我希望有更好的解决办法

顺便说一句:我的回退库中的符号(表情符号)总是得到很好的渲染。但我没有得到一个解决方案来运行,我只能在字体/回退中使用物理字体+回退字体

有人知道如何解决这个问题吗? 顺便说一句:我已经尝试过在PDF中嵌入字体,但是没有效果(我认为这是没有必要的,因为我使用的是非常普通的字体)


您好,Andy

Arial Unicode是一种巨大的字体,因此它是一种非常好的最后一种字体。你确定你的“外来字符”(哪些?)应该在投石机MS中可用吗?这是一个应用程序,用户可以通过编辑器插入任何类型的内容。所以为了确保它们不会遇到任何边界,我想确保涵盖所有内容。Arial Unicode是一种巨大的字体,因此它是一种非常好的最后一种字体。你确定你的“外来字符”(哪些?)应该在投石机MS中可用吗?这是一个应用程序,用户可以通过编辑器插入任何类型的内容。所以,为了确保它们不会遇到任何边界,我想确保涵盖所有边界。