zoukankan      html  css  js  c++  java
  • itextpdf 解析带中文的html问题

    官网连接 官网上有很多DEMO,下面就说几个我碰到的问题!

    Question:

    1. 中文不显示 或者是乱码(本打算用Apache pdfbox来实现业务,但是折腾了一个上午也没解决中午乱码问题,就找到itextpdf 替换,如果有人知道怎么解决pdfbox 乱码,请告知,毕竟开源的不要钱!)

    2. 页面纸张大小设置

    3. 解析带html标签的时候不能解析中文问题

    Answer:

    1. 对于中文乱码,itextpdf 可以通过读取字体文件解决,STFANGSO.TTF 是我本机上的仿宋的字体文件, 通过如下方式获取字体对象。只能读取.TTF格式文件,其他格式的字体文件会报错,这点要注意。然后再每个new Paragraph(arg1,arg2)的时候,arg1是一个要显示的对象,arg2就是你获得的中文字体。

    BaseFont bfChinese =BaseFont.createFont("C:\Windows\Fonts\STFANGSO.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
    Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);
    View Code
    datatable.addCell(new Paragraph(tableHeader[i], fontChinese));
    View Code

    这样中文问题就解决了。

    2. 对于纸张大小设置,参见官方的API

    new Document();有三种方式,无参构造,带一个参数的构造和带五个参数的构造。

    无参构造自不用解释、

    带一个参数的构造,是一个com.itextpdf.text.Rectangle 对象 可以通过com.itextpdf.text.PageSize 点出很多常用的文件大小、

    带五个参数的构造,就是可以自定义一张大小的画布了。

    3. 由于业务需要将带html标签的文本解析为PDF,但是发现无论解析出来的中文全丢失了,itext自身提供解析html的工具类,但是很多人说需要修改源码,但是我试过也不行。偶然发现一篇使用itext解析html片段,而且解决中文显示问题的博客http://www.cnblogs.com/mvilplss/p/5646675.html,便尝试了一下,居然可以显示中文了(毕竟,完整的html也是多个html片段组成的吗)

    自定义一个解析html文本的标签类,可以设定字体大小

    public class MyXMLWorkerHelper {
        public static class MyFontsProvider extends XMLWorkerFontProvider {
            public MyFontsProvider() {
                super(null, null);
            }
    
            @Override
            public Font getFont(final String fontname, String encoding, float size, final int style) {
                size=9.0f;//可以指定字体大小,不设置默认为12pt
                String fntname = fontname;
                if (fntname == null) {
                    fntname = "宋体";
                }
                return super.getFont(fntname, encoding, size, style);
            }
        }
    
        public static ElementList parseToElementList(String html, String css) throws IOException {
            // CSS
            CSSResolver cssResolver = new StyleAttrCSSResolver();
            if (css != null) {
                CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(css.getBytes()));
                cssResolver.addCss(cssFile);
            }
    
            // HTML
            MyFontsProvider fontProvider = new MyFontsProvider();
            CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
            HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
            htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
            htmlContext.autoBookmark(false);
    
            // Pipelines
            ElementList elements = new ElementList();
            ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
            HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext, end);
            CssResolverPipeline cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
    
            // XML Worker
            XMLWorker worker = new XMLWorker(cssPipeline, true);
            XMLParser p = new XMLParser(worker);
            html = html.replace("<br>", "").replace("<hr>", "").replace("<img>", "").replace("<param>", "")
                    .replace("<link>", "");
            p.parse(new ByteArrayInputStream(html.getBytes()));
    
            return elements;
        }
    
    }        
    View Code

    用例Demo 注意字体必须是ttf格式的,我试了用ttc的会报错。

    private static void itextPdf() throws Exception {
    Document document = null;
    BaseFont bf = null;
    Font fontChinese = null;
    bf = BaseFont.createFont("D:\simsun.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
    String dest = "D:\itextout.pdf";
    String inFile = "d:\in.html";
    File file = new File(inFile);
    StringBuffer sBuffer = new StringBuffer();
    BufferedReader reader = null; 
    reader = new BufferedReader(new FileReader(inFile)); 
    String tempString = null; 
    int line = 1; 
    // 一次读入一行,直到读入null为文件结束 
    while ((tempString = reader.readLine()) != null) { 
    // 显示行号 
    System.out.println("line " + line + ": " + tempString); 
    line++; 
    sBuffer.append(tempString);
    } 
    reader.close(); 
    
    OutputStream outputStream = new FileOutputStream(new File(dest));
    try {
    /** create the right font for chinese **/
    bf = BaseFont.createFont("D:\simsun.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
    fontChinese = new Font(bf, 10);
    document = new Document(PageSize.A4);
    
    /** get the html content from javabean and convert to string **/
    PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
    document.open();
    
    /** add the head of the pdf **/
    Paragraph head = new Paragraph("确认函", new Font(bf, 11));
    head.setAlignment(1); // 0 align to the left , 1 align to the center
    document.add(head);
    /** add the content of the pdf **/
    Paragraph context = new Paragraph();
    ElementList elementList =MyXMLWorkerHelper.parseToElementList(sBuffer.toString(), null);
    for (Element element : elementList) {
    context.add(element);
    }
    document.add(context);
    
    document.add(new Paragraph(" "));
    document.add(new Paragraph(
    "亲笔签名/公司公章: _______________________________", fontChinese));
    document.add(new Paragraph("日期: ", fontChinese));
    document.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    View Code
  • 相关阅读:
    Wayland中的跨进程过程调用浅析
    设计模式总结
    C语言---整型字符串转换
    抽象工厂模式
    SVNclient安装与使用
    [置顶] MyEclipse下安装插件方法(properties文件编辑器Propedit为例)
    脑筋急转弯的歧义性
    脑筋急转弯的歧义性
    从和式积分到定积分
    从和式积分到定积分
  • 原文地址:https://www.cnblogs.com/Pikzas/p/6515610.html
Copyright © 2011-2022 走看看