Commit fcf7d8c2120ac81c445278682b204b1db32dd868

Authored by yeqianyong
1 parent 4ff76aa4

楚江erp:订货单批量导出

... ... @@ -8,6 +8,7 @@ import com.lframework.starter.bpm.mappers.FlowTaskWrapperMapper;
8 8 import com.lframework.starter.bpm.vo.flow.task.QueryTodoTaskListVo;
9 9 import com.lframework.starter.common.exceptions.impl.DefaultClientException;
10 10 import com.lframework.starter.common.utils.CollectionUtil;
  11 +import com.lframework.starter.mq.core.utils.ExportTaskUtil;
11 12 import com.lframework.starter.web.core.annotations.security.HasPermission;
12 13 import com.lframework.starter.web.core.components.resp.InvokeResult;
13 14 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
... ... @@ -22,6 +23,8 @@ import com.lframework.xingyun.sc.bo.order.GetPurchaseOrderInfoBo;
22 23 import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
23 24 import com.lframework.xingyun.sc.entity.PurchaseOrderInfo;
24 25 import com.lframework.xingyun.sc.entity.PurchaseOrderLine;
  26 +import com.lframework.xingyun.sc.enums.ExportType;
  27 +import com.lframework.xingyun.sc.excel.order.OrderInfoExportTaskWorker;
25 28 import com.lframework.xingyun.sc.handlers.TransactorHandler;
26 29 import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService;
27 30 import com.lframework.xingyun.sc.service.order.PurchaseOrderInfoService;
... ... @@ -515,6 +518,14 @@ public class PurchaseOrderInfoController extends DefaultBaseController {
515 518 }
516 519 }
517 520
  521 + @ApiOperation("订货单批量打印")
  522 + @GetMapping("/batchPrintPurchaseOrder")
  523 + public InvokeResult<Void> batchPrintPurchaseOrder( QueryPurchaseOrderInfoVo vo) {
  524 + vo.setExportType(ExportType.ORDER_EXPORT_ZIP.getCode());
  525 + ExportTaskUtil.exportTask("订货单信息", OrderInfoExportTaskWorker.class, vo);
  526 + return InvokeResultBuilder.success();
  527 + }
  528 +
