yuan
11 小时以前 816e5b54488621cf3bf57b770641f167190b5b43
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -20,6 +20,7 @@
import com.ruoyi.basic.utils.FileUtil;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -51,6 +52,10 @@
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
@@ -60,8 +65,11 @@
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -647,4 +655,102 @@
        }
        return sb.toString();
    }
    @Override
    public void exportPurchaseOrderDocx(HttpServletResponse response, Long id) {
        // 1. 查询主表数据
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
        if (purchaseLedger == null) {
            throw new BaseException("采购台账不存在");
        }
        // 2. 查询产品列表
        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId())
                .eq(SalesLedgerProduct::getType, 2);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
        // 3. 查询供应商信息
        SupplierManage supplier = null;
        if (purchaseLedger.getSupplierId() != null) {
            supplier = supplierManageMapper.selectById(purchaseLedger.getSupplierId());
        }
        // 4. 计算合计金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (SalesLedgerProduct product : products) {
            if (product.getTaxInclusiveTotalPrice() != null) {
                totalAmount = totalAmount.add(product.getTaxInclusiveTotalPrice());
            }
        }
        // 5. 加载模板
        InputStream inputStream = this.getClass().getResourceAsStream("/static/purchase-order-template.docx");
        if (inputStream == null) {
            throw new BaseException("采购订单模板文件不存在");
        }
        // 6. 配置 poi-tl(产品列表使用 HackLoopTableRenderPolicy,onSameLine=true 因为标签和字段在同一行)
        Configure configure = Configure.builder()
                .bind("productList", new HackLoopTableRenderPolicy(true))
                .build();
        // 7. 格式化日期
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String orderDate = "";
        String signDate = "";
        if (purchaseLedger.getExecutionDate() != null) {
            orderDate = dateFormatter.format(purchaseLedger.getExecutionDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
            signDate = orderDate;
        } else if (purchaseLedger.getEntryDate() != null) {
            orderDate = dateFormatter.format(purchaseLedger.getEntryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
            signDate = orderDate;
        }
        // 8. 组装模板数据
        Map<String, Object> data = new HashMap<>();
        data.put("orderDate", orderDate);
        data.put("purchaseContractNumber", purchaseLedger.getPurchaseContractNumber() != null ? purchaseLedger.getPurchaseContractNumber() : "");
        data.put("supplierName", purchaseLedger.getSupplierName() != null ? purchaseLedger.getSupplierName() : "");
        data.put("contactUserName", supplier != null && supplier.getContactUserName() != null ? supplier.getContactUserName() : "");
        data.put("contactPhone", supplier != null && supplier.getContactUserPhone() != null ? supplier.getContactUserPhone() : "");
        data.put("fax", supplier != null && supplier.getCompanyPhone() != null ? supplier.getCompanyPhone() : "");
        data.put("supplierAddress", supplier != null && supplier.getCompanyAddress() != null ? supplier.getCompanyAddress() : "");
        // 给产品列表添加序号
        List<Map<String, Object>> productList = new ArrayList<>();
        int seq = 1;
        for (SalesLedgerProduct p : products) {
            Map<String, Object> map = new HashMap<>();
            map.put("index", seq++);
            map.put("productCategory", p.getProductCategory());
            map.put("specificationModel", p.getSpecificationModel());
            map.put("unit", p.getUnit());
            map.put("quantity", p.getQuantity());
            map.put("taxInclusiveUnitPrice", p.getTaxInclusiveUnitPrice());
            map.put("taxInclusiveTotalPrice", p.getTaxInclusiveTotalPrice());
            productList.add(map);
        }
        data.put("productList", productList);
        data.put("totalAmount", totalAmount.setScale(2, RoundingMode.HALF_UP).toString());
        data.put("totalAmountChinese", Convert.digitUppercase(totalAmount.doubleValue()));
        data.put("signDate", signDate);
        // 9. 渲染模板并输出
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(data);
        try {
            response.setContentType("application/msword");
            String fileName = URLEncoder.encode("采购订单", StandardCharsets.UTF_8);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx");
            OutputStream os = response.getOutputStream();
            template.write(os);
            os.flush();
            os.close();
            template.close();
            inputStream.close();
        } catch (Exception e) {
            log.error("导出采购订单失败", e);
            throw new BaseException("导出采购订单失败:" + e.getMessage());
        }
    }
}