文档章节

使用freemarker和itext导出pdf文件

阿信sxq
 阿信sxq
发布于 2018/09/27 11:18
字数 746
阅读 15
收藏 0

要实现的效果是这样的:给定一个对象列表,对于列表中的每一个对象使用pdf中的一页进行呈现,同时需要使用一些图片。

首先,引入maven依赖

<properties>
    <itextpdf.version>5.5.13</itextpdf.version>
    <freemarker.version>2.3.28</freemarker.version>
    <slf4j.version>1.7.25</slf4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>${itextpdf.version}</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>${itextpdf.version}</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>${freemarker.version}</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
</dependencies>

使用用户信息来作为演示,其实体模型类

public class User {

    private String username;
    private String password;

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    getter/setter

}

生成pdf分为两个步骤:使用freemarker生成出文字内容(xhtml);使用itext的xml转换器生成pdf文件。

测试样例类

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;

import cn.songxinqiang.example.model.User;
import cn.songxinqiang.example.util.PathUtil;

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

/**
 *
 * @author 阿信sxq
 *
 */
public class JavaToPdfHtmlFreeMarker {

    private static final Logger logger = LoggerFactory.getLogger(JavaToPdfHtmlFreeMarker.class);

    private static final String DEST = "/tmp/itext_target.pdf";
    private static final String HTML = "freemarker-template.html";
    private static final String FONT = "simhei.ttf";

    private static Configuration freemarkerCfg = null;
    private static String classPath;

    static {
        freemarkerCfg = new Configuration(Configuration.VERSION_2_3_28);
        // freemarker的模板目录
        try {
            //XXX 工具类获取类文件的当前路径,也可以使用文件系统绝对路径
            classPath = PathUtil.getCurrentPath();
            freemarkerCfg.setDirectoryForTemplateLoading(new File(classPath));
//            freemarkerCfg.setDirectoryForTemplateLoading(new File("/opt/chaos"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException, DocumentException {
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            userList.add(new User("name " + i, "passwd " + i));
        }

        JavaToPdfHtmlFreeMarker render = new JavaToPdfHtmlFreeMarker();
        String content = render.freeMarkerRender(userList, HTML);
        logger.info("content:{}", content);
        render.createPdf(content, DEST);
    }

    public void createPdf(String content, String dest) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        // step 3
        document.open();
        // step 4
        XMLWorkerFontProvider fontImp =
                new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontImp.register(FONT);
        XMLWorkerHelper.getInstance()
                .parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null,
                        Charset.forName("UTF-8"), fontImp);
        // step 5
        document.close();

    }

    /**
     * freemarker渲染html
     */
    public String freeMarkerRender(List<?> list, String htmlTmp) {
        Map<String, Object> data = new HashMap<>();
        data.put("list", list);
        data.put("locationPath", classPath);
        Writer out = new StringWriter();
        try {
            // 获取模板,并设置编码方式
            Template template = freemarkerCfg.getTemplate(htmlTmp);
            // 合并数据模型与模板
            template.process(data, out); // 将合并后的数据和模板写入到流中,这里使用的字符流
            out.flush();
            return out.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

}

freemarker模板

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<style>
body {
    font-family: SimHei;
}
.pageNext{
    page-break-after: always;
}
</style>
</head>
<body>
    <#list list as user>
        用户名:${user.username}<br/>
        密码:${user.password}<br/>
        插入图片:<br/>
        <img width="100px" src="file://${locationPath}/github.png"/>
        <span class="pageNext"></span>
    </#list>
</body>
</html>

这里需要使用xhtml的语法,所有标签都需要闭合,因为经过处理得到的内容会使用itext的xml处理器去处理。

而且对于汉字需要指定汉字字体。

对于代码,已经托管到码云:https://gitee.com/songxinqiang/BlogExampleCode

写的不好,望大家批评指正

© 著作权归作者所有

共有 人打赏支持
阿信sxq

阿信sxq

粉丝 227
博文 83
码字总数 73652
作品 1
成都
后端工程师
私信 提问
利用itext导出word表格,处理图片

在实际的项目开发中我们需要将后台大量数据导出为word或者是excel方便用户操作,当然能完成这一功能的有freemarker,itext,poi等技术,本文讲述以itext导出word。 首先我们需要明白的是无论...

小夜的传说
2018/06/26
0
0
FreeMarker(二):利用FreeMarker转pdf

设计需求 订票成功后,生成一个pdf 文件,用户打印入场票,门票大致如下所示: 2. 设计思想 1). 使用FreeMarker 转换 ftl(就是FreeMarker 魔板文件),生成HTML 2). 使用jtidy库将 HTML转换...

AHUSKY
2018/04/17
0
0
请教关于java利用现有word文档生成pdf的问题

我现在手上有一个十页的合同,word形式的文档,现在的需求是每生成一笔订单,就要动态的修改这个合同,替换姓名,身份证号等一些地方,没有图片,并生成pdf,供客户在app端下载他自己的电子合同. 在网...

开过光的红薯
2016/08/16
305
4
使用iText库创建PDF文件

原文地址:使用iText库创建PDF文件 阅读目录 前言 iText库概述 iText库常用类 iText Hello World示例 给PDF文件设置文件属性 PDF中添加图片 PDF中创建表格 PDF中创建列表 PDF中设置样式/格式...

spinachgit
2017/10/24
0
0
将oschina收藏的博客在线转换为PDF文档

前一段时间无意获得了一个Kindle,有时候无聊的时候会简单的看下,简单的看了下里面与技术相关的书籍大多都是收费的,结合自己之前的又比较喜欢浏览osc自己收藏的文章的习惯。于是就简单的想...

hibegin
2016/08/01
178
0

没有更多内容

加载失败,请刷新页面

加载更多

rabbitMQ 在spring 的使用

一、准备工作 maven依赖 <dependency>  <groupId>com.rabbitmq</groupId>  <artifactId>amqp-client</artifactId>  <version>4.0.2</version></dependency> <dependency......

狼王黄师傅
昨天
1
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
1
0
大数据教程(11.8)Hive1.2.2简介&初体验

上一篇文章分析了Hive1.2.2的安装,本节博主将分享Hive的体验&Hive服务端和客户端的使用方法。 一、Hive与hadoop直接的关系 Hive利用HDFS存储数据,利用MapReduce查询数据。 二、Hive与传统数...

em_aaron
昨天
3
0
跟我学Spring Cloud(Finchley版)-15-Hystrix监控详解

Hystrix提供了监控Hystrix Command的能力,本节来详细探讨。 监控端点与数据 应用整合Hystrix,同时应用包含spring-boot-starter-actuator 依赖,就会存在一个/actuator/hystrix.stream 端点...

周立_ITMuch
昨天
6
0
day26:shell题

1、 判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。 如果其生产商为AuthenticAMD,就显示其为AMD公司; 如果其生产商为GenuineIntel,就显示其为Intel公司; 否则,...

芬野de博客
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部