Quellcode durchsuchen

收回单打印

wangxin vor 1 Jahr
Ursprung
Commit
70303ba0db

+ 15 - 0
pom.xml

@@ -154,6 +154,21 @@
             <version>${mybatis.spring.boot.starter.version}</version>
         </dependency>
          -->
+        <!--  pdf输出中文要用的jar  -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-freemarker</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.xhtmlrenderer</groupId>
+            <artifactId>flying-saucer-pdf-itext5</artifactId>
+            <version>9.1.20</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>html2pdf</artifactId>
+            <version>4.0.3</version>
+        </dependency>
 
         <!-- mybaits-plus  -->
         <dependency>

+ 88 - 0
src/main/java/cn/ezhizao/common/utils/PdfUtil.java

@@ -0,0 +1,88 @@
+package cn.ezhizao.common.utils;
+
+import com.itextpdf.html2pdf.ConverterProperties;
+import com.itextpdf.html2pdf.HtmlConverter;
+import com.itextpdf.kernel.geom.PageSize;
+import com.itextpdf.kernel.pdf.PdfDocument;
+import com.itextpdf.kernel.pdf.PdfWriter;
+import com.itextpdf.layout.font.FontProvider;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+import java.io.*;
+import java.util.Map;
+
+public class PdfUtil {
+
+    /**
+     * 获取模板内容
+     * @param templateDirectory 模板文件夹
+     * @param templateName      模板文件名
+     * @param paramMap          模板参数
+     * @return
+     * @throws Exception
+     */
+    public static String getTemplateContent(String templateDirectory, String templateName, Map<String, Object> paramMap) throws Exception {
+        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
+        try {
+            configuration.setDirectoryForTemplateLoading(new File(templateDirectory));
+        } catch (Exception e) {
+            System.out.println("-- exception --");
+        }
+
+        Writer out = new StringWriter();
+        Template template = configuration.getTemplate(templateName,"UTF-8");
+        template.process(paramMap, out);
+        out.flush();
+        out.close();
+        return out.toString();
+    }
+    /**
+     * HTML 转 PDF
+     * @param content html内容
+     * @param outPath           输出pdf路径
+     * @return 是否创建成功
+     */
+    public static boolean html2Pdf(String content, String outPath) {
+        try {
+            ConverterProperties converterProperties = new ConverterProperties();
+            converterProperties.setCharset("UTF-8");
+            FontProvider fontProvider = new FontProvider();
+            fontProvider.addSystemFonts();
+            converterProperties.setFontProvider(fontProvider);
+            HtmlConverter.convertToPdf(content, new FileOutputStream(outPath), converterProperties);
+        } catch (Exception e) {
+            System.out.println("生成模板内容失败,{}"+e);
+            return false;
+        }
+        return true;
+    }
+    /**
+     * HTML 转 PDF
+     * @param content html内容
+     * @return PDF字节数组
+     */
+    public static byte[] html2Pdf(String content) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            ConverterProperties converterProperties = new ConverterProperties();
+            converterProperties.setCharset("UTF-8");
+            FontProvider fontProvider = new FontProvider();
+            fontProvider.addSystemFonts();
+            converterProperties.setFontProvider(fontProvider);
+            //设置pdf纸张
+            PdfWriter writer = new PdfWriter(outputStream);
+            PdfDocument pdf = new PdfDocument(writer);
+            pdf.setTagged();
+            //设置纸张的大小,并且设置默认的pdf大小
+            PageSize pageSize = new PageSize(241f / 72 * 25.4f, 140f / 72 * 25.4f);
+//            PageSize pageSize = new PageSize(241f,140f);
+
+            pdf.setDefaultPageSize(pageSize);
+            HtmlConverter.convertToPdf(content,pdf,converterProperties);
+        } catch (Exception e) {
+            System.out.print("生成 PDF 失败,{}"+e);
+        }
+        return outputStream.toByteArray();
+    }
+}

+ 136 - 3
src/main/java/cn/ezhizao/project/business/controller/BizReturnReceiptController.java

@@ -1,5 +1,6 @@
 package cn.ezhizao.project.business.controller;
 
+import cn.ezhizao.common.utils.PdfUtil;
 import cn.ezhizao.common.utils.poi.ExcelUtil;
 import cn.ezhizao.framework.aspectj.lang.annotation.Log;
 import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
@@ -7,17 +8,23 @@ import cn.ezhizao.framework.redis.RedisCache;
 import cn.ezhizao.framework.web.controller.BaseController;
 import cn.ezhizao.framework.web.domain.AjaxResult;
 import cn.ezhizao.framework.web.page.TableDataInfo;
-import cn.ezhizao.project.business.domain.BizReturnReceipt;
-import cn.ezhizao.project.business.domain.BizOutsourcedOrderDetailProcess;
-import cn.ezhizao.project.business.domain.BizReturnReceiptDetail;
+import cn.ezhizao.project.business.domain.*;
 import cn.ezhizao.project.business.service.*;
