背景:最近项目里有个需求,需要动态配置一个模板,来打印各种不同银行或者其他行业的小票,下面小小记录一下实现过程。
关键词:Springboot, thymeleaf, Freemarker,html2image
一,引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<dependency>
<groupId>com.github.xuwei-k</groupId>
<artifactId>html2image</artifactId>
<version>0.1.0</version>
</dependency>
<!-- freemarker模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
二,准备数据
1,动态配置的字段
2,包含所有配置信息的字段Dto
@Data
public class TemplateFieldDto {
/**
* 模板id
*/
private long templateId;
/**
* 字段id
*/
private long fieldId;
/**
* bankId
*/
private long bankId;
/**
* 商户ID
*/
private long merchantId;
/**
* 发票联类型, MERCHANT,CARDHOLDER,SETTLEMENT
*/
private String ftlType;
/**
* 字段编码
*/
private String fieldCode;
/**
* 字段名,多语言
*/
private String fieldName;
/**
* 字段值
*/
private String fieldValue;
/**
* 语言
*/
private String languageType;
/**
* 顺序
*/
private Integer fieldOrder;
/**
* 字体颜色,#333333
*/
private String fontColor;
/**
* 标题字体大小,单位px
*/
private String titleFontSize;
/**
* 字体大小,单位px
*/
private String fontSize;
/**
* 是否粗体,bold
*/
private String fontStyle;
/**
* 是否展示字段名标题
*/
private boolean showTitle;
/**
* 是否换行, 0 否,1 是
*/
private boolean newLine;
/**
* 是否合并到title
*/
private boolean mergeToTitle;
/**
* 对齐方式,left,right,center
*/
private String position;
}
3,组装成需要的数据结构
三,配置动态模板
这里是关键,需要遍历数据,并判断数据中属性
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8"/>
<style>
table {
font-family: "Times New Roman", serif;
}
</style>
<title>FreeMarker</title>
</head>
<body>
<table border="0" width="300">
<#if data??>
<#list data as item>
<#if item.showTitle>
<#if item.newLine>
<tr>
<td colspan="3" style="text-align: left; font-size: ${item.titleFontSize};">${item.fieldName}:</td>
</tr>
<tr>
<td colspan="3" style="text-align: ${item.position}; font-weight: ${item.fontStyle}; font-size:${item.fontSize};">${item.fieldValue}</td>
</tr>
<#else>
<#if item.mergeToTitle>
<tr>
<td colspan="3" style="text-align: ${item.position}; font-weight: ${item.fontStyle};font-size: ${item.fontSize};">${item.fieldName}: ${item.fieldValue}</td>
</tr>
<#else>
<tr>
<td style="text-align: left; font-weight: ${item.fontStyle};font-size: ${item.titleFontSize};">${item.fieldName}:</td>
<td colspan="2" style="text-align: ${item.position}; font-weight: ${item.fontStyle}; font-size: ${item.fontSize};">${item.fieldValue}</td>
</tr>
</#if>
</#if>
<#else>
<#if item.fieldCode=='amountTitleLine'>
<tr>
<td style="text-align: left; font-size: 12px; width: 20%">TYPE</td>
<td style="text-align: center; font-size: 12px; width: 60%">SUM</td>
<td style="text-align: right; font-size: 12px; width: 20%">AMOUNT</td>
</tr>
<#elseif item.fieldCode=='creditCard'>
<tr>
<td colspan="3" style="text-align: left; font-size: ${item.fontSize}; width: 20%">${item.fieldName}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">SALE</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${creditCard.creditSaleCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${creditCard.creditSaleAmount}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">VOID</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${creditCard.creditVoidCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${creditCard.creditVoidAmount}</td>
</tr>
<#elseif item.fieldCode=='debitCard'>
<tr>
<td colspan="3" style="text-align: left; font-size: ${item.fontSize}; width: 20%">${item.fieldName}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">SALE</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${debitCard.debitSaleCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${debitCard.debitSaleAmount}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">REFUND</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${debitCard.debitRefundCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${debitCard.debitRefundAmount}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">CASHBACK</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${debitCard.debitCashbackCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${debitCard.debitCashbackAmount}</td>
</tr>
<#elseif item.fieldCode=='allCards'>
<tr>
<td colspan="3" style="text-align: left; font-size: ${item.fontSize}; width: 20%">${item.fieldName}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">SALE</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${allCards.totalSaleCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${allCards.totalSaleAmount}</td>
</tr>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">REFUND</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${allCards.totalRefundCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${allCards.totalRefundAmount}</td>
</tr>
<#elseif item.fieldCode=='totalAmoutEnd'>
<tr>
<td style="text-align: left; font-size: ${item.fontSize}; width: 20%">${item.fieldName}</td>
<td style="text-align: center; font-size: ${item.fontSize}; width: 60%">${totalAmoutEnd.totalCount}</td>
<td style="text-align: right; font-size: ${item.fontSize}; width: 20%">${totalAmoutEnd.totalAmount}</td>
</tr>
<#else>
<#if item.fieldCode=='bankLogo'>
<tr>
<td colspan="3" style="text-align: ${item.position};">
<img src="${item.fieldValue}" width="250" height="100" alt="BankLogo"/>
</td>
</tr>
<#elseif item.fieldCode='emptyLine'>
<tr>
<td colspan="3" style="height:15px;">
</td>
</tr>
<#elseif item.fieldCode='grayLine'>
<tr>
<td colspan="3">
<hr style="border: none; border-bottom:1px solid black"/>
</td>
</tr>
<#else>
<tr>
<td colspan="3" style="text-align: ${item.position}; font-weight: ${item.fontStyle}; font-size: ${item.fontSize};">${item.fieldValue}</td>
</tr>
</#if>
</#if>
</#if>
</#list>
<#else>
</#if>
</table>
</body>
</html>
四,结果展示
码字不易,记得点赞关注哟