打印修改预览

This commit is contained in:
funny 2026-04-14 16:31:31 +08:00
parent ceb6c19a2e
commit c643d26632
4 changed files with 144 additions and 173 deletions

View File

@ -831,38 +831,36 @@ public class MaterialCodeController extends BaseController {
*/ */
@PostMapping("exportToPdf") @PostMapping("exportToPdf")
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception { public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
// 根据物料主数据ID查询物料编号 // 根据清单ID查询二维码数据
List<WmsShipmentMaterial> materials = materialService.listByIds(ids); List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByCodeIds(ids);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(materials)).throwMessage("物料数据不存在"); VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("物料数据不存在");
Set<String> materialNos = materials.stream() // 取第一条数据
.map(WmsShipmentMaterial::getNo) ShipmentMaterialCodeQRVO data = datas.get(0);
.collect(Collectors.toSet());
// 根据物料编号查询物料图片 // 根据物料编号查询物料图片
Map<String, String> images = materials.stream() Map<String, String> images = materialService.lambdaQuery()
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
.list()
.stream()
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)); .collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
// 根据物料编号查询清单明细二维码数据
List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByMaterialNos(materialNos);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据");
// 构建打印数据 // 构建打印数据
Map<String, Object> variables = new HashMap<>(); Map<String, Object> variables = new HashMap<>();
variables.put("list", datas.stream()
.map(data -> new MaterialCodePrintDTO() Map<String, Object> info = new HashMap<>();
.setNo(data.getNo()) info.put("no", data.getNo());
.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200)) info.put("materialNo", data.getMaterialNo());
.setMaterialNo(data.getMaterialNo()) info.put("numText", data.getNumText());
.setMaterialDescribe(data.getMaterialDescribe()) info.put("customerName", data.getCustomerName());
.setNum(data.getNum())
.setNumText(data.getNumText()) Map<String, String> ext = new HashMap<>();
.setUnit(data.getUnit()) ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200));
.setDeviceNo(data.getDeviceNo()) ext.put("lst", images.get(data.getMaterialNo()));
.setCustomerName(data.getCustomerName())
.setLst(images.get(data.getMaterialNo())) variables.put("info", info);
).toList() variables.put("ext", ext);
);
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables); String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
URL baseUrl = new ClassPathResource("template/label/").getURL(); URL baseUrl = new ClassPathResource("template/label/").getURL();
@ -878,79 +876,35 @@ public class MaterialCodeController extends BaseController {
@PostMapping("exportItemToPdf") @PostMapping("exportItemToPdf")
public void exportItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception { public void exportItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
// 根据明细ID查询数据 // 根据明细ID查询数据
List<MaterialItemPrintVO> datas = materialCodeItemService.getListByItemIds(ids); List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByItemIds(ids);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据"); VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据");
// 获取物料图片 // 取第一条数据
ShipmentMaterialCodeQRVO data = datas.get(0);
// 根据物料编号查询物料图片
Map<String, String> images = materialService.lambdaQuery() Map<String, String> images = materialService.lambdaQuery()
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage) .select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
.in(WmsShipmentMaterial::getNo, datas.stream().map(MaterialItemPrintVO::getMaterialNo).collect(Collectors.toSet())) .in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
.list() .list()
.stream() .stream()
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)); .collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
// 构建打印数据 // 构建打印数据
Map<String, Object> variables = new HashMap<>(); Map<String, Object> variables = new HashMap<>();
variables.put("list", datas.stream()
.map(data -> new MaterialCodePrintDTO()
.setNo(data.getMaterialNo() + "-" + data.getId())
.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getMaterialNo() + "-" + data.getId(), 200, 200))
.setMaterialNo(data.getMaterialNo())
.setMaterialDescribe(data.getMaterialDescribe())
.setNum(data.getNum())
.setNumText(data.getNumText())
.setUnit(data.getUnit())
.setDeviceNo(data.getDeviceNo())
.setCustomerName(data.getCustomerName())
.setLst(images.get(data.getMaterialNo()))
).toList()
);
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables); Map<String, Object> info = new HashMap<>();
URL baseUrl = new ClassPathResource("template/label/").getURL(); info.put("no", data.getNo());
PdfGeneratorUtil.generatePdf("物料明细标签", html, baseUrl.toString(), response); info.put("materialNo", data.getMaterialNo());
} info.put("numText", data.getNumText());
info.put("customerName", data.getCustomerName());
/**
* 根据物料主数据ID导出物料明细PDF打印预览
*
* @param response HTTP响应
* @param ids 物料主数据id列表wms_shipment_material.id
*/
@PostMapping("exportMaterialItemToPdf")
public void exportMaterialItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
// 根据物料主数据ID查询物料编号
List<WmsShipmentMaterial> materials = materialService.listByIds(ids);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(materials)).throwMessage("物料数据不存在");
Set<String> materialNos = materials.stream() Map<String, String> ext = new HashMap<>();
.map(WmsShipmentMaterial::getNo) ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200));
.collect(Collectors.toSet()); ext.put("lst", images.get(data.getMaterialNo()));
// 根据物料编号查询物料图片 variables.put("info", info);
Map<String, String> images = materials.stream() variables.put("ext", ext);
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
// 根据物料编号查询明细数据
List<MaterialItemPrintVO> datas = materialCodeItemService.getListByMaterialNos(materialNos);
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据");
// 构建打印数据
Map<String, Object> variables = new HashMap<>();
variables.put("list", datas.stream()
.map(data -> new MaterialCodePrintDTO()
.setNo(data.getMaterialNo() + "-" + data.getId())
.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getMaterialNo() + "-" + data.getId(), 200, 200))
.setMaterialNo(data.getMaterialNo())
.setMaterialDescribe(data.getMaterialDescribe())
.setNum(data.getNum())
.setNumText(data.getNumText())
.setUnit(data.getUnit())
.setDeviceNo(data.getDeviceNo())
.setCustomerName(data.getCustomerName())
.setLst(images.get(data.getMaterialNo()))
).toList()
);
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables); String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
URL baseUrl = new ClassPathResource("template/label/").getURL(); URL baseUrl = new ClassPathResource("template/label/").getURL();