+import cn.hutool.extra.template.TemplateException;
+import freemarker.template.Template;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
 
 import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -39,9 +46,17 @@ public class BizReturnReceiptController extends BaseController
     @Resource
     private IBizOutsourcedOrderDetailProcessService bizOutsourcedOrderDetailProcessService;
     @Resource
+    private IBizSupplierService bizSupplierService;
+    @Resource
     private RedisCache redisCache;
     @Resource
     HttpServletRequest request;
+
+    /**
+     * 生成pdf
+     */
+    @Autowired
+    private FreeMarkerConfigurer freeMarkerConfigurer;
     /**
      * 查询收回单主
      */
@@ -206,4 +221,122 @@ public class BizReturnReceiptController extends BaseController
         List<Long> bizReturnReceiptDetailIds = bizReturnReceiptDetailList.stream().map(BizReturnReceiptDetail::getId).collect(Collectors.toList());
         return toAjax(bizReturnReceiptDetailService.removeBatchByIds(bizReturnReceiptDetailIds));
     }
+
+
+    @Log(title = "外协打印", businessType = BusinessType.EXPORT)
+    @PostMapping("/printDetailPdf")
+    public void SocialSecurityPdf(BizReturnReceipt bizReturnReceipt, HttpServletResponse response) throws IOException, TemplateException, freemarker.template.TemplateException {
+
+        /** 正常打印 **/
+        //查询回收单数据
+        bizReturnReceipt=bizReturnReceiptService.getById(bizReturnReceipt);
+        //查询回收单明细
+//        List<BizReturnReceiptDetail> detailList=bizReturnReceiptDetailService.query().in("master_id", bizReturnReceipt.getId()).list();
+        // 根据收回订单id,获取到该收回订单的所有明细
+        List<BizReturnReceiptDetail> returnReceiptDetails = bizReturnReceiptDetailService.query()
+                .eq("master_id", bizReturnReceipt.getId())
+                .list();
+
+        // 将得到的收回明细的id,组合成一个集合,用于查询这个订单下的,所有收回出来的工序,
+        // 这里得到的工序清单,是混合的,并没有根据各自对应的明细,进行分组,仅仅是获取全部,为后续分组做准备
+        List<Long> detailIds = returnReceiptDetails.stream()
+                .map(BizReturnReceiptDetail::getOutsourceDetailId)
+                .collect(Collectors.toList());
+        List<BizOutsourcedOrderDetailProcess> detailProcesses = bizOutsourcedOrderDetailProcessService.query()
+                .in("detail_id", detailIds)
+                .orderByAsc(Arrays.asList("detail_id", "process_step_number"))
+                .list();
+
+        // 遍历明细,将对应的工序,与订单明细进行匹配
+        returnReceiptDetails.forEach(item -> {
+            // 根据明细的id,获取到该明细对应的收回工序,并将得到的工序,组成中文逗号分割的字符串
+            String processNames = detailProcesses.stream()
+                    .filter(dp -> dp.getDetailId().equals(item.getOutsourceDetailId()))
+                    .sorted(Comparator.comparing((BizOutsourcedOrderDetailProcess::getProcessStepNumber)))
+                    .map(BizOutsourcedOrderDetailProcess::getProcessAlias)
+                    .collect(Collectors.joining(","));
+
+            item.setProcessNames(processNames);
+        });
+
+        //查询外协厂code
+        BizSupplier supplier=bizSupplierService.getById(bizReturnReceipt.getSupplierId());
+        bizReturnReceipt.setSupplierCode(supplier.getCode());
+
+        // 创建SimpleDateFormat对象,并设置日期格式
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        bizReturnReceipt.setStringDate(dateFormat.format(bizReturnReceipt.getFormDate()));
+
+        List<List<BizReturnReceiptDetail> > list = new ArrayList<>();
+
+        //打印数据时每页14条
+        if(returnReceiptDetails.size() > 14){
+            // 用于临时存储每组数据的列表
+            List<BizReturnReceiptDetail> group = new ArrayList<>();
+            // 遍历 outsourcedOrderDetails 列表
+            for (BizReturnReceiptDetail detail : returnReceiptDetails) {
+                group.add(detail);
+                // 每添加 14 个元素后,将其添加到 list 中,并重置 group
+                if (group.size() == 14) {
+                    // 使用流过滤出 productNum 不为空的元素,并对其 productNum 值求和
+                    Integer sum = group.stream()
+                            .filter(item -> item.getProductNum() != null) // 过滤出 productNum 不为空的元素
+                            .mapToInt(BizReturnReceiptDetail::getProductNum) // 映射到 productNum 属性
+                            .sum(); // 计算总和
+                    // 然后,给每个对象的 sum 属性赋值
+                    for (BizReturnReceiptDetail item : group) {
+                        item.setSum(sum);
+                        item.setOriginalCarrierCount(item.getNewCarrierCount()==null?item.getOriginalCarrierCount():item.getNewCarrierCount());
+                    }
+                    list.add(new ArrayList<>(group));
+                    group = new ArrayList<>();
+                }
+            }
+            // 如果最后一组不足 14 个元素,也将其添加到 list 中
+            if (!group.isEmpty()) {
+                BizReturnReceiptDetail detail=new BizReturnReceiptDetail();
+                while (group.size() < 14) {
+                    group.add(detail); // 添加默认元素直到总数为14
+                }
+                list.add(group);
+            }
+        }else{
+            BizReturnReceiptDetail detail=new BizReturnReceiptDetail();
+            while (returnReceiptDetails.size() < 14) {
+                returnReceiptDetails.add(detail); // 添加默认元素直到总数为14
+            }
+            // 使用流过滤出 productNum 不为空的元素,并对其 productNum 值求和
+            Integer sum = returnReceiptDetails.stream()
+                    .filter(item -> item.getReceiptNum() != null) // 过滤出 productNum 不为空的元素
+                    .mapToInt(BizReturnReceiptDetail::getReceiptNum) // 映射到 productNum 属性
+                    .sum(); // 计算总和
+            // 然后,给每个对象的 sum 属性赋值
+            for (BizReturnReceiptDetail receiptDetail : returnReceiptDetails) {
+                receiptDetail.setSum(sum);
+                receiptDetail.setOriginalCarrierCount(receiptDetail.getNewCarrierCount()==null?receiptDetail.getOriginalCarrierCount():receiptDetail.getNewCarrierCount());
+            }
+
+            list.add(returnReceiptDetails);
+        }
+        bizReturnReceipt.setDetailLists(list);
+
+
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("returnReceipt" , bizReturnReceipt);
+        Writer out = new StringWriter();
+        //获取模板地址
+        Template template = freeMarkerConfigurer.getConfiguration().getTemplate("returnReceiptPdf.html");
+        template.process(paramMap, out);
+        out.flush();
+        out.close();
+        String templateContent = out.toString();
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/pdf");
+        String fileName ="外协收回明细";
+        response.setHeader("Content-Disposition", "filename=" + new String(fileName.getBytes()));
+        byte[] resources = PdfUtil.html2Pdf(templateContent);
+        ServletOutputStream outputStream = response.getOutputStream();
+        outputStream.write(resources);
+        outputStream.close();
+    }
 }

