From 90742aa5e9d2c596623017d5c9de1be9b3a5fc45 Mon Sep 17 00:00:00 2001 From: zhangdaiscott Date: Mon, 10 Apr 2023 10:23:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=88=B0=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC1.4.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- autopoi-web/pom.xml | 2 +- autopoi/pom.xml | 2 +- .../poi/excel/entity/ImportParams.java | 13 +++ .../poi/excel/export/ExcelExportServer.java | 4 +- .../template/ExcelExportOfTemplateUtil.java | 12 ++- .../excel/html/helper/MergedRegionHelper.java | 48 ++++++++- .../poi/excel/imports/CellValueServer.java | 11 +- .../poi/excel/imports/ExcelImportServer.java | 12 +++ .../poi/util/PoiExcelTempUtil.java | 102 ++++++++++++++++++ pom.xml | 4 +- 11 files changed, 199 insertions(+), 17 deletions(-) create mode 100644 autopoi/src/main/java/org/jeecgframework/poi/util/PoiExcelTempUtil.java diff --git a/README.md b/README.md index b4af2be..34e7dae 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ AutoPOI (Excel和 Word简易工具类) =========================== AutoPOI 功能如同名字auto,追求的就是自动化,让一个没接触过poi的人员,可以傻瓜化的快速实现Excel导入导出、Word模板导出、可以仅仅5行代码就可以完成Excel的导入导出。 - 当前最新版本: 1.4.3(发布日期:20220902) - - > 反馈问题:发现bug请在github [发issue](https://github.com/jeecgboot/autopoi/issues/new) + 当前最新版本: 1.4.6(发布日期:20230305) --------------------------- AutoPOI的主要特点 @@ -45,7 +43,7 @@ maven org.jeecgframework autopoi-web - 1.4.3 + 1.4.6 ``` diff --git a/autopoi-web/pom.xml b/autopoi-web/pom.xml index be92143..1c74991 100644 --- a/autopoi-web/pom.xml +++ b/autopoi-web/pom.xml @@ -5,7 +5,7 @@ org.jeecgframework autopoi-parent - 1.4.3 + 1.4.6 autopoi-web diff --git a/autopoi/pom.xml b/autopoi/pom.xml index 8adb114..59908ee 100644 --- a/autopoi/pom.xml +++ b/autopoi/pom.xml @@ -4,7 +4,7 @@ org.jeecgframework autopoi-parent - 1.4.3 + 1.4.6 autopoi diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/entity/ImportParams.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/entity/ImportParams.java index ad527f3..599706d 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/entity/ImportParams.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/entity/ImportParams.java @@ -79,6 +79,11 @@ public class ImportParams extends ExcelBaseParams { */ private List ignoreHeaderList; + /** + * 指定导入的sheetName + */ + private String sheetName; + /** * 图片列 集合 */ @@ -172,6 +177,14 @@ public void setIgnoreHeaderList(List ignoreHeaderList) { this.ignoreHeaderList = ignoreHeaderList; } + public String getSheetName() { + return sheetName; + } + + public void setSheetName(String sheetName) { + this.sheetName = sheetName; + } + /** * 根据表头显示的文字 判断是否忽略该表头 * @param text diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/export/ExcelExportServer.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/export/ExcelExportServer.java index 2e3c473..67abc39 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/export/ExcelExportServer.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/export/ExcelExportServer.java @@ -88,8 +88,10 @@ public int createHeaderRow(ExportParams entity, Sheet sheet, Workbook workbook, if (entity.getSecondTitle() != null) { row = sheet.createRow(1); row.setHeight(entity.getSecondTitleHeight()); - CellStyle style = workbook.createCellStyle(); + //update-begin-author:liusq date:20230407 for:[issue/4342]autopoi导出带副标题的数据表,副标题缺左边框 + CellStyle style = getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()); style.setAlignment(HorizontalAlignment.RIGHT); + //update-end-author:liusq date:20230407 for:[issue/4342]autopoi导出带副标题的数据表,副标题缺左边框 createStringCell(row, 0, entity.getSecondTitle(), style, null); for (int i = 1; i <= feildWidth; i++) { createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java index 215915c..3a805f1 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java @@ -372,6 +372,10 @@ private void addListDataToExcel(Cell cell, Map map, String name) int lastRowNum = cell.getRow().getSheet().getLastRowNum(); int shiftRows = lastRowNum - cell.getRowIndex() - rowspan; cell.getRow().getSheet().shiftRows(cell.getRowIndex() + rowspan, lastRowNum, (datas.size() - 1) * rowspan, true, true); + //update-begin-author:liusq---date:20221103--for: [issues/4142]exlce模板导出如果模板中有多个合并单元格的循环表格,第二个表格读取错误 --- + mergedRegionHelper.shiftRows(cell.getSheet(), cell.getRowIndex() + rowspan, (datas.size() - 1) * rowspan, shiftRows); + PoiExcelTempUtil.reset(cell.getSheet(), cell.getRowIndex() + rowspan + (datas.size() - 1) * rowspan, cell.getRow().getSheet().getLastRowNum()); + //update-end-author:liusq---date:20221103--for: [issues/4142]exlce模板导出如果模板中有多个合并单元格的循环表格,第二个表格读取错误 --- } while (its.hasNext()) { Object t = its.next(); @@ -658,9 +662,11 @@ private int[] setForeachRowCellValue(boolean isCreate, Row row, int columnIndex, //如果合并单元格,就把这个单元格的样式和之前的保持一致 setMergedRegionStyle(row, ci, params); //合并对应单元格 - if ((params.getRowspan() != 1 || params.getColspan() != 1) - && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci) - && PoiCellUtil.isMergedRegion(row.getSheet(), row.getRowNum(), ci)) { + //update-begin-author:liusq---date:20221103--for: [issues/4142]exlce模板导出如果模板中有多个合并单元格的循环表格,第二个表格读取错误 --- + boolean isNeedMerge = (params.getRowspan() != 1 || params.getColspan() != 1) + && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci); + //update-end-author:liusq---date:20221103--for: [issues/4142]exlce模板导出如果模板中有多个合并单元格的循环表格,第二个表格读取错误 --- + if (isNeedMerge) { PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(), row.getRowNum() + params.getRowspan() - 1, ci, ci + params.getColspan() - 1); diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/html/helper/MergedRegionHelper.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/html/helper/MergedRegionHelper.java index b39196b..acc0a07 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/html/helper/MergedRegionHelper.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/html/helper/MergedRegionHelper.java @@ -6,6 +6,8 @@ import java.util.Set; import org.apache.poi.ss.usermodel.Sheet; +import org.jeecgframework.poi.util.PoiCellUtil; +import org.jeecgframework.poi.util.PoiMergeCellUtil; /** * 合并单元格帮助类 @@ -32,7 +34,7 @@ private void getAllMergedRegion(Sheet sheet) { /** * 根据合并输出内容,处理合并单元格事情 - * + * * @param formatAsString */ private void handerMergedString(String formatAsString) { @@ -61,7 +63,7 @@ private void handerMergedString(String formatAsString) { /** * 是不是需要创建这个TD - * + * * @param row * @param col * @return @@ -72,7 +74,7 @@ public boolean isNeedCreate(int row, int col) { /** * 是不是合并区域 - * + * * @param row * @param col * @return @@ -83,7 +85,7 @@ public boolean isMergedRegion(int row, int col) { /** * 获取合并区域 - * + * * @param row * @param col * @return @@ -92,4 +94,42 @@ public Integer[] getRowAndColSpan(int row, int col) { return mergedCache.get(row + "_" + col); } + /** + * 插入之后还原之前的合并单元格 + * + * @param rowIndex + * @param size + */ + public void shiftRows(Sheet sheet, int rowIndex, int size, int shiftRows) { + Set keys = new HashSet(); + keys.addAll(mergedCache.keySet()); + for (String key : keys) { + String[] temp = key.split("_"); + if (Integer.parseInt(temp[0]) >= rowIndex) { + Integer[] data = mergedCache.get(key); + String newKey = (Integer.parseInt(temp[0]) + size) + "_" + temp[1]; + if (!mergedCache.containsKey(newKey)) { + mergedCache.put(newKey, mergedCache.get(key)); + try { + // 还原合并单元格 + if (!PoiCellUtil.isMergedRegion(sheet, Integer.parseInt(temp[0]) + size - 1, Integer.parseInt(temp[1]))) { + PoiMergeCellUtil.addMergedRegion(sheet, + Integer.parseInt(temp[0]) + size - 1, Integer.parseInt(temp[0]) + data[0] + size - 2, + Integer.parseInt(temp[1]), Integer.parseInt(temp[1]) + data[1] - 1 + ); + } + } catch (Exception e) { + } + } + } + } + //删除掉原始的缓存KEY + for (String key : keys) { + String[] temp = key.split("_"); + if (Integer.parseInt(temp[0]) >= rowIndex + size && Integer.parseInt(temp[0]) <= rowIndex + size + shiftRows) { + mergedCache.remove(key); + } + } + } + } diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/CellValueServer.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/CellValueServer.java index 5245b56..d41c6ff 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/CellValueServer.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/CellValueServer.java @@ -31,6 +31,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.math.BigDecimal; +import java.math.RoundingMode; import java.sql.Time; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -82,8 +83,16 @@ private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) result = cell.getBooleanCellValue(); } else if ( CellType.FORMULA == cell.getCellTypeEnum() && PoiPublicUtil.isNumber(xclass)) { //如果单元格是表达式 且 字段是数字类型 - result = cell.getNumericCellValue(); + double cellValue = cell.getNumericCellValue(); + //---author:liusq---date:20221102-----for: [issues/3369]Excel导入 带公式的时候精度丢失--- + //setScale方法的第一个参数设置小数点保留位数,第二个参数设置进位方法、此处是四舍五入 + BigDecimal bigDecimal= new BigDecimal(cellValue).setScale(4, RoundingMode.HALF_UP); + //stripTrailingZeros方法去除末尾的0,toPlainString避免输出科学计数法的字符串 + result = bigDecimal.stripTrailingZeros().toPlainString(); + //---author:liusq---date:20221102-----for:[issues/3369] Excel导入 带公式的时候精度丢失--- } else { + //设置单元格类型 + cell.setCellType(CellType.STRING); result = cell.getStringCellValue(); } return result; diff --git a/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java b/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java index 9de3bf9..6b2f98e 100644 --- a/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java +++ b/autopoi/src/main/java/org/jeecgframework/poi/excel/imports/ExcelImportServer.java @@ -453,11 +453,23 @@ public ExcelImportResult importExcelByIs(InputStream inputstream, Class pojoC //end-------author:liusq------date:20210313-----for:-------多sheet导入改造点-------- createErrorCellStyle(book); Map pictures; + // 获取指定的sheet名称 + String sheetName = params.getSheetName(); //update-begin-author:liusq date:20220609 for:issues/I57UPC excel导入 ImportParams 中没有startSheetIndex参数 for (int i = params.getStartSheetIndex(); i < params.getStartSheetIndex() + params.getSheetNum(); i++) { //update-end-author:liusq date:20220609 for:issues/I57UPC excel导入 ImportParams 中没有startSheetIndex参数 + + //update-begin-author:taoyan date:2023-3-4 for: 导入数据支持指定sheet名称 + if(sheetName!=null && !"".equals(sheetName)){ + Sheet tempSheet = book.getSheetAt(i); + if(!sheetName.equals(tempSheet.getSheetName())){ + continue; + } + } + //update-end-author:taoyan date:2023-3-4 for: 导入数据支持指定sheet名称 + if (LOGGER.isDebugEnabled()) { LOGGER.debug(" start to read excel by is ,startTime is {}", System.currentTimeMillis()); } diff --git a/autopoi/src/main/java/org/jeecgframework/poi/util/PoiExcelTempUtil.java b/autopoi/src/main/java/org/jeecgframework/poi/util/PoiExcelTempUtil.java new file mode 100644 index 0000000..4f3ba0f --- /dev/null +++ b/autopoi/src/main/java/org/jeecgframework/poi/util/PoiExcelTempUtil.java @@ -0,0 +1,102 @@ +package org.jeecgframework.poi.util; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * poi 4.0 07版本在 shift操作下有bug,不移动了单元格以及单元格样式,没有移动cell + * cell还是复用的原理的cell,导致wb输出的时候没有输出值 + * 等待修复的时候删除这个问题 + * + * @author by jueyue on 19-6-17. + */ +public class PoiExcelTempUtil { + + /** + * 把这N行的数据,cell重新设置下,修复因为shift的浅复制问题,导致文本不显示的错误 + * + * @param sheet + * @param startRow + * @param endRow + */ + public static void reset(Sheet sheet, int startRow, int endRow) { + if (sheet.getWorkbook() instanceof HSSFWorkbook) { + return; + } + for (int i = startRow; i <= endRow; i++) { + Row row = sheet.getRow(i); + if (row == null) { + continue; + } + int cellNum = row.getLastCellNum(); + for (int j = 0; j < cellNum; j++) { + if (row.getCell(j) == null) { + continue; + } + Map map = copyCell(row.getCell(j)); + row.removeCell(row.getCell(j)); + Cell cell = row.createCell(j); + cell.setCellStyle((CellStyle) map.get("cellStyle")); + if ((boolean) map.get("isDate")) { + cell.setCellValue((Date) map.get("value")); + } else { + CellType cellType = (CellType) map.get("cellType"); + switch (cellType) { + case NUMERIC: + cell.setCellValue((double) map.get("value")); + break; + case STRING: + cell.setCellValue((String) map.get("value")); + case FORMULA: + break; + case BLANK: + break; + case BOOLEAN: + cell.setCellValue((boolean) map.get("value")); + case ERROR: + break; + } + } + } + } + + } + + private static Map copyCell(Cell cell) { + Map map = new HashMap<>(); + map.put("cellType", cell.getCellType()); + map.put("isDate", CellType.NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)); + map.put("value", getValue(cell)); + map.put("cellStyle", cell.getCellStyle()); + return map; + } + + private static Object getValue(Cell cell) { + if (CellType.NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue(); + } + switch (cell.getCellType()) { + case _NONE: + return null; + case NUMERIC: + return cell.getNumericCellValue(); + case STRING: + return cell.getStringCellValue(); + case FORMULA: + return cell.getCellFormula(); + case BLANK: + break; + case BOOLEAN: + return cell.getBooleanCellValue(); + case ERROR: + break; + } + return null; + } + + +} diff --git a/pom.xml b/pom.xml index afb241c..741f84b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jeecgframework autopoi-parent - 1.4.3 + 1.4.6 pom autopoi-parent @@ -36,7 +36,7 @@ - 1.4.3 + 1.4.6 4.1.2 2.9.1 29.0-jre