【问题标题】:How to use CJK Fonts in iText with XMLWorker on Android?如何在 Android 上通过 XMLWorker 在 iText 中使用 CJK 字体?
【发布时间】:2014-12-09 15:08:34
【问题描述】:

我使用以下设置使用 iText(商业许可,iText 版本:5.4.5)创建 PDF 文档:

  • HTML 模板是使用 jmustache 生成的,在此步骤中会执行国际化,即文档可以包含欧洲语言,也可以包含日语和中文(也可以同时包含这两种语言,因为某些文本部分可能仍然是英语)

  • 使用 XMLWorker 渲染最终的 HTML,如下所示:

    final float marginPt = 28.35f;//1cm == 28.35pt
    final Document document = new Document(PageSize.A4, marginPt, marginPt, marginPt, 0);
    final PdfWriter writer = PdfWriter.getInstance(document, output);
    //we write multiple documents to a ZipOutputStream, so we close the output stream later
    writer.setCloseStream(false);
    document.open();
    
    final HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    
    htmlContext.setImageProvider(new DynamicImageProvider(privateStorageFolder));
    
    final CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
    
    final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver,
            new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));
    final XMLWorker worker = new XMLWorker(pipeline, true);
    final XMLParser p = new XMLParser(worker);
    p.parse(new StringReader(input));
    
    document.close();
    

一切都适用于欧洲字符(拉丁字母、变音符号、重音符号等)。但是,对于 CJK 字符(例如日文),不会显示 PDF 中的结果文本,也没有消息提示我安装其他字体。

我尝试将 extrajars-2.3.zip 中的 itext-asian.jar 添加到 android 库 (http://sourceforge.net/projects/itext/files/extrajars/) 但这没有帮助。

我正在寻找一种解决方案,通过以下任一方式将 CJK 文本正确添加到生成的 PDF 中:

1.) 使用 PDF CJK 功能(即最终用户需要安装了 CJK 字体的阅读器)

2.) 在 PDF 中嵌入包含拉丁字符和 CJK 字符的字体。

解决方案 1 更可取,但也非常感谢使用方法 2 进行修复。

解决方案 1 应该适用于 itext-asian.jar,但它不适用于我的设置(由于某种原因,它不适用于 Android itext 版本吗?)

对于解决方案 2,我需要找到一种在 Android 中向 XMLWorker 添加多种字体的方法,因为大多数支持多个脚本的字体都被拆分为不同的 ttf 文件(例如 google noto 字体https://www.google.com/get/noto/

【问题讨论】:

    标签: android itext cjk xmlworker


    【解决方案1】:

    经过大量的反复试验,我想出了以下适用于 Android 和桌面的解决方案:

    1.) 为您的 itext 版本添加适当的 itext-asian.jar 到您的类路径

    2.) 像这样实现自定义FontFactory

    public class MyFontFactory extends FontFactoryImp {
    @Override
    public Font getFont(final String fontname, final String encoding, final boolean embedded, final float size, final int style, final BaseColor color, final boolean cached) {
        if ("CJK".equals(fontname)){
            //these parameters were found out via trial-and-error, it is the asian font that looked best for our needs
            //look into the itext-asian.jar for alternatives
            return FontFactory.getFont("HeiseiKakuGo-W5","UniJIS-UCS2-H", BaseFont.NOT_EMBEDDED, size, style, color, cached);           
        } else {
            return super.getFont(fontname, encoding, embedded, size, style, color, cached);
        }
    }
    

    3.) 像这样将字体工厂添加到您的XMLWorker 链中:

    final MyFontFactory fontFactory = new MyFontFactory();
    //this sets the custom font factory for everything *but* the XMLWorker
    //(now that's amazing API design -.- )
    FontFactory.setFontImp(fontFactory);
    //this is the trick to get our fontFactory into the XmlWorker: 
    //build the processing pipeline manually and inject the factory along the way
    final HtmlPipelineContext htmlContext = new HtmlPipelineContext(new CssAppliersImpl(fontFactory));
    final CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
    final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));
    final XMLWorker worker = new XMLWorker(pipeline, true);
    final XMLParser p = new XMLParser(worker);
    p.parse(new StringReader(input));
    

    现在您可以在 HTML/CSS 中使用伪字体“CJK”,并且您可以得到亚洲字符而无需嵌入整个字体:

    * { 
        font-family:CJK; 
        font-size: 8pt;
    }
    

    如果您想嵌入字体,只需在 FontFactory 中以不同方式构建您的字体,例如:

    return FontFactory.getFont("/system/fonts/DroidSans.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, style, color, cached);
    

    当然,您必须确保您有可用的 ttf 文件,一旦您开始嵌入硬编码字体文件,您的代码就不再具有很好的可移植性了。

    【讨论】:

      猜你喜欢
      • 2015-08-23
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 2015-05-07
      • 2016-01-13
      相关资源
      最近更新 更多