+ 12 - 0
src/main/java/cn/ezhizao/project/business/domain/BizReturnReceipt.java

@@ -70,4 +70,16 @@ public class BizReturnReceipt extends BaseEntity
     private String endTime;
 
     private Integer status;
+
+    /** 打印使用 */
+    @TableField(exist = false)
+    private String supplierCode;
+
+    @TableField(exist = false)
+    private List<List<BizReturnReceiptDetail>> detailLists;
+
+
+    @TableField(exist = false)
+    private String stringDate;
+
 }

+ 6 - 0
src/main/java/cn/ezhizao/project/business/domain/BizReturnReceiptDetail.java

@@ -125,4 +125,10 @@ public class BizReturnReceiptDetail extends BaseEntity
     private String processStepNumber;
     private String processCode;
     private Integer auditNum;
+
+    /** 打印 */
+    //发出总数量 只在打印时用到
+    @TableField(exist = false)
+    private Integer sum;
+
 }

+ 168 - 0
src/main/resources/templates/returnReceiptPdf.html

@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html lang="zh">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <style>
+        @page {
+            margin: 15px 40px 20px 10px;
+            size: 211mm 140mm;
+        }
+
+        body {
+
+            font-family: Arial, sans-serif;
+        }
+
+        table {
+            width: 100%;
+            border-collapse: collapse;
+            /*margin-bottom: 300px;*/
+            font-size: 10px;
+        }
+
+        th, td {
+            text-align: center;
+            padding: 5px;
+            border: 1px solid black;
+        }
+
+        .border {
+            border: 1px solid black !important;
+        }
+
+        .total-row {
+            font-weight: bold;
+            /*background-color: lightgray;*/
+            text-align: center;
+        }
+
+        /* 用于模拟13列布局 */
+        .col-1 {
+
+        }
+        .right-align { text-align: right; }
+        .center-align { text-align: center; }
+        .left-align { text-align: left; }
+        .title-row {
+            font-size: 13px ;
+            display: flex;
+            justify-content: space-between; /* 元素之间的间距均匀分布 */
+            align-items: center; /* 垂直居中对齐 */
+            width: 100%; /* 确保标题行占满整个容器宽度 */
+            /*margin-bottom: 10px; !* 根据需要调整间距 *!*/
+        }
+
+        .title-row div {
+            margin: 0; /* 移除默认的外边距 */
+        }
+    </style>
+</head>
+<#list returnReceipt.detailLists as detail>
+<body>
+
+<!-- 标题行 -->
+<div class="title-row">
+    <div class="right-align" style=" font-size: 12px ; margin-left: 5px;padding-right: 150px ">外协单位:${returnReceipt.supplierCode} ${returnReceipt.supplierName}</div>
+    <div class="center-align"  style="font-size: 13px ;padding-right: 90px">大连德迈仕精密科技股份有限公司</div>
+    <div class="left-align"  style=" font-size: 12px ;margin-right: 5px">单据号:${returnReceipt.formCode}</div>
+</div>
+<!-- 标题行 -->
+<div class="title-row" style="margin-top: 5px ; font-size: 12px ;">
+    <div class="right-align" style="margin-left: 5px; padding-right:220px;" >单据日期:${returnReceipt.stringDate}</div>
+    <div class="center-align" style="font-size: 14px ; padding-right: 170px">外协收回明细表</div>
+    <div class="left-align" style="margin-right: 5px">第${detail_index+1}页 共 ${returnReceipt.detailLists?size}页</div>
+</div>
+<table>
+
+
+    <!-- 第三行 -->
+    <tr class="header border">
+        <td class="col-0" align="center" valign="middle" style="width: 13px;">序号</td>
+        <td class="col-1" align="center" valign="middle">产品描述</td>
+        <td class="col-1" align="center" valign="middle" style="width: 60px;">批号</td>
+<!--        <td class="col-1" align="center" valign="middle">工序名称</td>-->
+        <td class="col-1" align="center" valign="middle" style="width: 30px;">数量</td>
+<!--        <td class="col-1" align="center" valign="middle" style="width: 13px;">箱数</td>-->
+        <td class="col-1" align="center" valign="middle" style="width: 100px;"> 发出箱号</td>
+        <td class="col-1" align="center" valign="middle" style="width: 60px;">备注</td>
+    </tr>
+
+    <!-- 动态数据行 -->
+    <#list detail as item>
+    <tr class=" border">
+        <td class="col-1" align="center">${ item_index + 1 }</td>
+        <td class="col-1" style="text-align: left;">
+            <#if item.productDescription??>
+            ${ item.productDescription}
+            <#else>
+
+            </#if>
+        </td>
+        <td class="col-1" style="text-align: left;" >
+            <#if item.lotCode??>
+            ${ item.lotCode }
+            <#else>
+
+        </#if>
+        </td>
+<!--        <td class="col-1" style="text-align: left;" >-->
+<!--            <#if item.processAlias??>-->
+<!--            ${ item.processAlias }-->
+<!--            <#else>-->
+
+<!--        </#if>-->
+<!--        </td>-->
+        <td class="col-1" style=" text-align: right;" >
+            <#if item.receiptNum??>
+            ${ item.receiptNum }
+            <#else>
+
+        </#if>
+           </td>
+<!--        <td class="col-1" >-->
+<!--            <#if item.originalCarrierCount??>-->
+<!--            ${ item.originalCarrierCount }-->
+<!--            <#else>-->
+
+<!--        </#if>-->
+<!--            </td>-->
+        <td class="col-1" style="text-align: left;">
+            <#if item.newCarrier??>
+            ${ item.newCarrier }
+            <#else>
+
+        </#if>
+       </td>
+        <td class="col-1" style="text-align: left;" >
+            <#if item.remark??>
+            ${ item.remark }
+            <#else>
+
+        </#if>
+        </td>
+
+    </tr>
+    </#list>
+<!--小计行-->
+<tr class="total-row border">
+    <td class="col-1" align="center" colspan="1"></td>
+    <td class="col-1" align="center" colspan="1">小计</td>
+    <!-- 这里根据实际计算结果填充 -->
+    <td class="col-1" align="center" colspan="1"></td>
+<!--    <td class="col-1" align="center" colspan="1"></td>-->
+    <td class="col-1" align="center" colspan="1" style=" text-align: right;">${detail[0].sum}</td>
+<!--    <td class="col-1" align="center" colspan="1"></td>-->
+    <td class="col-1" align="center" colspan="1"></td>
+    <td class="col-1" align="center" colspan="1"></td>
+    <!-- ... 类似地填充剩余单元格 -->
+</tr>
+</table>
+<div class="title-row"  style="margin-bottom: 30px">
+    <div class="center-align"  style="margin-left: 60px;padding-right: 90px">外协发出人:</div>
+    <div class="center-align"  style="margin-left: 60px;padding-right: 120px">搬运接收人:</div>
+    <div class="left-align" style="margin-right: 15px">白-存根, 粉-外协, 黄-结算</div>
+</div>
+</body>
+</#list>
+</html>