金蝶资产卡片
This commit is contained in:
parent
512f5fa908
commit
3318f3e988
@ -20,7 +20,6 @@ import org.springframework.cache.annotation.EnableCaching;
|
|||||||
@MapperScan("com.ruoyi.**.mapper")
|
@MapperScan("com.ruoyi.**.mapper")
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class RuoYiApplication {
|
public class RuoYiApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("spring.devtools.restart.enabled", "false");
|
System.setProperty("spring.devtools.restart.enabled", "false");
|
||||||
SpringApplication application = new SpringApplication(RuoYiApplication.class);
|
SpringApplication application = new SpringApplication(RuoYiApplication.class);
|
||||||
|
|||||||
@ -49,7 +49,8 @@ spring:
|
|||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
||||||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
||||||
url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
#url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
|
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
@ -57,7 +58,8 @@ spring:
|
|||||||
lazy: true
|
lazy: true
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
#url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
|
url: jdbc:mysql://192.168.5.121:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
# oracle:
|
# oracle:
|
||||||
|
|||||||
@ -52,7 +52,8 @@ spring:
|
|||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
|
||||||
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
|
||||||
url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
#url: jdbc:mysql://localhost:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
|
url: jdbc:mysql://192.168.5.121:3306/item_retrieval-evo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
@ -60,7 +61,8 @@ spring:
|
|||||||
lazy: true
|
lazy: true
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
# url: jdbc:mysql://localhost:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
|
url: jdbc:mysql://192.168.5.121:3306/item_retrieval_salve?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: root
|
||||||
# oracle:
|
# oracle:
|
||||||
|
|||||||
@ -30,7 +30,6 @@ server:
|
|||||||
servlet:
|
servlet:
|
||||||
# 应用的访问路径
|
# 应用的访问路径
|
||||||
context-path: /
|
context-path: /
|
||||||
# undertow 配置
|
|
||||||
undertow:
|
undertow:
|
||||||
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
# HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
|
||||||
max-http-post-size: -1
|
max-http-post-size: -1
|
||||||
@ -144,6 +143,12 @@ security:
|
|||||||
- /index/JDList
|
- /index/JDList
|
||||||
- /jmreport/**
|
- /jmreport/**
|
||||||
- /system/procedure/**
|
- /system/procedure/**
|
||||||
|
- /system/dict/data/type/**
|
||||||
|
- /system/proPlan/expiryProjects
|
||||||
|
- /system/proPlan/overdue
|
||||||
|
- /system/proPlan/list2
|
||||||
|
- /system/mrp/**
|
||||||
|
- /system/orderPro/**
|
||||||
|
|
||||||
# MyBatisPlus配置
|
# MyBatisPlus配置
|
||||||
# https://baomidou.com/config/
|
# https://baomidou.com/config/
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.ruoyi;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.FtpUtil;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
@SpringBootTest(classes=RuoYiApplication.class)
|
||||||
|
public class RuoYiTestApplication {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void asfsrfsf() throws FileNotFoundException {
|
||||||
|
FtpUtil.uploadFile("192.168.5.18", 8022, "admin", "hbyt2025", "", "test11/111111111/222222", "33333.dwg", new FileInputStream(new File("D:\\dwg\\111111111111111.dwg")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -173,6 +173,11 @@
|
|||||||
<artifactId>itextpdf</artifactId>
|
<artifactId>itextpdf</artifactId>
|
||||||
<version>5.5.13</version>
|
<version>5.5.13</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-beanutils</groupId>
|
||||||
|
<artifactId>commons-beanutils</artifactId>
|
||||||
|
<version>1.9.4</version>
|
||||||
|
</dependency>
|
||||||
<!-- 离线IP地址定位库 -->
|
<!-- 离线IP地址定位库 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.lionsoul</groupId>
|
<groupId>org.lionsoul</groupId>
|
||||||
|
|||||||
@ -0,0 +1,106 @@
|
|||||||
|
package com.ruoyi.common.convert;
|
||||||
|
|
||||||
|
import com.alibaba.excel.converters.Converter;
|
||||||
|
import com.alibaba.excel.converters.ReadConverterContext;
|
||||||
|
import com.alibaba.excel.converters.WriteConverterContext;
|
||||||
|
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||||
|
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||||
|
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
|
import org.apache.poi.ss.usermodel.RichTextString;
|
||||||
|
|
||||||
|
public class KeepSpaceStringConverter implements Converter<String> {
|
||||||
|
|
||||||
|
private static boolean printedFields = false;
|
||||||
|
@Override
|
||||||
|
public Class<?> supportJavaTypeKey() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CellDataTypeEnum supportExcelTypeKey() {
|
||||||
|
return CellDataTypeEnum.STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToJavaData(ReadConverterContext<?> context) {
|
||||||
|
// 打印所有可用字段(仅第一次)
|
||||||
|
if (!printedFields) {
|
||||||
|
System.out.println("KeepSpaceStringConverter - ReadConverterContext字段:");
|
||||||
|
java.lang.reflect.Field[] fields = context.getClass().getDeclaredFields();
|
||||||
|
for (java.lang.reflect.Field field : fields) {
|
||||||
|
System.out.println(" - " + field.getName() + " (" + field.getType().getSimpleName() + ")");
|
||||||
|
}
|
||||||
|
printedFields = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试通过readCellData字段获取底层的POI Cell
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Field readCellDataField = context.getClass().getDeclaredField("readCellData");
|
||||||
|
readCellDataField.setAccessible(true);
|
||||||
|
ReadCellData<?> readCellData = (ReadCellData<?>) readCellDataField.get(context);
|
||||||
|
|
||||||
|
if (readCellData != null) {
|
||||||
|
// 打印ReadCellData的字段
|
||||||
|
System.out.println("KeepSpaceStringConverter - ReadCellData字段:");
|
||||||
|
java.lang.reflect.Field[] cellDataFields = readCellData.getClass().getDeclaredFields();
|
||||||
|
for (java.lang.reflect.Field field : cellDataFields) {
|
||||||
|
System.out.println(" - " + field.getName() + " (" + field.getType().getSimpleName() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试不同的字段名获取POI Cell
|
||||||
|
String[] possibleFieldNames = {"cell", "poiCell", "xssfCell", "xssfCellData"};
|
||||||
|
|
||||||
|
for (String fieldName : possibleFieldNames) {
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Field cellField = readCellData.getClass().getDeclaredField(fieldName);
|
||||||
|
cellField.setAccessible(true);
|
||||||
|
Object cellObj = cellField.get(readCellData);
|
||||||
|
|
||||||
|
if (cellObj instanceof Cell) {
|
||||||
|
Cell poiCell = (Cell) cellObj;
|
||||||
|
|
||||||
|
if (poiCell.getCellType() == CellType.STRING) {
|
||||||
|
// 直接从POI Cell获取原始数据
|
||||||
|
RichTextString richTextString = poiCell.getRichStringCellValue();
|
||||||
|
String rawValue = richTextString.getString();
|
||||||
|
|
||||||
|
System.out.println("KeepSpaceStringConverter - POI原始数据: '" + rawValue + "'");
|
||||||
|
System.out.println("KeepSpaceStringConverter - POI数据长度: " + rawValue.length());
|
||||||
|
|
||||||
|
// 检查是否包含前后空格
|
||||||
|
if (!rawValue.equals(rawValue.trim())) {
|
||||||
|
System.out.println("KeepSpaceStringConverter - POI检测到前后空格!");
|
||||||
|
} else {
|
||||||
|
System.out.println("KeepSpaceStringConverter - POI没有检测到前后空格");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// 继续尝试下一个字段名
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("KeepSpaceStringConverter - 反射获取ReadCellData失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果反射失败,使用EasyExcel的方法
|
||||||
|
ReadCellData<?> cellData = context.getReadCellData();
|
||||||
|
String easyExcelValue = cellData.getStringValue();
|
||||||
|
System.out.println("KeepSpaceStringConverter - EasyExcel数据: '" + easyExcelValue + "'");
|
||||||
|
System.out.println("KeepSpaceStringConverter - EasyExcel数据长度: " + easyExcelValue.length());
|
||||||
|
|
||||||
|
return easyExcelValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
|
||||||
|
return new WriteCellData<>(context.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.ruoyi.common.poi;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 存放需要导出的动态数据
|
||||||
|
* @Author susu
|
||||||
|
* @Date 2024/2/19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DynamicDataMapping {
|
||||||
|
|
||||||
|
private String dataId;
|
||||||
|
private List<Map<String, Object>> dataList;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 组装只有一个list类型的动态数据
|
||||||
|
* @param dataId
|
||||||
|
* @param dataList
|
||||||
|
* @return java.util.List<com.liu.susu.excel.template.poi.common.DynamicDataMapping>
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static List<DynamicDataMapping> createOneDataList(String dataId, List<Map<String, Object>> dataList) {
|
||||||
|
if (dataList == null)
|
||||||
|
return null;
|
||||||
|
return Collections.singletonList(getDynamicDataMapping(dataId,dataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 组装只有多个list类型的动态数据
|
||||||
|
* @param transMap
|
||||||
|
* @return java.util.List<com.liu.susu.excel.template.poi.common.DynamicDataMapping>
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static List<DynamicDataMapping> createMorDataList(Map<String,List<Map<String, Object>>> transMap) {
|
||||||
|
if (transMap == null)
|
||||||
|
return null;
|
||||||
|
List<DynamicDataMapping> list = new ArrayList<>();
|
||||||
|
transMap.forEach((dataId,dataList)->{
|
||||||
|
list.add(getDynamicDataMapping(dataId,dataList));
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DynamicDataMapping getDynamicDataMapping(String dataId, List<Map<String, Object>> dataList){
|
||||||
|
DynamicDataMapping dynamicData = new DynamicDataMapping();
|
||||||
|
dynamicData.dataId = dataId;
|
||||||
|
dynamicData.dataList = dataList;
|
||||||
|
return dynamicData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,455 @@
|
|||||||
|
package com.ruoyi.common.poi;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.poi.ss.usermodel.CellCopyPolicy;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 根据模版导出Excel程序
|
||||||
|
* @Author susu
|
||||||
|
* @Date 2024/2/19
|
||||||
|
*/
|
||||||
|
public class ExcelTemplateProc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param templateFileName
|
||||||
|
* @param exportFilePathAndName
|
||||||
|
* @param staticDataMap
|
||||||
|
* @param dynamicDataMappingList
|
||||||
|
* @return void
|
||||||
|
* @description: 根据模版导出Excel入口
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static void doExportExcelByTemplateProc(String templateFileName, String exportFilePathAndName,
|
||||||
|
Map<String, Object> staticDataMap,
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList) throws IOException {
|
||||||
|
/**
|
||||||
|
* 1. 从resources下加载模板并替换
|
||||||
|
* 使用 ResourceUtils 加载文件
|
||||||
|
*/
|
||||||
|
File file = ResourceUtils.getFile("classpath:"+templateFileName);
|
||||||
|
InputStream inputStream = new FileInputStream(file);
|
||||||
|
|
||||||
|
Workbook workbook = dealAllSheetsByTemplate(inputStream, staticDataMap, dynamicDataMappingList);
|
||||||
|
// 2. 保存到本地
|
||||||
|
saveExportFile(workbook, exportFilePathAndName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param workbook
|
||||||
|
* @param excelFilePath
|
||||||
|
* @return void
|
||||||
|
* @description: 保存导出的Excel文件到服务器
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static void saveExportFile(Workbook workbook, String excelFilePath) throws IOException {
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(excelFilePath);
|
||||||
|
executeWorkBookWrite(workbook, outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param workbook
|
||||||
|
* @param outputStream
|
||||||
|
* @return void
|
||||||
|
* @description: 数据输出
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static void executeWorkBookWrite(Workbook workbook, OutputStream outputStream) throws IOException {
|
||||||
|
workbook.write(outputStream);
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param inputStream
|
||||||
|
* @param staticDataMap
|
||||||
|
* @param dynamicDataMappingList
|
||||||
|
* @return org.apache.poi.ss.usermodel.Workbook
|
||||||
|
* @description: 处理所有sheet页的模版
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static Workbook dealAllSheetsByTemplate(InputStream inputStream,
|
||||||
|
Map<String, Object> staticDataMap,
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList) throws IOException {
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||||||
|
|
||||||
|
|
||||||
|
// 处理所有sheet页
|
||||||
|
for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
|
||||||
|
XSSFSheet sheet = workbook.getSheetAt(sheetIndex);
|
||||||
|
// 按模板处理sheet页
|
||||||
|
dealSheetDataByTemplate(sheet, staticDataMap, dynamicDataMappingList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param inputStream
|
||||||
|
* @param staticDataMap
|
||||||
|
* @param dynamicDataMappingList
|
||||||
|
* @return org.apache.poi.ss.usermodel.Workbook
|
||||||
|
* @description: 处理只有一个sheet页的模版
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static Workbook dealFirstSheetByTemplate(InputStream inputStream,
|
||||||
|
Map<String, Object> staticDataMap,
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList) throws IOException {
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||||||
|
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||||
|
// 按模板处理sheet页
|
||||||
|
dealSheetDataByTemplate(sheet, staticDataMap, dynamicDataMappingList);
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sheet
|
||||||
|
* @param staticDataMap
|
||||||
|
* @param dynamicDataMappingList
|
||||||
|
* @return void
|
||||||
|
* @description: 按模板处理sheet页里的数据
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/19
|
||||||
|
*/
|
||||||
|
private static void dealSheetDataByTemplate(XSSFSheet sheet, Map<String, Object> staticDataMap, List<DynamicDataMapping> dynamicDataMappingList) {
|
||||||
|
// 循环sheet里每一行
|
||||||
|
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
|
||||||
|
XSSFRow row = sheet.getRow(i);
|
||||||
|
if (row == null) {
|
||||||
|
continue; // 跳过空行
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加调试信息:检查每一行是否有静态数据占位符
|
||||||
|
if (row.getFirstCellNum() != -1 && row.getLastCellNum() != -1) {
|
||||||
|
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell != null) {
|
||||||
|
String cellValue = cell.getStringCellValue();
|
||||||
|
if (cellValue != null && cellValue.contains("{{") && !cellValue.contains(".")) {
|
||||||
|
System.out.println("发现静态数据占位符: 行" + i + ", 列" + j + ", 内容: " + cellValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先处理静态数据,再处理动态数据
|
||||||
|
dealTemplateDataRow(row, null, staticDataMap);
|
||||||
|
|
||||||
|
DynamicDataMapping dynamicDataMapping = getDynamicRowDataByMatch(row, dynamicDataMappingList);
|
||||||
|
if (dynamicDataMapping != null) {
|
||||||
|
i = getTemplateLastRowIndexAfterDealTemplate(sheet, i, dynamicDataMapping);
|
||||||
|
} else {
|
||||||
|
// 检查是否有动态数据占位符但没有匹配的数据映射
|
||||||
|
if (hasDynamicPlaceholders(row) && !hasMatchingDataMapping(row, dynamicDataMappingList)) {
|
||||||
|
// 清理没有数据映射的占位符
|
||||||
|
clearDynamicPlaceholders(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param row
|
||||||
|
* @param dataMap
|
||||||
|
* @param dataPrefix
|
||||||
|
* @return void
|
||||||
|
* @description: 循环处理模版中每行的数据
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
private static void dealTemplateDataRow(XSSFRow row, String dataPrefix, Map<String, Object> dataMap) {
|
||||||
|
if (dataMap == null || row == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstCellNum = row.getFirstCellNum();
|
||||||
|
int lastCellNum = row.getLastCellNum();
|
||||||
|
|
||||||
|
// 检查是否有有效的单元格范围
|
||||||
|
if (firstCellNum == -1 || lastCellNum == -1 || firstCellNum >= lastCellNum) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加调试信息:显示静态数据处理
|
||||||
|
if (dataPrefix == null || dataPrefix.isEmpty()) {
|
||||||
|
System.out.println("开始处理静态数据行: " + row.getRowNum() + ", dataMap=" + dataMap.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = firstCellNum; i < lastCellNum; i++) {
|
||||||
|
XSSFCell cell = row.getCell(i);
|
||||||
|
if (cell != null) {
|
||||||
|
// 添加调试信息:检查静态数据处理
|
||||||
|
if (dataPrefix == null || dataPrefix.isEmpty()) {
|
||||||
|
String cellValue = cell.getStringCellValue();
|
||||||
|
if (cellValue != null && cellValue.contains("{{")) {
|
||||||
|
System.out.println("处理静态数据行,单元格" + i + ": " + cellValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fillInTemplateCellDataValue(cell, dataPrefix, dataMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cell
|
||||||
|
* @param dataPrefix
|
||||||
|
* @param dataMap
|
||||||
|
* @return void
|
||||||
|
* @description: 填充模版里单元格的值
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
private static void fillInTemplateCellDataValue(XSSFCell cell, String dataPrefix, Map<String, Object> dataMap) {
|
||||||
|
if (cell == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String cellValue = cell.getStringCellValue();//获取模版里设置的数据
|
||||||
|
if (StringUtils.isEmpty(cellValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean flag = false;
|
||||||
|
dataPrefix = StringUtils.isEmpty(dataPrefix) ? "" : (dataPrefix + ".");
|
||||||
|
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
|
||||||
|
// 循环所有,因为可能一行有多个占位符
|
||||||
|
String cellTemplateStr = "{{" + dataPrefix + entry.getKey() + "}}";
|
||||||
|
|
||||||
|
|
||||||
|
if (cellValue.contains(cellTemplateStr)) {
|
||||||
|
// 替换模版中单元格的数据
|
||||||
|
String replacementValue = entry.getValue() == null ? "" : entry.getValue().toString();
|
||||||
|
cellValue = cellValue.replace(cellTemplateStr, replacementValue);
|
||||||
|
flag = true;
|
||||||
|
// 添加静态数据替换的调试信息
|
||||||
|
if (dataPrefix == null || dataPrefix.isEmpty()) {
|
||||||
|
System.out.println("静态数据替换: " + cellTemplateStr + " -> " + replacementValue);
|
||||||
|
System.out.println("替换后内容: " + cellValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
cell.setCellValue(cellValue);
|
||||||
|
// 添加调试信息:确认值被设置
|
||||||
|
if (dataPrefix == null || dataPrefix.isEmpty()) {
|
||||||
|
System.out.println("设置单元格值: " + cellValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param row
|
||||||
|
* @param dynamicDataMappingList
|
||||||
|
* @return com.liu.susu.excel.template.poi.common.DynamicDataMapping
|
||||||
|
* @description: 通过模版sheet中的行数据 与 动态数据匹配,获取此行需要填充的动态数据
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/21
|
||||||
|
*/
|
||||||
|
private static DynamicDataMapping getDynamicRowDataByMatch(XSSFRow row, List<DynamicDataMapping> dynamicDataMappingList) {
|
||||||
|
if (dynamicDataMappingList == null || dynamicDataMappingList.size() < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查行是否为空
|
||||||
|
if (row == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstCellNum = row.getFirstCellNum();
|
||||||
|
int lastCellNum = row.getLastCellNum();
|
||||||
|
|
||||||
|
// 检查是否有有效的单元格范围
|
||||||
|
if (firstCellNum == -1 || lastCellNum == -1 || firstCellNum >= lastCellNum) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = firstCellNum; j < lastCellNum; j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = cell.getStringCellValue();
|
||||||
|
if (value != null) {
|
||||||
|
|
||||||
|
for (DynamicDataMapping dynamicData : dynamicDataMappingList) {
|
||||||
|
if (value.startsWith("{{" + dynamicData.getDataId() + ".")) {
|
||||||
|
return dynamicData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sheet
|
||||||
|
* @param rowIndex
|
||||||
|
* @param dynamicDataMapping
|
||||||
|
* @return int
|
||||||
|
* @description: 根据动态数据的条数动态复制模版行,每处理一个类型的list返回最后的行数,进而处理下一个类型的list
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
private static int getTemplateLastRowIndexAfterDealTemplate(XSSFSheet sheet, int rowIndex, DynamicDataMapping dynamicDataMapping) {
|
||||||
|
if (dynamicDataMapping == null) {
|
||||||
|
return rowIndex;
|
||||||
|
}
|
||||||
|
int dataRows = dynamicDataMapping.getDataList().size();
|
||||||
|
// 需要拷贝的行数(因为模板行本身占1行,所以-1)
|
||||||
|
int copyRows = dataRows - 1;
|
||||||
|
if (copyRows > 0) {
|
||||||
|
/**
|
||||||
|
* shiftRows: 从动态数据模版行(rowIndex)到最后一行,这些全部行都向下移copyRows行
|
||||||
|
* 相当于模版行上面插入n行空行(n=copyRows)
|
||||||
|
*/
|
||||||
|
sheet.shiftRows(rowIndex, sheet.getLastRowNum(), copyRows, true, false);
|
||||||
|
// 拷贝策略
|
||||||
|
CellCopyPolicy cellCopyPolicy = makeCellCopyPolicy();
|
||||||
|
// 因为从模版行开始向下平移了copyRows行,所以这里 模板行=rowIndex + copyRows,
|
||||||
|
int templateDataRow = rowIndex + copyRows;
|
||||||
|
// 因为模版行上新增了空行,所以要把模板所在行的模版 拷贝到上面新增的空行
|
||||||
|
for (int i = 0; i < copyRows; i++) {
|
||||||
|
//templateDataRow-模版行数据 rowIndex + i循环的当前空行
|
||||||
|
sheet.copyRows(templateDataRow, templateDataRow, rowIndex + i, cellCopyPolicy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 循环模版行:动态替换模版行(将模版行里的模版替换成动态数据)
|
||||||
|
for (int j = rowIndex; j < rowIndex + dataRows; j++) {
|
||||||
|
Map<String, Object> dataMap = dynamicDataMapping.getDataList().get(j - rowIndex);
|
||||||
|
dealTemplateDataRow(sheet.getRow(j), dynamicDataMapping.getDataId(), dataMap);
|
||||||
|
}
|
||||||
|
return rowIndex + copyRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return org.apache.poi.ss.usermodel.CellCopyPolicy
|
||||||
|
* @description: 拷贝策略
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static CellCopyPolicy makeCellCopyPolicy() {
|
||||||
|
CellCopyPolicy cellCopyPolicy = new CellCopyPolicy();
|
||||||
|
cellCopyPolicy.setCopyCellValue(true);
|
||||||
|
cellCopyPolicy.setCopyCellStyle(true);
|
||||||
|
return cellCopyPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查行中是否有动态数据占位符
|
||||||
|
*/
|
||||||
|
private static boolean hasDynamicPlaceholders(XSSFRow row) {
|
||||||
|
if (row == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstCellNum = row.getFirstCellNum();
|
||||||
|
int lastCellNum = row.getLastCellNum();
|
||||||
|
|
||||||
|
if (firstCellNum == -1 || lastCellNum == -1 || firstCellNum >= lastCellNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = firstCellNum; j < lastCellNum; j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = cell.getStringCellValue();
|
||||||
|
if (value != null && value.contains("{{") && value.contains("}}")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查行中是否有匹配的数据映射
|
||||||
|
*/
|
||||||
|
private static boolean hasMatchingDataMapping(XSSFRow row, List<DynamicDataMapping> dynamicDataMappingList) {
|
||||||
|
if (dynamicDataMappingList == null || dynamicDataMappingList.size() < 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstCellNum = row.getFirstCellNum();
|
||||||
|
int lastCellNum = row.getLastCellNum();
|
||||||
|
|
||||||
|
if (firstCellNum == -1 || lastCellNum == -1 || firstCellNum >= lastCellNum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = firstCellNum; j < lastCellNum; j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = cell.getStringCellValue();
|
||||||
|
if (value != null) {
|
||||||
|
for (DynamicDataMapping dynamicData : dynamicDataMappingList) {
|
||||||
|
if (value.startsWith("{{" + dynamicData.getDataId() + ".")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理行中的动态数据占位符
|
||||||
|
*/
|
||||||
|
private static void clearDynamicPlaceholders(XSSFRow row) {
|
||||||
|
if (row == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstCellNum = row.getFirstCellNum();
|
||||||
|
int lastCellNum = row.getLastCellNum();
|
||||||
|
|
||||||
|
if (firstCellNum == -1 || lastCellNum == -1 || firstCellNum >= lastCellNum) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = firstCellNum; j < lastCellNum; j++) {
|
||||||
|
XSSFCell cell = row.getCell(j);
|
||||||
|
if (cell == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = cell.getStringCellValue();
|
||||||
|
if (value != null && value.contains("{{") && value.contains("}}")) {
|
||||||
|
// 清理动态数据占位符,保留静态内容
|
||||||
|
String cleanedValue = value.replaceAll("\\{\\{[^}]+\\}\\}", "");
|
||||||
|
cell.setCellValue(cleanedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
package com.ruoyi.common.poi;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description 根据模版导出Excel工具类
|
||||||
|
* @Author susu
|
||||||
|
* @Date 2024/2/19
|
||||||
|
*/
|
||||||
|
public class ExportExcelByTemplateUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据模版导出Excel入口(单个list数据)
|
||||||
|
* @param templateFileName
|
||||||
|
* @param exportFilePathAndName
|
||||||
|
* @param staticDataMap
|
||||||
|
* @param dataId
|
||||||
|
* @param originDataList
|
||||||
|
* @return void
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/21
|
||||||
|
*/
|
||||||
|
public static void doExportExcelOneListByTemplate(String templateFileName, String exportFilePathAndName,
|
||||||
|
Map<String, Object> staticDataMap,
|
||||||
|
String dataId,
|
||||||
|
List<?> originDataList) throws Exception{
|
||||||
|
|
||||||
|
List<Map<String, Object>> exportDataList = MapObjectUtil.objListToMapList(originDataList);
|
||||||
|
// 只有一个list数据
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createOneDataList(dataId, exportDataList);
|
||||||
|
// 导出
|
||||||
|
ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticDataMap,dynamicDataMappingList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据模版导出Excel入口(多个list数据)
|
||||||
|
* @param templateFileName
|
||||||
|
* @param exportFilePathAndName
|
||||||
|
* @param staticSource
|
||||||
|
* @param originDataMapList
|
||||||
|
* @return void
|
||||||
|
* @author susu
|
||||||
|
* @date 2024/2/20
|
||||||
|
*/
|
||||||
|
public static void doExportExcelMoreListByTemplate(String templateFileName,
|
||||||
|
String exportFilePathAndName,
|
||||||
|
Map<String, Object> staticSource,
|
||||||
|
Map<String, List<?>> originDataMapList) throws Exception{
|
||||||
|
|
||||||
|
Map<String,List<Map<String, Object>>> transMap = new HashMap<>();
|
||||||
|
originDataMapList.forEach((dataId,originDataList)->{
|
||||||
|
List<Map<String, Object>> transDataList = MapObjectUtil.objListToMapList(originDataList);
|
||||||
|
transMap.put(dataId,transDataList);
|
||||||
|
});
|
||||||
|
// 多个list类型数据
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList = DynamicDataMapping.createMorDataList(transMap);
|
||||||
|
// 导出
|
||||||
|
ExcelTemplateProc.doExportExcelByTemplateProc(templateFileName,exportFilePathAndName,staticSource,dynamicDataMappingList);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.ruoyi.common.poi;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.commons.beanutils.BeanMap;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description
|
||||||
|
* @Author susu
|
||||||
|
* @Date 2024/2/19
|
||||||
|
*/
|
||||||
|
public class MapObjectUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 将object的list数据 转换成 map的list(如:List<Map<String, Object>>)
|
||||||
|
* @param objDataList
|
||||||
|
* @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
|
||||||
|
* @author susu
|
||||||
|
*/
|
||||||
|
public static List<Map<String, Object>> objListToMapList(List<?> objDataList){
|
||||||
|
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||||
|
if (objDataList==null || objDataList.size()<1){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
objDataList.forEach(obj->{
|
||||||
|
try {
|
||||||
|
Map<String, Object> map = MapObjectUtil.objectToMap(obj);
|
||||||
|
dataList.add(map);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 将object数据转换成map数据
|
||||||
|
* @param obj
|
||||||
|
* @return java.util.Map<java.lang.String,java.lang.Object>
|
||||||
|
* @author susu
|
||||||
|
*/
|
||||||
|
public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
|
||||||
|
Map<String, Object> map = new HashMap();
|
||||||
|
Class<?> cla = obj.getClass();
|
||||||
|
Field[] fields = cla.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String keyName = field.getName();
|
||||||
|
Object value = field.get(obj);
|
||||||
|
if (value == null)
|
||||||
|
value = "";
|
||||||
|
map.put(keyName, value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 使用 JSONObject 将object转换成map
|
||||||
|
* @param obj
|
||||||
|
* @return java.util.Map<?,?>
|
||||||
|
* @author susu
|
||||||
|
*/
|
||||||
|
public static Map<?, ?> objectToMap2(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return null;
|
||||||
|
return JSONObject.parseObject(JSONObject.toJSONString(obj),Map.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 使用BeanMap将object转换成map
|
||||||
|
* @param obj
|
||||||
|
* @return java.util.Map<?,?>
|
||||||
|
* @author susu
|
||||||
|
*/
|
||||||
|
public static Map<?, ?> objectToMap3(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return null;
|
||||||
|
return new BeanMap(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -91,21 +91,27 @@ public class SmbUtil {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 指定要下载的文件名
|
// 定义要下载的文件列表
|
||||||
String targetFileName = targetFolder+"汇总表.xlsx";
|
String[] fileNames = {
|
||||||
|
targetFolder + "汇总表.xlsx",
|
||||||
|
"RawDataTable.xlsx"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 循环下载每个文件
|
||||||
|
for (String fileName : fileNames) {
|
||||||
// 构造远程文件路径
|
// 构造远程文件路径
|
||||||
SmbFile remoteFile = new SmbFile(remoteDir, targetFileName);
|
SmbFile remoteFile = new SmbFile(remoteDir, fileName);
|
||||||
|
|
||||||
if (!remoteFile.exists() || !remoteFile.isFile()) {
|
if (!remoteFile.exists() || !remoteFile.isFile()) {
|
||||||
System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath());
|
System.err.println("目标文件不存在: " + remoteFile.getCanonicalPath());
|
||||||
return;
|
continue; // 继续下载其他文件
|
||||||
}
|
}
|
||||||
|
|
||||||
// 本地保存路径:D:/file/项目生产数据表.xlsx
|
// 本地保存路径
|
||||||
File localFile = new File(localDir, targetFileName);
|
File localFile = new File(localDir, fileName);
|
||||||
|
|
||||||
transferFile(remoteFile, localFile);
|
transferFile(remoteFile, localFile);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("操作失败: " + e.getMessage());
|
System.err.println("操作失败: " + e.getMessage());
|
||||||
|
|||||||
@ -68,7 +68,8 @@ public class ExcelUtil {
|
|||||||
}
|
}
|
||||||
public static <T> ExcelResult<T> importExcelSheet6(InputStream is, Class<T> clazz, boolean isValidate) {
|
public static <T> ExcelResult<T> importExcelSheet6(InputStream is, Class<T> clazz, boolean isValidate) {
|
||||||
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
|
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
|
||||||
EasyExcel.read(is, clazz, listener).sheet(6).doRead();
|
EasyExcel.read(is, clazz, listener).sheet(6)
|
||||||
|
.headRowNumber(2).doRead();
|
||||||
return listener.getExcelResult();
|
return listener.getExcelResult();
|
||||||
}
|
}
|
||||||
public static <T> ExcelResult<T> importExcelSheet1(InputStream is, Class<T> clazz, boolean isValidate) {
|
public static <T> ExcelResult<T> importExcelSheet1(InputStream is, Class<T> clazz, boolean isValidate) {
|
||||||
@ -76,6 +77,11 @@ public class ExcelUtil {
|
|||||||
EasyExcel.read(is, clazz, listener).sheet(0).doRead();
|
EasyExcel.read(is, clazz, listener).sheet(0).doRead();
|
||||||
return listener.getExcelResult();
|
return listener.getExcelResult();
|
||||||
}
|
}
|
||||||
|
public static <T> ExcelResult<T> importExcelSheet2(InputStream is, Class<T> clazz, boolean isValidate) {
|
||||||
|
DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
|
||||||
|
EasyExcel.read(is, clazz, listener).sheet(2).doRead();
|
||||||
|
return listener.getExcelResult();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用自定义监听器 异步导入 自定义返回
|
* 使用自定义监听器 异步导入 自定义返回
|
||||||
|
|||||||
@ -16,8 +16,10 @@ import com.ruoyi.common.core.domain.R;
|
|||||||
import com.ruoyi.common.excel.ExcelResult;
|
import com.ruoyi.common.excel.ExcelResult;
|
||||||
import com.ruoyi.common.utils.JdUtils;
|
import com.ruoyi.common.utils.JdUtils;
|
||||||
import com.ruoyi.system.domain.EleMaterials;
|
import com.ruoyi.system.domain.EleMaterials;
|
||||||
|
import com.ruoyi.system.domain.ImMaterial;
|
||||||
import com.ruoyi.system.domain.dto.*;
|
import com.ruoyi.system.domain.dto.*;
|
||||||
import com.ruoyi.system.domain.vo.ExcelVo;
|
import com.ruoyi.system.domain.vo.ExcelVo;
|
||||||
|
import com.ruoyi.system.mapper.ImMaterialMapper;
|
||||||
import com.ruoyi.system.runner.JdUtil;
|
import com.ruoyi.system.runner.JdUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -54,6 +56,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
public class EleMaterialsController extends BaseController {
|
public class EleMaterialsController extends BaseController {
|
||||||
|
|
||||||
private final IEleMaterialsService iEleMaterialsService;
|
private final IEleMaterialsService iEleMaterialsService;
|
||||||
|
private final ImMaterialMapper materialMapper;
|
||||||
private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class);
|
private static final Logger log = LoggerFactory.getLogger(EleMaterialsController.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -482,4 +485,47 @@ public class EleMaterialsController extends BaseController {
|
|||||||
|
|
||||||
return R.ok("更新成功");
|
return R.ok("更新成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Log(title = "更新VMI仓位", businessType = BusinessType.IMPORT)
|
||||||
|
@SaCheckPermission("system:route:updaDateCangwei")
|
||||||
|
@PostMapping(value = "/updaDateCangwei12", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public R<Void> updaDateCangwei1(@RequestParam("file") MultipartFile file) throws Exception {
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
log.info("读取文件名: " + originalFilename);
|
||||||
|
ExcelResult<JdVMIVo> result = ExcelUtil.importExcelSheet1(file.getInputStream(), JdVMIVo.class, true);
|
||||||
|
List<JdVMIVo> list = result.getList();
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||||
|
list.forEach(vmi -> executor.submit(() -> {
|
||||||
|
log.info("===============>开始查询物料编码: " + vmi.getMaterialCode() + "的entryID");
|
||||||
|
List<JdEntryVmi> entryID = JdUtil.getEntryID2(vmi.getMaterialCode());
|
||||||
|
entryID.forEach(jdEntryVmi -> {
|
||||||
|
int fmaterialid = jdEntryVmi.getFMATERIALID();
|
||||||
|
int fEntryId1 = jdEntryVmi.getFEntryId1();
|
||||||
|
int fEntryId3 = jdEntryVmi.getFEntryId3();
|
||||||
|
try {
|
||||||
|
log.info("=====================>开始更新 " + vmi.getMaterialCode() + " 的VMI仓位");
|
||||||
|
JdUtil.updateVMI(fmaterialid, fEntryId1, fEntryId3, vmi.getFStockId(), vmi.getFStockPlaceId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 关闭线程池并等待所有任务完成
|
||||||
|
executor.shutdown();
|
||||||
|
try {
|
||||||
|
if (!executor.awaitTermination(60, TimeUnit.MINUTES)) {
|
||||||
|
executor.shutdownNow(); // 超时后强制关闭
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
executor.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt(); // 保留中断状态
|
||||||
|
}
|
||||||
|
|
||||||
|
return R.ok("更新成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -356,7 +356,7 @@ public class ImMaterialController extends BaseController {
|
|||||||
//请求参数,要求为json字符串
|
//请求参数,要求为json字符串
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("FormId", "BD_MATERIAL");
|
json.addProperty("FormId", "BD_MATERIAL");
|
||||||
json.addProperty("FieldKeys", "FMATERIALID,FNumber,FName,FCategoryID.FNumber,F_HBYT_DZ,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName,FModifyDate,FForbidStatus");
|
json.addProperty("FieldKeys", "FMATERIALID,FNumber,FName,FCategoryID.FNumber,F_HBYT_DZ,F_SVRI_Assistant.FNumber,FErpClsID,FBaseUnitId.FName,FModifyDate,FForbidStatus,FIsVmiBusiness");
|
||||||
JsonArray filterString = new JsonArray();
|
JsonArray filterString = new JsonArray();
|
||||||
|
|
||||||
log.debug("构建查询条件...");
|
log.debug("构建查询条件...");
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.system.controller;
|
package com.ruoyi.system.controller;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -9,17 +10,24 @@ import com.ruoyi.common.excel.DefaultExcelListener;
|
|||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.SmbUtil;
|
import com.ruoyi.common.utils.file.SmbUtil;
|
||||||
import com.ruoyi.system.domain.MrpResultCheck;
|
import com.ruoyi.common.poi.ExcelTemplateProc;
|
||||||
import com.ruoyi.system.domain.ProcessRoute;
|
import com.ruoyi.common.poi.DynamicDataMapping;
|
||||||
|
import com.ruoyi.system.domain.*;
|
||||||
import com.ruoyi.system.domain.bo.FigureSaveBo;
|
import com.ruoyi.system.domain.bo.FigureSaveBo;
|
||||||
import com.ruoyi.system.domain.vo.MrpResultCheckVo;
|
import com.ruoyi.system.domain.vo.*;
|
||||||
import com.ruoyi.system.domain.vo.OverdueProjectVo;
|
import com.ruoyi.system.domain.vo.BomDataVO;
|
||||||
import com.ruoyi.system.service.IBomDetailsService;
|
import com.ruoyi.system.mapper.ProcessOrderProMapper;
|
||||||
import com.ruoyi.system.service.IMrpResultCheckService;
|
import com.ruoyi.system.service.*;
|
||||||
import com.ruoyi.system.service.impl.ProductionOrderServiceImpl;
|
import com.ruoyi.system.service.impl.ProductionOrderServiceImpl;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -35,14 +43,13 @@ import com.ruoyi.common.core.validate.AddGroup;
|
|||||||
import com.ruoyi.common.core.validate.EditGroup;
|
import com.ruoyi.common.core.validate.EditGroup;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.system.domain.vo.ProcessOrderProVo;
|
|
||||||
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
|
import com.ruoyi.system.domain.bo.ProcessOrderProBo;
|
||||||
import com.ruoyi.system.service.IProcessOrderProService;
|
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目令号
|
* 项目令号
|
||||||
|
*
|
||||||
* @author tzy
|
* @author tzy
|
||||||
* @date 2024-10-22
|
* @date 2024-10-22
|
||||||
*/
|
*/
|
||||||
@ -58,6 +65,10 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
private final ProductionOrderServiceImpl productionOrderService;
|
private final ProductionOrderServiceImpl productionOrderService;
|
||||||
private final IMrpResultCheckService iMrpResultCheckService;
|
private final IMrpResultCheckService iMrpResultCheckService;
|
||||||
private final IBomDetailsService iBomDetailsService;
|
private final IBomDetailsService iBomDetailsService;
|
||||||
|
private final ProcessOrderProMapper processOrderProMapper;
|
||||||
|
private final IImMaterialService imMaterialService;
|
||||||
|
private final ISafetyStockService iSafetyStockService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询项目令号列表
|
* 查询项目令号列表
|
||||||
*/
|
*/
|
||||||
@ -66,12 +77,14 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
public TableDataInfo<ProcessOrderProVo> list(ProcessOrderProBo bo, PageQuery pageQuery) {
|
public TableDataInfo<ProcessOrderProVo> list(ProcessOrderProBo bo, PageQuery pageQuery) {
|
||||||
return iProcessOrderProService.queryPageList(bo, pageQuery);
|
return iProcessOrderProService.queryPageList(bo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SaCheckPermission("system:orderPro:list")
|
@SaCheckPermission("system:orderPro:list")
|
||||||
@GetMapping("/processlist")
|
@GetMapping("/processlist")
|
||||||
public List<ProcessRoute> processList(ProcessOrderProBo bo) {
|
public List<ProcessRoute> processList(ProcessOrderProBo bo) {
|
||||||
|
|
||||||
return iProcessOrderProService.selectProList(bo);
|
return iProcessOrderProService.selectProList(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出项目令号列表
|
* 导出项目令号列表
|
||||||
*/
|
*/
|
||||||
@ -85,6 +98,7 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目令号详细信息
|
* 获取项目令号详细信息
|
||||||
|
*
|
||||||
* @param id 主键
|
* @param id 主键
|
||||||
*/
|
*/
|
||||||
@SaCheckPermission("system:orderPro:query")
|
@SaCheckPermission("system:orderPro:query")
|
||||||
@ -164,6 +178,7 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
//读取excel文件sheet
|
//读取excel文件sheet
|
||||||
return toAjax(iProcessOrderProService.insertByBo(bo));
|
return toAjax(iProcessOrderProService.insertByBo(bo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量更新项目令号的计划开始和结束时间
|
* 批量更新项目令号的计划开始和结束时间
|
||||||
* 根据工艺路线中的工序获取每个项目令号的最早开始时间和最晚结束时间,并更新到ProcessOrderPro
|
* 根据工艺路线中的工序获取每个项目令号的最早开始时间和最晚结束时间,并更新到ProcessOrderPro
|
||||||
@ -190,8 +205,10 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
String s = iProcessOrderProService.executDrawing(orderPro);
|
String s = iProcessOrderProService.executDrawing(orderPro);
|
||||||
return R.ok(s);
|
return R.ok(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传dwg图纸
|
* 上传dwg图纸
|
||||||
|
*
|
||||||
* @param id
|
* @param id
|
||||||
* @param filePath
|
* @param filePath
|
||||||
* @return
|
* @return
|
||||||
@ -269,6 +286,7 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载ZIP包
|
* 下载ZIP包
|
||||||
*/
|
*/
|
||||||
@ -330,4 +348,678 @@ public class ProcessOrderProController extends BaseController {
|
|||||||
public R<List<MrpResultCheck>> geMRPResults(@PathVariable Long id) {
|
public R<List<MrpResultCheck>> geMRPResults(@PathVariable Long id) {
|
||||||
return iMrpResultCheckService.getMRPResults(id);
|
return iMrpResultCheckService.getMRPResults(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SaCheckPermission("system:route:exportRoute")
|
||||||
|
@Log(title = "下载工艺生产表", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/exportRoute")
|
||||||
|
public void exportRoute(@RequestParam("id") Long id, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
ProcessOrderPro orderPro = processOrderProMapper.selectById(id);
|
||||||
|
|
||||||
|
// 下载Excel文件
|
||||||
|
SmbUtil.downloadExcelFiles(orderPro.getProductionOrderNo());
|
||||||
|
|
||||||
|
// 构建文件路径
|
||||||
|
String excelName = "D:\\file\\" + orderPro.getProductionOrderNo() + "汇总表.xlsx";
|
||||||
|
String rawDataFile = "D:\\file\\RawDataTable.xlsx";
|
||||||
|
|
||||||
|
File file = new File(excelName);
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new ServiceException("项目 " + orderPro.getProductionOrderNo() + " 未出图");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 读取第一个sheet的数据list - 使用POI直接读取以保留空格
|
||||||
|
List<ProductionOrderVo> allDataList = readExcelWithPOI(excelName);
|
||||||
|
|
||||||
|
// 2. 读取原始表数据
|
||||||
|
List<BomDataVO> rawDataList = readRawDataTable(rawDataFile);
|
||||||
|
|
||||||
|
// 3. 数据分类处理
|
||||||
|
List<VMIDataVO> vmiList = new ArrayList<>(); // 009开头
|
||||||
|
List<ElecOutDataVO> elecOutList = new ArrayList<>(); // 两个空格和017开头
|
||||||
|
List<SupProvidDataVO> supplierList = new ArrayList<>(); // 甲供件
|
||||||
|
List<EVOProductsDataVO> evoProductsList = new ArrayList<>(); // 伊特
|
||||||
|
List<ProductionOrderVo> processDataList = new ArrayList<>(); // 工艺数据(剩余数据)
|
||||||
|
|
||||||
|
// 分类逻辑
|
||||||
|
for (ProductionOrderVo item : allDataList) {
|
||||||
|
String materialCode = item.getDrawingNo();
|
||||||
|
String remark = item.getRemark(); // 使用备注字段
|
||||||
|
|
||||||
|
// 009开头的加入VMI表
|
||||||
|
if (materialCode != null) {
|
||||||
|
String drawingNo = item.getDrawingNo();
|
||||||
|
String drawingName = item.getDrawingName();
|
||||||
|
if (drawingNo != null && drawingName != null) {
|
||||||
|
ImMaterial material = imMaterialService.selectByCodeAndName(drawingNo, drawingName);
|
||||||
|
if (material != null) {
|
||||||
|
//判断是否是VMI物料
|
||||||
|
if ("true".equals(material.getClassificationName())) {
|
||||||
|
// 检查是否已存在相同的DrawingNo
|
||||||
|
boolean found = false;
|
||||||
|
for (VMIDataVO existingVmi : vmiList) {
|
||||||
|
if (drawingNo.equals(existingVmi.getDrawingNo())) {
|
||||||
|
// 将数量和批次数量相加
|
||||||
|
Integer currentQuantity = existingVmi.getQuantity() != null ? existingVmi.getQuantity() : 0;
|
||||||
|
Integer itemQuantity = item.getQuantity() != null ? item.getQuantity().intValue() : 0;
|
||||||
|
existingVmi.setQuantity(currentQuantity + itemQuantity);
|
||||||
|
|
||||||
|
Integer currentBatchQuantity = existingVmi.getBatchQuantity() != null ? existingVmi.getBatchQuantity() : 0;
|
||||||
|
Integer itemBatchQuantity = item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : 0;
|
||||||
|
existingVmi.setBatchQuantity(currentBatchQuantity + itemBatchQuantity);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到相同的DrawingNo,则添加新的VMI数据
|
||||||
|
if (!found) {
|
||||||
|
VMIDataVO vmiData = convertToVMIDataVO(item);
|
||||||
|
vmiList.add(vmiData);
|
||||||
|
}
|
||||||
|
continue; // 已分类,跳过后续检查
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 电气外包分类条件:物料编码开头空格/特定前缀 或 备注包含"外购"
|
||||||
|
if (materialCode.startsWith(" ")
|
||||||
|
|| materialCode.startsWith("009301") || materialCode.startsWith("009999")
|
||||||
|
|| materialCode.startsWith("017003") || materialCode.startsWith("017002")
|
||||||
|
|| materialCode.startsWith("009001") || materialCode.startsWith("009081")
|
||||||
|
|| (remark != null && remark.contains("外购"))) {
|
||||||
|
// 过滤安全库存:如果属于安全库存,则进入工艺数据列表
|
||||||
|
Boolean isSafeStock = iSafetyStockService.isSafeCode(materialCode);
|
||||||
|
if (isSafeStock) {
|
||||||
|
// 属于安全库存,添加到工艺数据列表
|
||||||
|
processDataList.add(item);
|
||||||
|
continue; // 已分类,跳过后续检查
|
||||||
|
} else {
|
||||||
|
// 不属于安全库存,添加到电气外包列表
|
||||||
|
ElecOutDataVO elecData = convertToElecOutDataVO(item);
|
||||||
|
elecOutList.add(elecData);
|
||||||
|
continue; // 已分类,跳过后续检查
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备注是甲供件的
|
||||||
|
if (remark != null && remark.contains("甲供件")) {
|
||||||
|
SupProvidDataVO supplierData = convertToSupProvidDataVO(item);
|
||||||
|
supplierList.add(supplierData);
|
||||||
|
continue; // 已分类,跳过后续检查
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备注是伊特
|
||||||
|
if (remark != null && remark.contains("伊特")) {
|
||||||
|
EVOProductsDataVO evoData = convertToEVOProductsDataVO(item);
|
||||||
|
evoProductsList.add(evoData);
|
||||||
|
continue; // 已分类,跳过后续检查
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他数据作为工艺数据(剩余数据)
|
||||||
|
// 检查是否已存在相同的DrawingNo
|
||||||
|
boolean found = false;
|
||||||
|
for (ProductionOrderVo existingProcess : processDataList) {
|
||||||
|
if (materialCode != null && materialCode.equals(existingProcess.getDrawingNo())) {
|
||||||
|
// 将数量和批次数量相加
|
||||||
|
Double currentQuantity = existingProcess.getQuantity() != null ? existingProcess.getQuantity() : 0.0;
|
||||||
|
Double itemQuantity = item.getQuantity() != null ? item.getQuantity() : 0.0;
|
||||||
|
Double newQuantity = currentQuantity + itemQuantity;
|
||||||
|
existingProcess.setQuantity(newQuantity);
|
||||||
|
|
||||||
|
// 批次数量相加(String类型)
|
||||||
|
String currentBatchQuantity = existingProcess.getBatchQuantity() != null ? existingProcess.getBatchQuantity() : "0";
|
||||||
|
String itemBatchQuantity = item.getBatchQuantity() != null ? item.getBatchQuantity() : "0";
|
||||||
|
try {
|
||||||
|
Integer currentBatch = Integer.valueOf(currentBatchQuantity);
|
||||||
|
Integer itemBatch = Integer.valueOf(itemBatchQuantity);
|
||||||
|
String newBatchQuantity = String.valueOf(currentBatch + itemBatch);
|
||||||
|
existingProcess.setBatchQuantity(newBatchQuantity);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 如果转换失败,保持原值
|
||||||
|
existingProcess.setBatchQuantity(currentBatchQuantity);
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到相同的DrawingNo,则添加新的工艺数据
|
||||||
|
if (!found) {
|
||||||
|
processDataList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 使用Excel模板文件
|
||||||
|
String templatePath = "EXCEL模板/生产及工艺计划模版.xlsx";
|
||||||
|
String outputPath = "D:/file/" + orderPro.getProductionOrderNo() + "生产及工艺计划表.xlsx";
|
||||||
|
|
||||||
|
// 准备模板数据
|
||||||
|
Map<String, Object> staticDataMap = new HashMap<>();
|
||||||
|
staticDataMap.put("productionOrderNo", orderPro.getProductionOrderNo());
|
||||||
|
staticDataMap.put("productionName", orderPro.getProductionName());
|
||||||
|
|
||||||
|
// 添加静态数据调试信息
|
||||||
|
log.info("静态数据: {}", staticDataMap);
|
||||||
|
|
||||||
|
// 准备动态数据映射
|
||||||
|
List<DynamicDataMapping> dynamicDataMappingList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 添加生产订单数据
|
||||||
|
if (!allDataList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> productionDataList = convertProductionOrderToMapList(allDataList, orderPro.getProductionOrderNo());
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("ProductionOrder", productionDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加工艺数据(第七个sheet:工艺及生产计划表)
|
||||||
|
if (!processDataList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> processDataMapList = convertProductionOrderToMapList(processDataList, orderPro.getProductionOrderNo());
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("ProcessData", processDataMapList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加VMI数据
|
||||||
|
if (!vmiList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> vmiDataList = convertVMIDataToMapList(vmiList);
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("VMIDataVO", vmiDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加电气外购数据
|
||||||
|
if (!elecOutList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> elecDataList = convertElecOutDataToMapList(elecOutList);
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("ElecOutDataVO", elecDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加BOM数据
|
||||||
|
if (!rawDataList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> bomDataList = convertBomDataToMapList(rawDataList);
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("BomDataVO", bomDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加甲供件数据
|
||||||
|
if (!supplierList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> supplierDataList = convertSupProvidDataToMapList(supplierList);
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("SupProvidDataVO", supplierDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加伊特产品数据
|
||||||
|
if (!evoProductsList.isEmpty()) {
|
||||||
|
List<Map<String, Object>> evoDataList = convertEVOProductsDataToMapList(evoProductsList);
|
||||||
|
dynamicDataMappingList.addAll(DynamicDataMapping.createOneDataList("EVOProductsDataVO", evoDataList));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用模板导出Excel
|
||||||
|
ExcelTemplateProc.doExportExcelByTemplateProc(templatePath, outputPath, staticDataMap, dynamicDataMappingList);
|
||||||
|
|
||||||
|
// 设置响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode(orderPro.getProductionOrderNo() + "_分类BOM表", "UTF-8")
|
||||||
|
.replaceAll("\\+", "%20");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
// 将生成的文件写入响应
|
||||||
|
File outputFile = new File(outputPath);
|
||||||
|
if (outputFile.exists()) {
|
||||||
|
try (FileInputStream fis = new FileInputStream(outputFile);
|
||||||
|
OutputStream os = response.getOutputStream()) {
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int length;
|
||||||
|
while ((length = fis.read(buffer)) > 0) {
|
||||||
|
os.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
// 删除临时文件
|
||||||
|
outputFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出分类BOM表失败", e);
|
||||||
|
throw new RuntimeException("导出失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取RawDataTable数据
|
||||||
|
*/
|
||||||
|
private List<BomDataVO> readRawDataTable(String filePath) {
|
||||||
|
List<BomDataVO> dataList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (!file.exists()) {
|
||||||
|
log.warn("RawDataTable.xlsx文件不存在: {}", filePath);
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取Excel数据
|
||||||
|
DefaultExcelListener<BomDataVO> listener = new DefaultExcelListener<>(true);
|
||||||
|
EasyExcel.read(filePath, BomDataVO.class, listener)
|
||||||
|
.sheet(0) // 读取第一个sheet
|
||||||
|
.headRowNumber(2) // 从第1行开始读取
|
||||||
|
.doRead();
|
||||||
|
|
||||||
|
dataList = listener.getExcelResult().getList();
|
||||||
|
log.info("成功读取RawDataTable数据,共{}条记录", dataList.size());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("读取RawDataTable数据失败", e);
|
||||||
|
}
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertToMapList(List<ProcessRoute> routeList, ProcessOrderPro orderPro) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
for (ProcessRoute route : routeList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("materialCode", route.getMaterialCode());
|
||||||
|
map.put("materialName", route.getMaterialName());
|
||||||
|
map.put("material", route.getMaterial());
|
||||||
|
map.put("unitWeight", route.getDiscWeight());
|
||||||
|
map.put("quantity", route.getUnitQuantity());
|
||||||
|
map.put("batchQuantity", route.getBatchQuantity());
|
||||||
|
map.put("workCenter", route.getWorkCenter());
|
||||||
|
map.put("processName", route.getProcessName());
|
||||||
|
map.put("processDescription", route.getProcessDescription());
|
||||||
|
map.put("productionOrderNo", orderPro.getProductionOrderNo());
|
||||||
|
map.put("productionName", orderPro.getProductionName());
|
||||||
|
map.put("drawingNo", orderPro.getDrawingNo());
|
||||||
|
map.put("mainProducts", orderPro.getDrawingName());
|
||||||
|
map.put("mainProductsName", orderPro.getDrawingName());
|
||||||
|
mapList.add(map);
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用POI直接读取Excel文件,保留前后空格
|
||||||
|
*/
|
||||||
|
private List<ProductionOrderVo> readExcelWithPOI(String excelPath) {
|
||||||
|
List<ProductionOrderVo> resultList = new ArrayList<>();
|
||||||
|
|
||||||
|
try (FileInputStream fis = new FileInputStream(excelPath);
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
|
||||||
|
|
||||||
|
XSSFSheet sheet = workbook.getSheetAt(0); // 读取第一个sheet
|
||||||
|
|
||||||
|
// 从第3行开始读取(headRowNumber=2,所以从第3行开始)
|
||||||
|
for (int rowIndex = 2; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
|
||||||
|
XSSFRow row = sheet.getRow(rowIndex);
|
||||||
|
if (row == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProductionOrderVo vo = new ProductionOrderVo();
|
||||||
|
|
||||||
|
// 根据列索引读取数据,保留原始空格
|
||||||
|
vo.setId(getCellValueAsLong(row.getCell(0)));
|
||||||
|
vo.setDrawingNo(getCellValueAsString(row.getCell(1))); // 图号
|
||||||
|
vo.setDrawingName(getCellValueAsString(row.getCell(2))); // 名称
|
||||||
|
vo.setQuantity(getCellValueAsDouble(row.getCell(3))); // 数量
|
||||||
|
vo.setMaterial(getCellValueAsString(row.getCell(4))); // 材料
|
||||||
|
vo.setSingleWeight(getCellValueAsDouble(row.getCell(5))); // 单重
|
||||||
|
vo.setTotalWeight(getCellValueAsDouble(row.getCell(6))); // 总重
|
||||||
|
vo.setRemark(getCellValueAsString(row.getCell(7))); // 备注
|
||||||
|
vo.setBatchQuantity(getCellValueAsString(row.getCell(8))); // 批次数量
|
||||||
|
vo.setParentPart(getCellValueAsString(row.getCell(9))); // 上级部件
|
||||||
|
vo.setParentDrawingNo(getCellValueAsString(row.getCell(10))); // 上级部件图号
|
||||||
|
vo.setMainProducts(getCellValueAsString(row.getCell(11))); // 主产品图号
|
||||||
|
vo.setMainProductsName(getCellValueAsString(row.getCell(12))); // 主产品名称
|
||||||
|
|
||||||
|
resultList.add(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("使用POI读取Excel成功,共{}条记录", resultList.size());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("使用POI读取Excel失败", e);
|
||||||
|
throw new ServiceException("读取Excel文件失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单元格的字符串值,保留前后空格
|
||||||
|
*/
|
||||||
|
private String getCellValueAsString(XSSFCell cell) {
|
||||||
|
if (cell == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
case STRING:
|
||||||
|
// 直接从POI获取原始字符串,保留前后空格
|
||||||
|
String value = cell.getStringCellValue();
|
||||||
|
return value;
|
||||||
|
case NUMERIC:
|
||||||
|
return String.valueOf(cell.getNumericCellValue());
|
||||||
|
case BOOLEAN:
|
||||||
|
return String.valueOf(cell.getBooleanCellValue());
|
||||||
|
case FORMULA:
|
||||||
|
return cell.getCellFormula();
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单元格的Long值
|
||||||
|
*/
|
||||||
|
private Long getCellValueAsLong(XSSFCell cell) {
|
||||||
|
if (cell == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
case NUMERIC:
|
||||||
|
return (long) cell.getNumericCellValue();
|
||||||
|
case STRING:
|
||||||
|
try {
|
||||||
|
return Long.valueOf(cell.getStringCellValue());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单元格的Double值
|
||||||
|
*/
|
||||||
|
private Double getCellValueAsDouble(XSSFCell cell) {
|
||||||
|
if (cell == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
case NUMERIC:
|
||||||
|
return cell.getNumericCellValue();
|
||||||
|
case STRING:
|
||||||
|
try {
|
||||||
|
return Double.valueOf(cell.getStringCellValue());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字符串的Unicode表示
|
||||||
|
*/
|
||||||
|
private String getUnicodeString(String str) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (char c : str.toCharArray()) {
|
||||||
|
sb.append("\\u").append(String.format("%04x", (int) c));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ProductionOrder为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertProductionOrderToMapList(List<ProductionOrderVo> productionOrderList, String proName) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
for (ProductionOrderVo item : productionOrderList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("productionOrderNo", proName);
|
||||||
|
map.put("drawingNo", item.getDrawingNo());
|
||||||
|
map.put("drawingName", item.getDrawingName());
|
||||||
|
map.put("quantity", item.getQuantity());
|
||||||
|
map.put("material", item.getMaterial());
|
||||||
|
map.put("singleWeight", item.getSingleWeight());
|
||||||
|
map.put("totalWeight", item.getTotalWeight());
|
||||||
|
map.put("remark", item.getRemark());
|
||||||
|
map.put("parentPart", item.getParentPart());
|
||||||
|
map.put("parentDrawingNo", item.getParentDrawingNo());
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity());
|
||||||
|
|
||||||
|
// 为了兼容模板,也提供数字格式的batchQuantity
|
||||||
|
Integer batchQuantityInt = null;
|
||||||
|
if (item.getBatchQuantity() != null && !item.getBatchQuantity().isEmpty()) {
|
||||||
|
try {
|
||||||
|
batchQuantityInt = Integer.valueOf(item.getBatchQuantity());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 如果转换失败,保持原值
|
||||||
|
map.put("batchQuantityInt", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.put("batchQuantityInt", batchQuantityInt);
|
||||||
|
|
||||||
|
map.put("mainProducts", item.getMainProducts());
|
||||||
|
map.put("mainProductsName", item.getMainProductsName());
|
||||||
|
mapList.add(map);
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换BOM数据为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertBomDataToMapList(List<BomDataVO> bomDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
for (BomDataVO bom : bomDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", bom.getIndex());
|
||||||
|
map.put("drawingNo", bom.getDrawingNo());
|
||||||
|
map.put("name", bom.getName());
|
||||||
|
map.put("quantity", bom.getQuantity());
|
||||||
|
map.put("material", bom.getMaterial());
|
||||||
|
map.put("unitWeight", bom.getUnitWeight());
|
||||||
|
map.put("totalWeight", bom.getTotalWeight());
|
||||||
|
map.put("remark", bom.getRemark());
|
||||||
|
map.put("component", bom.getComponent());
|
||||||
|
map.put("componentDrawingNo", bom.getComponentDrawingNo());
|
||||||
|
mapList.add(map);
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ProductionOrder为VMIDataVO
|
||||||
|
*/
|
||||||
|
private VMIDataVO convertToVMIDataVO(ProductionOrderVo item) {
|
||||||
|
VMIDataVO vmiData = new VMIDataVO();
|
||||||
|
vmiData.setIndex(null); // ProductionOrder没有index字段
|
||||||
|
vmiData.setDrawingNo(item.getDrawingNo());
|
||||||
|
vmiData.setName(item.getDrawingName());
|
||||||
|
vmiData.setQuantity(item.getQuantity() != null ? item.getQuantity().intValue() : null);
|
||||||
|
vmiData.setMaterial(item.getMaterial());
|
||||||
|
vmiData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||||
|
vmiData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||||
|
vmiData.setRemark(item.getRemark());
|
||||||
|
vmiData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||||
|
return vmiData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ProductionOrder为ElecOutDataVO
|
||||||
|
*/
|
||||||
|
private ElecOutDataVO convertToElecOutDataVO(ProductionOrderVo item) {
|
||||||
|
ElecOutDataVO elecData = new ElecOutDataVO();
|
||||||
|
elecData.setIndex(null); // ProductionOrder没有index字段
|
||||||
|
elecData.setDrawingNo(item.getDrawingNo());
|
||||||
|
elecData.setName(item.getDrawingName());
|
||||||
|
elecData.setQuantity(item.getQuantity() != null ? item.getQuantity().intValue() : null);
|
||||||
|
elecData.setMaterial(item.getMaterial());
|
||||||
|
elecData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||||
|
elecData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||||
|
elecData.setRemark(item.getRemark());
|
||||||
|
elecData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||||
|
return elecData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ProductionOrder为SupProvidDataVO
|
||||||
|
*/
|
||||||
|
private SupProvidDataVO convertToSupProvidDataVO(ProductionOrderVo item) {
|
||||||
|
SupProvidDataVO supplierData = new SupProvidDataVO();
|
||||||
|
supplierData.setIndex(null); // ProductionOrder没有index字段
|
||||||
|
supplierData.setDrawingNo(item.getDrawingNo());
|
||||||
|
supplierData.setName(item.getDrawingName());
|
||||||
|
supplierData.setQuantity(item.getQuantity() != null ? item.getQuantity().intValue() : null);
|
||||||
|
supplierData.setMaterial(item.getMaterial());
|
||||||
|
supplierData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||||
|
supplierData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||||
|
supplierData.setRemark(item.getRemark());
|
||||||
|
supplierData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||||
|
return supplierData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ProductionOrder为EVOProductsDataVO
|
||||||
|
*/
|
||||||
|
private EVOProductsDataVO convertToEVOProductsDataVO(ProductionOrderVo item) {
|
||||||
|
EVOProductsDataVO evoData = new EVOProductsDataVO();
|
||||||
|
evoData.setIndex(null); // ProductionOrder没有index字段
|
||||||
|
evoData.setDrawingNo(item.getDrawingNo());
|
||||||
|
evoData.setName(item.getDrawingName());
|
||||||
|
evoData.setQuantity(item.getQuantity() != null ? item.getQuantity().intValue() : null);
|
||||||
|
evoData.setMaterial(item.getMaterial());
|
||||||
|
evoData.setUnitWeight(item.getSingleWeight() != null ? BigDecimal.valueOf(item.getSingleWeight()) : null);
|
||||||
|
evoData.setTotalWeight(item.getTotalWeight() != null ? BigDecimal.valueOf(item.getTotalWeight()) : null);
|
||||||
|
evoData.setRemark(item.getRemark());
|
||||||
|
evoData.setBatchQuantity(item.getBatchQuantity() != null ? Integer.valueOf(item.getBatchQuantity()) : null);
|
||||||
|
return evoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换VMIDataVO为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertVMIDataToMapList(List<VMIDataVO> vmiDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
int index = 1;
|
||||||
|
for (VMIDataVO item : vmiDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", index);
|
||||||
|
map.put("drawingNo", item.getDrawingNo());
|
||||||
|
map.put("name", item.getName());
|
||||||
|
map.put("quantity", item.getQuantity());
|
||||||
|
map.put("material", item.getMaterial());
|
||||||
|
map.put("unitWeight", item.getUnitWeight());
|
||||||
|
map.put("totalWeight", item.getTotalWeight());
|
||||||
|
map.put("remark", item.getRemark());
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity());
|
||||||
|
mapList.add(map);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换ElecOutDataVO为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertElecOutDataToMapList(List<ElecOutDataVO> elecOutDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
int index = 1;
|
||||||
|
for (ElecOutDataVO item : elecOutDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", index);
|
||||||
|
map.put("drawingNo", item.getDrawingNo());
|
||||||
|
map.put("name", item.getName());
|
||||||
|
map.put("quantity", item.getQuantity());
|
||||||
|
map.put("material", item.getMaterial());
|
||||||
|
map.put("unitWeight", item.getUnitWeight());
|
||||||
|
map.put("totalWeight", item.getTotalWeight());
|
||||||
|
map.put("remark", item.getRemark());
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity());
|
||||||
|
mapList.add(map);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换SupProvidDataVO为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertSupProvidDataToMapList(List<SupProvidDataVO> supplierDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
int index = 1;
|
||||||
|
for (SupProvidDataVO item : supplierDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", index);
|
||||||
|
map.put("drawingNo", item.getDrawingNo());
|
||||||
|
map.put("name", item.getName());
|
||||||
|
map.put("quantity", item.getQuantity());
|
||||||
|
map.put("material", item.getMaterial());
|
||||||
|
map.put("unitWeight", item.getUnitWeight());
|
||||||
|
map.put("totalWeight", item.getTotalWeight());
|
||||||
|
map.put("remark", item.getRemark());
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity());
|
||||||
|
mapList.add(map);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换EVOProductsDataVO为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertEVOProductsDataToMapList(List<EVOProductsDataVO> evoProductsDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
int index = 1;
|
||||||
|
for (EVOProductsDataVO item : evoProductsDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", index);
|
||||||
|
map.put("drawingNo", item.getDrawingNo());
|
||||||
|
map.put("name", item.getName());
|
||||||
|
map.put("quantity", item.getQuantity());
|
||||||
|
map.put("material", item.getMaterial());
|
||||||
|
map.put("unitWeight", item.getUnitWeight());
|
||||||
|
map.put("totalWeight", item.getTotalWeight());
|
||||||
|
map.put("remark", item.getRemark());
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity());
|
||||||
|
mapList.add(map);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换工艺VO为Map列表(用于模板)
|
||||||
|
*/
|
||||||
|
private List<Map<String, Object>> convertRouteDataToMapList(List<ProcessRouteVo> routeDataList) {
|
||||||
|
List<Map<String, Object>> mapList = new ArrayList<>();
|
||||||
|
int index = 1;
|
||||||
|
for (ProcessRouteVo item : routeDataList) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put("index", index);
|
||||||
|
map.put("routeDescription", item.getRouteDescription()); // 生产令号
|
||||||
|
map.put("materialCode", item.getMaterialCode()); // 物料编码
|
||||||
|
map.put("materialName", item.getMaterialName()); // 物料名称
|
||||||
|
map.put("material", item.getMaterial()); // 材质
|
||||||
|
map.put("discWeight", item.getDiscWeight()); // 单重KG
|
||||||
|
map.put("rawMaterialCode", item.getRawMaterialCode()); // 材料BOM物料编码
|
||||||
|
map.put("rawMaterialName", item.getRawMaterialName()); // 材料BOM物料名称
|
||||||
|
map.put("bomMaterial", item.getBomMaterial()); // BOM材质
|
||||||
|
map.put("bomDanZhong", item.getBomDanZhong()); // 材料单重KG
|
||||||
|
map.put("discUsage", item.getDiscUsage()); // 用量
|
||||||
|
map.put("bomUnit", item.getBomUnit()); // 单位
|
||||||
|
map.put("processNo", item.getProcessNo()); // 工序号
|
||||||
|
map.put("workCenter", item.getWorkCenter()); // 工作中心
|
||||||
|
map.put("processName", item.getProcessName()); // 工序名称
|
||||||
|
map.put("processDescription", item.getProcessDescription()); // 工序说明
|
||||||
|
map.put("processControl", item.getProcessControl()); // 工序控制
|
||||||
|
map.put("activityDuration", item.getActivityDuration()); // 活动时长
|
||||||
|
map.put("activityUnit", item.getActivityUnit()); // 活动单位
|
||||||
|
map.put("unitQuantity", item.getUnitQuantity()); // 单台数量
|
||||||
|
map.put("batchQuantity", item.getBatchQuantity()); // 本批数量
|
||||||
|
map.put("firstBatchQuantity", item.getFirstBatchQuantity()); // 首批数量
|
||||||
|
map.put("planStartTime", item.getPlanStartTime()); // 计划开始时间
|
||||||
|
map.put("planEndTime", item.getPlanEndTime()); // 计划结束时间
|
||||||
|
map.put("xuStartTime", item.getXuStartTime()); // 序开始时间
|
||||||
|
map.put("xuEndTime", item.getXuEndTime()); // 序结束时间
|
||||||
|
mapList.add(map);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return mapList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -379,7 +379,7 @@ public class ProcessRouteController extends BaseController {
|
|||||||
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class, true);
|
ExcelResult<ProcessRouteVo> result = ExcelUtil.importExcelSheet6(file.getInputStream(), ProcessRouteVo.class, true);
|
||||||
List<ProcessRouteVo> list1 = result.getList();
|
List<ProcessRouteVo> list1 = result.getList();
|
||||||
// 读取总装部分sheet
|
// 读取总装部分sheet
|
||||||
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet1(file.getInputStream(), ProductionOrderVo.class, true);
|
ExcelResult<ProductionOrderVo> result1 = ExcelUtil.importExcelSheet2(file.getInputStream(), ProductionOrderVo.class, true);
|
||||||
List<ProductionOrderVo> list = result1.getList();
|
List<ProductionOrderVo> list = result1.getList();
|
||||||
String productionOrderNo = list1.get(0).getRouteDescription();
|
String productionOrderNo = list1.get(0).getRouteDescription();
|
||||||
List<BomDetails> bomDetails = iBomDetailsService.selectByProjectNumber(list1.get(0).getRouteDescription());
|
List<BomDetails> bomDetails = iBomDetailsService.selectByProjectNumber(list1.get(0).getRouteDescription());
|
||||||
|
|||||||
@ -59,6 +59,7 @@ public class ImMaterial extends BaseEntity {
|
|||||||
/*
|
/*
|
||||||
所属名称:danwei
|
所属名称:danwei
|
||||||
*/
|
*/
|
||||||
|
@JsonProperty("FIsVmiBusiness")
|
||||||
private String classificationName;
|
private String classificationName;
|
||||||
/*
|
/*
|
||||||
所属编号
|
所属编号
|
||||||
|
|||||||
@ -0,0 +1,55 @@
|
|||||||
|
package com.ruoyi.system.domain.vo;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
/**
|
||||||
|
* 基础BOM明细
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BomDataVO {
|
||||||
|
|
||||||
|
/** 序号 */
|
||||||
|
@ExcelProperty(value = "序号")
|
||||||
|
private String index;
|
||||||
|
|
||||||
|
/** 图号 */
|
||||||
|
@ExcelProperty(value = "图号")
|
||||||
|
private String drawingNo;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
@ExcelProperty(value = "名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 数量 */
|
||||||
|
@ExcelProperty(value = "数量")
|
||||||
|
private String quantity;
|
||||||
|
|
||||||
|
/** 材料 */
|
||||||
|
@ExcelProperty(value = "材料")
|
||||||
|
private String material;
|
||||||
|
|
||||||
|
/** 单重 */
|
||||||
|
@ExcelProperty(value = "单重")
|
||||||
|
private String unitWeight;
|
||||||
|
|
||||||
|
/** 总重 */
|
||||||
|
@ExcelProperty(value = "总重")
|
||||||
|
private String totalWeight;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
@ExcelProperty(value = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 部件 */
|
||||||
|
@ExcelProperty(value = "部件")
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
/** 部件图号 */
|
||||||
|
@ExcelProperty(value = "部件图号")
|
||||||
|
private String componentDrawingNo;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.ruoyi.system.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 伊特产品明细
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class EVOProductsDataVO
|
||||||
|
{
|
||||||
|
/** 序号 */
|
||||||
|
private Integer index;
|
||||||
|
|
||||||
|
/** 图号 */
|
||||||
|
private String drawingNo;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 数量 */
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
/** 材料 */
|
||||||
|
private String material;
|
||||||
|
|
||||||
|
/** 单重 */
|
||||||
|
private BigDecimal unitWeight;
|
||||||
|
|
||||||
|
/** 总重 */
|
||||||
|
private BigDecimal totalWeight;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 批次数量 */
|
||||||
|
private Integer batchQuantity;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.ruoyi.system.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
/**
|
||||||
|
* 机电外购明细
|
||||||
|
*
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ElecOutDataVO {
|
||||||
|
/** 序号 */
|
||||||
|
private Integer index;
|
||||||
|
|
||||||
|
/** 图号 */
|
||||||
|
private String drawingNo;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 数量 */
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
/** 材料 */
|
||||||
|
private String material;
|
||||||
|
|
||||||
|
/** 单重 */
|
||||||
|
private BigDecimal unitWeight;
|
||||||
|
|
||||||
|
/** 总重 */
|
||||||
|
private BigDecimal totalWeight;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 批次数量 */
|
||||||
|
private Integer batchQuantity;
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,7 +7,11 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
/**
|
||||||
|
* 金蝶资产卡片
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class JdKingdeeAssetCardVo {
|
public class JdKingdeeAssetCardVo {
|
||||||
|
|||||||
@ -2,12 +2,9 @@ package com.ruoyi.system.domain.vo;
|
|||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import com.ruoyi.common.annotation.ExcelDictFormat;
|
import com.ruoyi.common.convert.KeepSpaceStringConverter;
|
||||||
import com.ruoyi.common.convert.ExcelDictConvert;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生产订单视图对象 production_order
|
* 生产订单视图对象 production_order
|
||||||
@ -19,18 +16,17 @@ import java.math.BigDecimal;
|
|||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class ProductionOrderVo {
|
public class ProductionOrderVo {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID
|
* ID
|
||||||
*/
|
*/
|
||||||
|
@ExcelProperty(value = "序号")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生产令号
|
* 生产令号
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "生产令号")
|
|
||||||
private String productionOrderNo;
|
private String productionOrderNo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,16 +46,13 @@ public class ProductionOrderVo {
|
|||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "数量")
|
@ExcelProperty(value = "数量")
|
||||||
private Double quantity;
|
private Double quantity;
|
||||||
|
|
||||||
@ExcelProperty(value = "批次数量")
|
|
||||||
private String batchQuantity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生产材料
|
* 生产材料
|
||||||
*/
|
*/
|
||||||
@ExcelProperty(value = "材料")
|
@ExcelProperty(value = "材料")
|
||||||
private String material;
|
private String material;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单重(kg)
|
* 单重(kg)
|
||||||
*/
|
*/
|
||||||
@ -78,6 +71,9 @@ public class ProductionOrderVo {
|
|||||||
@ExcelProperty(value = "备注")
|
@ExcelProperty(value = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "批次数量")
|
||||||
|
private String batchQuantity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部件名称
|
* 部件名称
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,40 @@
|
|||||||
|
package com.ruoyi.system.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
/**
|
||||||
|
* 甲供件明细
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SupProvidDataVO {
|
||||||
|
/** 序号 */
|
||||||
|
private Integer index;
|
||||||
|
|
||||||
|
/** 图号 */
|
||||||
|
private String drawingNo;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 数量 */
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
/** 材料 */
|
||||||
|
private String material;
|
||||||
|
|
||||||
|
/** 单重 */
|
||||||
|
private BigDecimal unitWeight;
|
||||||
|
|
||||||
|
/** 总重 */
|
||||||
|
private BigDecimal totalWeight;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 批次数量 */
|
||||||
|
private Integer batchQuantity;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.ruoyi.system.domain.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
/**
|
||||||
|
* VMI明细
|
||||||
|
*
|
||||||
|
* @author 田志阳
|
||||||
|
* @date 2025-09-04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class VMIDataVO {
|
||||||
|
/** 序号 */
|
||||||
|
private Integer index;
|
||||||
|
|
||||||
|
/** 图号 */
|
||||||
|
private String drawingNo;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/** 数量 */
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
/** 材料 */
|
||||||
|
private String material;
|
||||||
|
|
||||||
|
/** 单重 */
|
||||||
|
private BigDecimal unitWeight;
|
||||||
|
|
||||||
|
/** 总重 */
|
||||||
|
private BigDecimal totalWeight;
|
||||||
|
|
||||||
|
/** 备注 */
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
/** 批次数量 */
|
||||||
|
private Integer batchQuantity;
|
||||||
|
|
||||||
|
}
|
||||||
@ -48,4 +48,6 @@ public interface ISafetyStockService {
|
|||||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
List<SafetyStock> selectByType(String type1);
|
List<SafetyStock> selectByType(String type1);
|
||||||
|
|
||||||
|
Boolean isSafeCode(String materialCode);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -532,7 +532,8 @@ public class ImMaterialServiceImpl implements IImMaterialService {
|
|||||||
@Override
|
@Override
|
||||||
public ImMaterial selectByCodeAndName(String materialCode, String materialName) {
|
public ImMaterial selectByCodeAndName(String materialCode, String materialName) {
|
||||||
LambdaQueryWrapper<ImMaterial> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<ImMaterial> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(ImMaterial::getMaterialCode, materialCode).eq(ImMaterial::getMaterialName, materialName);
|
queryWrapper.eq(ImMaterial::getMaterialCode, materialCode)
|
||||||
|
.eq(ImMaterial::getMaterialName, materialName);
|
||||||
return baseMapper.selectOne(queryWrapper);
|
return baseMapper.selectOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,6 +148,21 @@ public class SafetyStockServiceImpl implements ISafetyStockService {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询此物料是否是安全库存
|
||||||
|
*
|
||||||
|
* @param materialCode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean isSafeCode(String materialCode) {
|
||||||
|
LambdaQueryWrapper<SafetyStock> safetyStockLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
safetyStockLambdaQueryWrapper.eq(SafetyStock::getMaterialCode,materialCode);
|
||||||
|
SafetyStock safetyStock = baseMapper.selectOne(safetyStockLambdaQueryWrapper);
|
||||||
|
return safetyStock != null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料批量查询
|
* 物料批量查询
|
||||||
*/
|
*/
|
||||||
|
|||||||
Binary file not shown.
BIN
ruoyi-system/src/main/resources/EXCEL模板/生产及工艺计划模版.xlsx
Normal file
BIN
ruoyi-system/src/main/resources/EXCEL模板/生产及工艺计划模版.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user