Commit b70a350678b3092b2500ab7bd4233b46a09e1d0e

Authored by 谢茂盛
1 parent 61f9a255

feat: ERP升级

1、生产指示书PDF文件生成
... ... @@ -46,6 +46,7 @@
46 46 <thumbnailator.version>0.4.8</thumbnailator.version>
47 47 <jjwt.version>0.10.6</jjwt.version>
48 48 <easyexcel.version>2.2.3</easyexcel.version>
  49 + <x-easypdf-pdfbox.version>2.11.10</x-easypdf-pdfbox.version>
49 50 </properties>
50 51  
51 52 <dependencies>
... ... @@ -273,6 +274,14 @@
273 274 <version>${thumbnailator.version}</version>
274 275 </dependency>
275 276  
  277 + <!--pdf-->
  278 + <!-- 引入pdf 依赖 底层是org.apache.pdfbox-->
  279 + <dependency>
  280 + <groupId>wiki.xsx</groupId>
  281 + <artifactId>x-easypdf-pdfbox</artifactId>
  282 + <version>${x-easypdf-pdfbox.version}</version>
  283 + </dependency>
  284 +
276 285 </dependencies>
277 286 <build>
278 287 <finalName>order-erp.service-1.0-SNAPSHOT</finalName>
... ...
src/main/java/com/order/erp/common/utils/EasyPdfUtils.java 0 → 100644
  1 +package com.order.erp.common.utils;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.order.erp.common.constant.Constant;
  5 +import com.order.erp.domain.dto.order.OrderBaseInfoDO;
  6 +import com.order.erp.domain.dto.order.OrderProfitAnalysisDO;
  7 +import com.order.erp.domain.pdf.OrderProducePdfVO;
  8 +import com.order.erp.service.order.OrderBaseInfoService;
  9 +import com.order.erp.service.order.OrderProfitAnalysisService;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import org.springframework.beans.BeanUtils;
  12 +import org.springframework.beans.factory.annotation.Value;
  13 +import org.springframework.stereotype.Service;
  14 +import wiki.xsx.core.pdf.component.image.XEasyPdfImage;
  15 +import wiki.xsx.core.pdf.component.table.XEasyPdfCell;
  16 +import wiki.xsx.core.pdf.component.table.XEasyPdfRow;
  17 +import wiki.xsx.core.pdf.component.table.XEasyPdfTable;
  18 +import wiki.xsx.core.pdf.doc.*;
  19 +import wiki.xsx.core.pdf.handler.XEasyPdfHandler;
  20 +
  21 +import javax.annotation.Resource;
  22 +import java.io.File;
  23 +import java.io.InputStream;
  24 +import java.io.OutputStream;
  25 +import java.math.BigDecimal;
  26 +import java.net.URL;
  27 +import java.util.*;
  28 +import java.util.function.Function;
  29 +import java.util.stream.Collectors;
  30 +
  31 +/**
  32 + * @author: xms
  33 + * @description: TODO
  34 + * @date: 2024/7/17 16:30
  35 + * @version: 1.0
  36 + */
  37 +@Slf4j
  38 +@Service
  39 +public class EasyPdfUtils {
  40 +
  41 + @Resource
  42 + private OrderBaseInfoService orderBaseInfoService;
  43 +
  44 + @Resource
  45 + private OrderProfitAnalysisService profitAnalysisService;
  46 +
  47 + @Value("${file.path}")
  48 + private String path;
  49 +
  50 + public List<OrderProducePdfVO> build() {
  51 + List<OrderBaseInfoDO> orderBaseInfoDOList = orderBaseInfoService.list(new LambdaQueryWrapper<OrderBaseInfoDO>().gt(OrderBaseInfoDO::getId, 1).last("limit 10"));
  52 + Set<Long> orderIds = orderBaseInfoDOList.stream().map(OrderBaseInfoDO::getId).collect(Collectors.toSet());
  53 + List<OrderProfitAnalysisDO> profitAnalysisDOS = profitAnalysisService.list(new LambdaQueryWrapper<OrderProfitAnalysisDO>().in(OrderProfitAnalysisDO::getOrderId, orderIds));
  54 + Map<Long, OrderProfitAnalysisDO> profitAnalysisDOMap = profitAnalysisDOS.stream().collect(Collectors.toMap(OrderProfitAnalysisDO::getOrderId, Function.identity()));
  55 + return orderBaseInfoDOList.stream().map(x -> {
  56 + OrderProducePdfVO producePdfVO = new OrderProducePdfVO();
  57 + BeanUtils.copyProperties(x, producePdfVO);
  58 + OrderProfitAnalysisDO profitAnalysisDO = profitAnalysisDOMap.get(x.getId());
  59 + if (Objects.nonNull(profitAnalysisDO)) {
  60 + producePdfVO.setProductionDepartmentPrice(producePdfVO.getProductionDepartmentPrice());
  61 + producePdfVO.setProductionDepartmentTotalPrice(producePdfVO.getProductionDepartmentTotalPrice());
  62 + }
  63 + return producePdfVO;
  64 + }).collect(Collectors.toList());
  65 + }
  66 +
  67 + /**
  68 + * @param pdfVOList
  69 + * @param fileName
  70 + * @return
  71 + */
  72 + public File createProducePdf(List<OrderProducePdfVO> pdfVOList, String fileName) {
  73 + String pathUri = path + "pdfs" + File.separator + AliOssUtil.getUniqueFileName(fileName);
  74 + OutputStream os = FileUtil.getOutputStream(pathUri);
  75 + XEasyPdfDocument document = createProducePdf(pdfVOList);
  76 + document.save(os);
  77 + return FileUtil.file(pathUri);
  78 + }
  79 +
  80 + /**
  81 + * @param pdfVOList
  82 + * @return
  83 + */
  84 + public XEasyPdfDocument createProducePdf(List<OrderProducePdfVO> pdfVOList) {
  85 + // 构建文档
  86 + XEasyPdfDocument document = XEasyPdfHandler.Document.build();
  87 +
  88 + try {
  89 + // 表格
  90 + XEasyPdfTable table = createTable(pdfVOList);
  91 + // 创建页面
  92 + XEasyPdfPage page = XEasyPdfHandler.Page.build(XEasyPdfPageRectangle.create(1700F, 1000F), table);
  93 + // 将页面添加到文档
  94 + document.addPage(page);
  95 + // 添加页脚
  96 + document.setGlobalFooter(XEasyPdfHandler.Footer.build(
  97 + //构建文本(使用当前页占位符)
  98 + XEasyPdfHandler.Text.build(
  99 + XEasyPdfHandler.Page.getCurrentPagePlaceholder() +
  100 + "/" +
  101 + XEasyPdfHandler.Page.getTotalPagePlaceholder()).
  102 + setFontSize(10F).setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  103 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT)
  104 + ));
  105 + // 开启总页码占位符替换
  106 + document.enableReplaceTotalPagePlaceholder();
  107 + return document;
  108 + } catch (Exception e) {
  109 + return null;
  110 + }
  111 + }
  112 +
  113 + /**
  114 + * @param imageFile
  115 + * @param width
  116 + * @return
  117 + */
  118 + private XEasyPdfCell createImageCell(File imageFile, float width) {
  119 + XEasyPdfImage image = XEasyPdfHandler.Image.build(imageFile).
  120 + setHeight(40F).setWidth(80F).
  121 + setMarginTop(0F).setMarginLeft(0F).
  122 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).setHorizontalStyle(XEasyPdfPositionStyle.CENTER);
  123 +
  124 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, 60F).
  125 + addContent(image).
  126 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  127 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  128 + enableCenterStyle().enableComponentSelfStyle();
  129 + return cell;
  130 + }
  131 +
  132 + /**
  133 + * @param text
  134 + * @param width
  135 + * @return
  136 + */
  137 + private XEasyPdfCell createCell(String text, float width, float fontSize) {
  138 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, 50F).
  139 + addContent(XEasyPdfHandler.Text.build(text).
  140 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  141 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  142 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT).setFontSize(fontSize)).
  143 + enableCenterStyle().enableComponentSelfStyle();
  144 + return cell;
  145 + }
  146 +
  147 + /**
  148 + * @param text
  149 + * @param width
  150 + * @return
  151 + */
  152 + private XEasyPdfCell createCell(String text, float width, float height, float fontSize, XEasyPdfDefaultFontStyle fontStyle) {
  153 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, height).
  154 + addContent(XEasyPdfHandler.Text.build(text).
  155 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  156 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  157 + setDefaultFontStyle(fontStyle).setFontSize(fontSize)).
  158 + enableCenterStyle().enableComponentSelfStyle();
  159 + return cell;
  160 + }
  161 +
  162 + /**
  163 + * @param text
  164 + * @param width
  165 + * @return
  166 + */
  167 + private XEasyPdfCell createCell(String text, float width) {
  168 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width).
  169 + addContent(XEasyPdfHandler.Text.build(text).
  170 + setVerticalStyle(XEasyPdfPositionStyle.CENTER).
  171 + setHorizontalStyle(XEasyPdfPositionStyle.CENTER).
  172 + setDefaultFontStyle(XEasyPdfDefaultFontStyle.LIGHT).setFontSize(16)).
  173 + enableCenterStyle().enableComponentSelfStyle();
  174 + return cell;
  175 + }
  176 +
  177 + /**
  178 + * @param text
  179 + * @param width
  180 + * @return
  181 + */
  182 + private XEasyPdfCell createCell(String text, float width, float height, float fontSize,
  183 + XEasyPdfDefaultFontStyle fontStyle,
  184 + XEasyPdfPositionStyle verticalStyle,
  185 + XEasyPdfPositionStyle horizontalStyle) {
  186 + XEasyPdfCell cell = XEasyPdfHandler.Table.Row.Cell.build(width, height).
  187 + addContent(XEasyPdfHandler.Text.build(text).
  188 + setVerticalStyle(verticalStyle).
  189 + setHorizontalStyle(horizontalStyle).
  190 + setDefaultFontStyle(fontStyle).setFontSize(fontSize)).
  191 + enableCenterStyle().enableComponentSelfStyle();
  192 + return cell;
  193 + }
  194 +
  195 + /**
  196 + * @return
  197 + */
  198 + private XEasyPdfTable createTable(List<OrderProducePdfVO> pdfVOList) throws Exception {
  199 + XEasyPdfTable table = XEasyPdfHandler.Table.build();
  200 + List<XEasyPdfRow> rowList = new ArrayList<>();
  201 + List<XEasyPdfCell> cellList = new ArrayList<>(15);
  202 + List<XEasyPdfCell> header = new ArrayList<>(1);
  203 + header.add(createCell("青岛吉庆天成生产订单", 1660F, 70F, 24F, XEasyPdfDefaultFontStyle.BOLD));
  204 + rowList.add(XEasyPdfHandler.Table.Row.build(header));
  205 +
  206 + // 第一行设置表头,默认标题
  207 + cellList.add(createCell("编号", 90F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  208 + cellList.add(createCell("项目号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  209 + cellList.add(createCell("生产科", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  210 + cellList.add(createCell("内部编号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  211 + cellList.add(createCell("客户订单号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  212 + cellList.add(createCell("客户款号", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  213 + cellList.add(createCell("订单颜色", 140F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  214 + cellList.add(createCell("颜色中文", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  215 + cellList.add(createCell("订单图片", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  216 + cellList.add(createCell("产品意见", 150F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  217 + cellList.add(createCell("订单数量", 90F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  218 + cellList.add(createCell("生产科交期", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  219 + cellList.add(createCell("包装类型", 90F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  220 + cellList.add(createCell("生产科单价", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  221 + cellList.add(createCell("生产科总价", 110F, 60F, 16F, XEasyPdfDefaultFontStyle.BOLD));
  222 + rowList.add(XEasyPdfHandler.Table.Row.build(cellList));
  223 + Integer orderTotalCount = 0;
  224 + BigDecimal totalPrice = new BigDecimal(Constant.ZERO);
  225 + for (int i = 0; i < pdfVOList.size(); i++) {
  226 + OrderProducePdfVO producePdfVO = pdfVOList.get(i);
  227 + URL url = new URL(producePdfVO.getPicUrl());
  228 + InputStream inputStream = url.openStream();
  229 + File imageFile = FileUtil.inputStreamToFile(inputStream, "order.png");
  230 + orderTotalCount += Objects.nonNull(producePdfVO.getOrderCount()) ? producePdfVO.getOrderCount() : Constant.ZERO;
  231 + String productionDepartmentConsignTime = StringUtils.isNotEmpty(producePdfVO.getProductionDepartmentConsignTime()) ?
  232 + DateUtils.format(DateUtils.parseDate(producePdfVO.getProductionDepartmentConsignTime(), DateUtils.DATE_TIME), DateUtils.DATE) : "";
  233 + totalPrice = totalPrice.add(new BigDecimal(Objects.nonNull(producePdfVO.getProductionDepartmentTotalPrice()) ? producePdfVO.getProductionDepartmentTotalPrice() : Constant.ZERO));
  234 + List<XEasyPdfCell> dataCellList = new ArrayList<>(15);
  235 + dataCellList.add(createCell("" + (i + 1), 90F));
  236 + dataCellList.add(createCell(producePdfVO.getProjectNo(), 110F));
  237 + dataCellList.add(createCell(producePdfVO.getProductionDepartment(), 110F));
  238 + dataCellList.add(createCell(producePdfVO.getInnerNo(), 110F));
  239 + dataCellList.add(createCell(producePdfVO.getCustomerPo(), 110F));
  240 + dataCellList.add(createCell(producePdfVO.getCustomerStyle(), 110F));
  241 + dataCellList.add(createCell(producePdfVO.getPoColor(), 140F));
  242 + dataCellList.add(createCell(producePdfVO.getCnColor(), 110F));
  243 + dataCellList.add(createImageCell(imageFile, 110F));
  244 + dataCellList.add(createCell(producePdfVO.getProductionComment(), 150F));
  245 + dataCellList.add(createCell("" + producePdfVO.getOrderCount(), 90F));
  246 + dataCellList.add(createCell(productionDepartmentConsignTime, 110F));
  247 + dataCellList.add(createCell(producePdfVO.getPacketType(), 90F));
  248 + dataCellList.add(createCell(Objects.nonNull(producePdfVO.getProductionDepartmentPrice()) ? "" + producePdfVO.getProductionDepartmentPrice() : "", 110F));
  249 + dataCellList.add(createCell(Objects.nonNull(producePdfVO.getProductionDepartmentTotalPrice()) ? "" + producePdfVO.getProductionDepartmentTotalPrice() : "", 110F));
  250 + rowList.add(XEasyPdfHandler.Table.Row.build(dataCellList));
  251 + }
  252 + List<XEasyPdfCell> endCellList = new ArrayList<>(15);
  253 + endCellList.add(createCell("合计", 90F, 16F));
  254 + endCellList.add(createCell("", 110F));
  255 + endCellList.add(createCell("", 110F));
  256 + endCellList.add(createCell("", 110F));
  257 + endCellList.add(createCell("", 110F));
  258 + endCellList.add(createCell("", 110F));
  259 + endCellList.add(createCell("", 140F));
  260 + endCellList.add(createCell("", 110F));
  261 + endCellList.add(createCell("", 110F));
  262 + endCellList.add(createCell("", 150F));
  263 + endCellList.add(createCell("" + orderTotalCount, 90F, 16F));
  264 + endCellList.add(createCell("", 110F));
  265 + endCellList.add(createCell("", 90F));
  266 + endCellList.add(createCell("", 110F));
  267 + endCellList.add(createCell("" + totalPrice, 110F, 16F));
  268 + rowList.add(XEasyPdfHandler.Table.Row.build(endCellList));
  269 + List<XEasyPdfCell> signList = new ArrayList<>(2);
  270 + signList.add(createCell("吉庆天成签字+日期:", 640F, 80F, 20F, XEasyPdfDefaultFontStyle.BOLD, XEasyPdfPositionStyle.CENTER, XEasyPdfPositionStyle.LEFT));
  271 + signList.add(createCell("外加工签字+日期:", 1020F, 80F, 20F, XEasyPdfDefaultFontStyle.BOLD, XEasyPdfPositionStyle.CENTER, XEasyPdfPositionStyle.LEFT));
  272 + rowList.add(XEasyPdfHandler.Table.Row.build(signList));
  273 +
  274 + table.addRow(rowList);
  275 + table.setHorizontalStyle(XEasyPdfPositionStyle.CENTER).setMarginLeft(10F).setMarginTop(60F).setMarginBottom(10F);
  276 + return table;
  277 + }
  278 +
  279 +}
... ...
src/main/java/com/order/erp/controller/EmailTemplateController.java
... ... @@ -2,6 +2,8 @@ package com.order.erp.controller;
2 2  
3 3 import com.order.erp.common.constant.ServerResult;
4 4 import com.order.erp.common.jsr303.OperateGroup;
  5 +import com.order.erp.common.utils.EasyPdfUtils;
  6 +import com.order.erp.common.utils.FileUtil;
5 7 import com.order.erp.domain.vo.order.EmailTemplateQueryVO;
6 8 import com.order.erp.domain.vo.order.EmailTemplateVO;
7 9 import com.order.erp.service.order.EmailTemplateService;
... ... @@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
12 14 import org.springframework.web.bind.annotation.RestController;
13 15  
14 16 import javax.annotation.Resource;
  17 +import java.io.File;
15 18  
16 19 /**
17 20 * 邮件模板表(EmailTemplate)表控制层
... ... @@ -28,6 +31,24 @@ public class EmailTemplateController {
28 31 @Resource
29 32 private EmailTemplateService emailTemplateService;
30 33  
  34 + @Resource
  35 + private EasyPdfUtils pdfUtils;
  36 +
  37 + /**
  38 + * 分页查询
  39 + *
  40 + * @param emailTemplateQueryVO 查询条件
  41 + * @return 查询结果
  42 + */
  43 + @PostMapping("/test")
  44 + public ServerResult test(@RequestBody @Validated({OperateGroup.List.class}) EmailTemplateQueryVO emailTemplateQueryVO) {
  45 +
  46 +
  47 + pdfUtils.createProducePdf(pdfUtils.build(), "testPagePlaceholder.pdf");
  48 +
  49 + return ServerResult.success();
  50 + }
  51 +
31 52 /**
32 53 * 分页查询
33 54 *
... ...
src/main/java/com/order/erp/domain/pdf/OrderProducePdfVO.java 0 → 100644
  1 +package com.order.erp.domain.pdf;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.io.Serializable;
  7 +
  8 +/**
  9 + * 生产指示书pdf
  10 + *
  11 + * @author makejava
  12 + * @since 2023-09-08 15:26:43
  13 + */
  14 +@Data
  15 +@AllArgsConstructor
  16 +@ToString
  17 +@NoArgsConstructor
  18 +@EqualsAndHashCode(callSuper = false)
  19 +@SuperBuilder
  20 +public class OrderProducePdfVO implements Serializable {
  21 +
  22 + /**
  23 + * 项目号
  24 + */
  25 + private String projectNo;
  26 +
  27 + /**
  28 + * 生产科
  29 + */
  30 + private String productionDepartment;
  31 +
  32 + /**
  33 + * 内部编号
  34 + */
  35 + private String innerNo;
  36 +
  37 + /**
  38 + * 客户po号(客户订单号)
  39 + */
  40 + private String customerPo;
  41 +
  42 + /**
  43 + * 客户STYLE#(客户款号)
  44 + */
  45 + private String customerStyle;
  46 +
  47 + /**
  48 + * PO COLOR (订单颜色)
  49 + */
  50 + private String poColor;
  51 +
  52 + /**
  53 + * 颜色中文
  54 + */
  55 + private String cnColor;
  56 +
  57 + /**
  58 + * pic图片地址(订单图片)
  59 + */
  60 + private String picUrl;
  61 +
  62 + /**
  63 + * 产品意见
  64 + */
  65 + private String productionComment;
  66 +
  67 + /**
  68 + * 订单数量
  69 + */
  70 + private Integer orderCount;
  71 +
  72 + /**
  73 + * 生成科拖货时间(生产科交期)
  74 + */
  75 + private String productionDepartmentConsignTime;
  76 +
  77 + /**
  78 + * 包装类型
  79 + */
  80 + private String packetType;
  81 +
  82 + /**
  83 + * 生成科单价¥
  84 + */
  85 + private Double productionDepartmentPrice;
  86 +
  87 + /**
  88 + * 生成科总价¥
  89 + */
  90 + private Double productionDepartmentTotalPrice;
  91 +
  92 +}
... ...