Velocity+IText+Flying-saucer生成pdf文件

这篇文章比较长,包括三个模块的内容:


  1. 用到的相关jar包及其版本号
  2. 根据velocity模板生成html文件方法
  3. 根据html文件生成pdf文件方法

如果你是其它方法已经生成了html模板,则直接参考3即可。




文章中需要用到的jar包及代码文件下载地址:Jar包及素材下载

如果你实在是懒,我这里还有一个java项目,导入eclipse即可执行。大笑大笑大笑懒人直接下载项目,记得点赞哈



1:相关jar包及其版本号

flying-saucer-pdf-itext5-9.1.13
flying-saucer-core-9.1.13
itextpdf-5.5.11
xmlworker-5.5.11
itext-asian-5.2.0
    
<!--iText对PDF做数字证书时用到的第三方加密解密工具包-->
bcpkix-jdk15on-1.58
bcprov-jdk15on-1.58    
    
<!--读取velocity模板内容jar包 -->
jodd-core-3.7.1

    
    
maven依赖:

 <!--html转pdf,签章-->
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.5.11</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf.tool</groupId>
                <artifactId>xmlworker</artifactId>
                <version>5.5.11</version>
            </dependency>
             <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf -->
            <dependency>
                <groupId>org.xhtmlrenderer</groupId>
                <artifactId>flying-saucer-pdf-itext5</artifactId>
                <version>9.1.13</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-core -->
            <dependency>
                <groupId>org.xhtmlrenderer</groupId>
                <artifactId>flying-saucer-core</artifactId>
                <version>9.1.13</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <!--iText对PDF做数字证书时用到的第三方加密解密工具包-->
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcpkix-jdk15on</artifactId>
                <version>1.58</version>
            </dependency>
            <dependency>
                <groupId>org.bouncycastle</groupId>
                <artifactId>bcprov-jdk15on</artifactId>
                <version>1.58</version>
            </dependency>
    
           <dependency>
                <groupId>org.jodd</groupId>
                <artifactId>jodd-core</artifactId>
                <version>3.7.1</version>
            </dependency>      
                

2:根据velocity模板生成html文件方法




 核心代码;

import jodd.io.FileUtil;  //fileUtil所在jar包

//1:获取合同模板内容
    /**
     * 获取合同模板内容
     * @param templateName 模板路径
     * @return
     */
    public String getOrderContractTemplateContent(String contractFileUrl) {
   
     File contractFile = new File(contractFileUrl);
        /*
            合同模板不存在
         */
    if (!contractFile.exists()) {
        // 判断父文件夹是否存在
        File destFile = contractFile.getParentFile();
        if (!destFile.exists() && !destFile.isDirectory()) {
            destFile.mkdirs();
        }
        LOGGER.error(String.format("合同模板:%s 不存在,路径地址:%s,请及时上传!", templateName, orderContractFileUrl));
        return null;
    }

        try {
            return FileUtil.readString(contractFile);
           } catch (IOException e) {
        LOGGER.error(String.format("获取合同模板:%s 异常!", templateName), e);
        }
    }


//2:替换模板内容中的变量,templateDO是封装模板中变量的实体类,根据你的业务构建,传入即可

 String vmContent = getOrderContractTemplateContent("模板文件路径地址");
 Map<String, Object> dataMap = new HashedMap();
 dataMap.put("orderTemplate", templateDO);
 String htmlContent = VelocityUtil.parseString(vmContent, dataMap, "");
 
 
 String htmlFileName = String.format("%s/%s.html", path, fileName); //生成html文件路径+名称
 File htmlFile = new File(htmlFileName);
 return generateNewHtml(htmlFile, htmlContent);



/**
     * 保存替换变量后的模板为html文件  保存到磁盘
     * @param newFile 生成html文件
     * @param html   替换变量后的模板文件内容
     * @return
     */
    private String generateNewHtml(File newFile, String html) {
        if (newFile == null) {
            LOGGER.error("生成新html文件路径不能为空!");
            return null;
        }
        if (StringUtil.isNullorEmpty(html)) {
            LOGGER.error("替换模板中变量后,文件内容为空!");
            return null;
        }

        OutputStream out = null;
        InputStream in = null;
        OutputStreamWriter oStreamWriter = null;
        InputStreamReader inputStreamReader = null;
        try {
            if (!newFile.getParentFile().exists()) {
                newFile.getParentFile().mkdirs();
            }
            if (!newFile.exists()) {
                newFile.createNewFile();
            }

            //读写操作
            out = new FileOutputStream(newFile);
            in = new ByteArrayInputStream(html.getBytes());
            inputStreamReader = new InputStreamReader(in);
            oStreamWriter = new OutputStreamWriter(out, "UTF-8");
            //创建字符流缓冲区
            BufferedReader buffer = new BufferedReader(inputStreamReader);//缓冲
            String line;
            while ((line = buffer.readLine()) != null) {
                oStreamWriter.append(line);
            }
            oStreamWriter.flush();

            return newFile.getPath();
        } catch (Exception ex) {
            LOGGER.error("保存文件失败generateNewHtml", ex);
            return null;

        } finally {
            //放回资源
            try {
                if (in != null) {
                    in.close();
                }
                if (oStreamWriter != null) {
                    oStreamWriter.close();
                }
                if (out != null) {
                    out.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
            } catch (Exception ignored) {
                LOGGER.error("关闭流资源时异常,流关闭失败!", ignored);
            }
        }
    }

3:根据html文件生成pdf文件方法

import com.itextpdf.text.pdf.BaseFont;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
     * 根据html文件生成pdf文件
     * @param htmlPath  html文件路径
     * @param pdfPath 生成的pdf路径
     * @return
     */
    public static boolean generatePdf(String htmlPath,String pdfPath) {
        OutputStream output = null;
        try {
            output = new FileOutputStream(pdfPath);
            //实例ITextRenderer,加载html文档
            ITextRenderer renderer = new ITextRenderer();
            //添加字体,以支持中文
            renderer.getFontResolver().addFont( "G:\\a\\soft\\Fonts\\Nsimsun.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            String url = new File(htmlPath).toURI().toURL().toString();  //关键  不写这一句,中文字体出不来
            renderer.setDocument(url);
            //嵌入图片磁盘目录
            renderer.getSharedContext().setBaseURL("file:/G:/a/static/template/");
            renderer.layout();
            renderer.createPDF(output);
            output.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                    LOGGER.error("HtmlToPdfUtilForCss--->生成pdf输出流关闭失败!",e1);
                }
            }
            return false;
        }

    }

上面代码设置加载的字体为Nsimsun.TFF(新宋体),在html中一定要指定全文字体为新宋体,要不生成的pdf文件中文不显示。


注意事项:

(1):html生成pdf时,不支持一些特殊的html语法标签,比如: &nbsp; 所以需要在读取内容转html时,需把"&nbsp;" 替换掉。可以替换为""或替换成 " &#160;"
&#160;是xml文件格式中的空格符号。
(2):html文件转pdf文件时,加载的字体嵌入性一定要是“可编辑”以上权限的,要不会报错。



文章中需要用到的jar包及
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值