我是在官方4.4.0源码上修改的,获取需要的源码文件,然后修改:点击下载
本文解决三个问题
(1)模板导出图片不显示(实际上导出来了只是最小化显示了)
(2)fe循环指令存在而合并单元格的时候格式错乱问题
(3)fe存在一对多关系的时候格式错乱问题
嫌看文章麻烦的伙伴们可以直接下载 代码+模板:点击下载
目录
1.加载模板数据导出语句,图片替换成自己的图片,代码种的图你们那里访问不到的
2.获取 cn.afterturn.easypoi.excel.ExcelExportUtil
3.修改cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil
4.修改cn.afterturn.easypoi.excel.export.base.BaseExportService
5.新建工具类Sd3eUtil
使用xbx();方法
Workbook book = ExcelExportUtil.exportExcel(params, valueXbx);
package cn.afterturn.easypoi.test.excel.template;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.easy.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.junit.Before;
import org.junit.Test;
public class ExcelExportTemplateColFeTest {
Map value = new HashMap();
@Test
public void xbx() throws Exception {
//养护方案全部
Map valueXbx = new HashMap();
// List listMaintenanceRecordName = new ArrayList();
List
获取后无需修改代码,但是需要引用修改后的ExcelExportOfTemplateUtil.java
package com.ruoyi.framework.easypoi.excel;
/**
* @version v1.0
* @ProjectName: road
* @ClassName: ExcelExportUtil
* @Description: 4.4.0 版本进行修改
* @Author: xbx
* @Date: 2022/3/4 10:59
* 徐本锡 mod by xbx 2022.03.07 调用这个类加载模板导出 解决格式错乱问题
*/
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.export.ExcelBatchExportService;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
//import cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil;
import cn.afterturn.easypoi.handler.inter.IExcelExportServer;
import cn.afterturn.easypoi.handler.inter.IWriter;
import com.ruoyi.framework.easypoi.excel.export.template.ExcelExportOfTemplateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* excel 导出工具类
*
* @author JueYue
* @version 1.0
* 2013-10-17
*/
public final class ExcelExportUtil {
public static int USE_SXSSF_LIMIT = 1000000;
public static final String SHEET_NAME = "sheetName";
private ExcelExportUtil() {
}
/**
* 大数据量导出
*
* @param entity 表格标题属性
* @param pojoClass Excel对象Class
*/
public static IWriter exportBigExcel(ExportParams entity, Class> pojoClass) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, pojoClass);
return batchServer;
}
/**
* 大数据量导出
*
* @param entity
* @param excelParams
* @return
*/
public static IWriter exportBigExcel(ExportParams entity, List excelParams) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, excelParams);
return batchServer;
}
/**
* 大数据量导出
*
* @param entity 表格标题属性
* @param pojoClass Excel对象Class
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
*/
public static Workbook exportBigExcel(ExportParams entity, Class> pojoClass,
IExcelExportServer server, Object queryParams) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, pojoClass);
return batchServer.exportBigExcel(server, queryParams);
}
/**
* 大数据量导出
*
* @param entity
* @param excelParams
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
* @return
*/
public static Workbook exportBigExcel(ExportParams entity, List excelParams,
IExcelExportServer server, Object queryParams) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, excelParams);
return batchServer.exportBigExcel(server, queryParams);
}
/**
* @param entity 表格标题属性
* @param pojoClass Excel对象Class
* @param dataSet Excel对象数据List
*/
public static Workbook exportExcel(ExportParams entity, Class> pojoClass,
Collection> dataSet) {
Workbook workbook = getWorkbook(entity.getType(), dataSet.size());
new ExcelExportService().createSheet(workbook, entity, pojoClass, dataSet);
return workbook;
}
private static Workbook getWorkbook(ExcelType type, int size) {
if (ExcelType.HSSF.equals(type)) {
return new HSSFWorkbook();
} else {
return new XSSFWorkbook();
}
}
/**
* 根据Map创建对应的Excel
*
* @param entity 表格标题属性
* @param entityList Map对象列表
* @param dataSet Excel对象数据List
*/
public static Workbook exportExcel(ExportParams entity, List entityList,
Collection> dataSet) {
Workbook workbook = getWorkbook(entity.getType(), dataSet.size());
new ExcelExportService().createSheetForMap(workbook, entity, entityList, dataSet);
return workbook;
}
/**
* 根据Map创建对应的Excel(一个excel 创建多个sheet)
*
* @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data
* Collection 数据
* @return
*/
public static Workbook exportExcel(List> list, ExcelType type) {
Workbook workbook = getWorkbook(type, 0);
for (Map map : list) {
ExcelExportService service = new ExcelExportService();
ExportParams params = (ExportParams) map.get("title");
params.setType(type);
service.createSheet(workbook,params,
(Class>) map.get("entity"), (Collection>) map.get("data"));
}
return workbook;
}
/**
* 导出文件通过模板解析,不推荐这个了,推荐全部通过模板来执行处理
*
* @param params 导出参数类
* @param pojoClass 对应实体
* @param dataSet 实体集合
* @param map 模板集合
* @return
*/
@Deprecated
public static Workbook exportExcel(TemplateExportParams params, Class> pojoClass,
Collection> dataSet, Map map) {
return new ExcelExportOfTemplateUtil().createExcelByTemplate(params, pojoClass, dataSet,
map);
}
/**
* 导出文件通过模板解析只有模板,没有集合
*
* @param params 导出参数类
* @param map 模板集合
* @return
*/
public static Workbook exportExcel(TemplateExportParams params, Map map) {
return new ExcelExportOfTemplateUtil().createExcelByTemplate(params, null, null, map);
}
/**
* 导出文件通过模板解析只有模板,没有集合
* 每个sheet对应一个map,导出到处,key是sheet的NUM
*
* @param params 导出参数类
* @param map 模板集合
* @return
*/
public static Workbook exportExcel(Map> map,
TemplateExportParams params) {
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);
}
}
package cn.afterturn.easypoi.easy.excel.export.template;
/**
* @version v1.0
* @ProjectName: road
* @ClassName: ExcelExportOfTemplateUtil
* @Description: 4.4.0 版本进行修改
* @Author: xbx
* @Date: 2022/3/4 10:56
* addListDataToExcel(Cell, Map, String);
* foreachCol(Cell, Map, String);
* setForeachRowCellValue(boolean, Row, int, Object, List, Map,int, int, MergedRegionHelper,int);
* setForEachLoopRowCellValue(Row, int, Collection, List,ExcelForEachParams, Map,int, int,MergedRegionHelper, String);
* 徐本锡 mod by xbx 2022.03.07 list循环遍历的时候 存在合并单元格情况 导致格式错乱
*
* getLoopEachParams(List, int, String) 徐本锡 mod by xbx 2022.03.07 解决一对多 row循环中,row元素中包含list并且合并单元格时,报空的错误
*/
import cn.afterturn.easypoi.cache.ExcelCache;
import cn.afterturn.easypoi.easy.excel.export.base.BaseExportService;
import cn.afterturn.easypoi.easy.util.Sd3eUtil;
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;
//import cn.afterturn.easypoi.excel.export.base.BaseExportService;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import cn.afterturn.easypoi.excel.export.template.TemplateSumHandler;
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
* @version 1.0
*/
public final class ExcelExportOfTemplateUtil extends BaseExportService {
private static final Logger LOGGER = LoggerFactory
.getLogger(ExcelExportOfTemplateUtil.class);
/**
* 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率
*/
private Set tempCreateCellSet = new HashSet();
/**
* 模板参数,全局都用到
*/
private TemplateExportParams templateParams;
/**
* 单元格合并信息
*/
private MergedRegionHelper mergedRegionHelper;
private TemplateSumHandler templateSumHandler;
/**
* 往Sheet 填充正常数据,根据表头信息 使用导入的部分逻辑,坐对象映射
*
* @param sheet
* @param pojoClass
* @param dataSet
* @param workbook
*/
private void addDataToSheet(Class> pojoClass, Collection> dataSet, Sheet sheet,
Workbook workbook) throws Exception {
// 获取表头数据
Map titlemap = getTitleMap(sheet);
Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet);
// 得到所有字段
Field[] fileds = PoiPublicUtil.getClassFields(pojoClass);
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
String targetId = null;
if (etarget != null) {
targetId = etarget.value();
}
// 获取实体对象的导出数据
List excelParams = new ArrayList();
getAllExcelField(null, targetId, fileds, excelParams, pojoClass, null, null);
// 根据表头进行筛选排序
sortAndFilterExportField(excelParams, titlemap);
short rowHeight = getRowHeight(excelParams);
int index = templateParams.getHeadingRows() + templateParams.getHeadingStartRow(),
titleHeight = index;
int shiftRows = getShiftRows(dataSet, excelParams);
//下移数据,模拟插入
sheet.shiftRows(templateParams.getHeadingRows() + templateParams.getHeadingStartRow(),
sheet.getLastRowNum(), shiftRows, true, true);
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;
}
Iterator> its = dataSet.iterator();
while (its.hasNext()) {
Object t = its.next();
index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight, 0)[0];
}
// 合并同类项
mergeCells(sheet, excelParams, titleHeight);
}
/**
* 利用foreach循环输出数据
*
* @param cell
* @param map
* @param name
* @throws Exception
* 徐本锡 mod by xbx 2022.03.07 list循环遍历的时候 存在合并单元格情况 导致格式错乱
*/
private void addListDataToExcel(Cell cell, Map map,
String name) throws Exception {
//mod by xbx
// 每次利用foreach循环输出数据时,重新处理 mergedRegionHelper
// 原因:如果存在多个循环,前面循环时,下面的模板指令所在单元格的行号会发生变化,此时 mergedRegionHelper 中的缓存没有发生相应变化,需要重新获取一下 mergedRegionHelper
mergedRegionHelper = new MergedRegionHelper(cell.getSheet());
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);
String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" ");
Collection> datas = (Collection>) PoiPublicUtil.getParamsValue(keys[0], map);
if (datas == null) {
return;
}
Object[] columnsInfo = getAllDataColumns(cell, name.replace(keys[0], EMPTY),
mergedRegionHelper);
Iterator> its = datas.iterator();
int rowspan = (Integer) columnsInfo[0], colspan = (Integer) columnsInfo[1];
@SuppressWarnings("unchecked")
List columns = (List) columnsInfo[2];
Row row = null;
int rowIndex = cell.getRow().getRowNum() + 1;
ExcelForEachParams indexColumn = getIndexColumn(columns);
//mod by xbx
// 定义循环开始行号
int startRowNum = cell.getRow().getRowNum();
// 处理当前行
if (its.hasNext()) {
Object t = its.next();
this.setForeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map, rowspan, colspan, mergedRegionHelper,startRowNum);
rowIndex += rowspan - 1;
}
// //处理当前行
// int loopSize = 0;
// if (its.hasNext()) {
// Object t = its.next();
// loopSize = setForeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map,
// rowspan, colspan, mergedRegionHelper)[0];
// rowIndex += rowspan - 1 + loopSize - 1;
// }
//修复不论后面有没有数据,都应该执行的是插入操作
if (isShift && datas.size() > 1 && datas.size() * rowspan > 1 && cell.getRowIndex() + rowspan <= cell.getRow().getSheet().getLastRowNum()) {
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);
mergedRegionHelper.shiftRows(cell.getSheet(), cell.getRowIndex() + rowspan, (datas.size() - 1) * rowspan, shiftRows);
templateSumHandler.shiftRows(cell.getRowIndex() + rowspan, (datas.size() - 1) * rowspan);
PoiExcelTempUtil.reset(cell.getSheet(), cell.getRowIndex() + rowspan + (datas.size() - 1) * rowspan, cell.getRow().getSheet().getLastRowNum());
}
//mod by xbx
// 定义循环结束行号
int endRowNum = 0;
// // 创建行
while (its.hasNext()) {
Object t = its.next();
row = createRow(rowIndex, cell.getSheet(), isCreate, rowspan);
this.setForeachRowCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map, rowspan,
colspan, mergedRegionHelper,startRowNum);
rowIndex += rowspan;
// 每次创建行后,重新给循环结束行号赋值
endRowNum = row.getRowNum();
}
// 如果新创建行了
// 合并循环左侧竖向单元格
if (endRowNum != 0){
Sheet sheet = cell.getRow().getSheet();
int sheetMergeCount = sheet.getNumMergedRegions();
int columnIndex = cell.getColumnIndex();
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();
for (int ii = 0;ii < columnIndex;ii++){
if (firstRow <= startRowNum && lastRow > startRowNum && lastColumn == ii){
ca.setLastRow(lastRow + (endRowNum - startRowNum));
}
}
}
}
// while (its.hasNext()) {
// Object t = its.next();
// row = createRow(rowIndex, cell.getSheet(), isCreate, rowspan);
// indexColumn.addConstValue(1);
// loopSize = setForeachRowCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map, rowspan,
// colspan, mergedRegionHelper)[0];
// rowIndex += rowspan + loopSize - 1;
// }
}
private ExcelForEachParams getIndexColumn(List columns) {
for (int i = 0; i < columns.size(); i++) {
if (columns.get(i) != null && INDEX.equals(columns.get(i).getConstValue())) {
columns.get(i).setConstValue("1");
return columns.get(i);
}
}
return new ExcelForEachParams();
}
/**
* 下移数据
*
* @param dataSet
* @param excelParams
* @return
*/
private int getShiftRows(Collection> dataSet,
List excelParams) throws Exception {
int size = 0;
Iterator> its = dataSet.iterator();
while (its.hasNext()) {
Object t = its.next();
size += getOneObjectSize(t, excelParams);
}
return size;
}
/**
* 获取单个对象的高度,主要是处理一堆多的情况
*
* @param t
* @param excelParams
* @throws Exception
*/
private int getOneObjectSize(Object t, List excelParams) throws Exception {
ExcelExportEntity entity;
int maxHeight = 1;
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
entity = excelParams.get(k);
if (entity.getList() != null) {
Collection> list = (Collection>) entity.getMethod().invoke(t, new Object[]{});
if (list != null && list.size() > maxHeight) {
maxHeight = list.size();
}
}
}
return maxHeight;
}
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.templateParams = params;
wb = ExcelCache.getWorkbook(templateParams.getTemplateUrl(), templateParams.getSheetNum(),
true);
int oldSheetNum = wb.getNumberOfSheets();
List oldSheetName = new ArrayList<>();
for (int i = 0; i < oldSheetNum; i++) {
oldSheetName.add(wb.getSheetName(i));
}
// 把所有的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 < oldSheetName.size(); i++) {
wb.removeSheetAt(wb.getSheetIndex(oldSheetName.get(i)));
}
// 创建表格样式
setExcelExportStyler((IExcelExportStyler) templateParams.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());
if (params.isReadonly()) {
wb.getSheetAt(i).protectSheet(UUID.randomUUID().toString());
}
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.templateParams = params;
wb = getCloneWorkBook();
// 创建表格样式
setExcelExportStyler((IExcelExportStyler) templateParams.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());
if (params.isReadonly()) {
wb.getSheetAt(i).protectSheet(UUID.randomUUID().toString());
}
}
} 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)) {
throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
}
Workbook wb = null;
// step 2. 判断模板的Excel类型,解析模板
try {
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) templateParams.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, params.isColForEach());
if (params.isReadonly()) {
wb.getSheetAt(i).protectSheet(UUID.randomUUID().toString());
}
}
if (dataSet != null) {
// step 4. 正常的数据填充
dataHandler = params.getDataHandler();
if (dataHandler != null) {
needHandlerList = Arrays.asList(dataHandler.getNeedHandlerFields());
}
addDataToSheet(pojoClass, dataSet, wb.getSheetAt(params.getDataSheetNum()), wb);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return null;
}
return wb;
}
/**
* 克隆excel防止操作原对象,workbook无法克隆,只能对excel进行克隆
*
* @throws Exception
*/
private Workbook getCloneWorkBook() throws Exception {
return ExcelCache.getWorkbook(templateParams.getTemplateUrl(), templateParams.getSheetNum(),
templateParams.isScanAllsheet());
}
/**
* 获取表头数据,设置表头的序号
*
* @param sheet
* @return
*/
private Map getTitleMap(Sheet sheet) {
Row row = null;
Iterator cellTitle;
Map titlemap = new HashMap();
for (int j = 0; j < templateParams.getHeadingRows(); j++) {
row = sheet.getRow(j + templateParams.getHeadingStartRow());
cellTitle = row.cellIterator();
int i = row.getFirstCellNum();
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = cell.getStringCellValue();
if (!StringUtils.isEmpty(value)) {
titlemap.put(value, i);
}
i = i + 1;
}
}
return titlemap;
}
private void parseTemplate(Sheet sheet, Map map,
boolean colForeach) throws Exception {
if (sheet.getWorkbook() instanceof XSSFWorkbook) {
super.type = ExcelType.XSSF;
}
deleteCell(sheet, map);
mergedRegionHelper = new MergedRegionHelper(sheet);
templateSumHandler = new TemplateSumHandler(sheet);
if (colForeach) {
colForeach(sheet, map);
}
Row row = null;
int index = 0;
while (index <= sheet.getLastRowNum()) {
row = sheet.getRow(index++);
if (row == null) {
continue;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
if (row.getCell(i) != null && !tempCreateCellSet
.contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) {
setValueForCellByMap(row.getCell(i), map);
}
}
}
//修改需要处理的统计值
handlerSumCell(sheet);
}
private void handlerSumCell(Sheet sheet) {
for (TemplateSumEntity sumEntity : templateSumHandler.getDataList()) {
Cell cell = sheet.getRow(sumEntity.getRow()).getCell(sumEntity.getCol());
if (cell.getStringCellValue().contains(sumEntity.getSumKey())) {
cell.setCellValue(cell.getStringCellValue()
.replace("sum:(" + sumEntity.getSumKey() + ")", sumEntity.getValue() + ""));
} else {
cell.setCellValue(cell.getStringCellValue() + sumEntity.getValue());
}
}
}
/**
* 先进行列的循环,因为涉及很多数据
*
* @param sheet
* @param map
*/
private void colForeach(Sheet sheet, Map map) throws Exception {
Row row = null;
Cell cell = null;
int index = 0;
while (index <= sheet.getLastRowNum()) {
row = sheet.getRow(index++);
if (row == null) {
continue;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
cell = row.getCell(i);
if (row.getCell(i) != null && (cell.getCellType() == CellType.STRING
|| cell.getCellType() == CellType.NUMERIC)) {
String text = PoiCellUtil.getCellValue(cell);
if (text.contains(FOREACH_COL) || text.contains(FOREACH_COL_VALUE)) {
foreachCol(cell, map, text);
}
}
}
}
}
/**
* 循环列表
*
* @param cell
* @param map
* @param name
* @throws Exception
* 徐本锡 mod by xbx 2022.03.07 list循环遍历的时候 存在合并单元格情况 导致格式错乱
*/
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);
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];
@SuppressWarnings("unchecked")
List columns = (List) columnsInfo[2];
while (its.hasNext()) {
Object t = its.next();
//mod by xbx
// 定义循环开始行号
int startRowNum = cell.getRow().getRowNum();
setForeachRowCellValue(true, cell.getRow(), cell.getColumnIndex(), t, columns, map,
rowspan, colspan, mergedRegionHelper,startRowNum);
// 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);
}
cell = cell.getRow().getCell(cell.getColumnIndex() + colspan);
}
if (isCreate) {
cell = cell.getRow().getCell(cell.getColumnIndex() - 1);
cell.setCellValue(cell.getStringCellValue() + END_STR);
}
}
/**
* 先判断删除,省得影响效率
*
* @param sheet
* @param map
* @throws Exception
*/
private void deleteCell(Sheet sheet, Map map) throws Exception {
Row row = null;
Cell cell = null;
int index = 0;
while (index <= sheet.getLastRowNum()) {
row = sheet.getRow(index++);
if (row == null) {
continue;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
cell = row.getCell(i);
if (row.getCell(i) != null && (cell.getCellType() == CellType.STRING
|| cell.getCellType() == CellType.NUMERIC)) {
cell.setCellType(CellType.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())) {
PoiSheetUtil.deleteColumn(sheet, i);
i--;
}
cell.setCellValue("");
}
}
}
}
}
/**
* 给每个Cell通过解析方式set值
*
* @param cell
* @param map
*/
private void setValueForCellByMap(Cell cell, Map map) throws Exception {
CellType cellType = cell.getCellType();
if (cellType != CellType.STRING && cellType != CellType.NUMERIC) {
return;
}
String oldString;
oldString = cell.getStringCellValue();
if (oldString != null && oldString.indexOf(START_STR) != -1
&& !oldString.contains(FOREACH)) {
boolean isNumber = isHasSymbol(oldString, NUMBER_SYMBOL);
Object obj = getValByHandler(oldString,map, cell);
//如何是数值 类型,就按照数值类型进行设置;如果是图片就设置为图片
if (obj instanceof ImageEntity) {
ImageEntity img = (ImageEntity) obj;
cell.setCellValue("");
if (img.getRowspan() > 1 || img.getColspan() > 1) {
img.setHeight(0);
PoiMergeCellUtil.addMergedRegion(cell.getSheet(), cell.getRowIndex(),
cell.getRowIndex() + img.getRowspan() - 1, cell.getColumnIndex(), cell.getColumnIndex() + img.getColspan() - 1);
}
createImageCell(cell, img.getHeight(), img.getRowspan(), img.getColspan(), img.getUrl(), img.getData());
} else if (isNumber && StringUtils.isNotBlank(obj.toString())) {
cell.setCellValue(Double.parseDouble(obj.toString()));
} else {
cell.setCellValue(obj.toString());
}
}
//判断foreach 这种方法
if (oldString != null && oldString.contains(FOREACH)) {
addListDataToExcel(cell, map, oldString.trim());
}
}
/**
* 根据模板解析函数获取值
* @param funStr
* @param map
* @return
*/
private Object getValByHandler(String funStr,Map map, Cell cell) throws Exception {
// step 2. 判断是否含有解析函数
if (isHasSymbol(funStr, NUMBER_SYMBOL)) {
funStr = funStr.replaceFirst(NUMBER_SYMBOL, "");
}
boolean isStyleBySelf = false;
if (isHasSymbol(funStr, STYLE_SELF)) {
isStyleBySelf = true;
funStr = funStr.replaceFirst(STYLE_SELF, "");
}
boolean isDict = false;
String dict = null;
if (isHasSymbol(funStr, DICT_HANDLER)) {
isDict = true;
dict = funStr.substring(funStr.indexOf(DICT_HANDLER) + 5).split(";")[0];
funStr = funStr.replaceFirst(DICT_HANDLER, "");
funStr = funStr.replaceFirst(dict + ";", "");
}
boolean isI18n = false;
if (isHasSymbol(funStr, I18N_HANDLER)) {
isI18n = true;
funStr = funStr.replaceFirst(I18N_HANDLER, "");
}
boolean isDern = false;
String dern = null;
if (isHasSymbol(funStr, DESENSITIZATION_RULE)) {
isDern = true;
dern = funStr.substring(funStr.indexOf(DESENSITIZATION_RULE) + 5).split(";")[0];
funStr = funStr.replaceFirst(DESENSITIZATION_RULE, "");
funStr = funStr.replaceFirst(dern + ";", "");
}
if (isHasSymbol(funStr, MERGE)) {
String mergeStr = PoiPublicUtil.getElStr(funStr,MERGE);
funStr = funStr.replace(mergeStr, "");
mergeStr = mergeStr.replaceFirst(MERGE, "");
try {
int colSpan = (int)Double.parseDouble(PoiPublicUtil.getRealValue(mergeStr, map).toString());
PoiMergeCellUtil.addMergedRegion(cell.getSheet(), cell.getRowIndex(),
cell.getRowIndex() , cell.getColumnIndex(), cell.getColumnIndex() + colSpan - 1);
} catch (Exception e) {
LOGGER.error(e.getMessage(),e);
}
}
Object obj = funStr.indexOf(START_STR) == -1 ? eval(funStr, map) : PoiPublicUtil.getRealValue(funStr, map);
if (isDict) {
obj = dictHandler.toName(dict, null, funStr, obj);
}
if (isI18n) {
obj = i18nHandler.getLocaleName(obj.toString());
}
if (isDern) {
obj = PoiDataDesensitizationUtil.desensitization(dern,obj);
}
return obj;
}
private boolean isHasSymbol(String text, String symbol) {
return text.startsWith(symbol) || text.contains("{" + symbol)
|| text.contains(" " + symbol) || text.contains(";" + symbol);
}
/**
* 创建并返回第一个Row
*
* @param sheet
* @param rowIndex
* @param isCreate
* @param rows
* @return
*/
private Row createRow(int rowIndex, Sheet sheet, boolean isCreate, int rows) {
for (int i = 0; i < rows; i++) {
if (isCreate) {
sheet.createRow(rowIndex++);
} else if (sheet.getRow(rowIndex++) == null) {
sheet.createRow(rowIndex - 1);
}
}
return sheet.getRow(rowIndex - rows);
}
/**
* 循环迭代创建,遍历row
*
* @param isCreate
* @param row
* @param columnIndex
* @param t
* @param columns
* @param map
* @param rowspan
* @param colspan
* @param mergedRegionHelper
* @return rowSize, cellSize
* @throws Exception
* 徐本锡 mod by xbx 2022.03.07 list循环遍历的时候 存在合并单元格情况 导致格式错乱
*/
private int[] setForeachRowCellValue(boolean isCreate, Row row, int columnIndex, Object t,
List columns, Map map,
int rowspan, int colspan,
MergedRegionHelper mergedRegionHelper,
int startRowNum) throws Exception {
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;
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);
tempCreateCellSet.add(row.getRowNum() + "_" + (ci));
if (params == null) {
continue;
}
if (StringUtils.isEmpty(params.getName())
&& StringUtils.isEmpty(params.getConstValue())) {
row.getCell(ci).setCellStyle(params.getCellStyle());
ci = ci + params.getColspan();
continue;
}
String val;
Object obj = null;
//是不是常量
String tempStr = params.getName();
if (StringUtils.isEmpty(params.getName())) {
val = params.getConstValue();
} else {
map.put(templateParams.getTempParams(), t);
isNumber = isHasSymbol(tempStr, NUMBER_SYMBOL);
obj = getValByHandler(tempStr,map,row.getCell(ci));
val = obj.toString();
}
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) {
img.setHeight(0);
//mod by xbx
Sd3eUtil.addMergedRegionByListForEach(row.getCell(ci).getSheet(), 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).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));
}
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));
} else {
try {
row.getCell(ci).setCellValue(val);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
if (params.getCellStyle() != null) {
row.getCell(ci).setCellStyle(params.getCellStyle());
}
//判断这个属性是不是需要统计
if (params.isNeedSum()) {
templateSumHandler.addValueOfKey(params.getName(), obj.toString());
}
//如果合并单元格,就把这个单元格的样式和之前的保持一致
setMergedRegionStyle(row, ci, params);
// //合并对应单元格
// boolean isNeedMerge = (params.getRowspan() != 1 || params.getColspan() != 1)
// && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci);
// // 这里感觉判断没有意义,有点浪费性能,还不如后面报错
// // && !PoiCellUtil.isMergedRegion(row.getSheet(), row.getRowNum(), ci);
// if (isNeedMerge) {
// PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(),
// row.getRowNum() + params.getRowspan() - 1, ci,
// ci + params.getColspan() - 1);
// }
//mod by xbx
//合并对应单元格
// 存在合并单元格时,这个判断出问题了,需要注释
//&& !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci)
// 将第二个参数改为:循环开始行号
// 原因:这个方法原先是判断当前行这一列,是否需要合并单元格
// 如果是新创建的行,这个方法恒定返回 false ,判断出现问题
// 所以需要改为:判断循环开始行这一列,是否需要合并单元格
boolean isNeedMerge = (params.getRowspan() != 1 || params.getColspan() != 1) && PoiCellUtil.isMergedRegion(row.getSheet(), startRowNum, ci);
if (isNeedMerge) {
Sd3eUtil.addMergedRegionByListForEach(row.getSheet(), row.getRowNum(), row.getRowNum() + params.getRowspan() - 1, ci, ci + params.getColspan() - 1);
}
if (params.getRowspan() == 1 && params.getColspan() == 1){
row.getCell(ci).getSheet().setColumnWidth(row.getCell(ci).getColumnIndex(), params.getWidth());
}
ci = ci + params.getColspan();
}
loopCi = Math.max(loopCi, ci);
// 需要把需要合并的单元格合并了 --- 不是集合的栏位合并了
if (loopSize > 1) {
handlerLoopMergedRegion(row, columnIndex, columns, loopSize);
}
row = row.getSheet().getRow(row.getRowNum() + 1);
}
return new int[]{loopSize, loopCi};
}
// /**
// * 循环迭代创建,遍历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 {
// 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;
// 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);
// tempCreateCellSet.add(row.getRowNum() + "_" + (ci));
// if (params == null) {
// continue;
// }
// if (StringUtils.isEmpty(params.getName())
// && StringUtils.isEmpty(params.getConstValue())) {
// row.getCell(ci).setCellStyle(params.getCellStyle());
// ci = ci + params.getColspan();
// continue;
// }
// String val;
// Object obj = null;
// //是不是常量
// String tempStr = params.getName();
// if (StringUtils.isEmpty(params.getName())) {
// val = params.getConstValue();
// } else {
// map.put(templateParams.getTempParams(), t);
// isNumber = isHasSymbol(tempStr, NUMBER_SYMBOL);
// obj = getValByHandler(tempStr,map,row.getCell(ci));
// val = obj.toString();
// }
// 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) {
// 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));
// }
// 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));
// } else {
// try {
// row.getCell(ci).setCellValue(val);
// } catch (Exception e) {
// LOGGER.error(e.getMessage(), e);
// }
// }
// if (params.getCellStyle() != null) {
// row.getCell(ci).setCellStyle(params.getCellStyle());
// }
// //判断这个属性是不是需要统计
// if (params.isNeedSum()) {
// templateSumHandler.addValueOfKey(params.getName(), obj.toString());
// }
// //如果合并单元格,就把这个单元格的样式和之前的保持一致
// setMergedRegionStyle(row, ci, params);
// //合并对应单元格
// boolean isNeedMerge = (params.getRowspan() != 1 || params.getColspan() != 1)
// && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci);
// // 这里感觉判断没有意义,有点浪费性能,还不如后面报错
// // && !PoiCellUtil.isMergedRegion(row.getSheet(), row.getRowNum(), ci);
// if (isNeedMerge) {
// PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(),
// row.getRowNum() + params.getRowspan() - 1, ci,
// ci + params.getColspan() - 1);
// }
// if (params.getRowspan() == 1 && params.getColspan() == 1){
// row.getCell(ci).getSheet().setColumnWidth(row.getCell(ci).getColumnIndex(), params.getWidth());
// }
// ci = ci + params.getColspan();
// }
// loopCi = Math.max(loopCi, ci);
// // 需要把需要合并的单元格合并了 --- 不是集合的栏位合并了
// if (loopSize > 1) {
// handlerLoopMergedRegion(row, columnIndex, columns, loopSize);
// }
// row = row.getSheet().getRow(row.getRowNum() + 1);
// }
// return new int[]{loopSize, loopCi};
// }
/**
* 迭代把不是集合的数据都合并了
*
* @param row
* @param columnIndex
* @param columns
* @param loopSize
*/
private void handlerLoopMergedRegion(Row row, int columnIndex, List columns, int loopSize) {
for (int i = 0; i < columns.size(); i++) {
if (!columns.get(i).isCollectCell()) {
PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(),
row.getRowNum() + loopSize - 1, columnIndex,
columnIndex + columns.get(i).getColspan() - 1);
}
columnIndex = columnIndex + columns.get(i).getColspan();
}
}
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
* 徐本锡 mod by xbx 2022.03.07 list循环遍历的时候 存在合并单元格情况 导致格式错乱
*/
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);
// mod by xbx
// 定义循环开始行号
int startRowNum = tempRow.getRowNum();
int[] loopArr = setForeachRowCellValue(false, tempRow, columnIndex, data, temp, map, rowspan,
colspan, mergedRegionHelper,startRowNum);
// 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());
//都是集合
temp.get(i).setCollectCell(true);
}
return new int[]{nums, temp.size(), ci};
}
/**
* 根据 当前是集合的信息,把后面整个集合的迭代获取出来,并替换掉集合的前缀方便后面取数
*
* @param columns
* @param columnIndex
* @param collectName
* @return
* 徐本锡 mod by xbx 2022.03.07 解决一对多 row循环中,row元素中包含list并且合并单元格时,报空的错误
*/
private List getLoopEachParams(List columns, int columnIndex, String collectName) {
List temp = new ArrayList<>();
for (int i = 0; i < columns.size(); i++) {
//mod by xbx
//解决row循环中,row元素中包含list并且合并单元格时,报空的错误
if (columns.get(i)==null){
continue;
}
//先置为不是集合
columns.get(i).setCollectCell(false);
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).setCollectCell(true);
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) {
return excelExportStyler.getTemplateStyles(isSingle, excelForEachParams);
}
/**
* 设置合并单元格的样式
*
* @param row
* @param ci
* @param params
*/
private void setMergedRegionStyle(Row row, int ci, ExcelForEachParams params) {
//第一行数据
for (int i = 1; i < params.getColspan(); i++) {
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) {
row.getCell(ci + j).setCellStyle(params.getCellStyle());
}
}
}
}
/**
* 获取迭代的数据的值
*
* @param cell
* @param name
* @param mergedRegionHelper
* @return
*/
private Object[] getAllDataColumns(Cell cell, String name,
MergedRegionHelper mergedRegionHelper) {
List columns = new ArrayList();
cell.setCellValue("");
columns.add(getExcelTemplateParams(name.replace(END_STR, EMPTY), cell, mergedRegionHelper));
int rowspan = 1, colspan = 1;
if (!name.contains(END_STR)) {
int index = cell.getColumnIndex();
//保存col 的开始列
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;
index += colSpan;
for (int i = 1; i < colSpan; i++) {
//添加合并的单元格,这些单元可能不是空,但是没有值,所以也需要跳过
columns.add(null);
continue;
}
cell = row.getCell(index);
//可能是合并的单元格
if (cell == null) {
//读取是判断,跳过
columns.add(null);
continue;
}
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;
}
} catch (Exception e) {
throw new ExcelExportException(ExcelExportEnum.TEMPLATE_ERROR, e);
}
//把读取过的cell 置为空
cell.setCellValue("");
if (cellStringString.contains(END_STR)) {
columns.add(getExcelTemplateParams(cellStringString.replace(END_STR, EMPTY),
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));
//发现换行符,执行换行操作
colspan = 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));
}
}
}
colspan = 0;
for (int i = 0; i < columns.size(); i++) {
colspan += columns.get(i) != null ? columns.get(i).getColspan() : 0;
}
colspan = colspan / rowspan;
return new Object[]{rowspan, colspan, columns};
}
/**
* 获取模板参数
*
* @param name
* @param cell
* @param mergedRegionHelper
* @return
*/
private ExcelForEachParams getExcelTemplateParams(String name, Cell cell,
MergedRegionHelper mergedRegionHelper) {
name = name.trim();
ExcelForEachParams params = new ExcelForEachParams(name, cell.getCellStyle(),
cell.getRow().getHeight());
//判断是不是常量
if (name.startsWith(CONST) && name.endsWith(CONST)) {
params.setName(null);
params.setConstValue(name.substring(1, name.length() - 1));
}
//判断是不是空
if (NULL.equals(name)) {
params.setName(null);
params.setConstValue(EMPTY);
}
//是否是当前索引
if (INDEX.equals(name)) {
params.setName(null);
params.setConstValue(INDEX);
}
//获取合并单元格的数据
if (mergedRegionHelper.isMergedRegion(cell.getRowIndex() + 1, cell.getColumnIndex())) {
Integer[] colAndrow = mergedRegionHelper.getRowAndColSpan(cell.getRowIndex() + 1,
cell.getColumnIndex());
params.setRowspan(colAndrow[0]);
params.setColspan(colAndrow[1]);
}
params.setNeedSum(templateSumHandler.isSumKey(params.getName()));
params.setWidth(cell.getSheet().getColumnWidth(cell.getColumnIndex()));
return params;
}
/**
* 对导出序列进行排序和塞选
*
* @param excelParams
* @param titlemap
*/
private void sortAndFilterExportField(List excelParams,
Map titlemap) {
for (int i = excelParams.size() - 1; i >= 0; i--) {
if (excelParams.get(i).getList() != null && excelParams.get(i).getList().size() > 0) {
sortAndFilterExportField(excelParams.get(i).getList(), titlemap);
if (excelParams.get(i).getList().size() == 0) {
excelParams.remove(i);
} else {
excelParams.get(i).setOrderNum(i);
}
} else {
if (titlemap.containsKey(excelParams.get(i).getName())) {
excelParams.get(i).setOrderNum(i);
} else {
excelParams.remove(i);
}
}
}
sortAllParams(excelParams);
}
} |
要保证ExcelExportStylerDefaultImpl.java 继承的是这个修改后的BaseExportService.java
package cn.afterturn.easypoi.easy.excel.export.base;
/**
* @version v1.0
* @ProjectName: easypoi-test
* @ClassName: BaseExportService
* @Description: 4.4.0 版本进行修改
* @Author: xbx
* @Date: 2022/3/8 18:28
* createImageCell(Cell, double, int, int, String, byte[]) 徐本锡 mod by xbx 2022.03.07 生成图片的时候 图片不显示问题(实际上是最小显示了)
*/
import cn.afterturn.easypoi.cache.ImageCache;
import cn.afterturn.easypoi.entity.SpecialSymbolsEntity;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.entity.BaseTypeConstants;
import cn.afterturn.easypoi.entity.PoiBaseConstants;
import cn.afterturn.easypoi.excel.export.base.ExportCommonService;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import cn.afterturn.easypoi.exception.excel.ExcelExportException;
import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum;
import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil;
import cn.afterturn.easypoi.util.PoiMergeCellUtil;
import cn.afterturn.easypoi.util.PoiPublicUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import java.text.DecimalFormat;
import java.util.*;
/**
* 提供POI基础操作服务
*
* @author JueYue 2014年6月17日 下午6:15:13
*/
@SuppressWarnings("unchecked")
public abstract class BaseExportService extends ExportCommonService {
private int currentIndex = 0;
protected ExcelType type = ExcelType.XSSF;
private Map statistics = new HashMap();
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
protected IExcelExportStyler excelExportStyler;
/**
* 创建 最主要的 Cells
*/
public int[] createCells(Drawing patriarch, int index, Object t,
List excelParams, Sheet sheet, Workbook workbook,
short rowHeight, int cellNum) {
try {
ExcelExportEntity entity;
Row row = sheet.getRow(index) == null ? sheet.createRow(index) : sheet.getRow(index);
if (rowHeight != -1) {
row.setHeight(rowHeight);
}
int maxHeight = 1, listMaxHeight = 1;
// 合并需要合并的单元格
int margeCellNum = cellNum;
int indexKey = 0;
if (excelParams != null && !excelParams.isEmpty()) {
indexKey = createIndexCell(row, index, excelParams.get(0));
}
cellNum += indexKey;
for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) {
entity = excelParams.get(k);
//不论数据是否为空都应该把该列的数据跳过去
if (entity.getList() != null) {
Collection> list = getListCellValue(entity, t);
int tmpListHeight = 0;
if (list != null && list.size() > 0) {
int tempCellNum = 0;
for (Object obj : list) {
int[] temp = createCells(patriarch, index + tmpListHeight, obj, entity.getList(), sheet, workbook, rowHeight, cellNum);
tempCellNum = temp[1];
tmpListHeight += temp[0];
}
cellNum = tempCellNum;
listMaxHeight = Math.max(listMaxHeight, tmpListHeight);
} else {
cellNum = cellNum + getListCellSize(entity.getList());
}
} else {
Object value = getCellValue(entity, t);
if (entity.getType() == BaseTypeConstants.STRING_TYPE) {
createStringCell(row, cellNum++, value == null ? "" : value.toString(),
index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity),
entity);
} else if (entity.getType() == BaseTypeConstants.DOUBLE_TYPE) {
createDoubleCell(row, cellNum++, value == null ? "" : value.toString(),
index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity),
entity);
} else if (entity.getType() == BaseTypeConstants.Symbol_TYPE) {
createSymbolCell(row, cellNum++, value,
index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity),
entity);
} else {
createImageCell(patriarch, entity, row, cellNum++,
value == null ? "" : value.toString(), t);
}
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHandler.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), t,
entity.getName(), value));
}
}
}
maxHeight += listMaxHeight - 1;
if (indexKey == 1 && excelParams.get(1).isNeedMerge()) {
excelParams.get(0).setNeedMerge(true);
}
for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) {
entity = excelParams.get(k);
if (entity.getList() != null) {
margeCellNum += entity.getList().size();
} else if (entity.isNeedMerge() && maxHeight > 1) {
for (int i = index + 1; i < index + maxHeight; i++) {
if (sheet instanceof SXSSFSheet && i <= ((SXSSFSheet) sheet).getLastFlushedRowNum()) {
continue;
}
if (sheet.getRow(i) == null) {
try {
sheet.createRow(i);
} catch (Exception e) {
e.printStackTrace();
}
}
sheet.getRow(i).createCell(margeCellNum);
sheet.getRow(i).getCell(margeCellNum).setCellStyle(getStyles(false, entity));
}
PoiMergeCellUtil.addMergedRegion(sheet, index, index + maxHeight - 1, margeCellNum, margeCellNum);
margeCellNum++;
}
}
return new int[]{maxHeight, cellNum};
} catch (Exception e) {
LOGGER.error("excel cell export error ,data is :{}", ReflectionToStringBuilder.toString(t));
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
}
}
private void createSymbolCell(Row row, int index, Object specialSymbolsEnum, CellStyle style,
ExcelExportEntity entity) {
SpecialSymbolsEntity symbol = (SpecialSymbolsEntity) specialSymbolsEnum;
Cell cell = row.createCell(index);
Font font = cell.getSheet().getWorkbook().createFont();
font.setFontName(symbol.getFont());
RichTextString rtext;
if (cell instanceof HSSFCell) {
rtext = new HSSFRichTextString(symbol.getUnicode());
rtext.applyFont(font);
} else {
rtext = new XSSFRichTextString(symbol.getUnicode());
rtext.applyFont(font);
}
cell.setCellValue(rtext);
if (style != null) {
cell.setCellStyle(style);
}
}
/**
* 获取集合的宽度
*
* @param list
* @return
*/
protected int getListCellSize(List list) {
int cellSize = 0;
for (ExcelExportEntity ee : list) {
if (ee.getList() != null) {
cellSize += getListCellSize(ee.getList());
} else {
cellSize++;
}
}
return cellSize;
}
/**
* 图片类型的Cell
*/
public void createImageCell(Drawing patriarch, ExcelExportEntity entity, Row row, int i,
String imagePath, Object obj) throws Exception {
Cell cell = row.createCell(i);
byte[] value = null;
if (entity.getExportImageType() != 1) {
if (entity.getMethods() == null && entity.getMethod() == null) {
value = (byte[]) PoiPublicUtil.getParamsValue(entity.getKey().toString(), obj);
} else {
value = (byte[]) (entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj)
: entity.getMethod().invoke(obj, new Object[]{}));
}
}
createImageCell(cell, 50 * entity.getHeight(), entity.getExportImageType() == 1 ? imagePath : null, value);
}
/**
* 图片类型的Cell
*/
public void createImageCell(Cell cell, double height,
String imagePath, byte[] data) throws Exception {
if (height > cell.getRow().getHeight()) {
cell.getRow().setHeight((short) height);
}
ClientAnchor anchor;
if (type.equals(ExcelType.HSSF)) {
// x range 0-1023 y range 0-255
anchor = new HSSFClientAnchor(10, 10, 1010, 245, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex()),
cell.getRow().getRowNum());
} else {
anchor = new XSSFClientAnchor(10, 10, 1010, 245, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex()),
cell.getRow().getRowNum());
}
if (StringUtils.isNotEmpty(imagePath)) {
data = ImageCache.getImage(imagePath);
}
if (data != null) {
PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
}
}
/**
* 图片类型的Cell
* 徐本锡 mod by xbx 2022.03.07 生成图片的时候 图片不显示问题(实际上是最小显示了)
*/
public void createImageCell(Cell cell, double height, int rowspan, int colspan,
String imagePath, byte[] data) throws Exception {
if (height > cell.getRow().getHeight()) {
cell.getRow().setHeight((short) height);
}
ClientAnchor anchor;
// if (type.equals(ExcelType.HSSF)) {
// anchor = new HSSFClientAnchor(10, 10, 1010, 245, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + colspan - 1),
// cell.getRow().getRowNum() + rowspan - 1);
// } else {
// anchor = new XSSFClientAnchor(10, 10, 1010, 245, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + colspan - 1),
// cell.getRow().getRowNum() + rowspan - 1);
// }
if (this.type.equals(ExcelType.HSSF)) {
anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + colspan), cell.getRow().getRowNum() + rowspan);
} else {
anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)cell.getColumnIndex(), cell.getRow().getRowNum(), (short)(cell.getColumnIndex() + colspan), cell.getRow().getRowNum() + rowspan);
}
if (StringUtils.isNotEmpty(imagePath)) {
data = ImageCache.getImage(imagePath);
}
if (data != null) {
PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
}
}
private int createIndexCell(Row row, int index, ExcelExportEntity excelExportEntity) {
if (excelExportEntity.getFormat() != null && excelExportEntity.getFormat().equals(PoiBaseConstants.IS_ADD_INDEX)) {
createStringCell(row, 0, currentIndex + "",
index % 2 == 0 ? getStyles(false, null) : getStyles(true, null), null);
currentIndex = currentIndex + 1;
return 1;
}
return 0;
}
/**
* 创建List之后的各个Cells
*/
public void createListCells(Drawing patriarch, int index, int cellNum, Object obj,
List excelParams, Sheet sheet,
Workbook workbook, short rowHeight) throws Exception {
ExcelExportEntity entity;
Row row;
if (sheet.getRow(index) == null) {
row = sheet.createRow(index);
if (rowHeight != -1) {
row.setHeight(rowHeight);
}
} else {
row = sheet.getRow(index);
if (rowHeight != -1) {
row.setHeight(rowHeight);
}
}
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
entity = excelParams.get(k);
Object value = getCellValue(entity, obj);
if (entity.getType() == BaseTypeConstants.STRING_TYPE) {
createStringCell(row, cellNum++, value == null ? "" : value.toString(),
row.getRowNum() % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity),
entity);
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHandler.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(),
value));
}
} else if (entity.getType() == BaseTypeConstants.DOUBLE_TYPE) {
createDoubleCell(row, cellNum++, value == null ? "" : value.toString(),
index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHandler.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(),
value));
}
} else {
createImageCell(patriarch, entity, row, cellNum++,
value == null ? "" : value.toString(), obj);
}
}
}
/**
* 创建文本类型的Cell
*/
public void createStringCell(Row row, int index, String text, CellStyle style,
ExcelExportEntity entity) {
Cell cell = row.createCell(index);
if (style != null && style.getDataFormat() > 0 && style.getDataFormat() < 12) {
cell.setCellValue(Double.parseDouble(text));
} else {
RichTextString rtext;
if (cell instanceof HSSFCell) {
rtext = new HSSFRichTextString(text);
} else {
rtext = new XSSFRichTextString(text);
}
cell.setCellValue(rtext);
}
if (style != null) {
cell.setCellStyle(style);
}
createCellComment(row, cell, text, entity);
addStatisticsData(index, text, entity);
}
/**
* 创建数字类型的Cell
*/
public void createDoubleCell(Row row, int index, String text, CellStyle style,
ExcelExportEntity entity) {
Cell cell = row.createCell(index);
if (text != null && text.length() > 0) {
try {
cell.setCellValue(Double.parseDouble(text));
} catch (NumberFormatException e) {
cell.setCellValue(text);
}
}
if (style != null) {
cell.setCellStyle(style);
}
createCellComment(row, cell, text, entity);
addStatisticsData(index, text, entity);
}
/**
* 创建批注
*
* @param row
* @param cell
* @param text
* @param entity
*/
private void createCellComment(Row row, Cell cell, String text, ExcelExportEntity entity) {
if (commentHandler != null) {
String comment = entity == null || entity.getName().equals(text)
|| (entity.getGroupName() != null && entity.getGroupName().equals(text)) ?
commentHandler.getComment(text) : commentHandler.getComment(entity.getName(), text);
if (StringUtils.isNotBlank(comment)) {
cell.setCellComment(getComment(cell, comment, commentHandler.getAuthor()));
}
}
}
/**
* 获取注释对象
*
* @param cell
* @param commentText
* @param author
* @return
*/
private Comment getComment(Cell cell, String commentText, String author) {
Comment comment = null;
if (cell instanceof HSSFCell) {
//前四个参数是坐标点,后四个参数是编辑和显示批注时的大小.
comment = cell.getSheet().createDrawingPatriarch().createCellComment(
new HSSFClientAnchor(0, 0, 0, 0, (short) 3, 2, (short) 5,
commentText.length() / 15 + 2));
comment.setString(new HSSFRichTextString(commentText));
} else {
comment = cell.getSheet().createDrawingPatriarch().createCellComment(
new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 2, (short) 5,
commentText.length() / 15 + 2));
comment.setString(new XSSFRichTextString(commentText));
}
if (StringUtils.isNotBlank(author)) {
comment.setAuthor(author);
}
return comment;
}
/**
* 创建统计行
*/
public void addStatisticsRow(CellStyle styles, Sheet sheet) {
if (statistics.size() > 0) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("add statistics data ,size is {}", statistics.size());
}
Row row = sheet.createRow(sheet.getLastRowNum() + 1);
Set keys = statistics.keySet();
createStringCell(row, 0, "合计", styles, null);
for (Integer key : keys) {
createStringCell(row, key, DOUBLE_FORMAT.format(statistics.get(key)), styles, null);
}
statistics.clear();
}
}
/**
* 合计统计信息
*/
private void addStatisticsData(Integer index, String text, ExcelExportEntity entity) {
if (entity != null && entity.isStatistics()) {
Double temp = 0D;
if (!statistics.containsKey(index)) {
statistics.put(index, temp);
}
try {
temp = Double.valueOf(text);
} catch (NumberFormatException e) {
}
statistics.put(index, statistics.get(index) + temp);
}
}
/**
* 获取图片类型,设置图片插入类型
*
* @author JueYue 2013年11月25日
*/
public int getImageType(byte[] value) {
String type = PoiPublicUtil.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;
}
private Map getMergeDataMap(List excelParams) {
Map mergeMap = new HashMap();
// 设置参数顺序,为之后合并单元格做准备
int i = 0;
for (ExcelExportEntity entity : excelParams) {
if (entity.isMergeVertical()) {
mergeMap.put(i, entity.getMergeRely());
}
if (entity.getList() != null) {
for (ExcelExportEntity inner : entity.getList()) {
if (inner.isMergeVertical()) {
mergeMap.put(i, inner.getMergeRely());
}
i++;
}
} else {
i++;
}
}
return mergeMap;
}
/**
* 获取样式
*/
public CellStyle getStyles(boolean needOne, ExcelExportEntity entity) {
return excelExportStyler.getStyles(needOne, entity);
}
/**
* 合并单元格
*/
public void mergeCells(Sheet sheet, List excelParams, int titleHeight) {
Map mergeMap = getMergeDataMap(excelParams);
PoiMergeCellUtil.mergeCells(sheet, mergeMap, titleHeight);
}
public void setCellWith(List excelParams, Sheet sheet) {
int index = 0;
for (int i = 0; i < excelParams.size(); i++) {
if (excelParams.get(i).getList() != null) {
List list = excelParams.get(i).getList();
for (int j = 0; j < list.size(); j++) {
sheet.setColumnWidth(index, (int) (256 * list.get(j).getWidth()));
index++;
}
} else {
sheet.setColumnWidth(index, (int) (256 * excelParams.get(i).getWidth()));
index++;
}
}
}
public void setColumnHidden(List excelParams, Sheet sheet) {
int index = 0;
for (int i = 0; i < excelParams.size(); i++) {
if (excelParams.get(i).getList() != null) {
List list = excelParams.get(i).getList();
for (int j = 0; j < list.size(); j++) {
sheet.setColumnHidden(index, list.get(j).isColumnHidden());
index++;
}
} else {
sheet.setColumnHidden(index, excelParams.get(i).isColumnHidden());
index++;
}
}
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public void setExcelExportStyler(IExcelExportStyler excelExportStyler) {
this.excelExportStyler = excelExportStyler;
}
public IExcelExportStyler getExcelExportStyler() {
return excelExportStyler;
}
}
package cn.afterturn.easypoi.easy.util;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version v1.0
* @ProjectName: easypoi-test
* @ClassName: Sd3eUtil
* @Description:
* @Author: xbx
* @Date: 2022/3/7 16:49
*/
public class Sd3eUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(Sd3eUtil.class);
/**
* @Author: 徐本锡
* @Date: 2022/3/7 16:49
* @param: [sheet, firstRow, lastRow, firstCol, lastCol]
* @return: void
* @description: list循环的时候 存在合并单元格的时候 格式错乱问题
*/
public static void addMergedRegionByListForEach(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
try {
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
} catch (IllegalStateException var6){
//合并单元格的循环 可能存在 已经合并的再次合并 不管他
} catch (Exception var6) {
LOGGER.debug("发生了一次合并单元格错误,{},{},{},{}", new Integer[]{firstRow, lastRow, firstCol, lastCol});
LOGGER.debug(var6.getMessage(), var6);
}
}
}