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));

    }

 

完成