From fba7ffe77c5b9295b06b177cef3025b6d47ed48a Mon Sep 17 00:00:00 2001 From: RuoYi <yzz_ivy@163.com> Date: 星期一, 06 二月 2023 11:40:33 +0800 Subject: [PATCH] 修复匿名注解Anonymous空指针问题(I683DT) --- src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 271 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 7e28837..e6f069c 100644 --- a/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -7,12 +7,14 @@ import java.io.OutputStream; 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.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashMap; @@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFPicture; import org.apache.poi.hssf.usermodel.HSSFPictureData; @@ -45,6 +48,7 @@ import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.PictureData; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; @@ -150,6 +154,26 @@ private short maxHeight; /** + * 鍚堝苟鍚庢渶鍚庤鏁� + */ + private int subMergedLastRowNum = 0; + + /** + * 鍚堝苟鍚庡紑濮嬭鏁� + */ + private int subMergedFirstRowNum = 1; + + /** + * 瀵硅薄鐨勫瓙鍒楄〃鏂规硶 + */ + private Method subMethod; + + /** + * 瀵硅薄鐨勫瓙鍒楄〃灞炴�� + */ + private List<Field> subFields; + + /** * 缁熻鍒楄〃 */ private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); @@ -198,6 +222,7 @@ createExcelField(); createWorkbook(); createTitle(); + createSubHead(); } /** @@ -207,13 +232,48 @@ { 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(), - this.fields.size() - 1)); + 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++; } } @@ -593,8 +653,20 @@ // 鍐欏叆鍚勪釜瀛楁鐨勫垪澶村悕绉� for (Object[] os : fields) { + Field field = (Field) os[0]; Excel excel = (Excel) os[1]; - this.createCell(excel, row, column++); + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } } if (Type.EXPORT.equals(type)) { @@ -610,21 +682,67 @@ * @param index 搴忓彿 * @param row 鍗曞厓鏍艰 */ + @SuppressWarnings("unchecked") public void fillExcelData(int index, Row row) { int startNo = index * sheetSize; int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; for (int i = startNo; i < endNo; i++) { - row = sheet.createRow(i + 1 + rownum - startNo); + rowNo = isSubList() ? (i > 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]; - this.addCell(excel, row, vo, field, column++); + if (Collection.class.isAssignableFrom(field.getType()) && StringUtils.isNotNull(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List<Field> 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++); + } } } } @@ -698,7 +816,6 @@ if (!headerStyles.containsKey(key)) { CellStyle style = wb.createCellStyle(); - style = wb.createCellStyle(); style.cloneStyleFrom(styles.get("data")); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); @@ -732,7 +849,6 @@ if (!styles.containsKey(key)) { CellStyle style = wb.createCellStyle(); - style = wb.createCellStyle(); style.setAlignment(excel.align()); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setBorderRight(BorderStyle.THIN); @@ -759,7 +875,7 @@ /** * 鍒涘缓鍗曞厓鏍� */ - public Cell createCell(Excel attr, Row row, int column) + public Cell createHeadCell(Excel attr, Row row, int column) { // 鍒涘缓鍒� Cell cell = row.createCell(column); @@ -767,6 +883,15 @@ 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; } @@ -786,6 +911,10 @@ 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()); } @@ -854,8 +983,16 @@ } if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) { - // 鎻愮ず淇℃伅鎴栧彧鑳介�夋嫨涓嶈兘杈撳叆鐨勫垪鍐呭. - setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); + 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); + } } } @@ -874,6 +1011,11 @@ { // 鍒涘缓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()))); // 鐢ㄤ簬璇诲彇瀵硅薄涓殑灞炴�� @@ -896,7 +1038,7 @@ } else if (value instanceof BigDecimal && -1 != attr.scale()) { - cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString()); + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) { @@ -955,6 +1097,58 @@ } /** + * 璁剧疆鏌愪簺鍒楃殑鍊煎彧鑳借緭鍏ラ鍒剁殑鏁版嵁,鏄剧ず涓嬫媺妗嗭紙鍏煎瓒呭嚭涓�瀹氭暟閲忕殑涓嬫媺妗嗭級. + * + * @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); + } + + /** * 瑙f瀽瀵煎嚭鍊� 0=鐢�,1=濂�,2=鏈煡 * * @param propertyValue 鍙傛暟鍊� @@ -969,7 +1163,7 @@ for (String item : convertSource) { String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) + if (StringUtils.containsAny(propertyValue, separator)) { for (String value : propertyValue.split(separator)) { @@ -1006,7 +1200,7 @@ for (String item : convertSource) { String[] itemArray = item.split("="); - if (StringUtils.containsAny(separator, propertyValue)) + if (StringUtils.containsAny(propertyValue, separator)) { for (String value : propertyValue.split(separator)) { @@ -1229,6 +1423,13 @@ { 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); } } @@ -1473,4 +1674,61 @@ } 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<Object>(); + } + 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; + } } -- Gitblit v1.9.3