1.第一步先简单做个HTML页面,正常来说前端直接将整个HTML页面后端处理
直接复制使用即可
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"/> <title>Title</title> <style> body { font-family: SimHei; } input { -webkit-appearance: checkbox; } table { font-size: 8px; color: #333333; width: 100%; border-width: 1px; border-color: #729ea5; border-collapse: collapse; } th { font-size: 8px; background-color: #acc8cc; border-width: 1px; padding: 8px; border-style: solid; border-color: #729ea5; text-align: center; } tr { background-color: #d4e3e5; } td { font-size: 8px; border-width: 1px; padding: 8px; border-style: solid; border-color: #729ea5; text-align: center; } #div-head { line-height: 50px; text-align: center } </style> </head> <body> <div class="color pos"> <div id="div-head"> <b style="font-size: 25px;">动火安全作业许可证</b> </div> <div style="margin: 0;padding: 0"> <div style="margin: 0;padding: 0;display: inherit;float: left"><b>动火级别:123456</b> </div> <div style="margin: 0;padding: 0;display: inherit;float: right;"><b>许可证编号:123456</b> </div> </div> <table border="1"> <tr> <th colspan="7"><b style="font-size: 15px">作业申请</b></th> </tr> <tr> <td width="12%">申请单位</td> <td width="12%">123456</td> <td width="12%">作业负责人</td> <td width="12%">123456</td> <td width="12%">申请时间</td> <td colspan="2" width="12%">123456</td> </tr> <tr> <td>项目名称</td> <td>Antecs</td> <td>属地责任人</td> <td>阿萨德</td> <td>工单编号</td> <td colspan="2">123456</td> </tr> <tr> <td>所属装置</td> <td>123456</td> <td>动火地点</td> <td>123456</td> <td>动火方式</td> s <td colspan="2">123456</td> </tr> <tr> <td>作业内容</td> <td>123456</td> <td>动火部位</td> <td>123456</td> <td>作业监护人</td> <td colspan="2">123456</td> </tr> <tr> <td>计划作业时间</td> <td colspan="6">123456</td> </tr> <tr> <td>动火作业人</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> </tr> <tr> <td>特种作业证号</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> </tr> <tr> <td>准操项目</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> <td>现在没定字段</td> </tr> <tr> <td>涉及的其他 特殊作业</td> <td colspan="2">现在没定字段</td> <td>涉及的其他特殊作业 安全许可证编号</td> <td colspan="3">现在没定字段</td> </tr> <tr> <td>风险辨识结果</td> <td colspan="6">123456</td> </tr> </table> <table border="1"> <tr> <th width="5%">序号</th> <th width="75%">属地安全措施与风险告知</th> <th width="10%">是否涉及</th> <th width="10%">确认人</th> </tr> <tr> <td>123456</td> <td> 123456 </td> <td>123456</td> <td>123456</td> </tr> </table> <table border="1"> <tr> <th width="5%">序号</th> <th width="75%">作业安全措施</th> <th width="10%">是否涉及</th> <th width="10%">确认人</th> </tr> <tr> <td>123456</td> <td> 123456 </td> <td>123456</td> <td>123456</td> </tr> </table> <table border="1"> <tr> <th style="text-align: left">安全措施落实检查</th> <th style="text-align: left">作业申请人: <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638070264&t=2f6c64f6e171e5e06c71d20ed34bc762" width="40" height="20"/> </th> <th style="text-align: left">作业监护人: <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638070264&t=2f6c64f6e171e5e06c71d20ed34bc762" width="40" height="20"/> </th> <th style="text-align: left">属地监护人: <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638070264&t=2f6c64f6e171e5e06c71d20ed34bc762" width="40" height="20"/> </th> <th style="text-align: left">属地责任人: <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638070264&t=2f6c64f6e171e5e06c71d20ed34bc762" width="40" height="20"/> </th> <th style="text-align: left">质安环保安全员: <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Ffile02.16sucai.com%2Fd%2Ffile%2F2014%2F0829%2F372edfeb74c3119b666237bd4af92be5.jpg&refer=http%3A%2F%2Ffile02.16sucai.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1638070264&t=2f6c64f6e171e5e06c71d20ed34bc762" width="40" height="20"/> </th> </tr> <tr> <th style="text-align: left">安全交低人</th> <th colspan="2">123456</th> <th style="text-align: left">接受交底人</th> <th colspan="2" style="text-align: left">123456</th> </tr> </table> <table border="1"> <tr> <th style="text-align: left">动火分析时间</th> <th style="text-align: left">分析地点</th> <th style="text-align: left">检测方式</th> <th style="text-align: left">分析项目</th> <th style="text-align: left">合格标准(%LEL)</th> <th style="text-align: left">分析数据(%LEL)</th> <th style="text-align: left">分析人</th> <th style="text-align: left">分析结论</th> </tr> <tr> <td>2021/5/6</td> <td>123456</td> <td>123456</td> <td>123456</td> <td>123456</td> <td>123456</td> <td>123456</td> <td>123456</td> </tr> <tr> <th colspan="8">作 业 许 可 审 批</th> </tr> <tr> <td style="text-align: left">作业许可时间</td> <td colspan="7">******--******</td> </tr> <tr> <td style="text-align: left">特级/一级</td> <td style="text-align: left">质安环保负责人:</td> <td style="text-align: left">作业负责人:</td> <td style="text-align: left">属地单位负责人:</td> <td style="text-align: left">主管厂长:</td> <td colspan="3" style="text-align: left">时间-------</td> </tr> <tr> <td style="text-align: left">二级</td> <td style="text-align: left">质安环部安全员:</td> <td style="text-align: left">作业负责人:</td> <td colspan="2" style="text-align: left">属地车间负责人:</td> <td colspan="3" style="text-align: left">时间-------</td> </tr> <tr> <th colspan="8">作 业 过 程 安 全 监 督</th> </tr> <tr> <td colspan="2" style="text-align: left">属地单位安全员</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> </tr> <tr> <td colspan="2" style="text-align: left">施工管理部门安全员</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> <td colspan="2" style="text-align: left">巡查人: 时间</td> </tr> <tr> <th colspan="8">动 火 结 束 确 定</th> </tr> <tr> <td colspan="8" style="text-align: left"> 作业未完,许可证到期,同意关闭 作业已完,同意关闭 工单任务完成,质量合格,同意关闭 </td> </tr> <tr> <td colspan="8" style="text-align: left"> 现场无残留火种 未使用的灭火器已放回原位 使用过的灭火器已登记或更换 设备断电 撒火 从现场移走 现场卫生合格 </td> </tr> <tr> <td style="text-align: left">作业负责人:</td> <td style="text-align: left">作业监护人:</td> <td style="text-align: left">属地监护人:</td> <td style="text-align: left">作业批准人:</td> <td colspan="4" style="text-align: left">时间----009:</td> </tr> </table> </div> </body> </html>
2.导入pom依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.11</version> </dependency> <!-- freemarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> <!--Flying Saucer是基于iText的,支持对CSS高级特性的解析。--> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.1.5</version> </dependency> <!--file 转 multipartFile--> <!-- https://mvnrepository.com/artifact/org.springframework/spring-mock --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-mock</artifactId> <version>2.0.8</version> </dependency>
3.编写工具类
正常来说前端直接将整个HTML页面后端处理,这里就直接渲染生成了
package com.example.demo.util; 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 freemarker.template.Configuration; import freemarker.template.Template; import java.io.*; import java.nio.charset.Charset; import java.util.Map; /** * @Author Felix * @Date 2021-10-29 10:52:51 * @Description: */ public class PdfUtils { private static final String DEST = "D:\\ANTECS2\\demoExcel\\src\\main\\resources\\pdfFile\\test.pdf"; private static final String FONT = "D:\\ANTECS2\\demoExcel\\src\\main\\resources\\static\\font\\SimHei.ttf"; private static final String FILECATALOG = "D:\\ANTECS2\\demoExcel\\src\\main\\resources\\templates"; private static Configuration freemarkerCfg; static { freemarkerCfg = new Configuration(); try { freemarkerCfg.setDirectoryForTemplateLoading(new File(FILECATALOG)); } catch (IOException e) { e.printStackTrace(); } } public static void createPdf(String content) throws IOException, DocumentException { // step 1 Document document = new Document(); //返回给前端的话就使用ByteArrayOutputStream加载到域中,替换掉下面的PdfWriter.getInstance(document, stream)即可 //OutputStream stream = new ByteArrayOutputStream(); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(FILECATALOG)); // 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 static String freeMarkerRender(Map<String, Object> data, String htmlTmp) { Writer out = new StringWriter(); try { // 获取模板,并设置编码方式 Template template = freemarkerCfg.getTemplate(htmlTmp); // template.setEncoding("UTF-8"); // 合并数据模型与模板 //将合并后的数据和模板写入到流中,这里使用的字符流 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; } }
4.测试
@Test public void pdfTest() throws IOException, DocumentException { //模板路径 String fileTemp = "index.html"; //模板渲染,其实页面没有用到,假数据 Map<String, Object> data = new HashMap<>(); data.put("data",123); PdfUtils.createPdf(PdfUtils.freeMarkerRender(data, fileTemp)); }
完成