首先在maven中引入相关依赖
org.freemarker
freemarker
2.3.22
org.xhtmlrenderer
flying-saucer-pdf
9.1.11
其中freemarker版本随意,flying-saucer-pdf架包建议使用最新的,因为老版本对html不友好,新版本做了很多兼容,还原度较高。
干活在这里
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
/**
* 基于freemarker生成pdf
* Author:杨杰超
* Date:2019年11月15日 下午3:33:07
* Copyright (c) 2019, [email protected] All Rights Reserved.
*
*/
public class GenPdfTest {
/**
* 生成测试数据
*/
private static Map newData() {
Map data = new HashMap();
// 存入一个集合
List cureseList = new ArrayList();
cureseList.add(newCureseData("▲公共必修课1", "数理统计", "1/春", "2.5", "85"));
cureseList.add(newCureseData("▲公共必修课2", "数理统计", "1/春", "2.5", "85"));
cureseList.add(newCureseData("▲公共必修课3", "数理统计", "1/春", "2.5", "85"));
cureseList.add(newCureseData("▲公共必修课4", "数理统计", "1/春", "2.5", "85"));
cureseList.add(newCureseData("▲公共必修课5", "数理统计", "1/春", "2.5", "85"));
// 课程加权平均成绩
String avgAchievement = "-";
String stuName = "Jc";
String stuNo = "1111111";
String stuGrade = "2019";
String stuType = "研究生";
String stuCollege = "软件学院";
String stuTeacher = "何XX";
String stuMajor = "计算机科学与技术";
data.put("courseList", cureseList);
data.put("avgAchievement", avgAchievement);
data.put("stuName", stuName);
data.put("stuNo", stuNo);
data.put("stuGrade", stuGrade);
data.put("stuType", stuType);
data.put("stuCollege", stuCollege);
data.put("stuTeacher", stuTeacher);
data.put("stuMajor", stuMajor);
return data;
}
/**
* 生成测试数据
*
* @param type
* @param name
* @param semester
* @param credit
* @param achievement
* @return
*/
private static Map newCureseData(String type, String name, String semester, String credit,
String achievement) {
Map map = new HashMap();
map.put("type", type);
map.put("name", name);
map.put("semester", semester);
map.put("credit", credit);
map.put("achievement", achievement);
return map;
}
public static void main(String[] args) throws Exception {
Map data = newData();
// 根路径
String path = GenPdfTest.class.getResource("/").getPath().substring(1);
// 模板名称
String ftlName = "pdftest.ftl";
// 图片路径
String imageDiskPath = path + "imgs/";
// 文件生成全路径
String outputFile = "D:\\pdftest.pdf";
generateToFile(path, ftlName, imageDiskPath, data, outputFile);
}
/**
* 获取freemarker模板对象
*
* @param ftlPath
* FTL模板路径
* @param ftlName
* FTL模板名称
* @return
* @throws IOException
*/
public static Template generateTemplate(String ftlPath, String ftlName) throws IOException {
Configuration config = new Configuration(new Version("2.3.22"));
config.setDirectoryForTemplateLoading(new File(ftlPath));
config.setEncoding(Locale.CHINA, "UTF-8");
Template template = config.getTemplate(ftlName);
return template;
}
/**
* 获取ITextRenderer渲染器
*
* @param path
* 根路径
* @return
* @throws DocumentException
* @throws IOException
*/
public static ITextRenderer generateITextRenderer(String path) throws DocumentException, IOException {
ITextRenderer render = new ITextRenderer();
// 添加字体,以支持中文
render.getFontResolver().addFont(path + "fonts/arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
render.getFontResolver().addFont(path + "fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
return render;
}
/**
* 生成PDF到文件
*
* @param ath
* 根路径
* @param ftlName
* 模板文件吗(不含路径)
* @param imageDiskPath
* 图片的磁盘路径
* @param data
* 数据
* @param outputFile
* 目标文件(全路径名称)
* @throws Exception
*/
public static void generateToFile(String path, String ftlName, String imageDiskPath, Object data, String outputFile)
throws Exception {
Template tpl = generateTemplate(path + "ftl/", ftlName);
StringWriter writer = new StringWriter();
tpl.process(data, writer);
writer.flush();
String html = writer.toString();
ITextRenderer render = generateITextRenderer(path);
OutputStream out = new FileOutputStream(outputFile);
render.setDocumentFromString(html);
if (imageDiskPath != null && !"".equals(imageDiskPath)) {
render.getSharedContext().setBaseURL("file:/" + imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
out.close();
}
}
freemarker模板ftl文件 print.ftl
XXXX成绩表
姓名
${stuName}
学号
${stuNo}
年级
${stuGrade}
学生类型
${stuType}
学院
${stuCollege}
指导教师
${stuTeacher}
专业
${stuMajor}
成绩表
课程类别
课程名称
上课学年/学期
学分
成绩
<#list courseList as course>
${course.type}
${course.name}
${course.semester}
${course.credit}
${course.achievement}
#list>
项目结构图:
最终生成pdf: 其中使用到了arialuni.ttf与simsum.ttc2个字体文件,这个在网上找找吧,就不放上来了。
就是这样,搞完收工~