首先 安装 wkhtmltopdf 插件 安装
链接: https://pan.baidu.com/s/1hd49JWEDcFBD4XjvosPwYg
提取码: cuxb
package com.yj.test;
import com.alibaba.fastjson.JSON;
import com.yj.XfContractServerApplication;
import com.yj.common.service.UploadService;
import com.yj.common.utils.BaseTestRunner;
import com.yj.service.settlement.ISettlementService;
import com.yj.vo.settlement.response.SettlementDetailByShopResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
/**
* @author lichaojie
* @version V1.0
* @date Date : 2022年10月11日 16:19
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = XfContractServerApplication.class)
@Slf4j
public class LcjDemo extends BaseTestRunner {
@Resource
private UploadService uploadService;
@Resource
private ISettlementService settlementService;
//wkhtmltopdf在系统中的路径
private static final String toPdfTool = "D:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";
@Test
public void test() {
String context = "<!DOCTYPE html>" +
"<html>" +
" <head>" +
" <meta charset=\"utf-8\" />" +
" <title>对账单</title>" +
"" +
" <style>" +
" page {" +
" display: block;" +
" }" +
"" +
" h1 {" +
" color: #000;" +
" font-size: 16px;" +
" margin-bottom: 10px;" +
" }" +
"" +
" .baseInfo {" +
" margin: 20px 0 20px 0;" +
" }" +
"" +
" .baseInfo span {" +
" margin: 10px 0 10px 20px;" +
" }" +
"" +
" .total {" +
" margin: 10px 0 10px 20px;" +
" }" +
"" +
" table {" +
" margin: 15px;" +
" }" +
"" +
" table thead th {" +
" padding: 10px;" +
" }" +
"" +
" table tbody td {" +
" padding: 10px;" +
" text-align: center;" +
" }" +
" </style>" +
"" +
" " +
" </head>" +
"" +
" <body>" +
" <page>" +
" <h1>基础信息</h1>" +
" <div class=\"baseInfo\">" +
" <span>结佣单号: settlementNo</span>" +
" <span>入账时间: reconciliationTime</span>" +
" </div>" +
" <div class=\"baseInfo\">" +
" <span>对账人信息: settlementName / settlementPhone</span>" +
" <span>楼盘名称/地址: houseName / houseAddress </span>" +
" </div>" +
" " +
" <h1>订单明细</h1>" +
" <div class=\"total\">本次总计可结: ¥totalCommission</div>" +
" " +
" <table border=\"1\" bordercolor=\"#aaa\" style=\"border-collapse: collapse\">" +
" <thead>" +
" <tr>" +
" <th>报备单号</th>" +
" <th>代理商渠道</th>" +
" <th>客户信息</th>" +
" <th>房间</th>" +
" <th>成交GMV</th>" +
" <th>本次成交佣金</th>" +
" <th>公司收入</th>" +
" <th>成交奖</th>" +
" <th>成销时间</th>" +
" </tr>" +
" </thead>" +
" <tbody>" +
" <tr>" +
" <td>reportNo</td>" +
" <td>cooperativeCompanyName</td>" +
" <td>" +
" <div>customerName</div>" +
" <div>customerPhone</div>" +
" </td>" +
" <td>" +
" <div>room</div>" +
" <div>buildingAream²</div>" +
" </td>" +
" <td>¥gmv</td>" +
" <td>¥commission</td>" +
" <td>¥companyCommission</td>" +
" <td>¥currentDealPrize</td>" +
" <td>sellTime</td>" +
" </tr>" +
" </tbody>" +
" </table>" +
" </page>" +
" </body>" +
" <script type='text/javascript'>" +
" watermark('京日新房');" +
" function watermark(str) {" +
" var can = document.createElement('canvas');" +
" var body = document.body.getElementsByTagName('page');" +
" for (var i = 0; i < body.length; i++) {" +
" body[i].appendChild(can);" +
" };" +
" can.width=150;" +
" can.height=150;" +
" can.style.display='none';" +
" var cans = can.getContext('2d');" +
" cans.rotate(-25*Math.PI/260);" +
" cans.font = '16px Microsoft JhengHei';" +
" cans.fillStyle = 'rgba(0,0,0,.3)';" +
" cans.textAlign = 'left';" +
" cans.textBaseline = 'Middle';" +
" cans.fillText(str, 40, 120);" +
" for (var i = 0; i < body.length; i++) {" +
" body[i].style.backgroundImage='url('+can.toDataURL('image/png')+')';" +
" };" +
" }" +
" </script>" +
"</html>";
SettlementDetailByShopResponse shopDetail = settlementService.getShopDetail("00a08a5e-f08c-402c-b932-d0504a80d788", "BB2112000430");
System.out.println(JSON.toJSONString(shopDetail));
context = context.replace("settlementNo", shopDetail.getSettlementNo());
context = context.replace("reconciliationTime", shopDetail.getReconciliationTime() == null ? "--" :
DateFormatUtils.format(shopDetail.getReconciliationTime(), "yyyy-MM-dd HH:mm:ss"));
context = context.replace("settlementName", shopDetail.getSettlementName());
context = context.replace("settlementPhone", shopDetail.getSettlementPhone());
context = context.replace("houseName", shopDetail.getHouseName());
context = context.replace("houseAddress", shopDetail.getHouseAddress());
context = context.replace("totalCommission", shopDetail.getTotalCommission().toString());
context = context.replace("reportNo", shopDetail.getReportNo());
context = context.replace("cooperativeCompanyName", shopDetail.getCooperativeCompanyName());
context = context.replace("customerName", shopDetail.getCustomName());
context = context.replace("customerPhone", shopDetail.getCustomPhone());
//房间 门牌号
context = context.replace("room", shopDetail.getRoomInfo());
context = context.replace("buildingArea", shopDetail.getRoomArea().toString());
context = context.replace("gmv", shopDetail.getGmv().toString());
context = context.replace("commission", shopDetail.getCommission().toString());
context = context.replace("companyCommission", shopDetail.getCompanyCommission().toString());
context = context.replace("currentDealPrize", shopDetail.getCurrentDealPrize().toString());
context = context.replace("sellTime", DateFormatUtils.format(shopDetail.getSellCheckTime(), "yyyy-MM-dd HH:mm:ss"));
String s = htmlBytes2PdfFile(context, "新建文本文档");
System.out.println(s);
}
public String htmlBytes2PdfFile(String context, String orderNo) {
try {
String htmlfileid = "bc106088-1d81-492a-9736-ce5bcffd56cc";
File htmlfile = new File("D:\\" + htmlfileid + ".html");
htmlfile.createNewFile();
// 获取该文件的缓冲输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(htmlfile.toPath()), StandardCharsets.UTF_8));
// 写入信息
bufferedWriter.write(context);
bufferedWriter.flush();// 清空缓冲区
bufferedWriter.close();// 关闭输出流
StringBuilder cmd = new StringBuilder();
//cmd.append("wkhtmltopdf"); mac
//cmd.append("cmd.exe /C wkhtmltopdf"); //windows
cmd.append(toPdfTool);
cmd.append(" ");
//设置为“风景(Landscape)”或“肖像(Portrait)”模式,默认是肖像模块(Portrait)
cmd.append("--orientation Landscape");
cmd.append(" ");
//页眉下面的线
cmd.append("--footer-center [page]");
cmd.append(" ");
cmd.append("D:\\").append(htmlfileid).append(".html");
cmd.append(" ");
cmd.append("D:\\").append(orderNo).append(".pdf");
try {
Process proc = Runtime.getRuntime().exec(cmd.toString());
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
log.error("wkhtmltopdf error:" + e.getMessage(), e);
}
File file = new File("D:\\" + orderNo + ".pdf");
if (!file.exists()) {
log.error("文件不存在,请重试");
}
//这里可以上传到阿里云 然后保留文件地址就行
FileInputStream inputStream = new FileInputStream(file);
String url = uploadService.upload(inputStream, orderNo + ".pdf", UploadService.EXPORT_PDF);
//本地调试 注释这行代码 正式使用时 还是要打开
//file.delete();
//htmlfile.delete();
return null;
} catch (Exception e) {
log.error("html生成pdf失败,异常", e);
}
return null;
}
}
然后结果是这样的。