From 157b3d691ac6e4e6624dd4e1903ffb9fd9b274c0 Mon Sep 17 00:00:00 2001 From: jueyue Date: Tue, 11 Jun 2019 17:49:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81sheet=E5=A4=8D=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easypoi/excel/ExcelExportUtil.java | 25 +- .../template/ExcelExportOfTemplateUtil.java | 235 +++++++++++------- .../excel/imports/sax/SaxReadExcel.java | 7 +- 3 files changed, 170 insertions(+), 97 deletions(-) diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/ExcelExportUtil.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/ExcelExportUtil.java index 04e9745..7ab56f8 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/ExcelExportUtil.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/ExcelExportUtil.java @@ -41,6 +41,9 @@ import cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil; */ public final class ExcelExportUtil { + public static int USE_SXSSF_LIMIT = 100000; + public static final String SHEET_NAME = "sheetName"; + private ExcelExportUtil() { } @@ -105,7 +108,7 @@ public final class ExcelExportUtil { private static Workbook getWorkbook(ExcelType type, int size) { if (ExcelType.HSSF.equals(type)) { return new HSSFWorkbook(); - } else if (size < 100000) { + } else if (size < USE_SXSSF_LIMIT) { return new XSSFWorkbook(); } else { return new SXSSFWorkbook(); @@ -162,7 +165,7 @@ public final class ExcelExportUtil { @Deprecated public static Workbook exportExcel(TemplateExportParams params, Class pojoClass, Collection dataSet, Map map) { - return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, pojoClass, dataSet, + return new ExcelExportOfTemplateUtil().createExcelByTemplate(params, pojoClass, dataSet, map); } @@ -176,7 +179,7 @@ public final class ExcelExportUtil { * @return */ public static Workbook exportExcel(TemplateExportParams params, Map map) { - return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, null, null, map); + return new ExcelExportOfTemplateUtil().createExcelByTemplate(params, null, null, map); } /** @@ -190,7 +193,21 @@ public final class ExcelExportUtil { */ public static Workbook exportExcel(Map> map, TemplateExportParams params) { - return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, map); + return new ExcelExportOfTemplateUtil().createExcelByTemplate(params, map); + } + + /** + * 导出文件通过模板解析只有模板,没有集合 + * 每个sheet对应一个list,按照数量进行导出排序,key是sheet的NUM + * @param params + * 导出参数类 + * @param map + * 模板集合 + * @return + */ + public static Workbook exportExcelClone(Map>> map, + TemplateExportParams params) { + return new ExcelExportOfTemplateUtil().createExcelCloneByTemplate(params, map); } } 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 03d2e05..fc773f8 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 @@ -15,32 +15,11 @@ */ package cn.afterturn.easypoi.excel.export.template; -import static cn.afterturn.easypoi.util.PoiElUtil.*; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import cn.afterturn.easypoi.excel.entity.TemplateSumEntity; -import cn.afterturn.easypoi.util.*; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import cn.afterturn.easypoi.cache.ExcelCache; import cn.afterturn.easypoi.entity.ImageEntity; import cn.afterturn.easypoi.excel.annotation.ExcelTarget; import cn.afterturn.easypoi.excel.entity.TemplateExportParams; +import cn.afterturn.easypoi.excel.entity.TemplateSumEntity; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams; @@ -49,12 +28,25 @@ import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; import cn.afterturn.easypoi.exception.excel.ExcelExportException; import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; +import cn.afterturn.easypoi.util.*; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.*; + +import static cn.afterturn.easypoi.excel.ExcelExportUtil.SHEET_NAME; +import static cn.afterturn.easypoi.util.PoiElUtil.*; /** * Excel 导出根据模板导出 * * @author JueYue - * 2013-10-17 + * 2013-10-17 * @version 1.0 */ public final class ExcelExportOfTemplateUtil extends BaseExportService { @@ -65,7 +57,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率 */ - private Set tempCreateCellSet = new HashSet(); + private Set tempCreateCellSet = new HashSet(); /** * 模板参数,全局都用到 */ @@ -73,7 +65,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 单元格合并信息 */ - private MergedRegionHelper mergedRegionHelper; + private MergedRegionHelper mergedRegionHelper; private TemplateSumHandler templateSumHandler; @@ -89,12 +81,12 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { Workbook workbook) throws Exception { // 获取表头数据 - Map titlemap = getTitleMap(sheet); - Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); + Map titlemap = getTitleMap(sheet); + Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); // 得到所有字段 - Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); - ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); - String targetId = null; + Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); + ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); + String targetId = null; if (etarget != null) { targetId = etarget.value(); } @@ -123,6 +115,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 利用foreach循环输出数据 + * * @param cell * @param map * @param name @@ -131,21 +124,21 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { private void addListDataToExcel(Cell cell, Map map, String name) throws Exception { boolean isCreate = !name.contains(FOREACH_NOT_CREATE); - boolean isShift = name.contains(FOREACH_AND_SHIFT); + 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); - String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" "); + 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); if (datas == null) { return; } - Iterator its = datas.iterator(); - int rowspan = (Integer) columnsInfo[0], colspan = (Integer) columnsInfo[1]; + Iterator its = datas.iterator(); + int rowspan = (Integer) columnsInfo[0], colspan = (Integer) columnsInfo[1]; @SuppressWarnings("unchecked") List columns = (List) columnsInfo[2]; - Row row = null; + Row row = null; int rowIndex = cell.getRow().getRowNum() + 1; //处理当前行 if (its.hasNext()) { @@ -174,14 +167,15 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 下移数据 + * * @param dataSet * @param excelParams * @return */ private int getShiftRows(Collection dataSet, List excelParams) throws Exception { - int size = 0; - Iterator its = dataSet.iterator(); + int size = 0; + Iterator its = dataSet.iterator(); while (its.hasNext()) { Object t = its.next(); size += getOneObjectSize(t, excelParams); @@ -198,7 +192,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { */ public int getOneObjectSize(Object t, List excelParams) throws Exception { ExcelExportEntity entity; - int maxHeight = 1; + int maxHeight = 1; for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { entity = excelParams.get(k); if (entity.getList() != null) { @@ -212,7 +206,90 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { } - public Workbook createExcleByTemplate(TemplateExportParams params, Class pojoClass, + public Workbook createExcelCloneByTemplate(TemplateExportParams params, + Map>> map) { + // step 1. 判断模板的地址 + if (params == null || map == null || StringUtils.isEmpty(params.getTemplateUrl())) { + throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); + } + Workbook wb = null; + // step 2. 判断模板的Excel类型,解析模板 + try { + this.teplateParams = params; + wb = ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), + true); + int oldSheetNum = wb.getNumberOfSheets(); + // 把所有的KEY排个顺序 + List> mapList; + List sheetNumList = new ArrayList<>(); + sheetNumList.addAll(map.keySet()); + Collections.sort(sheetNumList); + + //把需要克隆的全部克隆一遍 + for (Integer sheetNum : sheetNumList) { + mapList = map.get(sheetNum); + for (int i = mapList.size(); i > 0; i--) { + wb.cloneSheet(sheetNum); + } + } + for (int i = 0; i < oldSheetNum; i++) { + wb.removeSheetAt(i); + } + // 创建表格样式 + setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() + .getConstructor(Workbook.class).newInstance(wb)); + // step 3. 解析模板 + int sheetIndex = 0; + for (Integer sheetNum : sheetNumList) { + mapList = map.get(sheetNum); + for (int i = mapList.size() - 1; i >= 0; i--) { + tempCreateCellSet.clear(); + if (mapList.get(i).containsKey(SHEET_NAME)) { + wb.setSheetName(sheetIndex, mapList.get(i).get(SHEET_NAME).toString()); + } + parseTemplate(wb.getSheetAt(sheetIndex), mapList.get(i), params.isColForEach()); + sheetIndex++; + } + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + return null; + } + return wb; + } + + public Workbook createExcelByTemplate(TemplateExportParams params, + Map> map) { + // step 1. 判断模板的地址 + if (params == null || map == null || StringUtils.isEmpty(params.getTemplateUrl())) { + throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); + } + Workbook wb = null; + // step 2. 判断模板的Excel类型,解析模板 + try { + this.teplateParams = params; + wb = getCloneWorkBook(); + // 创建表格样式 + setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() + .getConstructor(Workbook.class).newInstance(wb)); + // step 3. 解析模板 + for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() + : params.getSheetNum().length; i < le; i++) { + if (params.getSheetName() != null && params.getSheetName().length > i + && StringUtils.isNotEmpty(params.getSheetName()[i])) { + wb.setSheetName(i, params.getSheetName()[i]); + } + tempCreateCellSet.clear(); + parseTemplate(wb.getSheetAt(i), map.get(i), params.isColForEach()); + } + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + return null; + } + return wb; + } + + public Workbook createExcelByTemplate(TemplateExportParams params, Class pojoClass, Collection dataSet, Map map) { // step 1. 判断模板的地址 if (params == null || map == null || (StringUtils.isEmpty(params.getTemplateUrl()) && params.getTemplateWb() == null)) { @@ -276,15 +353,15 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { * @return */ private Map getTitleMap(Sheet sheet) { - Row row = null; - Iterator cellTitle; + Row row = null; + Iterator cellTitle; Map titlemap = new HashMap(); for (int j = 0; j < teplateParams.getHeadingRows(); j++) { row = sheet.getRow(j + teplateParams.getHeadingStartRow()); cellTitle = row.cellIterator(); int i = row.getFirstCellNum(); while (cellTitle.hasNext()) { - Cell cell = cellTitle.next(); + Cell cell = cellTitle.next(); String value = cell.getStringCellValue(); if (!StringUtils.isEmpty(value)) { titlemap.put(value, i); @@ -304,7 +381,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (colForeach) { colForeach(sheet, map); } - Row row = null; + Row row = null; int index = 0; while (index <= sheet.getLastRowNum()) { row = sheet.getRow(index++); @@ -336,13 +413,14 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 先进行列的循环,因为涉及很多数据 + * * @param sheet * @param map */ private void colForeach(Sheet sheet, Map map) throws Exception { - Row row = null; - Cell cell = null; - int index = 0; + Row row = null; + Cell cell = null; + int index = 0; while (index <= sheet.getLastRowNum()) { row = sheet.getRow(index++); if (row == null) { @@ -363,6 +441,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 循环列表 + * * @param cell * @param map * @param name @@ -372,15 +451,15 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { boolean isCreate = name.contains(FOREACH_COL_VALUE); name = name.replace(FOREACH_COL_VALUE, EMPTY).replace(FOREACH_COL, EMPTY).replace(START_STR, EMPTY); - String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" "); + 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); if (datas == null) { return; } - Iterator its = datas.iterator(); - int rowspan = (Integer) columnsInfo[0], colspan = (Integer) columnsInfo[1]; + Iterator its = datas.iterator(); + int rowspan = (Integer) columnsInfo[0], colspan = (Integer) columnsInfo[1]; @SuppressWarnings("unchecked") List columns = (List) columnsInfo[2]; while (its.hasNext()) { @@ -400,14 +479,15 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 先判断删除,省得影响效率 + * * @param sheet * @param map * @throws Exception */ private void deleteCell(Sheet sheet, Map map) throws Exception { - Row row = null; - Cell cell = null; - int index = 0; + Row row = null; + Cell cell = null; + int index = 0; while (index <= sheet.getLastRowNum()) { row = sheet.getRow(index++); if (row == null) { @@ -450,7 +530,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (oldString != null && oldString.indexOf(START_STR) != -1 && !oldString.contains(FOREACH)) { // step 2. 判断是否含有解析函数 - String params = null; + String params = null; boolean isNumber = false; if (isNumber(oldString)) { isNumber = true; @@ -488,6 +568,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 创建并返回第一个Row + * * @param sheet * @param rowIndex * @param isCreate @@ -538,7 +619,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { int ci = columnIndex;//cell的序号 short high = columns.get(0).getHeight(); - int n = k; + int n = k; while (n > 0) { if (columns.get(n * colspan).getHeight() == 0) { n--; @@ -579,12 +660,12 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { if (obj != null && obj instanceof ImageEntity) { ImageEntity img = (ImageEntity) obj; row.getCell(ci).setCellValue(""); - if (img.getRowspan()>1 || img.getColspan() > 1){ + if (img.getRowspan() > 1 || img.getColspan() > 1) { img.setHeight(0); row.getCell(ci).getSheet().addMergedRegion(new CellRangeAddress(row.getCell(ci).getRowIndex(), - row.getCell(ci).getRowIndex() + img.getRowspan() - 1, row.getCell(ci).getColumnIndex(), row.getCell(ci).getColumnIndex() + img.getColspan() -1)); + row.getCell(ci).getRowIndex() + img.getRowspan() - 1, row.getCell(ci).getColumnIndex(), row.getCell(ci).getColumnIndex() + img.getColspan() - 1)); } - createImageCell(row.getCell(ci), img.getHeight(),img.getRowspan(),img.getColspan(), img.getUrl(), img.getData()); + createImageCell(row.getCell(ci), img.getHeight(), img.getRowspan(), img.getColspan(), img.getUrl(), img.getData()); } else if (isNumber && StringUtils.isNotEmpty(val)) { row.getCell(ci).setCellValue(Double.parseDouble(val)); row.getCell(ci).setCellType(CellType.NUMERIC); @@ -623,6 +704,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 设置合并单元格的样式 + * * @param row * @param ci * @param params @@ -630,13 +712,13 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { private void setMergedRegionStyle(Row row, int ci, ExcelForEachParams params) { //第一行数据 for (int i = 1; i < params.getColspan(); i++) { - if(params.getCellStyle() != null){ + if (params.getCellStyle() != null) { row.getCell(ci + i).setCellStyle(params.getCellStyle()); } } for (int i = 1; i < params.getRowspan(); i++) { for (int j = 0; j < params.getColspan(); j++) { - if(params.getCellStyle() != null){ + if (params.getCellStyle() != null) { row.getCell(ci + j).setCellStyle(params.getCellStyle()); } } @@ -645,6 +727,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 获取迭代的数据的值 + * * @param cell * @param name * @param mergedRegionHelper @@ -660,7 +743,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { int index = cell.getColumnIndex(); //保存col 的开始列 int startIndex = cell.getColumnIndex(); - Row row = cell.getRow(); + Row row = cell.getRow(); while (index < row.getLastCellNum()) { int colSpan = columns.get(columns.size() - 1) != null ? columns.get(columns.size() - 1).getColspan() : 1; @@ -729,6 +812,7 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { /** * 获取模板参数 + * * @param name * @param cell * @param mergedRegionHelper @@ -787,35 +871,4 @@ public final class ExcelExportOfTemplateUtil extends BaseExportService { sortAllParams(excelParams); } - public Workbook createExcleByTemplate(TemplateExportParams params, - Map> map) { - // step 1. 判断模板的地址 - if (params == null || map == null || StringUtils.isEmpty(params.getTemplateUrl())) { - throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); - } - Workbook wb = null; - // step 2. 判断模板的Excel类型,解析模板 - try { - this.teplateParams = params; - wb = getCloneWorkBook(); - // 创建表格样式 - setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle() - .getConstructor(Workbook.class).newInstance(wb)); - // step 3. 解析模板 - for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() - : params.getSheetNum().length; i < le; i++) { - if (params.getSheetName() != null && params.getSheetName().length > i - && StringUtils.isNotEmpty(params.getSheetName()[i])) { - wb.setSheetName(i, params.getSheetName()[i]); - } - tempCreateCellSet.clear(); - parseTemplate(wb.getSheetAt(i), map.get(i), params.isColForEach()); - } - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - return null; - } - return wb; - } - } \ No newline at end of file diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/sax/SaxReadExcel.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/sax/SaxReadExcel.java index bd4676f..4fc25ec 100644 --- a/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/sax/SaxReadExcel.java +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/sax/SaxReadExcel.java @@ -59,12 +59,12 @@ public class SaxReadExcel { } private List readExcel(OPCPackage opcPackage, Class pojoClass, ImportParams params, - ISaxRowRead rowRead, IReadHandler hanlder) { + ISaxRowRead rowRead, IReadHandler handler) { try { XSSFReader xssfReader = new XSSFReader(opcPackage); SharedStringsTable sst = xssfReader.getSharedStringsTable(); if (rowRead == null) { - rowRead = new SaxRowRead(pojoClass, params, hanlder); + rowRead = new SaxRowRead(pojoClass, params, handler); } XMLReader parser = fetchSheetParser(sst, rowRead); Iterator sheets = xssfReader.getSheetsData(); @@ -76,6 +76,9 @@ public class SaxReadExcel { parser.parse(sheetSource); sheet.close(); } + if (handler != null) { + handler.doAfterAll(); + } return rowRead.getList(); } catch (Exception e) { LOGGER.error(e.getMessage(), e);