easyexcel导出excel文件合并相同单元格数据
1、引入easyexcel依赖
!-- 阿里开源easyexcel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.0-beta2</version></dependency>
2、ExcelMergeUtil工具类
package com.sdy.resdir.biz.util;import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;import java.math.BigDecimal;
import java.util.List;import static org.apache.poi.ss.usermodel.CellType.NUMERIC;public class ExcelMergeUtil implements CellWriteHandler {private int[] mergeColumnIndex;private int mergeRowIndex;public ExcelMergeUtil() {}public ExcelMergeUtil(int mergeRowIndex, int[] mergeColumnIndex) {this.mergeRowIndex = mergeRowIndex;this.mergeColumnIndex = mergeColumnIndex;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {//当前行int curRowIndex = cell.getRowIndex();//当前列int curColIndex = cell.getColumnIndex();if (curRowIndex > mergeRowIndex) {for (int i = 0; i < mergeColumnIndex.length; i++) {if (curColIndex == mergeColumnIndex[i]) {mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);break;}}}}/*** 当前单元格向上合并** @param writeSheetHolder* @param cell 当前单元格* @param curRowIndex 当前行* @param curColIndex 当前列*/private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();// 将当前单元格数据与上一个单元格数据比较Boolean dataBool = preData.equals(curData);//此处需要注意:因为我是按照工程名称确定是否需要合并的,所以获取每一行第二列数据和上一行第一列数据进行比较,如果相等合并,getCell里面的值,是工程名称所在列的下标BigDecimal d1 = new BigDecimal(cell.getRow().getCell(0).getNumericCellValue());BigDecimal d2 = new BigDecimal(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getNumericCellValue());Boolean bool = d1.compareTo(d2) == 0 ? true:false;// 原始的// Boolean bool = cell.getRow().getCell(1).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(1).getStringCellValue());if (dataBool && bool) {Sheet sheet = writeSheetHolder.getSheet();List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();boolean isMerged = false;for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {CellRangeAddress cellRangeAddr = mergeRegions.get(i);// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {sheet.removeMergedRegion(i);cellRangeAddr.setLastRow(curRowIndex);sheet.addMergedRegion(cellRangeAddr);isMerged = true;}}// 若上一个单元格未被合并,则新增合并单元if (!isMerged) {CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);sheet.addMergedRegion(cellRangeAddress);}}}
}
3、导出的excel标题
package com.sdy.resdir.biz.vo;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.metadata.BaseRowModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.sdy.common.utils.DateUtil;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.util.Date;/*** Excel模板文件类** @author hyh*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ResItemExcelVo extends BaseRowModel {/*** 序号*/@ExcelProperty(value = {"资源基本信息", "序号"},index = 0)private Integer resNo;/*** 资源名称*/@ColumnWidth(20)// @ExcelProperty(value = "资源名称",index = 1)@ExcelProperty(value = {"资源基本信息", "资源名称"}, index = 1)private String resName;/*** 资源类型*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "资源类型"} ,index = 2)private String resType;/*** 资源提供部门*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "资源提供部门"},index = 3)private String resSourceDept;/*** 资源权限*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "资源权限"},index = 4)private String resPower;/*** 资源层级(1.省级 2.市级 3.区级)*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "资源层级"},index = 5)private String resLevel;/*** 归集情况(1.已上线 2.未上线)*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "归集情况"},index = 6)private String collectionSituation;/*** 是否导入省里(0-否,1-是)*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "是否导入省里"},index = 7)private String isImport;/*** 回流标记(0-否,1-是)*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "是否回流"}, index = 8)private String backFlow;/*** 单位名称*/@ColumnWidth(20)@ExcelProperty(value = {"资源基本信息", "单位名称"}, index = 9)private String companyName;/*** 数据项*/@ColumnWidth(10)@ExcelProperty(value = {"编目信息","数据项"}, index = 10)private String chineseName;/*** 英文名称*/@ColumnWidth(20)@ExcelProperty(value = {"编目信息","英文名称"}, index = 11)private String englishName;/*** 字段类型*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","字段类型"}, index = 12)private String fieldType;/*** 字段长度*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","字段长度"}, index = 13)private String fieldLength;/*** 字段精度*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","字段精度"}, index = 14)private String fieldAccuracy;/*** 是否主键*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","是否主键"}, index = 15)private String keywords;/*** 是否字典项(0-否,1-是)*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","是否字典项"}, index = 16)private String isDictionary;/*** 字段描述*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","字段描述"}, index = 17)private String fieldDesc;/*** 是否为空(0-否,1-是)*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","是否为空"}, index = 18)private String isEmpty;/*** 默认值*/@ColumnWidth(15)@ExcelProperty(value = {"编目信息","默认值"}, index = 19)private String defaultValue;/*** 共享属性*/@ColumnWidth(18)@ExcelProperty(value = {"编目信息","共享属性"}, index = 20)private String shareAttribute;/*** 共享条件*/@ColumnWidth(18)@ExcelProperty(value = {"编目信息","共享条件"}, index = 21)private String shareCondition;/*** 开放属性*/@ColumnWidth(18)@ExcelProperty(value = {"编目信息","开放属性"}, index = 22)private String openAttribute;}
4、控制层调用
public void downLoadResItem(HttpServletResponse response, String resName, Integer isOnline, Integer resType, Integer resLevel, Integer resPower, Integer resPowerDept, Integer realmId) throws IOException {if (StringUtil.isNotBlank(resName)) {resName = URLDecoder.decode(resName, "UTF-8");}List<RdResourceDirExcelDTO> rdResourceDirList = rdResourceDirService.getList(resName, isOnline, resType, resLevel, resPower, resPowerDept, realmId);response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = URLEncoder.encode("资源列表下载", "UTF-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");ServletOutputStream output = response.getOutputStream();ExcelWriter writer = new ExcelWriter(output, ExcelTypeEnum.XLS, true);Sheet sheet = new Sheet(1, 0, ResItemExcelVo.class);// sheet.setSheetName("第一页");List<ResItemExcelVo> voList = setResItemData(rdResourceDirList);// writer.write(voList, sheet);//需要合并的列int[] mergeColumeIndex = {0,1,2,3,4,5,6,7,8,9};// 从第二行后开始合并int mergeRowIndex = 2;EasyExcel.write(response.getOutputStream(), ResItemExcelVo.class).sheet("第一页")// .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumeIndex)).registerWriteHandler(new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex)).doWrite(voList);writer.finish();output.flush();}
导出的效果excel ,我是通过序号相同合并
导出的数据类似
序号 | 日志名称 | 日志时间 | 字段名 | 字段描述 | 字段值 |
1 | 根据ID查询详情 | 2021-01-13 | total | 总数 | 25 |
1 | 根据ID查询详情 | 2021-01-13 | total | 总数 | 25 |
1 | 根据ID查询详情 | 2021-01-13 | total | 总数 | 25 |
2 | 获取日志列表 | 2021-01-12 | logName | 日志名称 | 查询 |
2 | 获取日志列表 | 2021-01-12 | logTime | 日志时间 | 2021-10-01 14:25:14 |
2 | 获取日志列表 | 2021-01-12 | logUser | 查询人姓名 | 王杰 |
3 | 查询用户信息 | 2021-01-11 | userName | 用户名 | tqf_123 |
3 | 查询用户信息 | 2021-01-11 | age | 年龄 | 25 |
3 | 查询用户信息 | 2021-01-11 | sex | 性别(0-男,1-女,2-未知) | 0 |
easyexcel导出excel文件合并相同单元格数据相关推荐
- ExcelJs导出Excel文件并设置单元格样式
下载exceljs并引入 数据源格式:二维数组,null值是后面要合并单元格的,占个位置. //创建对象 var wb = new ExcelJS.Workbook(); //创建一个名称为Sheet ...
- POI导出Excel文件时,单元格内文字竖排、横排默认不展示,必须点击一下问题解决
//创建单元格样式设置CellStyle cs_vertical = wb.createCellStyle();//设置字体Font textFont = wb.createFont();textFo ...
- 批量提取多个Excel文件内指定单元格的数据(文件名和数据)
批量提取多个Excel文件内指定单元格的数据(文件名和数据) 例如收集了excel表格统一格式的个人简历,从中抽取个人基本信息,生成数据表. 将源数据excel文件放在同一个文件夹下. 新建一个sho ...
- swagger easyExcel导出Excel文件打不开,文件损坏
alibaba/easyexcel文件导出 swagger easyExcel导出Excel文件打不开,文件损坏 文件下载打不开,将文件输出到本地发现可以打开,而且swagger下载的文件大小比本地文 ...
- Java 使用EasyExcel导出excel文件
Java 使用EasyExcel导出excel文件 一.引入pom依赖 二.导出实体 三. 生成excelController 四.效果 一.引入pom依赖 <dependency>< ...
- thinkphp导出到excel,合并拆分单元格!
导出到excel合并拆解单元格操作(奇怪操作) 接到需求做一个奇怪的产品表格,时间紧任务重,开始演示,目的以下样式 目标确定开始操作! 首先数据格式为图中,我们需要先分析出这应该是一条数据但是需要合并 ...
- excel导出java不完整_有关Java POI导出excel表格中,单元格合并之后显示不全的解决方法。...
我在table变换excel之后发现合并的单元格不能显示全部边框,在网上找了半天解决方案,终于解决了.具体解决代码如下; /** * 设置合并单元格的边框样式 * * @param sheet 当前表 ...
- Java poi插件导出Excel文件合并多sheet页
文章目录 一.java导出excel格式文件 二.excel文件多sheet页合并 前言:2020年第一篇文章,就写这两天工作中遇到的这个小需求吧,导出多excel,每个excel有多个sheet页, ...
- poi导出Excel时设置某个单元格颜色
需求: 查询数据库表数据然后到另一个表找错误的对应字段(就是找到需要填充的单元格所在行的列),对这个单元格进行设置背景色,然后导出数据. 具体的工具类如下 import cn.afterturn.ea ...
最新文章
- 《精通自动化测试框架设计》—第2章 2.3节测试数据交互基本方法
- python写web难受-pythonweb为什么不火-问答-阿里云开发者社区-阿里云
- CNN(Convolutional Neural Networks)算法
- VMware 当中出现:无法将 Ethernet0 连接到虚拟网络VMnet8的问题
- 用计算机乘九位数怎么用,用计算器计算
- Python中的计数(词频)
- 转字符串_【转】什么是字符串?字符串是用来做什么的?
- java将明文变为密文,使用java编程实现明文和密文之间的互转
- 机器学习这10年我们能在各自的领域做点什么?
- mysql 5.6.21 winx64_mysql-advanced-5.6.21-winx64部署及使用
- 【杂叙】北京住房公积金提取
- 电视android已停止运行是什么意思,智能电视提示应用停止运行,三种方法亲测有效!...
- 计算机网络安全第一课
- 似然函数,极大似然估计(一文搞定,能用嘴说的不堆公式)
- HTML CSS杂记
- 在线拍卖系统、竞拍源码中降价拍(荷兰式拍卖)的逻辑和实现
- Java 下载多个文件至内存并压缩文件包返回,无需保存至本地打包压缩
- poi-tl循环表格列和行
- 老照片怎么修复清晰?掌握这个技巧,一键智能修复
- gym 自定义游戏环境