springboot+Thymeleaf生成PDF

springboot項目創建以後,pom添加

<!--pdf模板生成-->
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf</artifactId>
            <version>9.0.7</version>
        </dependency>

pdf工具類

package com.ydrx.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;

public class PDFGenerator {
	private Logger logger = LoggerFactory.getLogger(PDFGenerator.class);
	private AbstractConfigurableTemplateResolver templateResolver;
	private TemplateEngine templateEngine;

	public PDFGenerator(final String templatePrefix, final String templateSuffix) {

		this(templatePrefix, templateSuffix, "HTML5", "UTF-8");
	}

	public PDFGenerator(final String templatePrefix, final String templateSuffix, final String templateMode,
			final String templateEncoding) {

		this(new ClassLoaderTemplateResolver());

		this.templateResolver.setPrefix(templatePrefix);
		this.templateResolver.setSuffix(templateSuffix);
		this.templateResolver.setTemplateMode(templateMode);
		this.templateResolver.setCharacterEncoding(templateEncoding);
	}

	public PDFGenerator(AbstractConfigurableTemplateResolver templateResolver) {
		this.templateResolver = templateResolver;
	}

	public PDFGenerator(TemplateEngine templateEngine) {
		this.templateEngine = templateEngine;
	}

	private TemplateEngine getTemplateEngine() {
		if (templateEngine == null) {
			templateEngine = new TemplateEngine();
			templateEngine.setTemplateResolver(templateResolver);
		}

		return templateEngine;
	}

