1. 程式人生 > 其它 >Java使用iText根據HTML模板生成PDF報表

Java使用iText根據HTML模板生成PDF報表

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

    }

完成