• pdf文件之itextpdf插入html内容以及中文解决方案


    简述

    目前网上已经有很多种html文件直接转pdf的技术帖子,但是很少有直接将部分html作为段落插入到pdf中,而且也没有一个可以很好的解决中文显示的问题。

    因此今天上午围绕这个问题进行了研究,把解决方案分享给大家。

    itextpdf基础操作请访问:http://www.cnblogs.com/mvilplss/p/5640598.html

    感谢:http://gridmix.blog.51cto.com/4764051/1229585

    实现思路

    如果想插入html片段,我们使用一个类的静态方法:

    1         String html = "<div style='color:green;font-size:20px;'>你好世界!hello world !</div>";
    2         Paragraph context = new Paragraph();
    3         ElementList elementList =XMLWorkerHelper.parseToElementList(htmlString, null);
    4         for (Element element : elementList) {
    5             context.add(element);
    6         }
    7         document.add(context);

    不过你会发现不能显示中文,这个问题网上有很多种解决方法,但是都不好使。

    查看XMLWorkerHelper.parseToElementList(htmlString, null)这个方法的源码,发现

    CssAppliers cssAppliers = new CssAppliersImpl(FontFactory.getFontImp());可以进行字体的更换。
     1 public static ElementList parseToElementList(String html, String css) throws IOException {
     2         // CSS
     3         CSSResolver cssResolver = new StyleAttrCSSResolver();
     4         if (css != null) {
     5             CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
     6             cssResolver.addCss(cssFile);
     7         }
     8         
     9         // HTML
    10         CssAppliers cssAppliers = new CssAppliersImpl(FontFactory.getFontImp());//这里可以下手对字体进行操作
    11         HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
    12         htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    13         htmlContext.autoBookmark(false);
    14         
    15         // Pipelines
    16         ElementList elements = new ElementList();
    17         ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
    18         HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
    19         CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    20         
    21         // XML Worker
    22         XMLWorker worker = new XMLWorker(cssPipeline, true);
    23         XMLParser p = new XMLParser(worker);
    24         p.parse(new ByteArrayInputStream(html.getBytes()));
    25         
    26         return elements;
    27     }

    因此我们就想到重写XMLWorkerFontProvider类的getFont(*)方法,对于没有显示声明css样式的字体,默认使用undefine字体样式进行设置默认字体。

     1 public class MyXMLWorkerHelper {
     2     public static class MyFontsProvider extends XMLWorkerFontProvider {
     3         public MyFontsProvider() {
     4             super(null, null);
     5         }
     6 
     7         @Override
     8         public Font getFont(final String fontname, String encoding, float size, final int style) {
     9 
    10             String fntname = fontname;
    11             if (fntname == null) {
    12                 fntname = "宋体";
    13             }
    14             return super.getFont(fntname, encoding, size, style);
    15         }
    16     }
    17 
    18     public static ElementList parseToElementList(String html, String css) throws IOException {
    19         // CSS
    20         CSSResolver cssResolver = new StyleAttrCSSResolver();
    21         if (css != null) {
    22             CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
    23             cssResolver.addCss(cssFile);
    24         }
    25 
    26         // HTML
    27         MyFontsProvider fontProvider = new MyFontsProvider();
    28         CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
    29         HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
    30         htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    31         htmlContext.autoBookmark(false);
    32 
    33         // Pipelines
    34         ElementList elements = new ElementList();
    35         ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
    36         HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
    37         CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    38 
    39         // XML Worker
    40         XMLWorker worker = new XMLWorker(cssPipeline, true);
    41         XMLParser p = new XMLParser(worker);
    42         html = html.replace("<br>", "").replace("<hr>", "").replace("<img>", "").replace("<param>", "")
    43                 .replace("<link>", "");
    44         p.parse(new ByteArrayInputStream(html.getBytes()));
    45 
    46         return elements;
    47     }
    48 
    49 }

    因为XMLWork不支持html的单标签,所以要对但标签进行过滤。不然就会报错:Invalid nested tag div found, expected closing tag br

  • 相关阅读:
    android判断服务是否是运行状态
    Android调用OCR识别图像中的文字
    Java生成各种条形码
    android 实现摇一摇功能
    【读书笔记】Html5游戏开发
    SpeechLib 语音播报
    罗盘
    注释文档在线编辑及生成
    系统空闲时间判断&命名验证
    Asp.Net MVC中使用ACE模板之Jqgrid
  • 原文地址:https://www.cnblogs.com/mvilplss/p/5646675.html
Copyright © 2020-2023  润新知