feat(wms): 添加发货单Word导出功能

- 在服务接口中新增方法,组装Word导出所需数据
- 引入ruoyi-common-word依赖支持Word模板处理
- 控制器中实现导出接口,基于poi-tl模板引擎生成Word文件
- 组装导出数据包含主表字段及明细列表,支持模板循环渲染
- 文件名使用发货单号,增强导出文件识别性
- 增加操作日志记录,权限检查保障安全性
dev
zangch@mesnac.com 6 days ago
parent e6b4dbf55e
commit de99872347

@ -108,6 +108,12 @@
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-bus</artifactId>
</dependency>
<!-- Word模板导出 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-word</artifactId>
</dependency>
</dependencies>
<build>

@ -15,6 +15,7 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.word.util.WordTemplateUtil;
import org.dromara.wms.domain.bo.WmsShippingBillBo;
import org.dromara.wms.domain.vo.WmsShippingBillVo;
import org.dromara.wms.service.IWmsShippingBillService;
@ -22,6 +23,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
*
@ -125,4 +127,26 @@ public class WmsShippingBillController extends BaseController {
return R.ok(wmsShippingBillService.shippingBillSubmitAndFlowStart(bo));
}
/**
* Word
* 使poi-tl.docxWord
*
* @param shippingBillId ID
* @param response HttpServletResponse
*/
@SaCheckPermission("wms:wmsShippingBill:export")
@Log(title = "发货单Word导出", businessType = BusinessType.EXPORT)
@GetMapping("/exportWord/{shippingBillId}")
public void exportWord(@NotNull(message = "发货单ID不能为空")
@PathVariable("shippingBillId") Long shippingBillId,
HttpServletResponse response) {
// 组装模板数据
Map<String, Object> data = wmsShippingBillService.buildWordExportData(shippingBillId);
// 生成文件名(发货单号)
WmsShippingBillVo vo = wmsShippingBillService.queryById(shippingBillId);
String fileName = "发货单_" + (vo != null && vo.getShippingCode() != null ? vo.getShippingCode() : shippingBillId);
// 渲染并输出Word文档模板路径为classpath根目录
WordTemplateUtil.renderToResponse("发货单模板.docx", fileName, data, response);
}
}

@ -73,4 +73,12 @@ public interface IWmsShippingBillService {
* @return VO
*/
WmsShippingBillVo shippingBillSubmitAndFlowStart(WmsShippingBillBo bo);
/**
* Word
*
* @param shippingBillId ID
* @return WordMap
*/
java.util.Map<String, Object> buildWordExportData(Long shippingBillId);
}

@ -34,10 +34,8 @@ import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -336,4 +334,79 @@ public class WmsShippingBillServiceImpl implements IWmsShippingBillService {
baseMapper.updateById(shippingBill);
});
}
/**
* Word
* <p>
* {@code word.md} poi-tl 使
*
* <ul>
* <li> customerNamereceiverNamereceiverPhoneshippingDatecontractCode Word
* {{customerName}}{{receiverName}}{{receiverPhone}}{{shippingDate}}{{contractCode}} </li>
* <li>使 {@code details} seqmaterialNamequantityunitremark
* Word {{seq}}{{materialName}}{{quantity}}{{unit}}{{remark}}</li>
* </ul>
*
* @param shippingBillId ID
* @return Word Map {@link org.dromara.common.word.util.WordTemplateUtil}
*/
@Override
public Map<String, Object> buildWordExportData(Long shippingBillId) {
// 查询发货单(包含明细列表)
WmsShippingBillVo vo = queryById(shippingBillId);
if (vo == null) {
throw new ServiceException("发货单不存在ID" + shippingBillId);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Map<String, Object> data = new HashMap<>();
// === 主表字段 ===
// 客户名称
data.put("customerName", StringUtils.blankToDefault(vo.getCustomerName(), ""));
// 收货联系人(客户侧)
data.put("receiverName", StringUtils.blankToDefault(vo.getReceiverName(), ""));
// 收货联系电话(客户侧)
data.put("receiverPhone", StringUtils.blankToDefault(vo.getReceiverPhone(), ""));
// 发货日期(实际发货时间)
data.put("shippingDate", vo.getShippingTime() != null ? sdf.format(vo.getShippingTime()) : "");
// 合同编号
data.put("contractCode", StringUtils.blankToDefault(vo.getContractCode(), ""));
// 收货日期(留空,由客户签收时填写)
data.put("receivedDate", "");
// === 落款信息(供应商/发货方) ===
// 发货单位(供应商名称)
data.put("shippingUnit", StringUtils.blankToDefault(vo.getSupplier(), ""));
// 发货人(供应商联系人)
data.put("shipper", StringUtils.blankToDefault(vo.getContactUser(), ""));
// 发货方联系电话
data.put("contactNumber", StringUtils.blankToDefault(vo.getContactNumber(), ""));
// === 明细列表 ===
// 对应 Word 模板中的 {{#details}}...{{/details}} 循环表格:
// - seq → {{seq}} (行号)
// - materialName → {{materialName}}(物料名称)
// - quantity → {{quantity}} (发货数量)
// - unit → {{unit}} (计量单位)
// - remark → {{remark}} (备注)
// 如需在模板中添加单价、金额、合计行等字段,可在此处扩展 row 中的字段,并在 data 中追加 totalQuantity、totalAmount 等汇总字段。
List<Map<String, Object>> details = new ArrayList<>();
List<WmsShippingDetailsVo> itemsVo = vo.getItemsVo();
if (CollUtil.isNotEmpty(itemsVo)) {
int seq = 1;
for (WmsShippingDetailsVo item : itemsVo) {
Map<String, Object> row = new HashMap<>();
row.put("seq", String.valueOf(seq++));
row.put("materialName", StringUtils.blankToDefault(item.getMaterialName(), ""));
row.put("quantity", item.getShippingStockAmount() != null ? item.getShippingStockAmount().toPlainString() : "");
row.put("unit", StringUtils.blankToDefault(item.getUnitName(), ""));
row.put("remark", StringUtils.blankToDefault(item.getRemark(), ""));
details.add(row);
}
}
// poi-tl 列表占位符,对应 Word 模板中的 {{#details}}...{{/details}}
data.put("details", details);
return data;
}
}

Loading…
Cancel
Save