因为需要图片和中文,所以使用了pd4ml+freemarker来生成pdf
需要maven包
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency>
<dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.17</version> </dependency>
<dependency> <groupId>com.pdf</groupId> <artifactId>pdf-fonts</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/fonts.jar</systemPath> </dependency>
<dependency> <groupId>com.pdf</groupId> <artifactId>pdf-pd4ml</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/pd4ml-370fx2pro.jar</systemPath> </dependency>
<dependency> <groupId>com.pdf</groupId> <artifactId>pdf-sscss</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/ss_css2.jar</systemPath> </dependency>
其中 flying-saucer-pdf
、pdf-fonts
、pdf-pd4ml
我是放在项目根目录下的
要支持中文,还需要引入simsun.ttf
字体文件,我是放在resources
目录下
生成pdf文件
/** * 生成pdf文件 * @author zengwei * @email 15797630391@163.com * @param ftlPath * @param ftlName * @param imageDiskPath * @param data * @param response * @return * @throws Exception */ public static OutputStream generateToServletOutputStream(String ftlPath, String ftlName, String imageDiskPath, Object data, HttpServletResponse response) throws Exception { // 获取Freemarker配置 Configuration config = new Configuration(Configuration.VERSION_2_3_0); config.setDirectoryForTemplateLoading(new File(ftlPath)); config.setEncoding(Locale.CHINA, "utf-8"); // 得到模板内容 Template tpl = config.getTemplate(ftlName); StringWriter writer = new StringWriter(); tpl.process(data, writer); writer.flush(); String html = writer.toString(); OutputStream out = response.getOutputStream(); // 添加字体,以支持中文 ITextRenderer render = new ITextRenderer(); render.getFontResolver().addFont("font/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); render.setDocumentFromString(html); // html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径 if (imageDiskPath != null && !"".equals(imageDiskPath)) { render.getSharedContext().setBaseURL("file:/" + imageDiskPath); } // 能日赚30的手赚试玩平台,亲测有效 // https://www.cnblogs.com/shiqiboy3974/p/13380267.html render.layout(); render.createPDF(out); render.finishPDF(); return out; }
创建controller调用生成pdf文件
/** * 生成pdf文件 * @author zengwei * @email 15797630391@163.com * @param response * @throws Exception */ @GetMapping("/downloadPdfFile") public void downloadPdfFile(HttpServletResponse response) throws Exception { String path = "template/"; //ftl路径 String templateName = "template";//需要选用的模板名称 String outFilePath = "template.pdf"; List<Map<String, Object>> labelList = new ArrayList<>(); Map<String, Object> label = new HashMap<>(); label.put("imgUrl", "https://profile.csdnimg.cn/0/6/D/3_zengweib208"); label.put("name", "NO1 CSDN:田间稻草人"); labelList.add(label); Map<String, Object> label2 = new HashMap<>(); label2.put("imgUrl", "https://profile.csdnimg.cn/0/6/D/3_zengweib208"); label2.put("name", "NO2 CSDN:田间稻草人"); labelList.add(label2); // 能日赚30的手赚试玩平台,亲测有效 // https://www.cnblogs.com/shiqiboy3974/p/13380267.html Map<String, Object> map = new HashMap<>(); map.put("labelList", labelList); response.reset(); response.setCharacterEncoding("UTF-8"); response.setContentType("application/PDF;charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=" + outFilePath); generateToServletOutputStream(path, templateName + ".ftl", path + "/images/", map, response); }
ftl模板放在项目根目录下
ftl模板内容,body标签中必须填入style="font-family: SimSun;"
,否则无法显示中文
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Document</title> <style> @page { size: 250mm 320mm; } * { margin: 0; padding: 0; } ul { list-style: none; overflow: hidden; padding: 20px 20px 20px 20px; } html, body { width: 100%; height: 100%; } ul li { background: #fff; float: left; margin: 0 20px; padding: 10px; width: 200px; overflow: hidden; } .over_one_line { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } </style> </head> <!-- 能日赚30的手赚试玩平台,亲测有效 https://www.cnblogs.com/shiqiboy3974/p/13380267.html --> <body style="font-family: SimSun;"> <ul> <#list labelList as label> <li> <img style="width: 200px;" src="${label.imgUrl}"/> <p class="over_one_line" style="padding-left: 10px">${label.name}</p> </li> </#list> </ul> </body> </html>
调用接口后生成pdf文件