518 529 private File convertExcelToPdf(File excelFile) throws IOException, InterruptedException {
519 530 if (!excelFile.exists()) {
520 531 throw new IllegalArgumentException("Excel 文件不存在: " + excelFile.getAbsolutePath());
... ...
... ... @@ -12,6 +12,7 @@ public enum ExportType implements BaseEnum<String> {
12 12 RECEIVABLE_LEDGER_REPORT("RECEIVABLE_LEDGER_REPORT", "应收款台账报表"),
13 13 SHIPMENT_DETAIL_REPORT("SHIPMENT_DETAIL_REPORT", "发货明细报表"),
14 14 ORDER_DETAIL_REPORT("ORDER_DETAIL_REPORT", "订单明细报表"),
  15 + ORDER_EXPORT_ZIP("ORDER_EXPORT_ZIP", "订货单信息"),
15 16
16 17
17 18 ;
... ...
  1 +package com.lframework.xingyun.sc.excel.order;
  2 +
  3 +import com.lframework.starter.mq.core.components.export.ExportTaskWorker;
  4 +import com.lframework.starter.web.core.components.excel.ExcelModel;
  5 +import com.lframework.starter.web.core.components.resp.PageResult;
  6 +import com.lframework.starter.web.core.utils.ApplicationUtil;
  7 +import com.lframework.starter.web.core.utils.JsonUtil;
  8 +import com.lframework.xingyun.sc.entity.PurchaseOrderInfo;
  9 +import com.lframework.xingyun.sc.service.order.PurchaseOrderInfoService;
  10 +import com.lframework.xingyun.sc.vo.order.QueryPurchaseOrderInfoVo;
  11 +
  12 +
  13 +public class OrderInfoExportTaskWorker implements
  14 + ExportTaskWorker<QueryPurchaseOrderInfoVo, PurchaseOrderInfo, ExcelModel> {
  15 +
  16 +
  17 + @Override
  18 + public QueryPurchaseOrderInfoVo parseParams(String json) {
  19 + return JsonUtil.parseObject(json, QueryPurchaseOrderInfoVo.class);
  20 + }
  21 +
  22 + @Override
  23 + public PageResult<PurchaseOrderInfo> getDataList(int pageIndex, int pageSize, QueryPurchaseOrderInfoVo params) {
  24 + PurchaseOrderInfoService orderInfoService = ApplicationUtil.getBean(PurchaseOrderInfoService.class);
  25 + return orderInfoService.query(pageIndex, pageSize, params);
  26 + }
  27 +
  28 + @Override
  29 + public ExcelModel exportData(PurchaseOrderInfo purchaseOrderInfo) {
  30 + return null;
  31 + }
  32 +
  33 + @Override
  34 + public Class<ExcelModel> getModelClass() {
  35 + return null;
  36 + }
  37 +}
... ...
xingyun-sc/src/main/java/com/lframework/xingyun/sc/handlers/BusinessDataExportHandler.java renamed from xingyun-sc/src/main/java/com/lframework/xingyun/sc/excel/ledger/LedgerReportExportHandler.java
1   -package com.lframework.xingyun.sc.excel.ledger;
  1 +package com.lframework.xingyun.sc.handlers;
2 2
3 3
4 4 import cn.hutool.core.io.resource.ClassPathResource;
... ... @@ -9,8 +9,14 @@ import com.lframework.starter.web.core.utils.JsonUtil;
9 9 import com.lframework.starter.web.inner.entity.SysDataDicItem;
10 10 import com.lframework.starter.web.inner.service.system.SysDataDicItemService;
11 11 import com.lframework.xingyun.sc.bo.ledger.receipt.ReceiptLedgerReportDetail;
  12 +import com.lframework.xingyun.sc.entity.PurchaseOrderInfo;
  13 +import com.lframework.xingyun.sc.entity.PurchaseOrderLine;
  14 +import com.lframework.xingyun.sc.excel.ledger.LedgerReportExportModel;
  15 +import com.lframework.xingyun.sc.service.order.PurchaseOrderLineService;
12 16 import com.lframework.xingyun.sc.utils.ExcelUtil;
  17 +import com.lframework.xingyun.sc.utils.LatexFormulaExcelExporterUtil;
13 18 import com.lframework.xingyun.sc.vo.ledger.receipt.ReceiptLedgerReportVo;
  19 +import com.lframework.xingyun.sc.vo.order.QueryPurchaseOrderInfoVo;
14 20 import lombok.extern.slf4j.Slf4j;
15 21 import org.apache.commons.collections4.CollectionUtils;
16 22 import org.apache.commons.lang3.StringUtils;
... ... @@ -19,17 +25,29 @@ import org.apache.poi.ss.util.CellRangeAddress;
19 25 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
20 26 import org.springframework.stereotype.Component;
21 27
22   -import java.io.File;
23   -import java.io.FileOutputStream;
24   -import java.io.InputStream;
  28 +import javax.annotation.Resource;
  29 +import java.io.*;
  30 +import java.math.BigDecimal;
  31 +import java.math.RoundingMode;
  32 +import java.nio.file.Files;
  33 +import java.time.format.DateTimeFormatter;
  34 +import java.util.ArrayList;
25 35 import java.util.HashMap;
26 36 import java.util.List;
27 37 import java.util.Map;
  38 +import java.util.stream.Collectors;
  39 +import java.util.zip.ZipEntry;
  40 +import java.util.zip.ZipOutputStream;
28 41
29 42
30 43 @Slf4j
31 44 @Component
32   -public class LedgerReportExportHandler implements ExportHandler {
  45 +public class BusinessDataExportHandler implements ExportHandler {
  46 +
  47 +
  48 + @Resource
  49 + private PurchaseOrderLineService purchaseOrderLineService;
  50 +
33 51
34 52 @Override
35 53 public void exportLedgerReport(Object params, Object dataList, File xlsxFile, String exportType) {
... ... @@ -134,6 +152,159 @@ public class LedgerReportExportHandler implements ExportHandler {
134 152 }
135 153 }
136 154
  155 + @Override
  156 + public void exportOrderInfo(Object params, Object dataList, File file) {
  157 + // 订单信息
  158 + List<PurchaseOrderInfo> orderInfoList = JsonUtil.parseList(JsonUtil.toJsonString(dataList), PurchaseOrderInfo.class);
  159 + if (CollectionUtils.isEmpty(orderInfoList)) {
  160 + return;
  161 + }
  162 + List<String> orderIds = orderInfoList.stream().map(PurchaseOrderInfo::getId).collect(Collectors.toList());
  163 + Map<String, List<PurchaseOrderLine>> orderLineMap = new HashMap<>();
  164 + // 获取物料行数据
  165 + List<PurchaseOrderLine> orderLineList = purchaseOrderLineService.listByOrderIds(orderIds, true);
  166 + if (CollectionUtils.isNotEmpty(orderLineList)) {
  167 + for (PurchaseOrderLine orderLine: orderLineList) {
  168 + String orderId = orderLine.getPurchaseOrderId();
  169 + List<PurchaseOrderLine> list = orderLineMap.computeIfAbsent(orderId, k -> new ArrayList<>());
  170 + list.add(orderLine);
  171 + }
  172 + }
  173 + // 查询条件
  174 + QueryPurchaseOrderInfoVo queryVo = JsonUtil.parseObject(JsonUtil.toJsonString(params), QueryPurchaseOrderInfoVo.class);
  175 + // 获取导出模版
  176 + ClassPathResource templateResource = new ClassPathResource("templates/purchaseOrderTemplate.xlsx");
  177 + if ("PRODUCTION_PROCESS".equals(queryVo.getTemplateType())) {
  178 + templateResource = new ClassPathResource("templates/purchaseOrderTemplateForProduction.xlsx");
  179 + }
  180 + try (FileOutputStream fosZip = new FileOutputStream(file);
  181 + ZipOutputStream zos = new ZipOutputStream(fosZip)) {
  182 + for (PurchaseOrderInfo orderInfo : orderInfoList) {
  183 + try (InputStream inputStream = templateResource.getStream();
  184 + Workbook workbook = new XSSFWorkbook(inputStream)) {
  185 + Sheet sheet = workbook.getSheetAt(0);
  186 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  187 + int startRow = 7;
  188 + BigDecimal totalQuantity = BigDecimal.ZERO;
  189 + List<PurchaseOrderLine> purchaseOrderLineList = orderLineMap.get(orderInfo.getId());
  190 + if (CollectionUtils.isNotEmpty(purchaseOrderLineList)) {
  191 + for (int i = startRow + 1; i < startRow + purchaseOrderLineList.size(); i++) {
  192 + ExcelUtil.copyRow(workbook, sheet, startRow, i);
  193 + }
  194 + for (PurchaseOrderLine currentOrderLine : purchaseOrderLineList) {
  195 + ExcelUtil.setCellValue(sheet, startRow, 1, currentOrderLine.getIndustry());
  196 + ExcelUtil.setCellValue(sheet, startRow, 2, currentOrderLine.getQuality());
  197 + ExcelUtil.setCellValue(sheet, startRow, 3, currentOrderLine.getBrand());
  198 + List<LatexFormulaExcelExporterUtil.FormulaComponent> formulaComponentList = new ArrayList<>(3);
  199 + if (currentOrderLine.getThickness() != null) {
  200 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  201 + formulaComponent.setBase(currentOrderLine.getThickness());
  202 + formulaComponent.setSup(currentOrderLine.getThicknessTolPos());
  203 + formulaComponent.setSub(currentOrderLine.getThicknessTolNeg());
  204 + formulaComponentList.add(formulaComponent);
  205 + }
  206 + if (currentOrderLine.getWidth() != null) {
  207 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  208 + formulaComponent.setBase(currentOrderLine.getWidth());
  209 + formulaComponent.setSup(currentOrderLine.getWidthTolPos());
  210 + formulaComponent.setSub(currentOrderLine.getWidthTolNeg());
  211 + formulaComponentList.add(formulaComponent);
  212 + }
  213 + if (currentOrderLine.getLength() != null) {
  214 + LatexFormulaExcelExporterUtil.FormulaComponent formulaComponent = new LatexFormulaExcelExporterUtil.FormulaComponent();
  215 + formulaComponent.setBase(currentOrderLine.getLength());
  216 + formulaComponent.setSup(currentOrderLine.getLengthTolPos());
  217 + formulaComponent.setSub(currentOrderLine.getLengthTolNeg());
  218 + formulaComponentList.add(formulaComponent);
  219 + }
  220 + String latex = LatexFormulaExcelExporterUtil.convertToLatex(formulaComponentList);
  221 + if (StringUtils.isNotBlank(latex)) {
  222 + LatexFormulaExcelExporterUtil.insertLatexImageToCell(workbook, sheet, latex, startRow, 4, 1, 7);
  223 + }
  224 + ExcelUtil.setCellValue(sheet, startRow, 11, currentOrderLine.getStatus());
  225 + ExcelUtil.setCellValue(sheet, startRow, 13, currentOrderLine.getQuantity());
  226 + ExcelUtil.setCellValue(sheet, startRow, 14, currentOrderLine.getSalesPrice());
  227 + ExcelUtil.setCellValue(sheet, startRow, 16, currentOrderLine.getDeliveryDate());
  228 + ExcelUtil.setCellValue(sheet, startRow, 17, currentOrderLine.getAssessmentExceedsAgreement());
  229 + if (currentOrderLine.getQuantity() != null) {
  230 + totalQuantity = totalQuantity.add(currentOrderLine.getQuantity());
  231 + }
  232 + startRow++;
  233 + }
  234 + }
  235 + Map<String, Object> dataMap = new HashMap<>();
  236 + SysDataDicItemService sysDataDicItemService = ApplicationUtil.getBean(SysDataDicItemService.class);
  237 + SysDataDicItem supplyUnitDicItem = sysDataDicItemService.findByCode("SUPPLIER", orderInfo.getSupplyUnit());
  238 + dataMap.put("supplyUnit", supplyUnitDicItem == null ? "" : supplyUnitDicItem.getName());
  239 + dataMap.put("orderNo", orderInfo.getOrderNo());
  240 + dataMap.put("orderingUnitName", orderInfo.getOrderingUnitName());
  241 + dataMap.put("customerTier", orderInfo.getCustomerTier());
  242 + dataMap.put("orderDate", orderInfo.getOrderDate() == null ? "" : orderInfo.getOrderDate().format(dateFormatter));
  243 + dataMap.put("totalQuantity", totalQuantity.setScale(1, RoundingMode.HALF_UP));
  244 + SysDataDicItem esDicItem = sysDataDicItemService.findByCode("APPLICABLE_STANDARD", orderInfo.getExecutionStandard());
  245 + dataMap.put("executionStandard", esDicItem == null ? "" : esDicItem.getName());
  246 + dataMap.put("deliveryMethod", orderInfo.getDeliveryMethod());
  247 + dataMap.put("invoicingStatus", orderInfo.getInvoicingStatus());
  248 + dataMap.put("pieceWeightHeader", orderInfo.getPieceWeightHeader());
  249 + dataMap.put("surface", orderInfo.getSurface());
  250 + dataMap.put("tolerance", orderInfo.getTolerance());
  251 + dataMap.put("performanceance", orderInfo.getPerformance());
  252 + dataMap.put("packaging", orderInfo.getPackaging());
  253 + dataMap.put("shippingCost", orderInfo.getShippingCost());
  254 + dataMap.put("remarks", orderInfo.getRemarks());
  255 + dataMap.put("createUser", orderInfo.getCreateBy());
  256 + dataMap.put("element", orderInfo.getElement());
  257 + String et = orderInfo.getEnterpriseType();
  258 + dataMap.put("enterpriseType",
  259 + "DEALER".equals(et) ? "经销商" :
  260 + "TERMINAL".equals(et) ? "终端" :
  261 + "FOREIGN".equals(et) ? "外贸" : "");
  262 + dataMap.put("deptName", orderInfo.getDeptName() == null ? "" : orderInfo.getDeptName());
  263 + dataMap.put("regionName", orderInfo.getRegionName() == null ? "" : orderInfo.getRegionName());
  264 + dataMap.put("stockUpCompanyName", orderInfo.getStockUpCompanyName() == null ? "" : orderInfo.getStockUpCompanyName());
  265 + dataMap.put("priceListNo", orderInfo.getPriceListNo());
  266 + ExcelUtil.processTemplate(workbook, dataMap);
  267 + if ("PDF".equals(queryVo.getExportFileType())) {
  268 + // 输出PDF
  269 + File tempExcel = File.createTempFile("purchase_order_" + orderInfo.getOrderNo(), ".xlsx");
  270 + try (FileOutputStream fos = new FileOutputStream(tempExcel)) {
  271 + workbook.write(fos);
  272 + }
  273 + File pdfFile = ExcelUtil.convertExcelToPdf(tempExcel, "/usr/bin/libreoffice --headless --convert-to pdf --outdir %s %s");
  274 + try (InputStream pdfIn = new FileInputStream(pdfFile)) {
  275 + ZipEntry entry = new ZipEntry(orderInfo.getOrderNo() + "-订货单打印.pdf");
  276 + zos.putNextEntry(entry);
  277 + byte[] buffer = new byte[8192];
  278 + int len;
  279 + while ((len = pdfIn.read(buffer)) != -1) {
  280 + zos.write(buffer, 0, len);
  281 + }
  282 + zos.closeEntry();
  283 + } finally {
  284 + if (tempExcel != null && tempExcel.exists()) {
  285 + Files.delete(tempExcel.toPath());
  286 + }
  287 + if (pdfFile != null && pdfFile.exists()) {
  288 + Files.delete(pdfFile.toPath());
  289 + }
  290 + }
  291 + } else {
  292 + ByteArrayOutputStream baos = new ByteArrayOutputStream();
  293 + workbook.write(baos);
  294 + ZipEntry entry = new ZipEntry(orderInfo.getOrderNo() + "-订货单打印.xlsx");
  295 + zos.putNextEntry(entry);
  296 + zos.write(baos.toByteArray());
  297 + zos.closeEntry();
  298 + }
  299 + }
  300 + }
  301 + zos.flush();
  302 + } catch (Exception e) {
  303 + log.error("订货单批量打印失败: {}", e.getMessage(), e);
  304 + throw new DefaultClientException(e.getMessage());
  305 + }
  306 + }
  307 +
137 308 private int setCellValue(Workbook workbook, Sheet sheet, int rowIndex, List<ReceiptLedgerReportDetail> detailList) {
138 309 if (CollectionUtils.isEmpty(detailList)) {
139 310 return rowIndex;
... ...
... ... @@ -13,6 +13,12 @@ public class QueryPurchaseOrderInfoVo extends PageVo implements BaseVo, Serializ
13 13 private static final long serialVersionUID = 1L;
14 14
15 15 /**
  16 + * 订货单ID集合
  17 + */
  18 + @ApiModelProperty("订货单ID集合")
  19 + private List<String> ids;
  20 +
  21 + /**
16 22 * 查询类型
17 23 * REVOKE:撤销
18 24 * CHANGE:变更
... ... @@ -141,4 +147,25 @@ public class QueryPurchaseOrderInfoVo extends PageVo implements BaseVo, Serializ
141 147 */
142 148 @ApiModelProperty("状态集合")
143 149 private List<String> includeStatus;
  150 +
  151 + /**
  152 + * 导出类型
  153 + */
  154 + @ApiModelProperty("导出类型")
  155 + private String exportType;
  156 +
  157 + /**
  158 + * 导出文件类型
  159 + * EXCEL/PDF
  160 + */
  161 + @ApiModelProperty("导出文件类型")
  162 + private String exportFileType;
  163 +
  164 + /**
  165 + * 模版类型
  166 + * NORMAL:普通模版
  167 + * PRODUCTION_PROCESS:生产工艺模版
  168 + */
  169 + @ApiModelProperty("导出类型")
  170 + private String templateType;
144 171 }
... ...
... ... @@ -195,6 +195,12 @@
195 195 #{status}
196 196 </foreach>
197 197 </if>
  198 + <if test="vo.ids != null and vo.ids.size() > 0">
  199 + AND tb.id IN
  200 + <foreach collection="vo.ids" item="id" open="(" separator="," close=")">
  201 + #{id}
  202 + </foreach>
  203 + </if>
198 204 </where>
199 205 ORDER BY tb.update_time DESC
200 206 </select>
... ...