	/**
	 * 根據模板生成一個PDF
	 *
	 * @param ouputPDF
	 *            Target pdf file.
	 * @param template
	 *            Source template.
	 * @param model
	 *            The data for the template.
	 * @throws FileNotFoundException
	 * @throws DocumentException
	 */
	public void generate(File ouputPDF, String template, Map<String, Object> model)
			throws FileNotFoundException, DocumentException {
		final Context ctx = new Context();
		ctx.setVariables(model);

		final TemplateEngine templateEngine = getTemplateEngine();
		String htmlContent = templateEngine.process(template, ctx);

		ITextRenderer renderer = new ITextRenderer();
		ITextFontResolver fontResolver = renderer.getFontResolver();
		try {
			//避免中文爲空設置系統字體
			fontResolver.addFont("C:/Windows/Fonts/SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
			fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

		// 解決圖片的相對路徑問題
		// renderer.getSharedContext().setBaseURL("file:/C:/Users/Administrator.WIN7-1610080938/Desktop/word2pdf/");

		renderer.setDocumentFromString(htmlContent);
		renderer.layout();
		renderer.createPDF(new FileOutputStream(ouputPDF));
	}

}

如果你發現漢字打印沒有添加可能是因爲沒有引用字體。記得更改Linux和windows不同的位置

html頁面好多隻能使用table排版

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
    <!--<link rel="stylesheet" href="../css/bootstrap.min.css"/>-->
    <title>回執單</title>
    <style type="text/css">
        *{
            font-family: SimHei
        }
        .container {
            width: 210mm;
            margin-right: auto;
            margin-left: auto;
        }
        .row{
            margin: 0 auto;
            font-size: 14px;
        }
        @page {
            size: 210mm 297mm;
            margin: 0;
        }
        /*憑證回執*/
        .voucher{
            display: flex;
            padding-bottom: 30px;
            display: -ms-flexbox;
        }
        .voucher-table{
            border:1px dotted #999;
            margin-right: 20mm;
        }
        .voucher-table thead{
            font-size: 24px;
            text-align: center !important;
        }
        .voucher-table tr td{
            border: 1px dotted #999;
            border-top: 0;
            border-left: 0;
            line-height: 25px;
            padding-left: 5px;
            width: 15%;
        }
        .voucher-table .td{
            text-align: center;
        }
        .voucher-table .card{
            width: 80px;
        }
        .voucher-table .tdSign{
            height: 100px;
        }
        .tb-padding{
            padding: 10px;
        }

    </style>
</head>
<body style="font-family: SimHei">
<div class="session" id="session">
    <div class="container" style="text-align: center">
        <h4 style="font-weight: 600;font-size: 20px">回執單</h4>
        <div class="row voucher" id="table">
            <!--<div id="left">-->
            <!--銀行打印記錄-->
            <!--</div>-->
            <table class="voucher-table"  cellspacing="0" cellpadding="0">
                <tr>
                    <td style="padding-right: 5px;font-size: 16px" rowspan="18">銀<br/>行<br/>打<br/>印<br/>記<br/>錄</td>
                </tr>
                <tr>
                    <td class="td">交易流水號:</td><td colspan="5" align="left" th:text="${sequence}">151003</td>
                </tr>
                <tr>
                    <td class="td">終端設備號:</td><td th:text="${clientNo}">1222132</td>
                    <td class="td">交易機構號:</td><td th:text="${bankNo}">24</td>
                    <td class="td">開戶機構號:</td><td th:text="${bankNo}">24</td>
                </tr>
                <tr>
                    <td class="td">交易日期:</td><td th:text="${#dates.format(new java.util.Date(), 'yyyy-MM-dd')}"></td>
                    <td class="td">授權員編號:</td><td th:text="${userFingerInfo.userCode}"></td>
                    <td class="td">授權員姓名:</td><td th:text="${userFingerInfo.userName}"></td>
                </tr>
                <tr>
                    <td class="td">姓名:</td><td th:text="${personInfo.name}"></td>
                    <td class="td">性別:</td><td th:text="${personInfo.sex}"></td>
                    <td class="td">民族:</td><td th:text="${personInfo.nation}"></td>
                </tr>
                <tr>
                    <td class="td">證件類型:</td><td th:text="身份證"></td>
                    <td class="td">證件號碼:</td><td th:text="${personInfo.cardNo}"></td>
                    <td class="td">出生日期:</td><td th:text="${personInfo.born}"></td>
                </tr>
                <tr>
                    <td class="td">住址:</td><td colspan="5" align="left" th:text="${personInfo.cardAddress}"></td>
                </tr>
                <tr>
                    <td class="td">簽發機關:</td><td colspan="3" th:text="${personInfo.grantDept}"></td>
                    <td class="td">電話號碼:</td><td th:text="${personInfo.sex}"></td>
                </tr>
                <tr>
                    <td class="td">有效期限:</td><td th:text="${personInfo.userLifeEnd}"></td>
                    <td class="td">職業:</td><td th:text="${job}"></td>
                    <td class="td">月收入:</td><td th:text="${monthIncome}"></td>
                </tr>
                <tr>
                    <td class="td">聯繫住址:</td><td colspan="5" align="left" th:text="${personInfo.cardAddress}"></td>
                </tr>
                <tr>
                    <td class="td">聯網覈查結果 :</td><td colspan="5" align="left">號碼與姓名一致且照片存在</td>
                </tr>
                <tr>
                    <td class="td">業務類型 :</td><td colspan="5" th:text="開卡"></td>
                </tr>
                <tr>
                    <td class="td">賬戶類型:</td><td></td>
                    <td class="td">卡號:</td><td colspan="3"></td>
                </tr>
                <tr>
                    <td class="td">身份證頭像:</td><td class="card" colspan="2"><img style="height: 150px" class="" th:src="${head}" alt="" id="front"/></td>
                    <td class="td" rowspan="2">現場採集照片</td><td rowspan="2" colspan="2"><img th:src="${pic}" alt="" id="photo" style="width: 300px"/></td>
                </tr>
                <tr>
                    <td class="td">聯網覈查頭像:</td><td class="card" colspan="2"><img class="img" style="height: 150px" th:src="${head}" alt="" id="back" /></td>
                </tr>
                <tr>
                    <td colspan="6" align="center" style="font-weight: 600">客戶確認</td>
                </tr>
                <tr>
                    <td colspan="2" rowspan="2" class="tb-padding">本人確認以上打印資料準確無誤,並與本人提出的申請一致。</td>
                    <td class="td tdSign">客戶簽字</td><td colspan="3"><img width="300" th:src="${sign}" alt=""/></td>
                </tr>
                <tr>
                    <td colspan="4" th:text="${#dates.format(new java.util.Date(), 'yyyy-MM-dd HH:mm:ss')}">&nbsp;&nbsp;2018年6月15日</td>
                </tr>
            </table>
        </div>
    </div>
</div>
</body>
</html>

如果要打印的最好把@page樣式加上

使用

PDFGenerator pdfGenerator = new PDFGenerator("templates/",".html");
Map<String,Object> model = new HashMap<>();
        filePath = Base64Utils.getUrl(filepath,personInfo.getCardNo());
        model.put("front",Base64Utils.ImageToBase64ByLocal(filePath+"front.jpg"));
        model.put("back",Base64Utils.ImageToBase64ByLocal(filePath+"back.jpg"));
        File file = new File(filePath+personInfo.getCardNo()+"_id.pdf");

        try {
//file是要生成的文件名
//中間爲modlViewName
//model傳到頁面的參數
            pdfGenerator.generate(file,"card/voucher3",model);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章