使用freemarker模板生成pdf

1、使用freemarker编写html模板
2、利用flyingSaucer生成pdf
3、GitHub 源码地址

添加maven依赖

<dependency>    
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf</artifactId>
    <version>9.0.9</version>
</dependency>

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>

项目文件结构树


src
├─main
│  ├─java
│  │  └─com
│  │      └─zsx
│  │          └─pdfTemplate
│  │                  PDFTemplateUtil.java
│  │                  UtilTest.java
│  │
│  ├─resources
│  │  ├─pdf
│  │  │  │  pdf.ftl
│  │  │  │
│  │  │  └─font
│  │  │          simhei.ttf
│  │  │          simsun.ttc
│  │  │
│  │  └─static
│  │          style.css
│  │
│  └─webapp
│      │  index.jsp
│      │
│      └─WEB-INF
│              web.xml
│
└─test
    └─java 

主要工具类 PDFTemplateUtil.java

主要的配置项都设置了默认值,比如,freemarker模板的存放路径,模板名称,字体文件等。
提供了set方法,方便自定义各个配置项。


package com.zsx.pdfTemplate;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Locale;

import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.pdf.BaseFont;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * freemarker模板生成PDF工具类
 * @author ZSX
 */
public class PDFTemplateUtil {

    /**
     * classpath路径
     */
    private String classpath = getClass().getResource("/").getPath();

    /**
     * 指定FreeMarker模板文件的位置
     */ 
    private String templatePath = "/pdf";

    /**
     * freeMarker模板文件名称
     */
    private String templateFileName = "pdf.ftl";

    /**
     * 图片路径 —— 默认是classpath下面的images文件夹
     */
    private String imagePath = "/images/";

    /**
     * 字体资源文件 存放路径
     */
    private String fontPath = "pdf/font/";

    /**
     * 字体   [宋体][simsun.ttc]   [黑体][simhei.ttf]
     */
    private String font = "simsun.ttc";

    /**
     * 指定编码
     */
    private String encoding = "UTF-8";


    /**
     * 生成pdf
     * @param data  传入到freemarker模板里的数据
     * @param out   生成的pdf文件流
     */
    public void createPDF(Object data, OutputStream out) {
        // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
        Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        // 指定FreeMarker模板文件的位置
        cfg.setClassForTemplateLoading(getClass(), templatePath);

        ITextRenderer renderer = new ITextRenderer();
        try {
            // 设置 css中 的字体样式(暂时仅支持宋体和黑体)
            renderer.getFontResolver().addFont(classpath + fontPath + 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.getSharedContext().setBaseURL(classpath + imagePath);
            renderer.layout();

            renderer.createPDF(out, false);
            renderer.finishPDF();
            out.flush();
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void setClasspath(String classpath) {
        this.classpath = classpath;
    }


    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }


    public void setTemplateFileName(String templateFileName) {
        this.templateFileName = templateFileName;
    }


    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }


    public void setFontPath(String fontPath) {
        this.fontPath = fontPath;
    }


    public void setFont(String font) {
        this.font = font;
    }


    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }


    @Override
    public String toString() {
        return   "[templatePath] : " + templatePath + " \r\n "
                +"[templateFileName] : " + templateFileName + " \r\n "
                +"[imagePath] : " + imagePath + " \r\n "
                +"[fontPath] : " + fontPath + " \r\n "
                +"[font] : " + font + " \r\n "
                +"[encoding] : " + encoding;
    }

}

调用方法 UtilTest.java

传入的out输出流可以是一个文件流,也可以是servlet中的response的输出流


package com.zsx.pdfTemplate;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

public class UtilTest {

    public static void main(String[] args) throws Exception {

        Map<String, Object> data = new HashMap<String, Object>();

        data.put("title", "你的名字");

        FileOutputStream out = new FileOutputStream(new File("c://1.pdf"));

        PDFTemplateUtil pdfUtil = new PDFTemplateUtil();
        pdfUtil.createPDF(data, out);

    }

}



freemarker模板文件 pdf.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;
    }
</style>
</head>
<body>
${title}
</body>
</html>

  • 字体文件可以去 C:\Windows\Fonts路径下查找
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值