From b7cdd10f9f97bf01de65f9ba46a6daffec2b93e4 Mon Sep 17 00:00:00 2001 From: X.B-H <xbh_323@yeah.net> Date: 星期三, 06 一月 2021 11:11:11 +0800 Subject: [PATCH] 修复导入数据为负浮点数时丢失精度问题 --- ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 124 +++++++++++++++++++++++++++++++++++------ 1 files changed, 105 insertions(+), 19 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index d9f4efd..dcba68e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -18,15 +18,16 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; @@ -38,6 +39,7 @@ import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.util.CellRangeAddressList; 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; @@ -52,6 +54,8 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileTypeUtils; +import com.ruoyi.common.utils.file.ImageUtils; import com.ruoyi.common.utils.reflect.ReflectUtils; /** @@ -104,15 +108,20 @@ private List<Object[]> fields; /** + * 最大高度 + */ + private short maxHeight; + + /** * 统计列表 */ private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); - + /** * 数字格式 */ private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); - + /** * 实体对象 */ @@ -240,7 +249,15 @@ } else { - val = Convert.toStr(val); + String dateFormat = field.getAnnotation(Excel.class).dateFormat(); + if (StringUtils.isNotEmpty(dateFormat)) + { + val = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else + { + val = Convert.toStr(val); + } } } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) @@ -473,6 +490,21 @@ style.setFont(totalFont); styles.put("total", style); + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.LEFT); + styles.put("data1", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + styles.put("data2", style); + + style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.RIGHT); + styles.put("data3", style); + return styles; } @@ -501,14 +533,53 @@ { if (ColumnType.STRING == attr.cellType()) { - cell.setCellType(CellType.STRING); cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); } else if (ColumnType.NUMERIC == attr.cellType()) { - cell.setCellType(CellType.NUMERIC); 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; } /** @@ -524,7 +595,6 @@ { // 设置列宽 sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); - row.setHeight((short) (attr.height() * 20)); } // 如果设置了提示信息则鼠标放上去提示. if (StringUtils.isNotEmpty(attr.prompt())) @@ -549,13 +619,14 @@ try { // 设置行高 - row.setHeight((short) (attr.height() * 20)); + row.setHeight(maxHeight); // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. if (attr.isExport()) { // 创建cell cell = row.createCell(column); - cell.setCellStyle(styles.get("data")); + int align = attr.align().value(); + cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : ""))); // 用于读取对象中的属性 Object value = getTargetValue(vo, field, attr); @@ -724,7 +795,7 @@ } return StringUtils.stripEnd(propertyString.toString(), separator); } - + /** * 解析字典值 * @@ -750,7 +821,7 @@ { return DictUtils.getDictValue(dictType, dictLabel, separator); } - + /** * 合计统计信息 */ @@ -787,7 +858,7 @@ cell = row.createCell(0); cell.setCellStyle(styles.get("total")); cell.setCellValue("合计"); - + for (Integer key : keys) { cell = row.createCell(key); @@ -864,7 +935,7 @@ */ private Object getValue(Object o, String name) throws Exception { - if (StringUtils.isNotEmpty(name)) + if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { Class<?> clazz = o.getClass(); Field field = clazz.getDeclaredField(name); @@ -903,6 +974,21 @@ } } this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = maxHeight > excel.height() ? maxHeight : excel.height(); + } + return (short) (maxHeight * 20); } /** @@ -964,16 +1050,16 @@ Cell cell = row.getCell(column); if (StringUtils.isNotNull(cell)) { - if (cell.getCellTypeEnum() == CellType.NUMERIC || cell.getCellTypeEnum() == CellType.FORMULA) + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) { val = cell.getNumericCellValue(); - if (HSSFDateUtil.isCellDateFormatted(cell)) + if (DateUtil.isCellDateFormatted(cell)) { val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 } else { - if ((Double) val % 1 > 0) + if ((Double) val % 1 != 0) { val = new BigDecimal(val.toString()); } @@ -983,15 +1069,15 @@ } } } - else if (cell.getCellTypeEnum() == CellType.STRING) + else if (cell.getCellType() == CellType.STRING) { val = cell.getStringCellValue(); } - else if (cell.getCellTypeEnum() == CellType.BOOLEAN) + else if (cell.getCellType() == CellType.BOOLEAN) { val = cell.getBooleanCellValue(); } - else if (cell.getCellTypeEnum() == CellType.ERROR) + else if (cell.getCellType() == CellType.ERROR) { val = cell.getErrorCellValue(); } -- Gitblit v1.9.2