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 15c0a87..de25b2a 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 @@ -68,7 +68,7 @@ import cn.afterturn.easypoi.util.PoiSheetUtil; public final class ExcelExportOfTemplateUtil extends BaseExportService { private static final Logger LOGGER = LoggerFactory - .getLogger(ExcelExportOfTemplateUtil.class); + .getLogger(ExcelExportOfTemplateUtil.class); /** * 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率 @@ -116,7 +116,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { titleHeight = index; //下移数据,模拟插入 sheet.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), - sheet.getLastRowNum(), getShiftRows(dataSet, excelParams), true, true); + sheet.getLastRowNum(), getShiftRows(dataSet, excelParams), true, true); if (excelParams.size() == 0) { return; } @@ -185,12 +185,12 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } // 创建表格样式 setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() - .getConstructor(Workbook.class).newInstance(wb)); + .getConstructor(Workbook.class).newInstance(wb)); // step 3. 解析模板 for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() - : params.getSheetNum().length; i < le; i++) { + : params.getSheetNum().length; i < le; i++) { if (params.getSheetName() != null && params.getSheetName().length > i - && StringUtils.isNotEmpty(params.getSheetName()[i])) { + && StringUtils.isNotEmpty(params.getSheetName()[i])) { wb.setSheetName(i, params.getSheetName()[i]); } tempCreateCellSet.clear(); @@ -218,7 +218,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { */ private Workbook getCloneWorkBook() throws Exception { return ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), - teplateParams.isScanAllsheet()); + teplateParams.isScanAllsheet()); } @@ -266,7 +266,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { if (row.getCell(i) != null && !tempCreateCellSet - .contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) { + .contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) { setValueForCellByMap(row.getCell(i), map); } } @@ -280,7 +280,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { for (TemplateSumEntity sumEntity : templateSumHandler.getDataList()) { Cell cell = sheet.getRow(sumEntity.getRow()).getCell(sumEntity.getCol()); cell.setCellValue(cell.getStringCellValue() - .replace("sum:(" + sumEntity.getSumKey() + ")", sumEntity.getValue() + "")); + .replace("sum:(" + sumEntity.getSumKey() + ")", sumEntity.getValue() + "")); } } @@ -301,7 +301,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { cell = row.getCell(i); if (row.getCell(i) != null && (cell.getCellType() == Cell.CELL_TYPE_STRING - || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) { + || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) { String text = PoiCellUtil.getCellValue(cell); if (text.contains(FOREACH_COL) || text.contains(FOREACH_COL_VALUE)) { foreachCol(cell, map, text); @@ -321,11 +321,11 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { private void foreachCol(Cell cell, Map map, String name) throws Exception { boolean isCreate = name.contains(FOREACH_COL_VALUE); name = name.replace(FOREACH_COL_VALUE, EMPTY).replace(FOREACH_COL, EMPTY).replace(START_STR, - EMPTY); + EMPTY); String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" "); Collection datas = (Collection) PoiPublicUtil.getParamsValue(keys[0], map); Object[] columnsInfo = getAllDataColumns(cell, name.replace(keys[0], EMPTY), - mergedRegionHelper); + mergedRegionHelper); if (datas == null) { return; } @@ -336,7 +336,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { while (its.hasNext()) { Object t = its.next(); setForEeachRowCellValue(true, cell.getRow(), cell.getColumnIndex(), t, columns, map, - rowspan, colspan, mergedRegionHelper); + rowspan, colspan, mergedRegionHelper); if(cell.getRow().getCell(cell.getColumnIndex() + colspan) == null){ cell.getRow().createCell(cell.getColumnIndex() + colspan); } @@ -366,13 +366,13 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { cell = row.getCell(i); if (row.getCell(i) != null && (cell.getCellType() == Cell.CELL_TYPE_STRING - || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) { + || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) { cell.setCellType(Cell.CELL_TYPE_STRING); String text = cell.getStringCellValue(); if (text.contains(IF_DELETE)) { if (Boolean.valueOf( - eval(text.substring(text.indexOf(START_STR) + 2, text.indexOf(END_STR)) - .trim(), map).toString())) { + eval(text.substring(text.indexOf(START_STR) + 2, text.indexOf(END_STR)) + .trim(), map).toString())) { PoiSheetUtil.deleteColumn(sheet, i); i--; } @@ -398,7 +398,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { cell.setCellType(Cell.CELL_TYPE_STRING); oldString = cell.getStringCellValue(); if (oldString != null && oldString.indexOf(START_STR) != -1 - && !oldString.contains(FOREACH)) { + && !oldString.contains(FOREACH)) { // step 2. 判断是否含有解析函数 String params = null; boolean isNumber = false; @@ -433,7 +433,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { private boolean isNumber(String text) { return text.startsWith(NUMBER_SYMBOL) || text.contains("{" + NUMBER_SYMBOL) - || text.contains(" " + NUMBER_SYMBOL); + || text.contains(" " + NUMBER_SYMBOL); } /** @@ -448,11 +448,11 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { boolean isCreate = !name.contains(FOREACH_NOT_CREATE); boolean isShift = name.contains(FOREACH_AND_SHIFT); name = name.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY) - .replace(FOREACH, EMPTY).replace(START_STR, EMPTY); + .replace(FOREACH, EMPTY).replace(START_STR, EMPTY); String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" "); Collection datas = (Collection) PoiPublicUtil.getParamsValue(keys[0], map); Object[] columnsInfo = getAllDataColumns(cell, name.replace(keys[0], EMPTY), - mergedRegionHelper); + mergedRegionHelper); if (datas == null) { return; } @@ -466,7 +466,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (its.hasNext()) { Object t = its.next(); setForEeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map, - rowspan, colspan, mergedRegionHelper); + rowspan, colspan, mergedRegionHelper); rowIndex += rowspan - 1; } //不论后面有没有数据,都应该执行的是插入操作 @@ -474,14 +474,14 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (isShift && datas.size() * rowspan > 1) { createRowNoRow(cell.getRowIndex() + rowspan,cell.getRow().getSheet().getLastRowNum(),(datas.size() - 1) * rowspan); cell.getRow().getSheet().shiftRows(cell.getRowIndex() + rowspan, - cell.getRow().getSheet().getLastRowNum(), (datas.size() - 1) * rowspan, true, true); + cell.getRow().getSheet().getLastRowNum(), (datas.size() - 1) * rowspan, true, true); templateSumHandler.shiftRows(cell.getRowIndex(),(datas.size() - 1) * rowspan); } 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); + colspan, mergedRegionHelper); rowIndex += rowspan; } } @@ -520,9 +520,9 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (row.getCell(j) == null) { row.createCell(j); CellStyle style = row.getRowNum() % 2 == 0 - ? getStyles(false, + ? getStyles(false, size >= j - columnIndex ? null : columns.get(j - columnIndex)) - : getStyles(true, + : getStyles(true, size >= j - columnIndex ? null : columns.get(j - columnIndex)); //返回的styler不为空时才使用,否则使用Excel设置的,更加推荐Excel设置的样式 if (style != null) { @@ -540,7 +540,18 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { row = row.getSheet().getRow(row.getRowNum() - rowspan + 1); for (int k = 0; k < rowspan; k++) { int ci = columnIndex;//cell的序号 - row.setHeight(columns.get(0 * colspan).getHeight()); + + 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); for (int i = 0; i < colspan && i < columns.size(); i++) { boolean isNumber = false; params = columns.get(colspan * k + i); @@ -549,9 +560,9 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { continue; } if (StringUtils.isEmpty(params.getName()) - && StringUtils.isEmpty(params.getConstValue())) { - row.getCell(ci).setCellStyle(columns.get(i).getCellStyle()); - ci = ci + columns.get(i).getColspan(); + && StringUtils.isEmpty(params.getConstValue())) { + row.getCell(ci).setCellStyle(params.getCellStyle()); + ci = ci + params.getColspan(); continue; } String val = null; @@ -592,11 +603,11 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { setMergedRegionStyle(row, ci, params); //合并对应单元格 if ((params.getRowspan() != 1 || params.getColspan() != 1) - && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci)) { + && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci)) { row.getSheet() - .addMergedRegion(new CellRangeAddress(row.getRowNum(), - row.getRowNum() + params.getRowspan() - 1, ci, - ci + params.getColspan() - 1)); + .addMergedRegion(new CellRangeAddress(row.getRowNum(), + row.getRowNum() + params.getRowspan() - 1, ci, + ci + params.getColspan() - 1)); } ci = ci + params.getColspan(); } @@ -646,9 +657,11 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { int startIndex = cell.getColumnIndex(); Row row = cell.getRow(); while (index < row.getLastCellNum()) { - int colSpan = columns.get(columns.size() - 1) != null - ? columns.get(columns.size() - 1).getColspan() : 1; + int colSpan = columns.get(columns.size() - 1) != null + ? columns.get(columns.size() - 1).getColspan() : 1; index += colSpan; + + for (int i = 1; i < colSpan; i++) { //添加合并的单元格,这些单元可能不是空,但是没有值,所以也需要跳过 columns.add(null); @@ -663,35 +676,41 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } String cellStringString; try {//不允许为空 便利单元格必须有结尾和值 - cellStringString = cell.getStringCellValue(); - if (StringUtils.isBlank(cellStringString) && colspan + startIndex <= index) { - throw new ExcelExportException("for each 当中存在空字符串,请检查模板"); - } else if (StringUtils.isBlank(cellStringString) - && colspan + startIndex > index) { - //读取是判断,跳过,数据为空,但是不是第一次读这一列,所以可以跳过 - columns.add(new ExcelForEachParams(null, cell.getCellStyle(), (short) 0)); - continue; + cellStringString = cell.getStringCellValue(); + if (StringUtils.isBlank(cellStringString) && colspan + startIndex <= index) { + throw new ExcelExportException("for each 当中存在空字符串,请检查模板"); + } else if (StringUtils.isBlank(cellStringString) + && colspan + startIndex > index) { + //读取是判断,跳过,数据为空,但是不是第一次读这一列,所以可以跳过 + columns.add(new ExcelForEachParams(null, cell.getCellStyle(), (short) 0)); + continue; + } + } catch (Exception e) { + throw new ExcelExportException(ExcelExportEnum.TEMPLATE_ERROR, e); } - } catch (Exception e) { - throw new ExcelExportException(ExcelExportEnum.TEMPLATE_ERROR, e); - } - //把读取过的cell 置为空 + //把读取过的cell 置为空 cell.setCellValue(""); if (cellStringString.contains(END_STR)) { columns.add(getExcelTemplateParams(cellStringString.replace(END_STR, EMPTY), - cell, mergedRegionHelper)); + cell, mergedRegionHelper)); + //补全缺失的cell(合并单元格后面的) + int lastCellColspan =columns.get(columns.size() - 1).getColspan(); + for (int i = 1; i < lastCellColspan; i++) { + //添加合并的单元格,这些单元可能不是空,但是没有值,所以也需要跳过 + columns.add(null); + } break; } else if (cellStringString.contains(WRAP)) { columns.add(getExcelTemplateParams(cellStringString.replace(WRAP, EMPTY), cell, - mergedRegionHelper)); + mergedRegionHelper)); //发现换行符,执行换行操作 colspan = index - startIndex + 1; - index = startIndex - 1; + index = startIndex - columns.get(columns.size() - 1).getColspan(); row = row.getSheet().getRow(row.getRowNum() + 1); rowspan++; } else { columns.add(getExcelTemplateParams(cellStringString.replace(WRAP, EMPTY), cell, - mergedRegionHelper)); + mergedRegionHelper)); } } } @@ -714,7 +733,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { MergedRegionHelper mergedRegionHelper) { name = name.trim(); ExcelForEachParams params = new ExcelForEachParams(name, cell.getCellStyle(), - cell.getRow().getHeight()); + cell.getRow().getHeight()); //判断是不是常量 if (name.startsWith(CONST) && name.endsWith(CONST)) { params.setName(null); @@ -728,7 +747,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { //获取合并单元格的数据 if (mergedRegionHelper.isMergedRegion(cell.getRowIndex() + 1, cell.getColumnIndex())) { Integer[] colAndrow = mergedRegionHelper.getRowAndColSpan(cell.getRowIndex() + 1, - cell.getColumnIndex()); + cell.getColumnIndex()); params.setRowspan(colAndrow[0]); params.setColspan(colAndrow[1]); } @@ -776,9 +795,9 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { wb = getCloneWorkBook(); // step 3. 解析模板 for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() - : params.getSheetNum().length; i < le; i++) { + : params.getSheetNum().length; i < le; i++) { if (params.getSheetName() != null && params.getSheetName().length > i - && StringUtils.isNotEmpty(params.getSheetName()[i])) { + && StringUtils.isNotEmpty(params.getSheetName()[i])) { wb.setSheetName(i, params.getSheetName()[i]); } tempCreateCellSet.clear(); @@ -791,4 +810,4 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { return wb; } -} +} \ No newline at end of file