1.引入maven
<!--pdf-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.2.3</version>
</dependency>
2.工具类
public class PdfUtil {
static {
// Velocity初始化
Velocity.setProperty(RuntimeConstants.OUTPUT_ENCODING, StandardCharsets.UTF_8);
Velocity.setProperty(RuntimeConstants.INPUT_ENCODING, StandardCharsets.UTF_8);
Velocity.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
Velocity.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
Velocity.init();
}
/**
* 据模板生成pfd格式文件
* @param context 上下文对象
* @param template pdf模板
* @param outputStream 生成ofd文件输出流
*/
public static void pdfFile(Context context, String template, OutputStream outputStream) {
try (PdfWriter pdfWriter = new PdfWriter(outputStream)) {
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
pdfDocument.setDefaultPageSize(PageSize.A4);
ConverterProperties properties = new ConverterProperties();
FontProvider fontProvider = new FontProvider();
// 字体设置,解决中文不显示问题
PdfFont sysFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H");
fontProvider.addFont(sysFont.getFontProgram(), "UniGB-UCS2-H");
properties.setFontProvider(fontProvider);
Template pfdTemplate = Velocity.getTemplate(template, "UTF-8");
StringWriter writer = new StringWriter();
pfdTemplate.merge(context, writer);
HtmlConverter.convertToPdf(writer.toString(), pdfDocument, properties);
pdfDocument.close();
} catch (Exception e) {
throw new RuntimeException("PFD文件生成失败", e);
}
}
}
3.工具类调用
@GetMapping("/downDetailPdf") @ApiOperation(value = "导出对账单详情pdf", notes = "导出对账单详情pdf)") public void downDetailPdf(StatementLinePageRequest request, HttpServletResponse response) { String statementCode = request.getStatementCode(); String companyId = request.getCompanyId(); if (StringUtils.isEmpty(statementCode) && StringUtils.isEmpty(statementCode)) { throw new RuntimeException(EnterpriseExcelptionEnum.PARAM_NULL.getMsg()); } try { XLBaseResponse<StatementHeaderResponse> statementResponse = statementService.getStatementResponse(statementCode, companyId); if(!statementResponse.isOk() || null == statementResponse.getBody()){ throw new RuntimeException("对账单不存在"); } XLBaseResponse<StatementDetailPageResponse> detailPage = statementService.getDetailPage(statementCode, companyId, request); if(detailPage.isOk()){ StatementDetailPageResponse body = detailPage.getBody(); VelocityContext context = new VelocityContext(); StatementHeaderResponse top = statementResponse.getBody(); context.put("top", top); context.put("lines", 集合); String fileName = new String("对账单详情-".getBytes(), "ISO-8859-1") + DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN) + ".pdf"; response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf8"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); response.setHeader("Cache-Control", "no-store"); response.addHeader("Cache-Control", "max-age=0"); PdfUtil.pdfFile(context,"templates/statementDetailsPdf.html", response.getOutputStream()); } } catch (Exception e) { log.info("导出对账单详情pdf-异常:",e); throw new RuntimeException(EnterpriseExcelptionEnum.EXECUTE_FAILED.getMsg()); } }
4.html模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="ant-spin-container"> <table> <tr> <td class="code">对账单编号:</td> <td class="code">$!{top.statementCode}</td> <td style="width: 176px;"> <div class="status">$!{top.statementStatus}</div> </td> </tr> </table> </div> #if( !$orderChange) <div class="a1"> <span class="src-display-modules-ReconciliationCollaboration-components-Modification-index__title--2ferw">本单有变更:</span> <div class="src-display-modules-ReconciliationCollaboration-components-Modification-index__modificationData--2ViAS"> <div class="src-display-modules-ReconciliationCollaboration-components-Modification-index__modificationItem--1nVb4"> #foreach($order in $orderChange) <img src="templates/img/xxx.png" class="src-display-modules-ReconciliationCollaboration-components-Modification-index__linkIcon--G_CVd"> <span>$order.statementCode</span> <span class="src-display-modules-ReconciliationCollaboration-components-Modification-index__status--3LcrS"> #if(!$line.statementStatus == 'DRAFT') 草稿 #elseif(!$line.statementStatus == 'SENT') 已发送 #elseif(!$line.statementStatus == 'RECEIVED') 已接收 #elseif(!$line.statementStatus == 'PART_ACCEPTED') 部分确认 #elseif(!$line.statementStatus == 'ACCEPTED') 全部确认 #elseif(!$line.statementStatus == 'SENT_FAIL') 发送失败 #else 拒绝 #end </span> #end </div> </div> </div> #end <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__statistic--uYrBi"> <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__title--YJ_hx">统计</div> <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__statisticData--Zxjwg"> <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__statisticLabel--278xi"> <div>总条目</div> <div>总税额</div> <div>总金额(不含税)</div> <div>价税合计</div> </div> <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__statisticValue--agxcR"> <div>$!{top.totalEntries}</div> <div>$!{top.taxAmount}</div> <div>$!{top.detailAmount}</div> <div>$!{top.totalAmount}</div> </div> </div> </div> <div class="src-display-modules-ReconciliationCollaboration-Payables-Detail-index__dataList--3C17F"> <div class="ant-spin-nested-loading"> <table class="ant-table-fixed" style="width: max-content; "> <tbody class="ant-table-tbody"> #foreach($line in $lines) <tr class="ant-table-row ant-table-row-level-0" data-row-key="886490"> <td class="" style="text-align: center;"><span class="ant-table-row-indent indent-level-0" style="padding-left: 0px;"></span> <span>$line.lineNum</span> </td> <td class="" style="text-align: center;"> <div style="color: rgb(153, 153, 153);">$line.changeFlag</div> </td> <td class="" style="text-align: center;"> <div class="ellipsisText" style="width: 136px;"> <span> #if(!$line.isConfirm == 1) 待确认 #elseif(!$line.isConfirm == 2) 已确认 #else 拒绝 #end </span> </div> </td> <td class=""> <div class="ellipsisText" style="width: 200px;"> <span>$line.goodsCode</span> </div> </td> </tr> #end </tbody> </table> </div> </div> </body> </html>
注意