zoukankan      html  css  js  c++  java
  • Itext结合struts2 中的FreeMarker动态打印输出html页面为pdf文件


    背景资料我就不介绍了,可以参考相关关于Itex和FreeMarker的文章和博文,下面的内容参考了网上各种资料,由于找的时候没有仔细的记录相应的出处,因此可能有些内容和其他博主的内容重复,敬请谅解在实现的过程中遇到很多问题,下面着重讲解遇到的问题与查找到的解决方法:

    (1)用老版本的Itext ,最新的Itext 5.0.3我没实现成功,我用的是Itext 2.0.8

    (2)要解决中文,日文的输出要 这个文件  iTextAsian.jar  ,记得要放在classpath路径下噢,顺便提一个小技巧,对最新版的Itext 5.0.3这个 iTextAsian.jar没法用,网上找到的方法是手工解压这个文件,并讲包名改为这个开头的com.itextpdf.text,也就是改目录名字哈

    (3)测试输出时使用的FreeMarker模板文件如下:在这个模板文件中要动态输出两个内容:一条消息,用表格方式循环数输出一个列表中的内容代码

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>测试一下</title>
    </head>
    <body>
    随便输出点啥${message}
    
    <br></br>
    是非得失 test
    <table>
    <#list userList as listUser>
    				<tr>
    					<td>名称1 ${listUser.userName1}</td>
    					<td>名称2 ${listUser.userName2}</td>
    				</tr>
    </#list>														
    </table>
    </body>
    </html>
    

    (4)中文输出的问题是最不好解决的,开始搞了半天也没能实现FreeMaker输出的内容在itext打印为中文,后来参考晚上的一片文章说看itext源码后发现采用SAXmyHtmlHandler方式能手动设置字体,这样就实现中文中文输出,核心代码如下 代码

    private Configuration cfg;
    
    public void process() throws Exception {
    
            // 取得模版文件,就是上面第三步的模板文件哈
            Template t = cfg.getTemplate("test.ftl");
            
            
            // 建立数据模型
            Map root = new HashMap();
                   //构造列表数组,列表中的数据包含两个字段,即两个名字撒
            List<User> users=new ArrayList<User>();
            for (int i = 0; i < 10; i++) {
                User usertemp=new User();
                usertemp.setUserName1(i+"s随便弄个名字东");
                usertemp.setUserName2(i+"中国古高度发达");
                users.add(usertemp);
                
            }
            
            root.put("message", "Hello 随便输出点消息看看效果咯!");
            root.put("userList", users);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            OutputStreamWriter oStreamWriter=new OutputStreamWriter(baos);
            t.process(root,oStreamWriter );
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());</pre>
    <pre class="java">      //打印pdf咯
            html2pdf(bais, "/Users/sir/Desktop/test1.pdf");        
        
        }
        private void html2pdf(InputStream is,String outputPathName) throws Exception {
            Document doc = new Document();
            BaseFont bf = BaseFont.createFont("STSong-Light,Bold", "UniGB-UCS2-H",
                    BaseFont.NOT_EMBEDDED);//设置中文宋体字
            //下面这点代码就是解决中文输出的关键所在了
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            PdfWriter.getInstance(doc, new FileOutputStream(outputPathName));
            SAXmyHtmlHandler saxHandler = new SAXmyHtmlHandler(doc, bf);
            parser.parse(is, saxHandler);
        }
    

    (5)调用上面代码的process() 函数就可以输出pdf文件了

    (6)总结:感谢网上各位同志分享资料FreeMarker的模板文件随便编,这样就可以实现你想怎么打印输出就怎么打印输出当然Itext并不是所有的html都支持噢
    更详细的资料请您查看 http://today.java.net/pub/a/today/2007/06/26/generating-pdfs-with-flying-saucer-and-itext.html

  • 相关阅读:
    2021-01-27:如何把文件从服务器复制到本地,用什么命令?
    2020-01-26:mysql8.0做了什么改进?
    2020-01-25:redis中,哨兵如何选举?
    2020-01-24:手写代码:快速排序。
    2021-01-23:LFU手撸,说下时间复杂度和空间复杂度。
    2021-01-22:java中,HashMap的写流程是什么?
    2021-01-21:java中,HashMap的读流程是什么?
    2020-01-20:mysql中,一张表里有3亿数据,未分表,要求是在这个大表里添加一列数据。数据库不能停,并且还有增删改操作。请问如何操作?
    2021-01-19:mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量差不多占50%,根据条件把个体户的行都删掉。请问如何操作?
    USB Type-C设备是否需要CC逻辑芯片 ------ 转载
  • 原文地址:https://www.cnblogs.com/wordadobe/p/1842040.html
Copyright © 2011-2022 走看看