freemarker ftl模板的使用:批量打印
Controller代码:
@GetMapping("/batch-print")
@Operation(summary = "付款-批量打印")
public void batchPrint(@Valid PayApplPrintReqVO reqVO, HttpServletResponse response) throws IOException {
byte[] content = paySipfApplService.batchPrint(reqVO);
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("文件名", "UTF-8"));
response.setContentType("application/octet-stream");
// response.setHeader(Header.CONTENT_DISPOSITION.getValue(), PayStrConstants.ATTACHMENT_FILENAME + URLEncoder.encode(PayStrConstants.PAY_APPL_PDF, "UTF-8"));
// response.setContentType(ContentType.OCTET_STREAM.getValue());
IoUtil.write(response.getOutputStream(), false, content);
}
service代码:
@Override
public byte[] payApplPrint(List<PayApplPrintRespVO> payApplPrintRespVOList) {
try {
if (CollectionUtils.isEmpty(payApplPrintRespVOList)) {
// 数据不能为空
throw exception(PayErrorCodeConstants.PAY_SIPF_DATA_NOT_EMPTY_ERROR);
}
// 设置数据
Map<String, Object> map = new HashMap<>();
map.put("payList", payApplPrintRespVOList);
// 读取模板
Template template = configuration.getTemplate("pay_appl.ftl");
// 生成html
String htmlContent = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
// 生成pfd
return FileHandleUtils.convertHtmlToPdf(htmlContent);
} catch (Exception e) {
log.error("payApplPrint error===========批量打印失败", e);
throw new ServiceException(500, "批量打印失败:" + e.getMessage());
}
}
工具类:
import cn.hutool.core.util.StrUtil;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.IBlockElement;
import com.itextpdf.layout.element.IElement;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.property.AreaBreakType;
import org.springframework.core.io.ClassPathResource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
/**
* html转换pdf
*/
public class FileHandleUtils {
private static final String FONT_PATH = "/font/simsun.ttc";
/**
* html转换pdf
*
* @param htmlContent htmlContent
* @return 结果
*/
public static byte[] convertHtmlToPdf(String htmlContent) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfWriter pdfWriter = new PdfWriter(outputStream);
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
// 设置为 A4 大小 (横版)
pdfDoc.setDefaultPageSize(PageSize.A4.rotate());
// 添加中文字体支持
ConverterProperties properties = new ConverterProperties();
FontProvider fontProvider = new FontProvider();
// 添加自定义字体, 例如宋体
if (StrUtil.isNotBlank(FONT_PATH)) {
ClassPathResource classPathResource = new ClassPathResource(FONT_PATH);
String fontPath = classPathResource.getPath() + ",0";
PdfFont microsoft = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, false);
fontProvider.addFont(microsoft.getFontProgram(), PdfEncodings.IDENTITY_H);
properties.setFontProvider(fontProvider);
}
Document document = new Document(pdfDoc);
List<IElement> elements = HtmlConverter.convertToElements(htmlContent, properties);
int size = elements.size();
for (int i = 0; i < size; i++) {
IElement iElement = elements.get(i);
document.add((IBlockElement) iElement);
if (!(i == size - 1)) { // 不是最后一页
// 添加新的一页
document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
}
}
document.close();
pdfDoc.close();
pdfWriter.close();
return outputStream.toByteArray();
}
}
模板pay_appl.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PDF Example</title>
<style>
body {
font-family: "宋体";
font-size: 20px;
}
.tab_center_top {
width: 100%;
}
.tab_center td {
text-align: center;
height: 30px;
}
.div_height {
/*height: 800px;*/
margin-left: 100px;
margin-right: 100px;
}
.row_div {
height: 30px;
}
.large-text {
font-size: 50px;
}
</style>
</head>
<body>
<#list payList as list>
<!--付款申请单-->
<div class="div_height">
<table class="tab_center_top">
<tr >
<th class="large-text" colspan="3">付款申请单</th>
</tr>
<tr>
<td>单位名称:<#if list.legalOrg??>${list.legalOrg}</#if></td>
<td></td>
<td>打印日期:<#if list.date??>${list.date}</#if></td>
</tr>
</table>
<table class="tab_center" border="1" cellspacing="0" width="100%" align="center">
<tr>
<th bgcolor="#dcdcdc" colspan="4">付款申请信息</th>
</tr>
<tr>
<td>申请人</td>
<td>申请部门</td>
<td>申请货币</td>
<td>计划付款日期</td>
</tr>
<tr>
<td><#if list.applicant??>${list.applicant}</#if></td>
<td><#if list.applDeptName??>${list.applDeptName}</#if></td>
<td><#if list.currency??>${list.currency}</#if></td>
<td><#if list.planPayDate??>${list.planPayDate}</#if></td>
</tr>
<tr>
<td>付款申请编号</td>
<td>付款业务名称</td>
<td>申请金额</td>
<td>实付金额</td>
</tr>
<tr>
<td><#if list.payApplNo??>${list.payApplNo}</#if></td>
<td><#if list.feeItem??>${list.feeItem}</#if></td>
<td><#if list.totalAmount??>${list.totalAmount}</#if></td>
<td></td>
</tr>
<tr>
<td> 收款账户名称</td>
<td colspan="3"><#if list.collAccName??>${list.collAccName}</#if></td>
</tr>
<tr>
<td>收款开户行</td>
<td colspan="3"><#if list.collAccOpnBranch??>${list.collAccOpnBranch}</#if></td>
</tr>
<tr>
<td>收款账号</td>
<td colspan="3"><#if list.collAccNo??>${list.collAccNo}</#if></td>
</tr>
<tr>
<td>支付摘要</td>
<td colspan="3"><#if list.paySummary??>${list.paySummary}</#if></td>
</tr>
<tr>
<td>备注</td>
<td colspan="3"><#if list.payApplRemark??>${list.payApplRemark}</#if></td>
</tr>
</table>
<div class="row_div"></div>
<table class="tab_center" border="1" cellspacing="0" width="100%">
<tr bgcolor="#dcdcdc">
<th>任务节点名称</th>
<th>节点完成时间</th>
<th>节点操作人</th>
<th>节点操作</th>
<th>节点流转说明</th>
</tr>
<#if list.historyList??>
<#list list.historyList as history>
<tr>
<td><#if history.taskName??>${history.taskName}</#if></td>
<td><#if history.endTimeStr??>${history.endTimeStr}</#if></td>
<td><#if history.userName??>${history.userName}</#if></td>
<td><#if history.checkType??>${history.checkType}</#if></td>
<td><#if history.message??>${history.message}</#if></td>
</tr>
</#list>
</#if>
</table>
</div>
</#list>
</body>
</html>
字体: