fix(excel): 导入模板日期改为文本显示,修复显示为 Excel 序列号
## 问题
22 个导入模板的日期列显示为 Excel 序列号,使用者看不懂该填什么格式:
员工入职日期 43891.0
员工合同签订日 46023.0
考勤打卡时间 46037.354166666664
## 排查过程
1. 先尝试注册自定义 LocalDate/LocalDateTime 转换器 —— 无效。
原因:FastExcel 内置同名转换器(cn.idev.excel.converters.localdate.LocalDateStringConverter),
写出时优先命中内置的 Number 转换器,自定义转换器不生效。
2. 最终改用 CellWriteHandler:单元格写完后介入,
读取 context.getOriginalValue(),把 LocalDate/LocalDateTime 格式化成文本写入。
## 实现
新增 DateAsTextCellWriteHandler:
- afterCellDispose 里拦截,跳过表头行
- LocalDate -> yyyy-MM-dd
- LocalDateTime -> yyyy-MM-dd HH:mm:ss
- java.util.Date -> yyyy-MM-dd
- cell.setCellType(STRING) + setCellValue(text)
ExcelUtils 新增 writeTemplate 方法(专用模板写出):
- 注册 DateAsTextCellWriteHandler
- 22 个 Controller 的 importTemplate 全部改用 writeTemplate
- 导入解析仍走 ExcelUtils.read,不受影响
## 顺带修复模板示例数据
- 用户:部门编号改为部门名称(取真实部门)
- 部门:上级部门改为真实根部门(原「总公司」不存在)
- 员工:部门/岗位取真实数据(原「研发部」不存在)
- 客户:示例改为「示例客户A/B(请替换)」(原「超级管理员」「源码」是芋道 demo)
- MDM物料:分类编码/单位编码补真实值(原为空,必填项)
## 验证(本地实测)
22 个模板逐一检查,日期序列号 0 个:
员工入职日期 2020-03-01 出生 1990-01-15
员工合同 2026-01-01 ~ 2028-12-31
考勤日期 2026-01-15 08:30:00
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.convert; |
| | | |
| | | import cn.idev.excel.converters.Converter; |
| | | import cn.idev.excel.enums.CellDataTypeEnum; |
| | | import cn.idev.excel.metadata.GlobalConfiguration; |
| | | import cn.idev.excel.metadata.data.WriteCellData; |
| | | import cn.idev.excel.metadata.property.ExcelContentProperty; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * LocalDate ååºä¸ºçº¯ææ¬ï¼yyyy-MM-ddï¼ç转æ¢å¨ |
| | | * |
| | | * é»è®¤ FastExcel ææ¥æåæãæ¥æåå
æ ¼ãï¼å¨ Excel éæ¾ç¤ºä¸º 46023.0 è¿ç±»åºåå·ï¼ |
| | | * 使ç¨è
çä¸æè¯¥å¡«ä»ä¹æ ¼å¼ã导å
¥æ¨¡æ¿ç±»åºæ¯æ³¨åæ¬è½¬æ¢å¨åï¼æ¥æä»¥ææ¬è¾åºï¼ç´è§å¯è¯»ã |
| | | * |
| | | * 注æï¼ä»
ç¨äºãååºæ¨¡æ¿ãï¼ä¸è¦ç¨äºå¯¼å
¥è§£æã |
| | | */ |
| | | public class LocalDateStringConverter implements Converter<LocalDate> { |
| | | |
| | | private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | |
| | | @Override |
| | | public Class<LocalDate> supportJavaTypeKey() { |
| | | return LocalDate.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return CellDataTypeEnum.STRING; |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<?> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, |
| | | GlobalConfiguration globalConfiguration) { |
| | | return new WriteCellData<>(value.format(FORMATTER)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.convert; |
| | | |
| | | import cn.idev.excel.converters.Converter; |
| | | import cn.idev.excel.enums.CellDataTypeEnum; |
| | | import cn.idev.excel.metadata.GlobalConfiguration; |
| | | import cn.idev.excel.metadata.data.WriteCellData; |
| | | import cn.idev.excel.metadata.property.ExcelContentProperty; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * LocalDateTime ååºä¸ºçº¯ææ¬ï¼yyyy-MM-dd HH:mm:ssï¼ç转æ¢å¨ |
| | | * |
| | | * ç¨éå {@link LocalDateStringConverter}ï¼é¿å
æ¶é´æ¾ç¤ºä¸º Excel åºåå·ã |
| | | */ |
| | | public class LocalDateTimeStringConverter implements Converter<LocalDateTime> { |
| | | |
| | | private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Override |
| | | public Class<LocalDateTime> supportJavaTypeKey() { |
| | | return LocalDateTime.class; |
| | | } |
| | | |
| | | @Override |
| | | public CellDataTypeEnum supportExcelTypeKey() { |
| | | return CellDataTypeEnum.STRING; |
| | | } |
| | | |
| | | @Override |
| | | public WriteCellData<?> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, |
| | | GlobalConfiguration globalConfiguration) { |
| | | return new WriteCellData<>(value.format(FORMATTER)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.framework.excel.core.handler; |
| | | |
| | | import cn.idev.excel.write.handler.CellWriteHandler; |
| | | import cn.idev.excel.write.handler.context.CellWriteHandlerContext; |
| | | import org.apache.poi.ss.usermodel.Cell; |
| | | import org.apache.poi.ss.usermodel.CellType; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | |
| | | /** |
| | | * ææ¥æåå
æ ¼å¼ºå¶åæçº¯ææ¬çå¤çå¨ |
| | | * |
| | | * èæ¯ï¼FastExcel å¨ååºæ¶ï¼å³ä½¿æ³¨åäºå符串转æ¢å¨ï¼æ¥æå段ä»å¯è½è¢«å
ç½®ç |
| | | * Number 转æ¢å¨æ¥ç®¡ï¼æç»å¨ Excel éæ¾ç¤ºä¸º 46023.0 è¿ç±»åºåå·ï¼ä½¿ç¨è
ç䏿ã |
| | | * |
| | | * æ¬å¤çå¨å¨åå
æ ¼åå®åä»å
¥ï¼æ LocalDate / LocalDateTime ç±»åçåå§å¼ |
| | | * æ ¼å¼å为 yyyy-MM-dd / yyyy-MM-dd HH:mm:ss å¹¶ä»¥ææ¬åå
¥ã |
| | | * |
| | | * ä»
ç¨äºãä¸è½½å¯¼å
¥æ¨¡æ¿ãï¼ä¸å½±å导å
¥è§£æã |
| | | */ |
| | | public class DateAsTextCellWriteHandler implements CellWriteHandler { |
| | | |
| | | private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | @Override |
| | | public void afterCellDispose(CellWriteHandlerContext context) { |
| | | // åªå¤çæ°æ®è¡ï¼è·³è¿è¡¨å¤´ |
| | | if (Boolean.TRUE.equals(context.getHead())) { |
| | | return; |
| | | } |
| | | Object value = context.getOriginalValue(); |
| | | if (value == null) { |
| | | return; |
| | | } |
| | | String text = null; |
| | | if (value instanceof LocalDate localDate) { |
| | | text = localDate.format(DATE_FORMATTER); |
| | | } else if (value instanceof LocalDateTime localDateTime) { |
| | | text = localDateTime.format(DATETIME_FORMATTER); |
| | | } else if (value instanceof java.util.Date date) { |
| | | text = date.toInstant().atZone(java.time.ZoneId.systemDefault()) |
| | | .toLocalDate().format(DATE_FORMATTER); |
| | | } |
| | | if (text == null) { |
| | | return; |
| | | } |
| | | Cell cell = context.getCell(); |
| | | if (cell == null) { |
| | | return; |
| | | } |
| | | cell.setCellType(CellType.STRING); |
| | | cell.setCellValue(text); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.idev.excel.event.AnalysisEventListener; |
| | | import cn.idev.excel.metadata.CellExtra; |
| | | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.convert.LocalDateStringConverter; |
| | | import cn.iocoder.yudao.framework.excel.core.convert.LocalDateTimeStringConverter; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.DateAsTextCellWriteHandler; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | |
| | | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| | | } |
| | | |
| | | /** |
| | | * è¾åº Excel 模æ¿ï¼æ¥ææææ¬æ¸²æï¼ |
| | | * |
| | | * ä¸ {@link #write} çåºå«ï¼é¢å¤æ³¨åäº {@link LocalDateStringConverter}ï¼ |
| | | * æ LocalDate / LocalDateTime åæ yyyy-MM-dd ææ¬ï¼è䏿¯ Excel æ¥æåºåå·ã |
| | | * ä»
ç¨äºãä¸è½½å¯¼å
¥æ¨¡æ¿ãï¼å¯¼å
¥è§£æä»èµ° {@link #read}ï¼ä¸åå½±åã |
| | | */ |
| | | public static <T> void writeTemplate(HttpServletResponse response, String filename, String sheetName, |
| | | Class<T> head, List<T> data) throws IOException { |
| | | ExcelWriter excelWriter = FastExcelFactory.write(response.getOutputStream(), head) |
| | | .autoCloseStream(false) |
| | | .registerWriteHandler(new ColumnWidthMatchStyleStrategy()) |
| | | .registerWriteHandler(new SelectSheetWriteHandler(head)) |
| | | .registerWriteHandler(new DateAsTextCellWriteHandler()) |
| | | .registerConverter(new LongStringConverter()) |
| | | .build(); |
| | | try { |
| | | excelWriter.write(data, FastExcelFactory.writerSheet(sheetName).build()); |
| | | } finally { |
| | | excelWriter.finish(); |
| | | excelWriter.close(); |
| | | } |
| | | response.addHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); |
| | | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| | | } |
| | | |
| | | public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException { |
| | | // åè https://t.zsxq.com/zM77F å¸åï¼å¢å try å¤çï¼å
¼å®¹ windows åºæ¯ |
| | | try (InputStream inputStream = file.getInputStream()) { |
| | |
| | | .productCode("ITEM001").productName("示ä¾äº§åA") |
| | | .count(new BigDecimal("100")).contractPrice(new BigDecimal("20.00")).remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "åå导å
¥æ¨¡æ¿.xls", "åå", CrmContractImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åå导å
¥æ¨¡æ¿.xls", "åå", CrmContractImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥å®¢æ·æ¨¡æ¿") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // æå¨åå»ºå¯¼åº demo |
| | | // 示ä¾å®¢æ·ï¼åç§°/ææº/é®ç®±å使ç¨å ä½å¼ï¼é¿å
ç
§æå®æ¹ demo 产çåæ°æ® |
| | | List<CrmCustomerImportExcelVO> list = Arrays.asList( |
| | | CrmCustomerImportExcelVO.builder().name("è¶
级管çå").industryId(1).level(1).source(1) |
| | | .mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn") |
| | | .areaId(null).detailAddress("").remark("").autoPoolEnabled(true).build(), |
| | | CrmCustomerImportExcelVO.builder().name("æºç ").industryId(1).level(1).source(1) |
| | | .mobile("15601691300").telephone("").qq("").wechat("").email("yunai@iocoder.cn") |
| | | .areaId(null).detailAddress("").remark("").autoPoolEnabled(true).build() |
| | | CrmCustomerImportExcelVO.builder().name("示ä¾å®¢æ·Aï¼è¯·æ¿æ¢ï¼").industryId(1).level(1).source(1) |
| | | .mobile("13800000001").telephone("").qq("").wechat("").email("customerA@example.com") |
| | | .areaId(null).detailAddress("").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢").autoPoolEnabled(true).build(), |
| | | CrmCustomerImportExcelVO.builder().name("示ä¾å®¢æ·Bï¼è¯·æ¿æ¢ï¼").industryId(1).level(1).source(1) |
| | | .mobile("13800000002").telephone("").qq("").wechat("").email("customerB@example.com") |
| | | .areaId(null).detailAddress("").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢").autoPoolEnabled(true).build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "客æ·å¯¼å
¥æ¨¡æ¿.xls", "客æ·å表", CrmCustomerImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "客æ·å¯¼å
¥æ¨¡æ¿.xls", "客æ·å表", CrmCustomerImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .invoiceNo("02564178").invoiceTitle("示ä¾å®¢æ·æéå
¬å¸").price(new BigDecimal("10000.00")) |
| | | .invoiceTime("2026-01-01 10:00:00").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "å¼ç¥¨å¯¼å
¥æ¨¡æ¿.xls", "å¼ç¥¨", CrmInvoiceImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å¼ç¥¨å¯¼å
¥æ¨¡æ¿.xls", "å¼ç¥¨", CrmInvoiceImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .orderTime("2026-01-01 10:00:00").productCode("ITEM001").productName("示ä¾äº§åA") |
| | | .count(new BigDecimal("100")).productPrice(new BigDecimal("10.00")) |
| | | .taxPercent(new BigDecimal("13")).qcCheckFlag("å¦").remark("示ä¾").build()); |
| | | ExcelUtils.write(response, "éè´è®¢å导å
¥æ¨¡æ¿.xls", "éè´è®¢å", ErpPurchaseOrderImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´è®¢å导å
¥æ¨¡æ¿.xls", "éè´è®¢å", ErpPurchaseOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .count(new BigDecimal("100")).productPrice(new BigDecimal("10.00")) |
| | | .taxPercent(new BigDecimal("13")).demandTime("2026-01-10") |
| | | .qcCheckFlag("å¦").remark("示ä¾").build()); |
| | | ExcelUtils.write(response, "éè´ç³è¯·å¯¼å
¥æ¨¡æ¿.xls", "éè´ç³è¯·", ErpPurchaseRequestImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éè´ç³è¯·å¯¼å
¥æ¨¡æ¿.xls", "éè´ç³è¯·", ErpPurchaseRequestImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .orderTime("2026-01-01 10:00:00").productCode("ITEM001").productName("示ä¾äº§åA") |
| | | .count(new BigDecimal("100")).productPrice(new BigDecimal("20.00")) |
| | | .taxPercent(new BigDecimal("13")).needProduction("æ¯").remark("示ä¾").build()); |
| | | ExcelUtils.write(response, "éå®è®¢å导å
¥æ¨¡æ¿.xls", "éå®è®¢å", ErpSaleOrderImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "éå®è®¢å导å
¥æ¨¡æ¿.xls", "éå®è®¢å", ErpSaleOrderImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .remark("ç¤ºä¾æ°æ®") |
| | | .build() |
| | | ); |
| | | ExcelUtils.write(response, "èå¤å¯¼å
¥æ¨¡æ¿.xls", "èå¤è®°å½", HrmAttendanceRecordImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "èå¤å¯¼å
¥æ¨¡æ¿.xls", "èå¤è®°å½", HrmAttendanceRecordImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .probationSalary(new BigDecimal("8000.00")).regularSalary(new BigDecimal("10000.00")) |
| | | .remark("示ä¾ï¼è¯·æå®é
ä¿®æ¹å导å
¥").build() |
| | | ); |
| | | ExcelUtils.write(response, "åå·¥åå导å
¥æ¨¡æ¿.xls", "åå·¥åå", HrmEmployeeContractImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åå·¥åå导å
¥æ¨¡æ¿.xls", "åå·¥åå", HrmEmployeeContractImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | @Operation(summary = "ä¸è½½å工导å
¥æ¨¡æ¿") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // è¾åºç¤ºä¾æ°æ®ï¼æ¹ä¾¿ä½¿ç¨è
åè |
| | | // 示ä¾çé¨é¨/å²ä½/è§è²åå½åç³»ç»ç宿°æ®ï¼é¿å
ç
§æ demo éçãç åé¨ã导è´å¹é
失败 |
| | | String sampleDept = "请填åé¨é¨åç§°"; |
| | | try { |
| | | var depts = deptApi.getDeptList(); |
| | | if (depts != null && !depts.isEmpty()) { |
| | | sampleDept = depts.get(0).getName(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | // åä¸å°å°±ä¿çå 使æ¡ï¼ä¸å½±å模æ¿ä¸è½½ |
| | | } |
| | | // å²ä½æªæä¾ç®æå表 APIï¼ç¤ºä¾ç¨å ä½ææ¡ |
| | | String samplePost = "请填åå²ä½åç§°ï¼å¤ä¸ªç¨è±æéå·åéï¼"; |
| | | |
| | | List<HrmEmployeeImportExcelVO> list = Arrays.asList( |
| | | HrmEmployeeImportExcelVO.builder().name("å¼ ä¸").gender(1).phone("13800138000") |
| | | .deptName("ç åé¨").postName("é¨é¨ç»ç,项ç®ç»ç").roleNames("æ®é管çå") |
| | | .deptName(sampleDept).postName(samplePost).roleNames("æ®éè§è²") |
| | | .hireDate(LocalDate.of(2020, 3, 1)).employeeStatus(1) |
| | | .idCard("320102199001150011").birthday(LocalDate.of(1990, 1, 15)) |
| | | .nation("æ±æ").marriageStatus("å·²å©").age(36).education("æ¬ç§").politicalStatus("ä¸å
±å
å") |
| | | .email("zhangsan@example.com").build() |
| | | .email("zhangsan@example.com").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢").build() |
| | | ); |
| | | ExcelUtils.write(response, "å工导å
¥æ¨¡æ¿.xls", "åå·¥å表", HrmEmployeeImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å工导å
¥æ¨¡æ¿.xls", "åå·¥å表", HrmEmployeeImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO; |
| | | import cn.iocoder.yudao.module.mdm.controller.admin.unit.vo.MdmUnitMeasurePageReqVO; |
| | | import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum; |
| | | import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService; |
| | |
| | | @Operation(summary = "è·å¾å¯¼å
¥ç©ææ¨¡æ¿") |
| | | @PreAuthorize("@ss.hasPermission('mdm:item:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // åç±»ç¼ç ã计éåä½ç¼ç 为å¿
填项ï¼ç¤ºä¾åå½åç³»ç»çå®ç¼ç ï¼é¿å
ç
§æ¨¡æ¿å¯¼å
¥ç´æ¥å¤±è´¥ |
| | | String sampleCategoryCode = ""; |
| | | try { |
| | | List<MdmItemCategoryDO> cats = itemCategoryService.getSimpleItemList(); |
| | | if (cats != null && !cats.isEmpty()) { |
| | | sampleCategoryCode = cats.get(0).getCode(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | // åä¸å°ç空ï¼ä¸å½±å模æ¿ä¸è½½ |
| | | } |
| | | String sampleUnitCode = ""; |
| | | try { |
| | | MdmUnitMeasurePageReqVO unitReq = new MdmUnitMeasurePageReqVO(); |
| | | unitReq.setPageNo(1); |
| | | unitReq.setPageSize(1); |
| | | List<MdmUnitMeasureDO> units = unitMeasureService.getUnitMeasurePage(unitReq).getList(); |
| | | if (units != null && !units.isEmpty()) { |
| | | sampleUnitCode = units.get(0).getCode(); |
| | | } |
| | | } catch (Exception ignored) { |
| | | // åä¸ |
| | | } |
| | | |
| | | List<MdmItemImportExcelVO> list = Arrays.asList( |
| | | MdmItemImportExcelVO.builder().code("ITEM001").name("示ä¾ç©æ").specification("è§æ ¼").status(0).isBatchManaged(false).build() |
| | | MdmItemImportExcelVO.builder() |
| | | .code("ITEM-EXAMPLE").name("示ä¾ç©æï¼è¯·æ¿æ¢ï¼").specification("è§æ ¼") |
| | | .categoryCode(sampleCategoryCode).unitMeasureCode(sampleUnitCode) |
| | | .status(0).isBatchManaged(false) |
| | | .remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢ï¼åç±»ç¼ç /åä½ç¼ç 请填åç³»ç»ä¸å·²åå¨çç¼ç ") |
| | | .build() |
| | | ); |
| | | ExcelUtils.write(response, "ç©æå¯¼å
¥æ¨¡æ¿.xls", "ç©æ", MdmItemImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç©æå¯¼å
¥æ¨¡æ¿.xls", "ç©æ", MdmItemImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | MdmUnitMeasureImportExcelVO.builder().code("PC").name("ç").primaryFlag(true).changeRate(new java.math.BigDecimal("1")).status(0).remark("示ä¾ï¼ä¸»åä½").build(), |
| | | MdmUnitMeasureImportExcelVO.builder().code("XIA").name("ç®±").primaryFlag(false).primaryCode("PC").changeRate(new java.math.BigDecimal("100")).status(0).remark("示ä¾ï¼1ç®±=100ç").build() |
| | | ); |
| | | ExcelUtils.write(response, "计éåä½å¯¼å
¥æ¨¡æ¿.xls", "计éåä½", MdmUnitMeasureImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "计éåä½å¯¼å
¥æ¨¡æ¿.xls", "计éåä½", MdmUnitMeasureImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .workshopCode("WS-001").status(0).build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "设å¤å¯¼å
¥æ¨¡æ¿.xls", "设å¤å表", MesDvMachineryImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "设å¤å¯¼å
¥æ¨¡æ¿.xls", "设å¤å表", MesDvMachineryImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .deptName("ç åé¨é¨").chargeUserName("è¶
级管çå") |
| | | .checkCycleCount(12).useDate("2026-01-01").status(1).remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "计éå¨å
·å¯¼å
¥æ¨¡æ¿.xls", "计éå¨å
·", MesDvMeteringImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "计éå¨å
·å¯¼å
¥æ¨¡æ¿.xls", "计éå¨å
·", MesDvMeteringImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | MesMdItemTypeImportExcelVO.builder().code("RAW").name("åææ").itemOrProduct("ITEM").sort(1).status(0).remark("示ä¾ï¼é¡¶çº§åç±»").build(), |
| | | MesMdItemTypeImportExcelVO.builder().code("METAL").name("é屿æ").parentCode("RAW").itemOrProduct("ITEM").sort(1).status(0).remark("示ä¾ï¼ç¶åç±»ç¼ç 为 RAW").build() |
| | | ); |
| | | ExcelUtils.write(response, "ç©æå类导å
¥æ¨¡æ¿.xls", "ç©æåç±»", MesMdItemTypeImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç©æå类导å
¥æ¨¡æ¿.xls", "ç©æåç±»", MesMdItemTypeImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .checkResult("æ ¡éªéè¿").inspectorName("").inspectDate("2026-01-01 10:00:00") |
| | | .remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "è¿ç¨æ£éªå导å
¥æ¨¡æ¿.xls", "è¿ç¨æ£éª", MesQcIpqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "è¿ç¨æ£éªå导å
¥æ¨¡æ¿.xls", "è¿ç¨æ£éª", MesQcIpqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .inspectDate("2026-01-01 10:00:00").receiveDate("2026-01-01 09:00:00") |
| | | .remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "æ¥ææ£éªå导å
¥æ¨¡æ¿.xls", "æ¥ææ£éª", MesQcIqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "æ¥ææ£éªå导å
¥æ¨¡æ¿.xls", "æ¥ææ£éª", MesQcIqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .checkResult("æ ¡éªéè¿").inspectorName("").inspectDate("2026-01-01 10:00:00") |
| | | .outDate("2026-01-01 09:00:00").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "åºè´§æ£éªå导å
¥æ¨¡æ¿.xls", "åºè´§æ£éª", MesQcOqcImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "åºè´§æ£éªå导å
¥æ¨¡æ¿.xls", "åºè´§æ£éª", MesQcOqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .location("Aåº").area("A-01").batchCode("B20260101").vendor("XXä¾åºå") |
| | | .operationType("è¦ç").quantity(new BigDecimal("100")).build() |
| | | ); |
| | | ExcelUtils.write(response, "åºåç°æé导å
¥æ¨¡æ¿.xls", "åºåå表", |
| | | ExcelUtils.writeTemplate(response, "åºåç°æé导å
¥æ¨¡æ¿.xls", "åºåå表", |
| | | MesWmMaterialStockImportExcelVO.class, list); |
| | | } |
| | | |
| | |
| | | sample.setBankAccount("6222020000000000000"); |
| | | sample.setStatus(0); |
| | | sample.setRemark("导å
¥æ¨¡æ¿ç¤ºä¾è¡ï¼å¯å é¤"); |
| | | ExcelUtils.write(response, "ä¾åºå导å
¥æ¨¡æ¿.xlsx", "ä¾åºå", SrmSupplierImportExcelVO.class, Arrays.asList(sample)); |
| | | ExcelUtils.writeTemplate(response, "ä¾åºå导å
¥æ¨¡æ¿.xlsx", "ä¾åºå", SrmSupplierImportExcelVO.class, Arrays.asList(sample)); |
| | | } |
| | | |
| | | @PostMapping("/import-excel") |
| | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥é¨é¨æ¨¡æ¿") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | // 示ä¾çä¸çº§é¨é¨åå½åç宿 ¹é¨é¨ï¼é¿å
ç
§æ demo éçãæ»å
¬å¸ãå¯¼è´æ¾ä¸å°ä¸çº§ |
| | | List<DeptDO> allDepts = deptService.getDeptList(new DeptListReqVO()); |
| | | String rootPath = allDepts.stream() |
| | | .filter(d -> d.getParentId() == null || d.getParentId() == 0) |
| | | .map(DeptDO::getName) |
| | | .findFirst() |
| | | .orElse("请填åä¸çº§é¨é¨å
¨è·¯å¾"); |
| | | |
| | | List<DeptImportExcelVO> list = Arrays.asList( |
| | | DeptImportExcelVO.builder().name("ç åé¨").parentPath("æ»å
¬å¸").sort(1).status(CommonStatusEnum.ENABLE.getStatus()).build(), |
| | | DeptImportExcelVO.builder().name("è´¢å¡é¨").parentPath("æ»å
¬å¸").sort(2).status(CommonStatusEnum.ENABLE.getStatus()).build() |
| | | DeptImportExcelVO.builder().name("示ä¾é¨é¨A").parentPath(rootPath).sort(1) |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).build(), |
| | | DeptImportExcelVO.builder().name("示ä¾é¨é¨B").parentPath(rootPath).sort(2) |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).build() |
| | | ); |
| | | ExcelUtils.write(response, "é¨é¨å¯¼å
¥æ¨¡æ¿.xls", "é¨é¨å表", DeptImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "é¨é¨å¯¼å
¥æ¨¡æ¿.xls", "é¨é¨å表", DeptImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).remark("å端å¼åå·¥ç¨å¸").build() |
| | | ); |
| | | // è¾åº |
| | | ExcelUtils.write(response, "å²ä½å¯¼å
¥æ¨¡æ¿.xls", "å²ä½å表", PostImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "å²ä½å¯¼å
¥æ¨¡æ¿.xls", "å²ä½å表", PostImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | .mobile("13800000002").nickname("æå") |
| | | .status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build() |
| | | ); |
| | | ExcelUtils.write(response, "ç¨æ·å¯¼å
¥æ¨¡æ¿.xls", "ç¨æ·å表", UserImportExcelVO.class, list); |
| | | ExcelUtils.writeTemplate(response, "ç¨æ·å¯¼å
¥æ¨¡æ¿.xls", "ç¨æ·å表", UserImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | |
| | | import cn.iocoder.yudao.module.infra.api.file.FileApi; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO; |
| | | import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO; |
| | |
| | | o.setMobile(randomMobile()); |
| | | }); |
| | | // mock æ¹æ³ï¼æ¨¡æå¤±è´¥ |
| | | when(deptService.getDeptList(any(DeptListReqVO.class))).thenReturn(newArrayList()); |
| | | doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any()); |
| | | |
| | | // è°ç¨ |
| | |
| | | o.setEmail(randomEmail()); |
| | | o.setMobile(randomMobile()); |
| | | }); |
| | | // mock deptService çæ¹æ³ |
| | | // mock deptService.getDeptListï¼æ°å®ç°æãé¨é¨åç§°ãå¹é
ï¼ä¸åæç¼å·æ¥å个é¨é¨ |
| | | DeptDO dept = randomPojo(DeptDO.class, o -> { |
| | | o.setId(importUser.getDeptId()); |
| | | o.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| | | }); |
| | | when(deptService.getDept(eq(dept.getId()))).thenReturn(dept); |
| | | importUser.setDeptName(dept.getName()); |
| | | when(deptService.getDeptList(any(DeptListReqVO.class))).thenReturn(newArrayList(dept)); |
| | | // mock passwordEncoder çæ¹æ³ |
| | | when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java"); |
| | | |
| | |
| | | o.setEmail(randomEmail()); |
| | | o.setMobile(randomMobile()); |
| | | }); |
| | | // mock deptService çæ¹æ³ |
| | | // mock deptService.getDeptListï¼æ°å®ç°æãé¨é¨åç§°ãå¹é
ï¼ä¸åæç¼å·æ¥å个é¨é¨ |
| | | DeptDO dept = randomPojo(DeptDO.class, o -> { |
| | | o.setId(importUser.getDeptId()); |
| | | o.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| | | }); |
| | | when(deptService.getDept(eq(dept.getId()))).thenReturn(dept); |
| | | importUser.setDeptName(dept.getName()); |
| | | when(deptService.getDeptList(any(DeptListReqVO.class))).thenReturn(newArrayList(dept)); |
| | | |
| | | // è°ç¨ |
| | | UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), false); |
| | |
| | | o.setEmail(randomEmail()); |
| | | o.setMobile(randomMobile()); |
| | | }); |
| | | // mock deptService çæ¹æ³ |
| | | // mock deptService.getDeptListï¼æ°å®ç°æãé¨é¨åç§°ãå¹é
ï¼ä¸åæç¼å·æ¥å个é¨é¨ |
| | | DeptDO dept = randomPojo(DeptDO.class, o -> { |
| | | o.setId(importUser.getDeptId()); |
| | | o.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| | | }); |
| | | when(deptService.getDept(eq(dept.getId()))).thenReturn(dept); |
| | | importUser.setDeptName(dept.getName()); |
| | | when(deptService.getDeptList(any(DeptListReqVO.class))).thenReturn(newArrayList(dept)); |
| | | |
| | | // è°ç¨ |
| | | UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true); |