View File

@ -421,15 +421,14 @@ public class PackagingCodeController extends BaseController {
Map<String, Object> variables = new HashMap<>(); Map<String, Object> variables = new HashMap<>();
variables.put("list", list.stream() variables.put("list", list.stream()
.map(data -> { .map(data -> {
String typeName = types.stream()
.filter(type -> type.getId().equals(data.getType()))
.map(DictionaryItem::getName)
.findFirst()
.orElse("");
ShipmentPackagingCodeVO vo = new ShipmentPackagingCodeVO(); ShipmentPackagingCodeVO vo = new ShipmentPackagingCodeVO();
vo.setNo(data.getNo()); vo.setNo(data.getNo());
vo.setName(data.getName()); vo.setName(data.getName());
vo.setTypeName(typeName); vo.setTypeName(types.stream()
.filter(type -> type.getId().equals(data.getType()))
.map(DictionaryItem::getName)
.findFirst()
.orElse(""));
vo.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 100, 100)); vo.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 100, 100));
return vo; return vo;
}).toList() }).toList()

View File

@ -2,26 +2,23 @@
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head> <head>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<title>物料码标签</title> <title>包装码</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<style> <style>
@page {
size: 1200px 800px;
margin: 0;
}
body { body {
font-size: 10pt; width: 1200px;
height: 800px;
font-size: 20pt;
font-family: SimSun, Arial, sans-serif; font-family: SimSun, Arial, sans-serif;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.label-page {
width: 1200px;
height: 800px;
page-break-after: always;
}
.label-page:last-child {
page-break-after: auto;
}
table { table {
width: 1200px; width: 1200px;
height: 800px; height: 800px;
@ -29,7 +26,7 @@
border-collapse: collapse; border-collapse: collapse;
table-layout: fixed; table-layout: fixed;
} }
th, td { th, td {
border: 3px solid #000; border: 3px solid #000;
padding: 10px; padding: 10px;
@ -38,59 +35,56 @@
word-wrap: break-word; word-wrap: break-word;
overflow-wrap: break-word; overflow-wrap: break-word;
} }
.qrcode { .qrcode {
width: 380px; width: 380px;
height: 380px; height: 380px;
} }
.lst{
.lst {
width: 800px; width: 800px;
height: auto; height: auto;
} }
</style> </style>
</head> </head>
<body> <body>
<div class="label-page" th:each="item, iterStat : ${list}" th:style="${iterStat.index == 0} ? 'page-break-before: auto;' : 'page-break-before: always;'"> <table>
<table> <tr>
<tr> <td style="text-align: center; width: 400px" rowspan="3">
<td style="text-align: center; width: 400px" rowspan="3"> <img alt="" class="qrcode" th:src="${ext.qrCode}"/>
<img alt="" class="qrcode" th:src="${item.qrCode}"/> <div style="font-size: 16pt" th:text="${info.no}">0PC7B724KV6FM</div>
<div style="font-size: 16pt" th:text="${item.no}">0PC7B724KV6FM</div> </td>
</td> <td style="width: 140px;">
<td style="width: 140px;"> 机台编号
机台编号 </td>
</td> <td style="width: 200px;" th:text="${info.no}">
<td style="width: 200px;" th:text="${item.no}"> 26LBZ4000L001
26LBZ4000L001 </td>
</td> <td style="width: 140px;">
<td style="width: 140px;"> 客户名称
客户名称 </td>
</td> <td style="text-align: left" th:text="${info.customerName}">
<td style="text-align: left" th:text="${item.customerName}"> 北京市京联鑫路用材料有限公司
北京市京联鑫路用材料有限公司 </td>
</td> </tr>
</tr> <tr>
<tr> <td>
<td> 物料编码
物料编码 </td>
</td> <td th:text="${info.materialNo}">
<td th:text="${item.materialNo}"> 3100006701
3100006701 </td>
</td> <td>
<td> 数量
数量 </td>
</td> <td th:text="${info.numText}">
<td th:text="${item.numText}"> 10
10 </td>
</td> </tr>
</tr> <tr>
<tr> <td colspan="4">
<td colspan="4"> <img style="width: 750px;" alt="" src="https://img-s.msn.cn/tenant/amp/entityid/AA1VWN3Q.img?w=768&h=333&m=6" class="lst" th:src="${ext.lst}"/>
<img style="width: 750px;" alt="" class="lst" th:src="${item.lst}"/> </td>
</td> </tr>
</tr> </table>
</table>
</div>
</body> </body>
</html> </html>

View File

@ -2,37 +2,57 @@
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head> <head>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<title>包装码标签</title> <title>包装码标签-A4打印版</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<style> <style>
@page {
size: A4 portrait;
margin: 0;
}
body { body {
font-size: 10pt; font-size: 10pt;
font-family: SimSun, Arial, sans-serif; font-family: SimSun, Arial, sans-serif;
margin: 0; margin: 0;
padding: 0; padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
} }
.label-page { .label-page {
width: 600px; width: 210mm;
height: 400px; height: 297mm;
display: flex;
align-items: center;
justify-content: center;
page-break-after: always; page-break-after: always;
position: relative;
} }
.label-page:last-child { .label-page:last-child {
page-break-after: auto; page-break-after: auto;
} }
.label-content {
width: 600px;
height: 400px;
transform-origin: center center;
transform: scale(calc(210mm / 600px));
}
table { table {
width: 600px; width: 600px;
height: 400px; height: 400px;
border: 3px solid #000; border: 3px solid #000;
border-collapse: collapse; border-collapse: collapse;
} }
th, td { th, td {
border: 3px solid #000; border: 3px solid #000;
} }
.div-with-border { .div-with-border {
border-bottom: 3px solid #000; border-bottom: 3px solid #000;
padding: 18px; padding: 18px;
@ -41,7 +61,7 @@
display: block; display: block;
vertical-align: middle vertical-align: middle
} }
.qrcode { .qrcode {
width: 260px; width: 260px;
height: 260px; height: 260px;
@ -50,19 +70,23 @@
</style> </style>
</head> </head>
<body> <body>
<div class="label-page" th:each="item, iterStat : ${list}" th:style="${iterStat.index == 0} ? 'page-break-before: auto;' : 'page-break-before: always;'">
<table> <div class="label-page" th:each="item, iterStat : ${list}">
<tr> <div class="label-content">
<td style="text-align: center;"> <table>
<img alt="" class="qrcode" th:src="${item.qrCode}"/> <tr>
<div style="font-size: 16pt" th:text="${item.no}">NFLG-QZ-002</div> <td style="text-align: center;">
</td> <img alt="" class="qrcode" th:src="${item.qrCode}"/>
<td style="text-align: left;vertical-align: top"> <div style="font-size: 16pt" th:text="${item.no}">NFLG-QZ-002</div>
<div class="div-with-border">包装名称: <span th:text="${item.name}">NFLG-QZ-002 测试包装名称</span></div> </td>
<div class="div-with-border">包装类型: <span th:text="${item.typeName}">托盘</span></div> <td style="text-align: left;vertical-align: top">
</td> <div class="div-with-border">包装名称: <span th:text="${item.name}">NFLG-QZ-002 测试包装名称</span></div>
</tr> <div class="div-with-border">包装类型: <span th:text="${item.typeName}">托盘</span></div>
</table> </td>
</tr>
</table>
</div>
</div> </div>
</body> </body>
</html> </html>