zoukankan      html  css  js  c++  java
  • Java html模板生成PDF

    1、Maven依赖

           <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.23</version>
            </dependency>
    
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.4.2</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf.tool</groupId>
                <artifactId>xmlworker</artifactId>
                <version>5.4.1</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.xhtmlrenderer</groupId>
                <artifactId>flying-saucer-pdf</artifactId>
                <version>9.0.3</version>
            </dependency>

    2、pdfTemplate.ftl模板

    <!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>
        <style type="text/css">
            body {
                font-family: SimSun;
            }
            @page{size:A3 }
            .pianyi{
                display:block;
                font-family:SimSun;
                padding-left:15px;
                padding-right:15px;
                -webkit-margin-after:16px;
                -webkit-margin-before:16px;
                -webkit-margin-end:0px;
                -webkit-margin-start:0px;
            }
            .textSpan {
                padding-left: 15px;
                padding-right: 15px;
                line-height: 27px;
            }
    
        </style>
    </head>
    <body>
    <h3 style="text-align: center;">电子授权书</h3>
    <p class="pianyi">被授权人名称</p>
    <span class="textSpan">授权人(申请人)姓名: ${name}</span><br></br>
    <span class="textSpan">身份证号: ${idCardNo}</span><br></br>
    <span class="textSpan">授权协议生效日期: ${dateD} </span><br></br>
    <br/>
    <div style="word-wrap: break-word;word-break: break-all;overflow: hidden; ">
        ${content}
    </div>
    <div style="padding-left:15px;padding-right:15px;">签名处:</div>
    </body>
    </html>

    3、创建GeneratePdf类

    package com.wap.common;
    
    import com.itextpdf.text.pdf.BaseFont;
    import freemarker.template.Configuration;
    import freemarker.template.Template;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.xhtmlrenderer.pdf.ITextRenderer;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.io.StringWriter;
    import java.util.HashMap;
    import java.util.Locale;
    import java.util.Map;
    
    /**
     * 生成Pdf
     * Created by dgl on 2018/8/6.
     */
    public class GeneratePdf implements Runnable {
    
        private static Logger logger = LoggerFactory.getLogger(GeneratePdf.class);
    
        private String webPath; //= PathUtil.getPath();//web根目录
        /**
         * 指定FreeMarker模板文件的位置
         */
        private String templatePath;
    
        /**
         * freeMarker模板文件名称
         */
        private static String templateFileName = "pdfTemplate.ftl";
    
        /**
         * 图片路径 —— 默认是classpath下面的images文件夹
         */
        private static String imagePath = "/upload/";
    
        /**
         * 指定编码
         */
        private static String encoding = "UTF-8";
    
        /**
         * 字体   [宋体][simsun.ttc]   [黑体][simhei.ttf]
         */
        private String font;
    
        /**
         * 需要传入的数据
         */
        private Map<String, Object> dateMap;
    
        /**
         * 申请单号
         */
        private String applyFromCode;
    
        //上传的目录
        /*private static String directory;*/
    
        public GeneratePdf() {
        }
    
        public GeneratePdf(Map<String, Object> dateMap, String applyFromCode, String webPath) {
            this.dateMap = dateMap;
            this.applyFromCode = applyFromCode;
            this.webPath = webPath;
            this.templatePath = webPath + "/uf/template/";
            this.font = templatePath + "/simsun/simsun.ttc";
        }
    
    
        /**
         * 创建pdf
         *
         * @param data          变量数据
         * @param applyFromCode 新pdf地址 (一个单号只能有一个PDF文件,所以就直接用申请单号来命名)
         * @throws Exception
         */
        public Map<String, Object> createPdf(Map<String, Object> data, String applyFromCode) {
            Map<String, Object> map = new HashMap<>();
            String message = "";
            String detail = "";
            Boolean status = true;
            String code = "200";
            try {
                //创建文件
                //生成的pdf文件路径
                String newPdfPath = webPath + imagePath + applyFromCode + ".pdf";
    //            String newPdfPath = webPath + Setting.APPLY_FROM_PDF_PATH + "/" + applyFromCode + ".pdf";
                File file = new File(newPdfPath);
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                FileOutputStream out = new FileOutputStream(file);
                GeneratePdf pdf = new GeneratePdf();
                pdf.createPDF(data, out);
                message = "创建成功";
                //创建完成后的pdf文件所在地址
                detail = newPdfPath;
                logger.info("创建基础PDF完成");
                //线程休息
                Thread.sleep(1000);
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
                message = "创建pdf文件错误失败";
                status = false;
                code = "5005";
                detail = "";
                logger.error("创建pdf文件错误" + e.getMessage());
            }
            map.put("status", status);
            map.put("message", message);
            map.put("detail", detail);
            map.put("code", code);
            return map;
        }
    
        /**
         * 根据模板生成pdf
         *
         * @param data 传入到freemarker模板里的数据
         * @param out  生成的pdf文件流
         */
        public void createPDF(Object data, OutputStream out) throws Exception {
            // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
            Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            // 指定FreeMarker模板文件的位置
            ITextRenderer renderer = new ITextRenderer();
            try {
                cfg.setDirectoryForTemplateLoading(new File(templatePath));
    
                // 设置 css中 的字体样式(暂时仅支持宋体和黑体)
                renderer.getFontResolver().addFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                // 设置模板的编码格式
                cfg.setEncoding(Locale.CHINA, encoding);
                // 获取模板文件 template.ftl
                Template template = cfg.getTemplate(templateFileName, encoding);
                StringWriter writer = new StringWriter();
                // 将数据输出到html中
                template.process(data, writer);
                writer.flush();
                String html = writer.toString();
    
                // 把html代码传入渲染器中
                renderer.setDocumentFromString(html);
                // 解决图片的相对路径问题 ##必须在设置document后再设置图片路径,不然不起作用
                // 如果使用绝对路径依然有问题,可以在路径前面加"file:/"
                renderer.layout();
                renderer.createPDF(out, false);
                renderer.finishPDF();
                out.close();
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                out.close();
            }
        }
    
        @Override
        public void run() {
            logger.info("开始异步生成PDF文件");
            createPdf(dateMap, applyFromCode);
            logger.info("异步生成PDF文件完成");
        }
    
        public String getApplyFromCode() {
            return applyFromCode;
        }
    
        public void setApplyFromCode(String applyFromCode) {
            this.applyFromCode = applyFromCode;
        }
    }

    4、方法调用

    /***
         * Pdf sftp上传服务器
         * @param name 申请人名字
         * @param idCardNo 申请人身份证号
         * @param dateD 申请时间
         * @param content 内容说明
         * @param applyFromCode 申请单号
         * @paramdirectory 服务器存储路径
         */
        public static void printPdf(String webPath, String name, String idCardNo, String dateD, String content, String applyFromCode) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("name", name);
            map.put("idCardNo", idCardNo);
            map.put("dateD", dateD);
            map.put("content", content);
    
            GeneratePdf s = new GeneratePdf(map, applyFromCode, webPath);
            s.run();
        }
  • 相关阅读:
    一起谈.NET技术,.NET分布式架构开发实战之一 故事起源 狼人:
    JS替换节点
    mysql数据库的简单语句的介绍(1)
    JS对img进行操作
    POJ 1006 Biorhythms 数论(孙子定理)
    Tomcat与Jetty插件 配置根路径指定项目
    [置顶] cocos2dx 2.x版本之win32 window移植android 环境搭配 只用NDK 超级详细 android 环境搭配
    调频广播六十年
    ajax两个网页实现完美的 分页功能
    Cocos2dX数据、动作、消息的基本操作
  • 原文地址:https://www.cnblogs.com/hanmian4511/p/10876571.html
Copyright © 2011-2022 走看看