diff --git a/op-api/op-api-system/src/main/java/com/op/system/api/domain/dto/WCSDTO.java b/op-api/op-api-system/src/main/java/com/op/system/api/domain/dto/WCSDTO.java index 5ee20623..7e84e659 100644 --- a/op-api/op-api-system/src/main/java/com/op/system/api/domain/dto/WCSDTO.java +++ b/op-api/op-api-system/src/main/java/com/op/system/api/domain/dto/WCSDTO.java @@ -1,13 +1,15 @@ package com.op.system.api.domain.dto; +import com.fasterxml.jackson.annotation.JsonFormat; + import java.util.Date; import java.util.List; public class WCSDTO { private String reqCode; - - private Date reqTime; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private String reqTime; private String planNo; @@ -136,11 +138,11 @@ public class WCSDTO { this.reqCode = reqCode; } - public Date getReqTime() { + public String getReqTime() { return reqTime; } - public void setReqTime(Date reqTime) { + public void setReqTime(String reqTime) { this.reqTime = reqTime; } diff --git a/op-auth/src/main/resources/bootstrap.yml b/op-auth/src/main/resources/bootstrap.yml index 759df4ad..b455d9dd 100644 --- a/op-auth/src/main/resources/bootstrap.yml +++ b/op-auth/src/main/resources/bootstrap.yml @@ -17,12 +17,12 @@ spring: # 服务注册地址 #--spring.cloud.nacos.discovery.namespace=chj --spring.cloud.nacos.config.namespace=chj namespace: lanju-op - group: chj + group: zxl server-addr: 140.249.53.142:8848 config: #命名空间 namespace: lanju-op - group: chj + group: zxl # 配置中心地址 server-addr: 140.249.53.142:8848 # 配置文件格式 diff --git a/op-common/op-common-core/src/main/java/com/op/common/core/utils/poi/ExcelUtilDailyReport.java b/op-common/op-common-core/src/main/java/com/op/common/core/utils/poi/ExcelUtilDailyReport.java new file mode 100644 index 00000000..eea4bd25 --- /dev/null +++ b/op-common/op-common-core/src/main/java/com/op/common/core/utils/poi/ExcelUtilDailyReport.java @@ -0,0 +1,1481 @@ +package com.op.common.core.utils.poi; + +import com.op.common.core.annotation.Excel; +import com.op.common.core.annotation.Excel.ColumnType; +import com.op.common.core.annotation.Excel.Type; +import com.op.common.core.annotation.Excels; +import com.op.common.core.text.Convert; +import com.op.common.core.utils.DateUtils; +import com.op.common.core.utils.StringUtils; +import com.op.common.core.utils.file.FileTypeUtils; +import com.op.common.core.utils.file.ImageUtils; +import com.op.common.core.utils.reflect.ReflectUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; + +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Excel相关处理 + * + * @author OP + */ +public class ExcelUtilDailyReport { + private static final Logger log = LoggerFactory.getLogger(ExcelUtilDailyReport.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtilDailyReport(Class clazz) { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) { + if (list == null) { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + //createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() { + if (StringUtils.isNotEmpty(title)) { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), + titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() { + if (isSubList()) { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles + .get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(InputStream is) throws Exception { + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception { + return importExcel(StringUtils.EMPTY, is, titleNum); + } + + /** + * 对excel表单指定表格索引名转换成list + * + * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 + * @param is 输入流 + * @return 转换后集合 + */ + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception { + this.type = Type.IMPORT; + this.wb = WorkbookFactory.create(is); + List list = new ArrayList(); + // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet + Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); + if (sheet == null) { + throw new IOException("文件sheet不存在"); + } + + // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 + int rows = sheet.getLastRowNum(); + + if (rows > 0) { + // 定义一个map用于存放excel列的序号和field. + Map cellMap = new HashMap(); + // 获取表头 + Row heard = sheet.getRow(titleNum); + for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { + Cell cell = heard.getCell(i); + if (StringUtils.isNotNull(cell)) { + String value = this.getCellValue(heard, i).toString(); + cellMap.put(value, i); + } else { + cellMap.put(null, i); + } + } + // 有数据时才处理 得到类的所有field. + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) { + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) { + fieldsMap.put(column, objects); + } + } + for (int i = titleNum + 1; i <= rows; i++) { + // 从第2行开始取数据,默认第一行是表头. + Row row = sheet.getRow(i); + // 判断当前行是否是空行 + if (isRowEmpty(row)) { + continue; + } + T entity = null; + for (Map.Entry entry : fieldsMap.entrySet()) { + Object val = this.getCellValue(row, entry.getKey()); + + // 如果不存在实例则新建. + entity = (entity == null ? clazz.newInstance() : entity); + // 从map中得到对应列的field. + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; + // 取得类型,并根据对象类型设置值. + Class fieldType = field.getType(); + if (String.class == fieldType) { + String s = Convert.toStr(val); + if (StringUtils.endsWith(s, ".0")) { + val = StringUtils.substringBefore(s, ".0"); + } else { + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) { + val = parseDateToStr(dateFormat, val); + } else { + val = Convert.toStr(val); + } + } + } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) + && StringUtils.isNumeric(Convert.toStr(val))) { + val = Convert.toInt(val); + } else if ((Long.TYPE == fieldType || Long.class == fieldType) + && StringUtils.isNumeric(Convert.toStr(val))) { + val = Convert.toLong(val); + } else if (Double.TYPE == fieldType || Double.class == fieldType) { + val = Convert.toDouble(val); + } else if (Float.TYPE == fieldType || Float.class == fieldType) { + val = Convert.toFloat(val); + } else if (BigDecimal.class == fieldType) { + val = Convert.toBigDecimal(val); + } else if (Date.class == fieldType) { + if (val instanceof String) { + val = DateUtils.parseDate(val); + } else if (val instanceof Double) { + val = DateUtil.getJavaDate((Double) val); + } + } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) { + val = Convert.toBool(val, false); + } + if (StringUtils.isNotNull(fieldType)) { + String propertyName = field.getName(); + if (StringUtils.isNotEmpty(attr.targetAttr())) { + propertyName = field.getName() + "." + attr.targetAttr(); + } else if (StringUtils.isNotEmpty(attr.readConverterExp())) { + val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); + } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { + val = dataFormatHandlerAdapter(val, attr); + } + ReflectUtils.invokeSetter(entity, propertyName, val); + } + } + list.add(entity); + } + } + return list; + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName) { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(null, sheetName, title, Type.IMPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) { + try { + writeSheet(); + wb.write(response.getOutputStream()); + } catch (Exception e) { + log.error("导出Excel异常{}", e.getMessage()); + } finally { + IOUtils.closeQuietly(wb); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() throws Exception{ + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) { + createSheet(sheetNo, index); + + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + //大标题 + Row row0 = sheet.createRow(0);//第一行 + row0.setHeightInPoints(50); + Cell cell = row0.createCell(0); + cell.setCellValue(title); + cell.setCellStyle(style); + sheet.addMergedRegion(new CellRangeAddress(0,0,0,20)); + + + + Row row1 = sheet.createRow(1);//第二行 + Row row2 = sheet.createRow(2);//第三行 + row0.setHeightInPoints(45); + CellStyle style0 = wb.createCellStyle(); + style0.setAlignment(HorizontalAlignment.CENTER); + style0.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont1 = wb.createFont(); + titleFont1.setFontName("Arial"); + titleFont1.setFontHeightInPoints((short) 13); + titleFont1.setBold(true); + style0.setFont(titleFont1); + style0.setBorderRight(BorderStyle.THIN); + style0.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style0.setBorderLeft(BorderStyle.THIN); + style0.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style0.setBorderTop(BorderStyle.THIN); + style0.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style0.setBorderBottom(BorderStyle.THIN); + style0.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style0.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex()); + style0.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Cell cell0 = row1.createCell(0); + cell0.setCellValue("组别"); + cell0.setCellStyle(style0); + Cell cell_02 = row2.createCell(0); + cell_02.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,0,0)); + + Cell cell1 = row1.createCell(1); + cell1.setCellValue("分类"); + cell1.setCellStyle(style0); + Cell cell_12 = row2.createCell(1); + cell_12.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,1,1)); + + Cell cell2 = row1.createCell(2); + cell2.setCellValue("组长"); + cell2.setCellStyle(style0); + Cell cell_13 = row2.createCell(2); + cell_13.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,2,2)); + + Cell cell3 = row1.createCell(3); + cell3.setCellValue("产品编码"); + cell3.setCellStyle(style0); + Cell cell_14 = row2.createCell(3); + cell_14.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,3,3)); + + Cell cell4 = row1.createCell(4); + cell4.setCellValue("规格"); + cell4.setCellStyle(style0); + Cell cell_15 = row2.createCell(4); + cell_15.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,4,4)); + + Cell cell5 = row1.createCell(5); + cell5.setCellValue("产品名称"); + cell5.setCellStyle(style0); + Cell cell_16 = row2.createCell(5); + cell_16.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,5,5)); + + Cell cell6 = row1.createCell(6); + cell6.setCellValue("单位"); + cell6.setCellStyle(style0); + Cell cell_17 = row2.createCell(6); + cell_17.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,6,6)); + + Cell cell7 = row1.createCell(7); + cell7.setCellValue("本日产量"); + cell7.setCellStyle(style0); + Cell cell8 = row1.createCell(8); + cell8.setCellStyle(style0); + Cell cell9 = row1.createCell(9); + cell9.setCellStyle(style0); + Cell cell10 = row1.createCell(10); + cell10.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,1,7,10)); + + Cell cell11 = row1.createCell(11); + cell11.setCellValue("标准效率\n(PC/H)"); + cell11.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,11,11)); + + Cell cell12 = row1.createCell(12); + cell12.setCellValue("用人"); + cell12.setCellStyle(style0); + Cell cell13 = row1.createCell(13); + cell13.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,1,12,13)); + + Cell cell14 = row1.createCell(14); + cell14.setCellValue("工时"); + cell14.setCellStyle(style0); + Cell cell15 = row1.createCell(15); + cell15.setCellStyle(style0); + Cell cell16 = row1.createCell(16); + cell16.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,1,14,16)); + + Cell cell17 = row1.createCell(17); + cell17.setCellValue("人均效率"); + cell17.setCellStyle(style0); + Cell cell18 = row1.createCell(18); + cell18.setCellStyle(style0); + Cell cell19 = row1.createCell(19); + cell19.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,1,17,19)); + + Cell cell20 = row1.createCell(20); + cell20.setCellValue("实际人工时"); + cell20.setCellStyle(style0); + sheet.addMergedRegion(new CellRangeAddress(1,2,20,20)); + + + row2.setHeightInPoints(45); + Cell cell27 = row2.createCell(7); + cell27.setCellValue("计划"); + cell27.setCellStyle(style0); + Cell cell28 = row2.createCell(8); + cell28.setCellValue("实际"); + cell28.setCellStyle(style0); + Cell cell29 = row2.createCell(9); + cell29.setCellValue("盒量"); + cell29.setCellStyle(style0); + Cell cell210 = row2.createCell(10); + cell210.setCellValue("完成率"); + cell210.setCellStyle(style0); + Cell cell212 = row2.createCell(12); + cell212.setCellValue("标准");//createCell(1)位置 + cell212.setCellStyle(style0); + Cell cell213 = row2.createCell(13); + cell213.setCellValue("实际"); + cell213.setCellStyle(style0); + Cell cell214 = row2.createCell(14); + cell214.setCellValue("标准"); + cell214.setCellStyle(style0); + Cell cell215=row2.createCell(15); + cell215.setCellValue("实际"); + cell215.setCellStyle(style0); + Cell cell216 = row2.createCell(16); + cell216.setCellValue("产线效率"); + cell216.setCellStyle(style0); + Cell cell217 = row2.createCell(17); + cell217.setCellValue("标准"); + cell217.setCellStyle(style0); + Cell cell218 = row2.createCell(18); + cell218.setCellValue("实际"); + cell218.setCellStyle(style0); + Cell cell219 = row2.createCell(19); + cell219.setCellValue("达成"); + cell219.setCellStyle(style0); + + CellStyle style2 = wb.createCellStyle(); + style2.setAlignment(HorizontalAlignment.CENTER); + style2.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont2 = wb.createFont(); + titleFont2.setFontName("Arial"); + titleFont2.setFontHeightInPoints((short) 13); + style2.setFont(titleFont2); + style2.setBorderRight(BorderStyle.THIN); + style2.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style2.setBorderLeft(BorderStyle.THIN); + style2.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style2.setBorderTop(BorderStyle.THIN); + style2.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style2.setBorderBottom(BorderStyle.THIN); + style2.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + + + for(int r = 0;r 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) { + if (isSubListValue(vo)) { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } else { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) { + boolean subFirst = false; + for (Object obj : subList) { + if (subFirst) { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) { + if (subField.isAnnotationPresent(Excel.class)) { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } else { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) { + Map headerStyles = new HashMap(); + for (Object[] os : fields) { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) { + Map styles = new HashMap(); + for (Object[] os : fields) { + Excel excel = (Excel) os[1]; + String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor()); + if (!styles.containsKey(key)) { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + styles.put(key, style); + } + } + return styles; + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle( + styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles + .get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + if (attr.needMerge()) { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) { + if (ColumnType.STRING == attr.cellType()) { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } else if (ColumnType.NUMERIC == attr.cellType()) { + if (StringUtils.isNotNull(value)) { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) + : Convert.toInt(value)); + } + } else if (ColumnType.IMAGE == attr.cellType()) { + ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), + cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); + String imagePath = Convert.toStr(value); + if (StringUtils.isNotEmpty(imagePath)) { + byte[] data = ImageUtils.getImage(imagePath); + getDrawingPatriarch(cell.getSheet()).createPicture(anchor, + cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); + } + } + } + + /** + * 获取画布 + */ + public static Drawing getDrawingPatriarch(Sheet sheet) { + if (sheet.getDrawingPatriarch() == null) { + sheet.createDrawingPatriarch(); + } + return sheet.getDrawingPatriarch(); + } + + /** + * 获取图片类型,设置图片插入类型 + */ + public int getImageType(byte[] value) { + String type = FileTypeUtils.getFileExtendName(value); + if ("JPG".equalsIgnoreCase(type)) { + return Workbook.PICTURE_TYPE_JPEG; + } else if ("PNG".equalsIgnoreCase(type)) { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) { + if (attr.name().indexOf("注:") >= 0) { + sheet.setColumnWidth(column, 6000); + } else { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) { + if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255) { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } else { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) { + Cell cell = null; + try { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, + column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles + .get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } else if (value instanceof BigDecimal && -1 != attr.scale()) { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { + cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + } else { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } catch (Exception e) { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) + : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } else { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, + int endRow, int firstCol, int endCol) { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } else { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) { + for (String value : propertyValue.split(separator)) { + if (itemArray[0].equals(value)) { + propertyString.append(itemArray[1] + separator); + break; + } + } + } else { + if (itemArray[0].equals(propertyValue)) { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) { + for (String value : propertyValue.split(separator)) { + if (itemArray[1].equals(value)) { + propertyString.append(itemArray[0] + separator); + break; + } + } + } else { + if (itemArray[1].equals(propertyValue)) { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel) { + try { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); + value = formatMethod.invoke(instance, value, excel.args()); + } catch (Exception e) { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) { + if (entity != null && entity.isStatistics()) { + Double temp = 0D; + if (!statistics.containsKey(index)) { + statistics.put(index, temp); + } + try { + temp = Double.valueOf(text); + } catch (NumberFormatException e) { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() { + if (statistics.size() > 0) { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) { + String target = excel.targetAttr(); + if (target.contains(".")) { + String[] targets = target.split("[.]"); + for (String name : targets) { + o = getValue(o, name); + } + } else { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception { + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())) + .collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) { + if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() { + double maxHeight = 0; + for (Object[] os : this.fields) { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) { + this.sheet = wb.createSheet(); + //this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) { + if (row == null) { + return row; + } + Object val = ""; + try { + Cell cell = row.getCell(column); + if (StringUtils.isNotNull(cell)) { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } else { + if ((Double) val % 1 != 0) { + val = new BigDecimal(val.toString()); + } else { + val = new DecimalFormat("0").format(val); + } + } + } else if (cell.getCellType() == CellType.STRING) { + val = cell.getStringCellValue(); + } else if (cell.getCellType() == CellType.BOOLEAN) { + val = cell.getBooleanCellValue(); + } else if (cell.getCellType() == CellType.ERROR) { + val = cell.getErrorCellValue(); + } + + } + } catch (Exception e) { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) { + if (row == null) { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) { + return false; + } + } + return true; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) { + if (val == null) { + return ""; + } + String str; + if (val instanceof Date) { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } else if (val instanceof LocalDateTime) { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } else if (val instanceof LocalDate) { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } else { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() { + return StringUtils.isNotNull(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) { + return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) + && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) { + Object value; + try { + value = subMethod.invoke(obj, new Object[] {}); + } catch (Exception e) { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } catch (Exception e) { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/op-modules/op-mes/src/main/java/com/op/mes/controller/MesReportWorkController.java b/op-modules/op-mes/src/main/java/com/op/mes/controller/MesReportWorkController.java index d5953e87..f2b71fd5 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/controller/MesReportWorkController.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/controller/MesReportWorkController.java @@ -3,10 +3,14 @@ package com.op.mes.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; +import com.op.common.core.utils.DateUtils; import com.op.common.core.utils.uuid.IdUtils; import com.op.mes.domain.MesDailyReport; import com.op.mes.domain.MesProcessReport; import com.op.mes.domain.MesReportProduction; +import com.op.mes.domain.dto.SysFactoryDto; +import com.op.mes.mapper.MesReportWorkMapper; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -25,7 +29,7 @@ import com.op.common.core.web.controller.BaseController; import com.op.common.core.web.domain.AjaxResult; import com.op.common.core.utils.poi.ExcelUtil; import com.op.common.core.web.page.TableDataInfo; - +import com.op.common.core.utils.poi.ExcelUtilDailyReport; /** * 报工报表Controller * @@ -37,7 +41,8 @@ import com.op.common.core.web.page.TableDataInfo; public class MesReportWorkController extends BaseController { @Autowired private IMesReportWorkService mesReportWorkService; - + @Autowired + private MesReportWorkMapper mesReportWorkMapper; /** * 查询报工报表列表 */ @@ -140,7 +145,7 @@ public class MesReportWorkController extends BaseController { * 获取产量报表导出 */ @RequiresPermissions("mes:production:list") - @GetMapping("/productionExport") + @PostMapping("/productionExport") public void productionExport(HttpServletResponse response, MesReportProduction mesReportProduction) { List list = mesReportWorkService.getProductionList(mesReportProduction); ExcelUtil util = new ExcelUtil(MesReportProduction.class); @@ -153,10 +158,29 @@ public class MesReportWorkController extends BaseController { @RequiresPermissions("mes:dailyReport:list") @GetMapping("/getDailyReport") public TableDataInfo getDailyReport(MesDailyReport mesDailyReport) { + + if(!StringUtils.isNotBlank(mesDailyReport.getWorkCenter())){ + return null; + } + startPage(); List list = mesReportWorkService.getDailyReport(mesDailyReport); return getDataTable(list); } + @RequiresPermissions("mes:dailyReport:list") + @PostMapping("/getDailyReportExport") + public void getDailyReportExport(HttpServletResponse response,MesDailyReport mesDailyReport) { + List list = mesReportWorkService.getDailyReport(mesDailyReport); + String ymd = DateUtils.parseDateToStr("yyyy-MM-dd",mesDailyReport.getProductDate()); + String titleName = "("+mesReportWorkService.getTitleName(mesDailyReport)+")车间"+ymd+"生产日报表"; + ExcelUtilDailyReport util = new ExcelUtilDailyReport(MesDailyReport.class); + util.exportExcel(response, list, ymd+"生产日报表",titleName); + } + + @GetMapping("/getWorkcenterList") + public List getWorkcenterList(MesDailyReport mesDailyReport) { + return mesReportWorkService.getWorkcenterList(mesDailyReport); + } } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/controller/WCSInterfaceController.java b/op-modules/op-mes/src/main/java/com/op/mes/controller/WCSInterfaceController.java index d2eb1b8c..ec1bfd24 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/controller/WCSInterfaceController.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/controller/WCSInterfaceController.java @@ -23,86 +23,7 @@ public class WCSInterfaceController extends BaseController { @Autowired private IWCSInterfaceService WCInterfaceService; -// /** -// * 接料请求 -// * @param -// * @return -// */ -// @Log(title = "请求接料", businessType = BusinessType.WCS_requestMaterialLoadNo) -// @PostMapping("/requestMaterialLoadNo") -// public WCSDTO requestMaterialLoadNo(@RequestBody WCSDTO wcsdto) { -// if(StringUtils.isBlank(wcsdto.getFactory())){ -// wcsdto.setCode("1"); -// wcsdto.setMessage("factory is not null"); -// return wcsdto; -// } -// return WCInterfaceService.requestMaterialLoadNo(wcsdto); -// } -// -// /** -// * 接料完成(用不上) -// * @param -// * @return -// */ -// @Log(title = "接料完成", businessType = BusinessType.WCS) -// @PostMapping("/loadMaterialCompleted") -// public WCSDTO loadMaterialCompleted(@RequestBody WCSDTO wcsdto) { -// if(StringUtils.isBlank(wcsdto.getFactory())){ -// wcsdto.setCode("1"); -// wcsdto.setMessage("factory is not null"); -// return wcsdto; -// } -// return WCInterfaceService.loadMaterialCompleted(wcsdto); -// } -// -// /** -// * RGV 请求送料 -// * @param -// * @return -// */ -// //TODO; -// @Log(title = "请求送料", businessType = BusinessType.WCS) -// @PostMapping("/requestMaterialUnLoadNo") -// public WCSDTO requestMaterialUnLoadNo(@RequestBody WCSDTO wcsdto) { -// if(StringUtils.isBlank(wcsdto.getFactory())){ -// wcsdto.setCode("1"); -// wcsdto.setMessage("factory is not null"); -// return wcsdto; -// } -// return WCInterfaceService.requestMaterialUnLoadNo(wcsdto); -// } -// /** -// * RGV 送料完成 -// * @param -// * @return -// */ -// //TODO; -// @Log(title = "送料完成", businessType = BusinessType.WCS) -// @PostMapping("/unLoadMaterialCompleted") -// public WCSDTO unLoadMaterialCompleted(@RequestBody WCSDTO wcsdto) { -// if(StringUtils.isBlank(wcsdto.getFactory())){ -// wcsdto.setCode("1"); -// wcsdto.setMessage("factory is not null"); -// return wcsdto; -// } -// return WCInterfaceService.requestMaterialUnLoadNo(wcsdto); -// } -// /** -// * 生产机台到位信号 -// * •空筛盘车到达成型机吊筛处,筛盘车到达烘房、筛盘车到达收坯吊筛处 -// * @param -// * @return -// */ -// @Log(title = "生产机台到位信号", businessType = BusinessType.WCS) -// @PostMapping("/stationArrive") -// public WCSDTO stationArrive(@RequestBody WCSDTO wcsdto) { -// if(StringUtils.isBlank(wcsdto.getFactory())){ -// wcsdto.setCode("1"); -// wcsdto.setMessage("factory is not null"); -// return wcsdto; -// } -// return WCInterfaceService.stationArrive(wcsdto); -// } + /** * 下一工序机台集合获取 * •接口描述:成型机码垛完、暂存区、WCS 请求 MES 获取目的地集合 @@ -121,15 +42,4 @@ public class WCSInterfaceController extends BaseController { return WCInterfaceService.requestDestinationStations(wcsdto); } - /**********************手持接口**********************/ - @Log(title = "手持获取当前登陆人信息", businessType = BusinessType.GRANT) - @PostMapping("/handGetUserInfo") - public WCSDTO handGetUserInfo(@RequestBody WCSDTO wcsdto) { - if(StringUtils.isBlank(wcsdto.getFactory())){ - wcsdto.setCode("1"); - wcsdto.setMessage("factory is not null"); - return wcsdto; - } - return WCInterfaceService.requestDestinationStations(wcsdto); - } } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/domain/dto/SysFactoryDto.java b/op-modules/op-mes/src/main/java/com/op/mes/domain/dto/SysFactoryDto.java new file mode 100644 index 00000000..fd1c1968 --- /dev/null +++ b/op-modules/op-mes/src/main/java/com/op/mes/domain/dto/SysFactoryDto.java @@ -0,0 +1,126 @@ +package com.op.mes.domain.dto; + +import com.op.common.core.annotation.Excel; +import com.op.common.core.web.domain.TreeEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 工厂模型对象 sys_factory + * + * @author Open Platform + * @date 2023-07-03 + */ +public class SysFactoryDto extends TreeEntity { + private static final long serialVersionUID = 1L; + + /** 工厂id */ + private Long factoryId; + + /** 部门名称 */ + @Excel(name = "工厂名称") + private String factoryName; + + /** 负责人 */ + @Excel(name = "负责人") + private String leader; + + /** 联系电话 */ + @Excel(name = "联系电话") + private String phone; + + /** 邮箱 */ + @Excel(name = "邮箱") + private String email; + + /** 部门状态(0正常 */ + @Excel(name = "工厂状态") + private String status; + + /** 删除标志(0代表存在 */ + private String delFlag; + + /** 工厂编码 */ + @Excel(name = "工厂编码") + private String factoryCode; + + public void setFactoryId(Long factoryId) { + this.factoryId = factoryId; + } + + public Long getFactoryId() { + return factoryId; + } + + public void setFactoryName(String factoryName) { + this.factoryName = factoryName; + } + + public String getFactoryName() { + return factoryName; + } + + public void setLeader(String leader) { + this.leader = leader; + } + + public String getLeader() { + return leader; + } + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPhone() { + return phone; + } + public void setEmail(String email) { + this.email = email; + } + + public String getEmail() { + return email; + } + public void setStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } + public void setDelFlag(String delFlag) { + this.delFlag = delFlag; + } + + public String getDelFlag() { + return delFlag; + } + + public String getFactoryCode() { + return factoryCode; + } + public void setFactoryCode(String factoryCode) { + this.factoryCode = factoryCode; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("factoryId", getFactoryId()) + .append("parentId", getParentId()) + .append("ancestors", getAncestors()) + .append("factoryName", getFactoryName()) + .append("orderNum", getOrderNum()) + .append("leader", getLeader()) + .append("phone", getPhone()) + .append("email", getEmail()) + .append("status", getStatus()) + .append("delFlag", getDelFlag()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("factoryCode", getFactoryCode()) + .toString(); + } +} diff --git a/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesReportWorkMapper.java b/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesReportWorkMapper.java index 7a665776..e9c23eb1 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesReportWorkMapper.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/mapper/MesReportWorkMapper.java @@ -6,6 +6,7 @@ import com.op.mes.domain.MesDailyReport; import com.op.mes.domain.MesProcessReport; import com.op.mes.domain.MesReportProduction; import com.op.mes.domain.MesReportWork; +import com.op.mes.domain.dto.SysFactoryDto; /** * 报工报表Mapper接口 @@ -71,4 +72,8 @@ public interface MesReportWorkMapper { public void updateSyncSapStatus(MesReportWork work); public List getDailyReport(MesDailyReport mesDailyReport); + + String getTitleName(MesDailyReport mesDailyReport); + + List getWorkcenterList(MesDailyReport mesDailyReport); } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/service/IMesReportWorkService.java b/op-modules/op-mes/src/main/java/com/op/mes/service/IMesReportWorkService.java index 34cf877e..de6e661e 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/service/IMesReportWorkService.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/service/IMesReportWorkService.java @@ -6,6 +6,7 @@ import com.op.mes.domain.MesDailyReport; import com.op.mes.domain.MesProcessReport; import com.op.mes.domain.MesReportProduction; import com.op.mes.domain.MesReportWork; +import com.op.mes.domain.dto.SysFactoryDto; /** * 报工报表Service接口 @@ -67,4 +68,8 @@ public interface IMesReportWorkService { public List getProductionList(MesReportProduction mesReportProduction); public List getDailyReport(MesDailyReport mesDailyReport); + + String getTitleName(MesDailyReport mesDailyReport); + + List getWorkcenterList(MesDailyReport mesDailyReport); } diff --git a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/IWCInterfaceServiceImpl.java b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/IWCInterfaceServiceImpl.java index a455733d..5aacde51 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/IWCInterfaceServiceImpl.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/IWCInterfaceServiceImpl.java @@ -116,9 +116,10 @@ public class IWCInterfaceServiceImpl implements IWCSInterfaceService { wCSDataDTO = new WCSDataDTO(); if(StringUtils.isNotBlank(machineCode)){ wCSDataDTO.setStationNo(machineCode); + stationNos.add(wCSDataDTO); } - } + dto.setStationNos(stationNos); } return dto; diff --git a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesReportWorkServiceImpl.java b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesReportWorkServiceImpl.java index e059e3ab..6cf28f96 100644 --- a/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesReportWorkServiceImpl.java +++ b/op-modules/op-mes/src/main/java/com/op/mes/service/impl/MesReportWorkServiceImpl.java @@ -9,6 +9,7 @@ import com.op.common.core.utils.DateUtils; import com.op.mes.domain.MesDailyReport; import com.op.mes.domain.MesProcessReport; import com.op.mes.domain.MesReportProduction; +import com.op.mes.domain.dto.SysFactoryDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.op.mes.mapper.MesReportWorkMapper; @@ -213,4 +214,16 @@ public class MesReportWorkServiceImpl implements IMesReportWorkService { return dtos; } + @Override + @DS("#header.poolName") + public String getTitleName(MesDailyReport mesDailyReport) { + return mesReportWorkMapper.getTitleName(mesDailyReport); + } + + @Override + @DS("#header.poolName") + public List getWorkcenterList(MesDailyReport mesDailyReport) { + return mesReportWorkMapper.getWorkcenterList(mesDailyReport); + } + } diff --git a/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml b/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml index 0432beda..2b9e2ce2 100644 --- a/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml +++ b/op-modules/op-mes/src/main/resources/mapper/mes/MesReportWorkMapper.xml @@ -201,6 +201,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and mrw.work_center = #{workCenter} order by ow.workorder_code + + insert into mes_report_work diff --git a/op-modules/op-mes/src/main/resources/mapper/mes/ProRfidProcessDetailMapper.xml b/op-modules/op-mes/src/main/resources/mapper/mes/ProRfidProcessDetailMapper.xml index cc41b14d..70e27160 100644 --- a/op-modules/op-mes/src/main/resources/mapper/mes/ProRfidProcessDetailMapper.xml +++ b/op-modules/op-mes/src/main/resources/mapper/mes/ProRfidProcessDetailMapper.xml @@ -77,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join pro_order_workorder w on w.workorder_code = rfid.workorder_code left join base_product bp on bp.product_code = w.product_code where rfid.bind_status = '1' + and rfid.rfid = #{rfidNo} + update sys_menu