From 03730c5285e57ce410541f4e2ce37c53aa0a29b2 Mon Sep 17 00:00:00 2001 From: jueyue Date: Mon, 7 Oct 2019 22:35:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=A4=9A=E5=B1=82=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3,=E5=8F=AF=E4=BB=A5=E5=BE=AA=E7=8E=AF=E7=89=88?= =?UTF-8?q?=E6=9C=AC-=E8=BF=98=E4=B8=8D=E8=83=BD=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../entity/params/ExcelForEachParams.java | 26 +- .../excel/export/base/BaseExportService.java | 5 +- .../template/ExcelExportOfTemplateUtil.java | 286 +++++++++++++----- .../excel/imports/CellValueService.java | 6 +- .../afterturn/easypoi/util/PoiCellUtil.java | 49 ++- .../cn/afterturn/easypoi/util/PoiElUtil.java | 27 +- .../afterturn/easypoi/util/PoiPublicUtil.java | 52 ++-- 8 files changed, 316 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index ca64ddd..2cbe8df 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ EasyPoi Excel和 Word简易工具类 QQ群: 1群 364192721(满) 2 群116844390 开发者:魔幻之翼 xf.key@163.com - 优秀团队,承接私活,加微信:13165188222 ,添加备注一众 + 优秀团队,承接私活,加微信:13165188222 ,添加备注悟耘 Spring Boot 支持 https://gitee.com/lemur/easypoi-spring-boot-starter [官网](https://opensource.afterturn.cn) diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/entity/params/ExcelForEachParams.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/entity/params/ExcelForEachParams.java index e29a7d1..8044795 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/entity/params/ExcelForEachParams.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/entity/params/ExcelForEachParams.java @@ -1,6 +1,7 @@ package cn.afterturn.easypoi.excel.entity.params; import java.io.Serializable; +import java.util.Stack; import org.apache.poi.ss.usermodel.CellStyle; @@ -14,31 +15,35 @@ public class ExcelForEachParams implements Serializable { /** * */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; /** * key */ - private String name; + private String name; + /** + * key + */ + private Stack tempName; /** * 模板的cellStyle */ - private CellStyle cellStyle; + private CellStyle cellStyle; /** * 行高 */ - private short height; + private short height; /** * 常量值 */ - private String constValue; + private String constValue; /** * 列合并 */ - private int colspan = 1; + private int colspan = 1; /** * 行合并 */ - private int rowspan = 1; + private int rowspan = 1; private boolean needSum; @@ -116,4 +121,11 @@ public class ExcelForEachParams implements Serializable { this.needSum = needSum; } + public Stack getTempName() { + return tempName; + } + + public void setTempName(Stack tempName) { + this.tempName = tempName; + } } diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/base/BaseExportService.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/base/BaseExportService.java index ec1e52e..313ec44 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/base/BaseExportService.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/base/BaseExportService.java @@ -78,14 +78,13 @@ public abstract class BaseExportService extends ExportCommonService { entity = excelParams.get(k); if (entity.getList() != null) { Collection list = getListCellValue(entity, t); - int listIndex = 0, tmpListHeight = 0; + int tmpListHeight = 0; if (list != null && list.size() > 0) { int tempCellNum = 0; for (Object obj : list) { - int[] temp = createCells(patriarch, index + listIndex, obj, entity.getList(), sheet, workbook, rowHeight, cellNum); + int[] temp = createCells(patriarch, index + tmpListHeight, obj, entity.getList(), sheet, workbook, rowHeight, cellNum); tempCellNum = temp[1]; tmpListHeight += temp[0]; - listIndex++; } cellNum = tempCellNum; listMaxHeight = Math.max(listMaxHeight, tmpListHeight); diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/template/ExcelExportOfTemplateUtil.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/template/ExcelExportOfTemplateUtil.java index a713711..261efc4 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/template/ExcelExportOfTemplateUtil.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/export/template/ExcelExportOfTemplateUtil.java @@ -61,7 +61,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 模板参数,全局都用到 */ - private TemplateExportParams teplateParams; + private TemplateExportParams templateParams; /** * 单元格合并信息 */ @@ -96,16 +96,16 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { // 根据表头进行筛选排序 sortAndFilterExportField(excelParams, titlemap); short rowHeight = getRowHeight(excelParams); - int index = teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), + int index = templateParams.getHeadingRows() + templateParams.getHeadingStartRow(), titleHeight = index; int shiftRows = getShiftRows(dataSet, excelParams); //下移数据,模拟插入 - sheet.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), + sheet.shiftRows(templateParams.getHeadingRows() + templateParams.getHeadingStartRow(), sheet.getLastRowNum(), shiftRows, true, true); - mergedRegionHelper.shiftRows(sheet, teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), shiftRows, - sheet.getLastRowNum() - teplateParams.getHeadingRows() - teplateParams.getHeadingStartRow()); - templateSumHandler.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), shiftRows); - PoiExcelTempUtil.reset(sheet, teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), sheet.getLastRowNum()); + mergedRegionHelper.shiftRows(sheet, templateParams.getHeadingRows() + templateParams.getHeadingStartRow(), shiftRows, + sheet.getLastRowNum() - templateParams.getHeadingRows() - templateParams.getHeadingStartRow()); + templateSumHandler.shiftRows(templateParams.getHeadingRows() + templateParams.getHeadingStartRow(), shiftRows); + PoiExcelTempUtil.reset(sheet, templateParams.getHeadingRows() + templateParams.getHeadingStartRow(), sheet.getLastRowNum()); if (excelParams.size() == 0) { return; } @@ -146,11 +146,12 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Row row = null; int rowIndex = cell.getRow().getRowNum() + 1; //处理当前行 + int loopSize = 0; if (its.hasNext()) { Object t = its.next(); - setForEeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map, - rowspan, colspan, mergedRegionHelper); - rowIndex += rowspan - 1; + loopSize = setForeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map, + rowspan, colspan, mergedRegionHelper)[0]; + rowIndex += rowspan - 1 + loopSize - 1; } //修复不论后面有没有数据,都应该执行的是插入操作 if (isShift && datas.size() * rowspan > 1 && cell.getRowIndex() + rowspan < cell.getRow().getSheet().getLastRowNum()) { @@ -164,9 +165,9 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { while (its.hasNext()) { Object t = its.next(); row = createRow(rowIndex, cell.getSheet(), isCreate, rowspan); - setForEeachRowCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map, rowspan, - colspan, mergedRegionHelper); - rowIndex += rowspan; + loopSize = setForeachRowCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map, rowspan, + colspan, mergedRegionHelper)[0]; + rowIndex += rowspan + loopSize - 1; } } @@ -220,8 +221,8 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Workbook wb = null; // step 2. 判断模板的Excel类型,解析模板 try { - this.teplateParams = params; - wb = ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), + this.templateParams = params; + wb = ExcelCache.getWorkbook(templateParams.getTemplateUrl(), templateParams.getSheetNum(), true); int oldSheetNum = wb.getNumberOfSheets(); List oldSheetName = new ArrayList<>(); @@ -245,7 +246,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { wb.removeSheetAt(wb.getSheetIndex(oldSheetName.get(i))); } // 创建表格样式 - setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() + setExcelExportStyler((IExcelExportStyler) templateParams.getStyle() .getConstructor(Workbook.class).newInstance(wb)); // step 3. 解析模板 int sheetIndex = 0; @@ -276,10 +277,10 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Workbook wb = null; // step 2. 判断模板的Excel类型,解析模板 try { - this.teplateParams = params; + this.templateParams = params; wb = getCloneWorkBook(); // 创建表格样式 - setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() + setExcelExportStyler((IExcelExportStyler) templateParams.getStyle() .getConstructor(Workbook.class).newInstance(wb)); // step 3. 解析模板 for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() @@ -307,14 +308,20 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Workbook wb = null; // step 2. 判断模板的Excel类型,解析模板 try { - this.teplateParams = params; + this.templateParams = params; if (params.getTemplateWb() != null) { wb = params.getTemplateWb(); } else { wb = getCloneWorkBook(); } + if (params.getDictHandler() != null) { + this.dictHandler = params.getDictHandler(); + } + if (params.getI18nHandler() != null) { + this.i18nHandler = params.getI18nHandler(); + } // 创建表格样式 - setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() + setExcelExportStyler((IExcelExportStyler) templateParams.getStyle() .getConstructor(Workbook.class).newInstance(wb)); // step 3. 解析模板 for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() @@ -347,8 +354,8 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { * @throws Exception */ private Workbook getCloneWorkBook() throws Exception { - return ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), - teplateParams.isScanAllsheet()); + return ExcelCache.getWorkbook(templateParams.getTemplateUrl(), templateParams.getSheetNum(), + templateParams.isScanAllsheet()); } @@ -362,8 +369,8 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Row row = null; Iterator cellTitle; Map titlemap = new HashMap(); - for (int j = 0; j < teplateParams.getHeadingRows(); j++) { - row = sheet.getRow(j + teplateParams.getHeadingStartRow()); + for (int j = 0; j < templateParams.getHeadingRows(); j++) { + row = sheet.getRow(j + templateParams.getHeadingStartRow()); cellTitle = row.cellIterator(); int i = row.getFirstCellNum(); while (cellTitle.hasNext()) { @@ -474,7 +481,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { List columns = (List) columnsInfo[2]; while (its.hasNext()) { Object t = its.next(); - setForEeachRowCellValue(true, cell.getRow(), cell.getColumnIndex(), t, columns, map, + setForeachRowCellValue(true, cell.getRow(), cell.getColumnIndex(), t, columns, map, rowspan, colspan, mergedRegionHelper); if (cell.getRow().getCell(cell.getColumnIndex() + colspan) == null) { cell.getRow().createCell(cell.getColumnIndex() + colspan); @@ -539,18 +546,35 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (oldString != null && oldString.indexOf(START_STR) != -1 && !oldString.contains(FOREACH)) { // step 2. 判断是否含有解析函数 - String params = null; boolean isNumber = false; - if (isNumber(oldString)) { + if (isHasSymbol(oldString, NUMBER_SYMBOL)) { isNumber = true; oldString = oldString.replaceFirst(NUMBER_SYMBOL, ""); } boolean isStyleBySelf = false; - if (isStyleBySelf(oldString)) { + if (isHasSymbol(oldString, STYLE_SELF)) { isStyleBySelf = true; - oldString = oldString.replaceFirst(NUMBER_SYMBOL, ""); + oldString = oldString.replaceFirst(STYLE_SELF, ""); + } + boolean isDict = false; + String dict = null; + if (isHasSymbol(oldString, DICT_HANDLER)) { + isDict = true; + dict = oldString.substring(oldString.indexOf(DICT_HANDLER) + 5).split(";")[0]; + oldString = oldString.replaceFirst(DICT_HANDLER, ""); + } + boolean isI18n = false; + if (isHasSymbol(oldString, I18N_HANDLER)) { + isI18n = true; + oldString = oldString.replaceFirst(I18N_HANDLER, ""); } Object obj = PoiPublicUtil.getRealValue(oldString, map); + if (isDict) { + obj = dictHandler.toName(dict, null, oldString, obj); + } + if (isI18n) { + obj = i18nHandler.getLocaleName(obj.toString()); + } //如何是数值 类型,就按照数值类型进行设置// 如果是图片就设置为图片 if (obj instanceof ImageEntity) { ImageEntity img = (ImageEntity) obj; @@ -574,14 +598,9 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } - private boolean isNumber(String text) { - return text.startsWith(NUMBER_SYMBOL) || text.contains("{" + NUMBER_SYMBOL) - || text.contains(" " + NUMBER_SYMBOL); - } - - private boolean isStyleBySelf(String text) { - return text.startsWith(STYLE_SELF) || text.contains("{" + STYLE_SELF) - || text.contains(" " + STYLE_SELF); + private boolean isHasSymbol(String text, String symbol) { + return text.startsWith(symbol) || text.contains("{" + symbol) + || text.contains(" " + symbol); } /** @@ -604,48 +623,34 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { return sheet.getRow(rowIndex - rows); } - private void setForEeachRowCellValue(boolean isCreate, Row row, int columnIndex, Object t, + /** + * 循环迭代创建,遍历row + * + * @param isCreate + * @param row + * @param columnIndex + * @param t + * @param columns + * @param map + * @param rowspan + * @param colspan + * @param mergedRegionHelper + * @return rowSize, cellSize + * @throws Exception + */ + private int[] setForeachRowCellValue(boolean isCreate, Row row, int columnIndex, Object t, List columns, Map map, int rowspan, int colspan, MergedRegionHelper mergedRegionHelper) throws Exception { - //所有的cell创建一遍 - for (int i = 0; i < rowspan; i++) { - int size = columns.size();//判断是不是超出设置了 - for (int j = columnIndex, max = columnIndex + colspan; j < max; j++) { - if (row.getCell(j) == null) { - row.createCell(j); - CellStyle style = row.getRowNum() % 2 == 0 - ? getStyles(false, - size <= j - columnIndex ? null : columns.get(j - columnIndex)) - : getStyles(true, - size <= j - columnIndex ? null : columns.get(j - columnIndex)); - //返回的styler不为空时才使用,否则使用Excel设置的,更加推荐Excel设置的样式 - if (style != null) { - row.getCell(j).setCellStyle(style); - } - } - - } - if (i < rowspan - 1) { - row = row.getSheet().getRow(row.getRowNum() + 1); - } - } + createRowCellSetStyle(row, columnIndex, columns, rowspan, colspan); //填写数据 ExcelForEachParams params; + int loopSize = 1; + int loopCi = 1; row = row.getSheet().getRow(row.getRowNum() - rowspan + 1); for (int k = 0; k < rowspan; k++) { - int ci = columnIndex; - short high = columns.get(0).getHeight(); - int n = k; - while (n > 0) { - if (columns.get(n * colspan).getHeight() == 0) { - n--; - } else { - high = columns.get(n * colspan).getHeight(); - break; - } - } - row.setHeight(high); + int ci = columnIndex; + row.setHeight(getMaxHeight(k, colspan, columns)); for (int i = 0; i < colspan && i < columns.size(); i++) { boolean isNumber = false; params = columns.get(colspan * k + i); @@ -659,22 +664,41 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { ci = ci + params.getColspan(); continue; } - String val = null; + String val; Object obj = null; //是不是常量 + String tempStr = params.getName(); if (StringUtils.isEmpty(params.getName())) { val = params.getConstValue(); } else { - String tempStr = new String(params.getName()); - if (isNumber(tempStr)) { + if (isHasSymbol(tempStr, NUMBER_SYMBOL)) { isNumber = true; tempStr = tempStr.replaceFirst(NUMBER_SYMBOL, ""); } - map.put(teplateParams.getTempParams(), t); + map.put(templateParams.getTempParams(), t); + boolean isDict = false; + String dict = null; + if (isHasSymbol(tempStr, DICT_HANDLER)) { + isDict = true; + dict = tempStr.substring(tempStr.indexOf(DICT_HANDLER) + 5).split(";")[0]; + tempStr = tempStr.replaceFirst(DICT_HANDLER, ""); + tempStr = tempStr.replaceFirst(dict + ";", ""); + } obj = eval(tempStr, map); + if (isDict && !(obj instanceof Collection)) { + obj = dictHandler.toName(dict, t, tempStr, obj); + } val = obj.toString(); } - if (obj != null && obj instanceof ImageEntity) { + if (obj != null && obj instanceof Collection) { + // 需要找到哪一级别是集合 ,方便后面的replace + String collectName = evalFindName(tempStr, map); + int[] loop = setForEachLoopRowCellValue(row, ci, (Collection) obj, columns, + params, map, rowspan, colspan, mergedRegionHelper, collectName); + loopSize = Math.max(loopSize, loop[0]); + i += loop[1] - 1; + ci = loop[2] - params.getColspan(); + } else if (obj != null && obj instanceof ImageEntity) { ImageEntity img = (ImageEntity) obj; row.getCell(ci).setCellValue(""); if (img.getRowspan() > 1 || img.getColspan() > 1) { @@ -711,9 +735,117 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } ci = ci + params.getColspan(); } + loopCi = Math.max(loopCi, ci); row = row.getSheet().getRow(row.getRowNum() + 1); } + return new int[]{loopSize, loopCi}; + } + private short getMaxHeight(int k, int colspan, List columns) { + short high = columns.get(0).getHeight(); + int n = k; + while (n > 0) { + if (columns.get(n * colspan).getHeight() == 0) { + n--; + } else { + high = columns.get(n * colspan).getHeight(); + break; + } + } + return high; + } + + /** + * 处理内循环 + * + * @param row + * @param columnIndex + * @param obj + * @param columns + * @param params + * @param map + * @param rowspan + * @param colspan + * @param mergedRegionHelper + * @param collectName + * @return [rowNums, columnsNums, ciIndex] + * @throws Exception + */ + private int[] setForEachLoopRowCellValue(Row row, int columnIndex, Collection obj, List columns, + ExcelForEachParams params, Map map, + int rowspan, int colspan, + MergedRegionHelper mergedRegionHelper, String collectName) throws Exception { + + //多个一起遍历 -去掉第一层 把所有的数据遍历一遍 + //STEP 1拿到所有的和当前一样项目的字段 + List temp = getLoopEachParams(columns, columnIndex, collectName); + Iterator its = obj.iterator(); + Row tempRow = row; + int nums = 0; + int ci = columnIndex; + while (its.hasNext()) { + Object data = its.next(); + map.put("loop_" + columnIndex, data); + int[] loopArr = setForeachRowCellValue(false, tempRow, columnIndex, data, temp, map, rowspan, + colspan, mergedRegionHelper); + nums += loopArr[0]; + ci = Math.max(ci,loopArr[1]); + map.remove("loop_" + columnIndex); + tempRow = createRow(tempRow.getRowNum() + loopArr[0], row.getSheet(), false, rowspan); + } + for (int i = 0; i < temp.size(); i++) { + temp.get(i).setName(temp.get(i).getTempName().pop()); + } + return new int[]{nums, temp.size(), ci}; + } + + /** + * 根据 当前是集合的信息,把后面整个集合的迭代获取出来,并替换掉集合的前缀方便后面取数 + * + * @param columns + * @param columnIndex + * @param collectName + * @return + */ + private List getLoopEachParams(List columns, int columnIndex, String collectName) { + List temp = new ArrayList<>(); + for (int i = 0; i < columns.size(); i++) { + if (columns.get(i) == null || columns.get(i).getName().contains(collectName)) { + temp.add(columns.get(i)); + if (columns.get(i).getTempName() == null) { + columns.get(i).setTempName(new Stack<>()); + } + columns.get(i).getTempName().push(columns.get(i).getName()); + columns.get(i).setName(columns.get(i).getName().replace(collectName, "loop_" + columnIndex)); + } + } + return temp; + } + + private void createRowCellSetStyle(Row row, int columnIndex, List columns, + int rowspan, int colspan) { + //所有的cell创建一遍 + for (int i = 0; i < rowspan; i++) { + int size = columns.size(); + for (int j = columnIndex, max = columnIndex + colspan; j < max; j++) { + if (row.getCell(j) == null) { + row.createCell(j); + CellStyle style = row.getRowNum() % 2 == 0 + ? getStyles(false, + size <= j - columnIndex ? null : columns.get(j - columnIndex)) + : getStyles(true, + size <= j - columnIndex ? null : columns.get(j - columnIndex)); + //返回的styler不为空时才使用,否则使用Excel设置的,更加推荐Excel设置的样式 + if (style != null) { + row.getCell(j).setCellStyle(style); + } + } + + } + if (i < rowspan - 1) { + row = row.getSheet().getRow(row.getRowNum() + 1); + } + } } private CellStyle getStyles(boolean isSingle, ExcelForEachParams excelForEachParams) { diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/CellValueService.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/CellValueService.java index 3fda51a..f989e8f 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/CellValueService.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/CellValueService.java @@ -70,7 +70,8 @@ public class CellValueService { return ""; } Object result = null; - if ("class java.util.Date".equals(classFullName) || "class java.sql.Date".equals(classFullName) + if ("class java.util.Date".equals(classFullName) + || "class java.sql.Date".equals(classFullName) || ("class java.sql.Time").equals(classFullName) || ("class java.time.Instant").equals(classFullName) || ("class java.time.LocalDate").equals(classFullName) @@ -84,8 +85,7 @@ public class CellValueService { try { val = cell.getStringCellValue(); } catch (Exception e) { - cell.setCellType(CellType.STRING); - val = cell.getStringCellValue(); + return null; } result = getDateData(entity, val); diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiCellUtil.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiCellUtil.java index b7d737d..4f28e3b 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiCellUtil.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiCellUtil.java @@ -30,8 +30,8 @@ public class PoiCellUtil { if (isMergedRegion(sheet, row, column)) { value = getMergedRegionValue(sheet, row, column); } else { - Row rowData = sheet.getRow(row); - Cell cell = rowData.getCell(column); + Row rowData = sheet.getRow(row); + Cell cell = rowData.getCell(column); value = getCellValue(cell); } return value; @@ -49,16 +49,16 @@ public class PoiCellUtil { int sheetMergeCount = sheet.getNumMergedRegions(); for (int i = 0; i < sheetMergeCount; i++) { - CellRangeAddress ca = sheet.getMergedRegion(i); - int firstColumn = ca.getFirstColumn(); - int lastColumn = ca.getLastColumn(); - int firstRow = ca.getFirstRow(); - int lastRow = ca.getLastRow(); + CellRangeAddress ca = sheet.getMergedRegion(i); + int firstColumn = ca.getFirstColumn(); + int lastColumn = ca.getLastColumn(); + int firstRow = ca.getFirstRow(); + int lastRow = ca.getLastRow(); if (row >= firstRow && row <= lastRow) { if (column >= firstColumn && column <= lastColumn) { - Row fRow = sheet.getRow(firstRow); + Row fRow = sheet.getRow(firstRow); Cell fCell = fRow.getCell(firstColumn); return getCellValue(fCell); @@ -81,11 +81,11 @@ public class PoiCellUtil { int sheetMergeCount = sheet.getNumMergedRegions(); for (int i = 0; i < sheetMergeCount; i++) { - CellRangeAddress ca = sheet.getMergedRegion(i); - int firstColumn = ca.getFirstColumn(); - int lastColumn = ca.getLastColumn(); - int firstRow = ca.getFirstRow(); - int lastRow = ca.getLastRow(); + CellRangeAddress ca = sheet.getMergedRegion(i); + int firstColumn = ca.getFirstColumn(); + int lastColumn = ca.getLastColumn(); + int firstRow = ca.getFirstRow(); + int lastRow = ca.getLastRow(); if (row >= firstRow && row <= lastRow) { if (column >= firstColumn && column <= lastColumn) { @@ -100,7 +100,13 @@ public class PoiCellUtil { /** * 获取单元格的值 - * + * _NONE(-1), + * NUMERIC(0), + * STRING(1), + * FORMULA(2), + * BLANK(3), + * BOOLEAN(4), + * ERROR(5); * @param cell * @return */ @@ -108,31 +114,22 @@ public class PoiCellUtil { if (cell == null) { return ""; } - if (cell.getCellType() == CellType.STRING) { - return cell.getStringCellValue(); - } else if (cell.getCellType() == CellType.BOOLEAN) { - return String.valueOf(cell.getBooleanCellValue()); - } else if (cell.getCellType() == CellType.FORMULA) { - try { return cell.getCellFormula(); } catch (Exception e) { return String.valueOf(cell.getNumericCellValue()); } - } else if (cell.getCellType() == CellType.NUMERIC) { - return String.valueOf(cell.getNumericCellValue()); - - } else { - cell.setCellType(CellType.STRING); - return cell.getStringCellValue(); + } else if (cell.getCellType() == CellType.ERROR) { + return String.valueOf(cell.getErrorCellValue()); } + return ""; } } diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiElUtil.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiElUtil.java index 3ed2a76..95903bd 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiElUtil.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiElUtil.java @@ -17,7 +17,7 @@ package cn.afterturn.easypoi.util; import cn.afterturn.easypoi.exception.excel.ExcelExportException; -import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Stack; @@ -51,6 +51,8 @@ public final class PoiElUtil { public static final String LEFT_BRACKET = "("; public static final String RIGHT_BRACKET = ")"; public static final String CAL = "cal:"; + public static final String DICT_HANDLER = "dict:"; + public static final String I18N_HANDLER = "i18n:"; private PoiElUtil() { } @@ -77,6 +79,27 @@ public final class PoiElUtil { return obj; } + + /** + * 解析字符串, 不支持 le,fd,fn,!if,三目 ,获取是集合的字段前缀 + * + * @param text + * @param map + * @return + * @throws Exception + */ + public static String evalFindName(String text, Map map) throws Exception { + String[] keys = text.split("\\."); + StringBuilder sb = new StringBuilder().append(keys[0]); + for (int i = 1; i < keys.length; i++) { + sb.append(".").append(keys[i]); + if (eval(sb.toString(), map) instanceof Collection) { + return sb.toString(); + } + } + return null; + } + /** * 解析字符串,支持 le,fd,fn,!if,三目 找不到返回原值 * @@ -149,7 +172,7 @@ public final class PoiElUtil { char[] operations = new char[]{'+', '-', '*', '/', '(', ')', ' '}; boolean beforeMark = true; for (int i = 0; i < chars.length; i++) { - if ( operations[0] == chars[i] || operations[1] == chars[i] || operations[2] == chars[i] || operations[3] == chars[i] || operations[4] == chars[i] || operations[5] == chars[i]) { + if (operations[0] == chars[i] || operations[1] == chars[i] || operations[2] == chars[i] || operations[3] == chars[i] || operations[4] == chars[i] || operations[5] == chars[i]) { if (temp.length() > 0) { sb.append(evalNoParse(temp.toString().trim(), map).toString()); temp = new StringBuilder(); diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiPublicUtil.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiPublicUtil.java index 8136f8e..23fa896 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiPublicUtil.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiPublicUtil.java @@ -44,8 +44,9 @@ import static cn.afterturn.easypoi.util.PoiElUtil.START_STR; /** * EASYPOI 的公共基础类 + * * @author JueYue - * 2015年4月5日 上午12:59:22 + * 2015年4月5日 上午12:59:22 */ public final class PoiPublicUtil { @@ -143,6 +144,7 @@ public final class PoiPublicUtil { /** * 判断流是否含有BOM + * * @param in * @return * @throws IOException @@ -159,10 +161,8 @@ public final class PoiPublicUtil { /** * 获取Excel2003图片 * - * @param sheet - * 当前sheet对象 - * @param workbook - * 工作簿对象 + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData */ public static Map getSheetPictrues03(HSSFSheet sheet, @@ -190,10 +190,8 @@ public final class PoiPublicUtil { /** * 获取Excel2007图片 * - * @param sheet - * 当前sheet对象 - * @param workbook - * 工作簿对象 + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData */ public static Map getSheetPictrues07(XSSFSheet sheet, @@ -311,11 +309,12 @@ public final class PoiPublicUtil { /** * 返回流和图片类型 - *@author JueYue - * 2013-11-20 - *@param entity - *@return (byte[]) isAndType[0],(Integer)isAndType[1] + * + * @param entity + * @return (byte[]) isAndType[0],(Integer)isAndType[1] * @throws Exception + * @author JueYue + * 2013-11-20 */ public static Object[] getIsAndType(ImageEntity entity) throws Exception { Object[] result = new Object[2]; @@ -353,9 +352,9 @@ public final class PoiPublicUtil { /** * 解析数据 * - * @author JueYue - * 2013-11-16 * @return + * @author JueYue + * 2013-11-16 */ public static Object getRealValue(String currentText, Map map) throws Exception { @@ -366,7 +365,7 @@ public final class PoiPublicUtil { //判断图片或者是集合 if (obj instanceof ImageEntity || obj instanceof List || obj instanceof ExcelListEntity) { return obj; - } else if (obj != null){ + } else if (obj != null) { currentText = currentText.replace(START_STR + params + END_STR, obj.toString()); } else { currentText = currentText.replace(START_STR + params + END_STR, ""); @@ -399,12 +398,17 @@ public final class PoiPublicUtil { object = PoiReflectorUtil.fromCache(object.getClass()).getValue(object, paramsArr[index]); } + + if (object instanceof Collection) { + return object; + } return (index == paramsArr.length - 1) ? (object == null ? "" : object) : getValueDoWhile(object, paramsArr, ++index); } /** * double to String 防止科学计数法 + * * @param value * @return */ @@ -419,6 +423,7 @@ public final class PoiPublicUtil { /** * 统一 key的获取规则 + * * @param key * @param targetId * @return @@ -443,6 +448,7 @@ public final class PoiPublicUtil { /** * 支持换行操作 + * * @param currentRun * @param currentText */ @@ -454,9 +460,9 @@ public final class PoiPublicUtil { currentRun.addBreak(); } currentRun.setText(tempArr[tempArr.length - 1], tempArr.length - 1); - }else{ + } else { //对blank字符串做处理,避免显示"{{" - currentRun.setText("",0); + currentRun.setText("", 0); } } @@ -469,4 +475,14 @@ public final class PoiPublicUtil { return count; } + /** + * 多个点,截取最后一个 + * + * @param name + * @return + */ + public static String getLastFieldName(String name) { + String[] paramsArr = name.split("\\."); + return paramsArr[paramsArr.length - 1]; + } }