赞
踩
1、主要目录
2、maven依赖
<!--工具类依赖--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> <!--pdf--> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>4.0.3</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>font-asian</artifactId> <version>7.2.3</version> </dependency>
3、新建一个demo.html静态文件,后续导出模板就是按照此文件进行的
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> </head> <body> <div class="contianer"> <div class="bg-img-container"> </div> <h1>模板pdf</h1> <div class="flex-div"> <p>表1</p> </div> <table border="1" cellSpacing="1"> <tr> <th>姓名</th> <td colspan="3">$!{name}</td> </tr> <tr> <th #if($!{gender}==1) class="blue" #else class="red" #end>性别</th> <td colspan="3"> #if($!{gender}==1) 男 #else 女 #end </td> </tr> <tr> <th>出生日期</th> <td>$!{birthDate}</td> <th>联系方式</th> <td>$!{phone}</td> </tr> </table> <h1>双重For循环取值</h1> <div class="flex-div"> <p>表2</p> </div> <table border="1" cellSpacing="1"> <tr> <th>学历</th> <th>学科</th> <td class="gray-bg">分数</td> </tr> #foreach($item in $eduList) <tr> <th #set($len= $item.size+1) rowspan="$len">$item.name</th> #foreach($result in $item.itemList) <tr> <td>$velocityCount、$result.subject</td> <td #if($result.num > 60) class="green" #else class="red" #end>$result.num</td> </tr> #end </tr> #end </table> </div> </body> <style> .blue { color: #244385; margin-left: 30px; } .green { color: #52c41a; margin-left: 30px; } .red { color: #c1181e; margin-left: 30px; } .flex-div { margin: 30px 0 15px; display: flex; align-items: center; } .line { width: 540px; height: 0px; border: dashed 1px #edf0f5; } table { width: 700px; border-collapse: collapse; /*border-spacing: 0;*/ border-left: 1px solid #edf0f5; border-top: 1px solid #edf0f5; } th, td { border-right: 1px solid #edf0f5; border-bottom: 1px solid #edf0f5; padding: 5px 15px; } h1 { text-align: center; font-family: 'Microsoft YaHei'; line-height: 60px; letter-spacing: 8px; color: #244385; } p { font-family: 'Microsoft YaHei'; font-size: 20px; font-weight: normal; color: #244385; margin: 0 16px; } th { background-color: rgba(0, 0, 0, 0.01); width: 90px; min-width: 90px; max-width: 90px; text-align: left; text-indent: 10px; font-family: 'Microsoft YaHei'; font-size: 16px; font-weight: normal; font-stretch: normal; line-height: 48px; letter-spacing: 2px; color: #666666; } td { font-size: 16px; color: #000000; text-align: left; text-indent: 10px; padding-right: 20px; height: 50px; } table,tr, th, td { border: solid 1px #edf0f5; } .gray-bg { background-color: rgba(0, 0, 0, 0.01); } </style> </html>
4、新建PdfUtil工具类
import com.itextpdf.html2pdf.ConverterProperties; import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.kernel.geom.PageSize; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.font.FontProvider; import org.apache.velocity.Template; import org.apache.velocity.app.Velocity; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import java.io.OutputStream; import java.io.StringWriter; import java.nio.charset.StandardCharsets; /** * PDF工具 * * @author ppp * @date 2022/8/5 */ public class PdfUtil { static { // Velocity初始化 Velocity.setProperty(RuntimeConstants.OUTPUT_ENCODING, StandardCharsets.UTF_8); Velocity.setProperty(RuntimeConstants.INPUT_ENCODING, StandardCharsets.UTF_8); Velocity.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); Velocity.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); Velocity.init(); } /** * 据模板生成pfd格式文件 * * @param context 上下文对象 * @param template pdf模板 * @param outputStream 生成ofd文件输出流 */ public static void pdfFile(Context context, String template, OutputStream outputStream) { try (PdfWriter pdfWriter = new PdfWriter(outputStream)) { PdfDocument pdfDocument = new PdfDocument(pdfWriter); pdfDocument.setDefaultPageSize(PageSize.A4); ConverterProperties properties = new ConverterProperties(); FontProvider fontProvider = new FontProvider(); // 字体设置,解决中文不显示问题 PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H"); fontProvider.addFont(sysFont.getFontProgram(), "UniGB-UCS2-H"); properties.setFontProvider(fontProvider); Template pfdTemplate = Velocity.getTemplate(template, "UTF-8"); StringWriter writer = new StringWriter(); pfdTemplate.merge(context, writer); HtmlConverter.convertToPdf(writer.toString(), pdfDocument, properties); pdfDocument.close(); } catch (Exception e) { throw new RuntimeException("PFD文件生成失败", e); } } }
5、Controller接口测试,也可以根据业务来分层service
package com.example.springboot3.controller; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.URLUtil; import com.example.springboot3.utils.PdfUtil; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import org.apache.velocity.VelocityContext; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.*; @RestController @RequestMapping("/velocity") public class PdfController { @GetMapping("/getPdf") public void get(HttpServletResponse response){ response.reset(); response.setContentType("application/pdf"); String filename = System.currentTimeMillis()+".pdf"; response.addHeader("Content-Disposition", "inline; filename=" + URLUtil.encode(filename, CharsetUtil.CHARSET_UTF_8)); VelocityContext context = new VelocityContext(); context.put("name", "彭也行"); context.put("gender", 1); context.put("birthDate", DateUtil.formatDateTime(new Date())); context.put("phone", "13666666666"); List<Map<String, Object>> eduList = new ArrayList<>(); // 小学 Map<String, Object> primarySchoolMap = new HashMap<>(); primarySchoolMap.put("name", "小学"); List<Map<String, Object>> scoreList = new ArrayList<>(); // 语文成绩 Map<String, Object> chineseScore = new HashMap<>(); chineseScore.put("subject", "语文"); chineseScore.put("num", 60); // 数学成绩 Map<String, Object> mathScore = new HashMap<>(); mathScore.put("subject", "数学"); mathScore.put("num", 99); scoreList.add(chineseScore); scoreList.add(mathScore); primarySchoolMap.put("itemList", scoreList); primarySchoolMap.put("size", scoreList.size()); // 初中 Map<String, Object> middleSchoolMap = new HashMap<>(); middleSchoolMap.put("name", "初中"); List<Map<String, Object>> middleScoreList = new ArrayList<>(); // 语文成绩 Map<String, Object> middleChineseScore = new HashMap<>(); middleChineseScore.put("subject", "语文"); middleChineseScore.put("num", 60); // 数学成绩 Map<String, Object> middleMathScore = new HashMap<>(); middleMathScore.put("subject", "数学"); middleMathScore.put("num", 99); // 英语 Map<String, Object> middleEnScore = new HashMap<>(); middleEnScore.put("subject", "英语"); middleEnScore.put("num", 55); middleScoreList.add(middleChineseScore); middleScoreList.add(middleMathScore); middleScoreList.add(middleEnScore); middleScoreList.add(middleEnScore); middleScoreList.add(middleEnScore); middleScoreList.add(middleEnScore); middleScoreList.add(middleEnScore); middleScoreList.add(middleEnScore); middleSchoolMap.put("itemList", middleScoreList); middleSchoolMap.put("size", middleScoreList.size()); eduList.add(primarySchoolMap); eduList.add(middleSchoolMap); context.put("eduList", eduList); try(ServletOutputStream outputStream = response.getOutputStream()){ PdfUtil.pdfFile(context, "static/demo.html", outputStream); }catch (Exception e){ e.printStackTrace(); } } }
6、调用接口浏览器预览
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。