• ftl转pdf及问题集锦


    这是一个令人悲伤的问题,本人在网上大量查找资料,总是有这样那样的问题导致不能转换成功

    引入的maven     jar包如下

        <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.4.3</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf.tool</groupId>
                <artifactId>xmlworker</artifactId>
                <version>5.5.5</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.xhtmlrenderer</groupId>
                <artifactId>core-renderer</artifactId>
                <version>R8</version>
            </dependency>

    参考了很多资料,我选择的是  https://blog.csdn.net/NetSnake_/article/details/77161106   作为参考

    @RequestMapping("/printingcontractNew")
        public void printingcontractNew( HttpServletResponse response,Long orderId,HttpServletRequest request) throws Exception {
    
    
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderContract", order);
            map.put("orderinformation", orderinformation);
    
          //输入需要传输的数据
            try {
                ByteArrayOutputStream baos = FtlToPdf1.createPDF(request, "PrintingContract.ftl", map);    //"PrintingContract.ftl"为自己的ftl能展示的(注意结构必须严谨)
                System.out.println(baos);
                //设置response文件头
                 FtlToPdf1.renderPdf(response, baos.toByteArray(), "789");    //789  为输出pdf的名字可以自己命名
            } catch (Exception e) {
                throw new Exception(e);
            }
    
    
          /*  ftlTOPDF.FTL2PDF(srcPath, destPath, map);*/
        }
    package com.ningpai.site.pdf;
    
    /*import com.lowagie.text.pdf.BaseFont;*/
    
    import com.itextpdf.text.pdf.BaseFont;
    import com.itextpdf.text.pdf.PdfWriter;
    import com.itextpdf.tool.xml.XMLWorkerHelper;
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import org.xhtmlrenderer.pdf.ITextFontResolver;
    import org.xhtmlrenderer.pdf.ITextRenderer;
    
    import com.itextpdf.text.Font;
    import com.itextpdf.text.Document;
    import com.itextpdf.text.Paragraph;
    /*
    import org.xhtmlrenderer.pdf.ITextFontResolver;
    import org.xhtmlrenderer.pdf.ITextRenderer;
    */
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Locale;
    import java.util.Map;
    
    /**
     * Created by Administrator on 2018-5-19.
     */
    public class FtlToPdf1 {
    
        /**
         * 生成PDF文件流
         * @param request
         * @param ftlName 文件名称
         * @param root  数据
         * @return ByteArrayOutputStream
         * @throws Exception
         */
        public static ByteArrayOutputStream createPDF(HttpServletRequest request, String ftlName, Object root) throws Exception {
            String basePath = request.getSession().getServletContext().getRealPath("/");//绝对路径
            Configuration cfg = new Configuration();
            try {
                cfg.setLocale(Locale.CHINA);
                cfg.setEncoding(Locale.CHINA, "UTF-8");
                //设置编码
                cfg.setDefaultEncoding("UTF-8");
                //设置模板路径
                cfg.setDirectoryForTemplateLoading(new File(basePath + "view/contract/"));
    
                //获取模板
                Template template = cfg.getTemplate(ftlName);
                template.setEncoding("UTF-8");
    
                ITextRenderer iTextRenderer = new ITextRenderer();
                //设置字体
                ITextFontResolver fontResolver = iTextRenderer.getFontResolver();
                fontResolver.addFont(basePath + "view/contract/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);    "view/contract/simsun.ttf"  为下载的字体将其放入程序中的位置
    
                Writer writer = new StringWriter();
                //数据填充模板
                template.process(root, writer);
                //设置输出文件内容及路径
                String str = writer.toString();
                iTextRenderer.setDocumentFromString(str);
                iTextRenderer.getSharedContext().setBaseURL("file:/D:");  //图片共享路径file:/home/ddcj/
                iTextRenderer.layout();
                //生成PDF
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                iTextRenderer.createPDF(baos);      //这里会显示有乱码  , 但对最后输出结果没有影响
                baos.close();
    
                return baos;
            } catch(Exception e) {
                throw new Exception(e);
            }
        }
    
        //此方法主要是设置文件头,并把文件作为附件下载
        public static void renderPdf(HttpServletResponse response, final byte[] bytes, final String filename) {
            setFileDownloadHeader(response, filename, ".pdf");
            if (null != bytes) {
                try {
                    response.getOutputStream().write(bytes);
                    response.getOutputStream().flush();
                } catch (IOException e) {
                    throw new IllegalArgumentException(e);
                }
            }
        }
    
        /**
         * 设置让浏览器弹出下载对话框的Header.
         * @param fileName 下载后的文件名.
         */
        public static void setFileDownloadHeader(HttpServletResponse response, String fileName, String fileType) {
            try {
                // 中文文件名支持
                String encodedfileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
                response.setHeader("Content-Disposition", "attachment; filename="" + encodedfileName + fileType + """);
            } catch (UnsupportedEncodingException e) {
            }
        }
    }

    效果图如下:

    点击打印

     

    打开后

     格式有点丑,还没开始修改...

    问题集锦:

    1.org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException; lineNumber: 167; columnNumber: 44; 元素类型 "td" 必须由匹配的结束标记 "</td>" 终止。

    报错的代码如下:

       <tr>
                        <td class="product_table_th">供方:xxx</br>地址:xxx</br>电话:028-3xxxx59</br>传真:028-xxxxx909</br>
                            开户银行:中国建设xxx分行</br>账号:5100 xxxx xxxx xxx1 0200
                        </td>
                        <td class="product_table_th">需方:${orderinformation.invoiceCompanyName}</br>地址:${orderinformation.invoiceSite} </br>
                            电话:${orderinformation.invoicePhoneNumber}</br>传真:</br>
                            开户银行:${orderinformation.invoiceDepositBank}</br>账号:${orderinformation.invoiceBankAccount} </td>
                    </tr> 

    想做成的效果

    经过多次查找,发现没什么问题;页面也能正常的显示,但就是会再转pdf时报错

    最后无意间修改解决了问题

     <tr>
                        <td class="product_table_th">供方:四川xxxx有限公司<br></br>地址:xxxx开发区<br></br>电话:028-xxxx59<br></br>传真:028-3xxxx09<br></br>
                            开户银行:中国xxx分行<br></br>账号:5100 xxxxx 0200
                        </td>
                        <td class="product_table_th">需方:${orderinformation.invoiceCompanyName}<br></br>地址:${orderinformation.invoiceSite} <br></br>
                            电话:${orderinformation.invoicePhoneNumber}<br></br>传真:<br></br>
                            开户银行:${orderinformation.invoiceDepositBank}<br></br>账号:${orderinformation.invoiceBankAccount} </td>
                    </tr>

    重点为<br></br>  因为itex转pdf是非常严谨的必须有开头和结尾

    2.org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException; lineNumber: 89; columnNumber: 45; 元素类型 "td" 必须后跟属性规范 ">" 或 "/>"。

    报错代码为

     <tr>
                        <td class="product_table_th">备注</td>
                        <td class="product_table_th"colspan="5"> ${orderinformation.customerRemark} </td>
                    </tr>

    原因居然是

    这。。。尼....果然严谨

    3.  本因分开的结果没有分开对应显示

    错误代码

        <#list orderContract as good>
                    <thead align="center">
                        <tr>
                            <td class="product_table_th"><span>${good.goodsInfoName}</span></td>
                            <td class="product_table_th"><span>${good.goodsInfoNum}</span></td>
                            <td class="product_table_th"><span>件</span></td>
                            <td class="product_table_th"><span>${good.goodsInfoPrice}</span></td>
                            <td class="product_table_th"><span>${good.goodsInfoSumPrice}</span></td>
                        </tr>
                    </thead>
                    </#list>

    原因:加入了<thead align="center">属性,,,注释掉就好

     4.只显示数字和英文    ,  中文字符不显示问题

    在网上查了很多,各方面的问题解决方法都有

    我的问题是

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>合同打印预览</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
        <meta name="renderer" content="webkit"></meta>
    </head>
    
    <body style="font-size:12.0pt; font-family: SimSun; background: none;margin-left: auto;margin-right: auto">
    <table.....>
    ...

    主要是这个      <body style="font-size:12.0pt; font-family: SimSun; background: none;margin-left: auto;margin-right: auto">   加上就好了

  • 相关阅读:
    java实现文件上传下载至ftp服务器
    理解java代理模式
    [置顶] 理解java中的线程池
    wait,notify,非阻塞队列实现生产者,消费者模型
    理解java阻塞队列BlockingQueue
    CentOS下安装配置Nginx
    putty笔记
    CentOs下安装jdk、MySql、Redis笔记
    简述yum和apt-get的区别
    Linux 文件颜色说明
  • 原文地址:https://www.cnblogs.com/huanglp/p/9061046.html
Copyright © 2020-2023  润新知