easyExcel导出表格及合并单元格

前言

废话不多说,直接上效果图。

效果图

合并之前导出的:

合并之后导出的:

代码的实现主要是合并之后的,为了更好的分清数据之间的关系。

二、代码

目录 <只需要注意红色的>

easyExcel依赖

     <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency>

controller

package com.wondersgroup.easyexceldome.controller;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.wondersgroup.easyexceldome.dto.BizMergeStrategy;
import com.wondersgroup.easyexceldome.dto.RowRangeDto;
import com.wondersgroup.easyexceldome.dto.TitleSheetWriteHandler;
import com.wondersgroup.easyexceldome.model.Student;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** <p>* 该类的描述* </p>** @author* @Modified By:* @since 2020/11/23 11:31*/
@RestController
@RequestMapping("/user")
public class EasyExcelController {@GetMapping("/excel")public void excel(HttpServletResponse response) throws IOException {Map<String, List<RowRangeDto>> strategyMap = BizMergeStrategy.addAnnualMerStrategy(data());try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String filename = URLEncoder.encode("用户表测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");EasyExcel.write(response.getOutputStream(), Student.class).excelType(ExcelTypeEnum.XLSX).head(Student.class)//.registerWriteHandler(new TitleSheetWriteHandler("我是一个小标题",2)) // 标题及样式,lastCol为标题第0列到底lastCol列的宽度//设置默认样式及写入头信息开始的行数.relativeHeadRowIndex(1).registerWriteHandler(new BizMergeStrategy(strategyMap))    // 注册合并策略.registerWriteHandler(BizMergeStrategy.CellStyleStrategy()) // 设置样式.sheet("测试").doWrite(data());}catch (Exception e) {e.printStackTrace();response.reset();response.setCharacterEncoding("utf-8");response.setContentType("application/json");response.getWriter().println("打印失败");}}private List<Student> data(){List<Student> list=new ArrayList<>();Student student = new Student();//student.setId("1");student.setName("甲");student.setPhone("18102356548");student.setTime(new Date());student.setMom("XX科技有限公司");Student student2 = new Student();//student2.setId("2");student2.setName("甲");student2.setPhone("18978545213");student2.setTime(new Date());student2.setMom("XX科技有限公司");Student student3 = new Student();//student3.setId("3");student3.setName("甲");student3.setPhone("15369874563");student3.setTime(new Date());student3.setMom("XX科技有限公司");Student student4 = new Student();//student4.setId("4");student4.setName("乙");student4.setPhone("19433687456");student4.setTime(new Date());student4.setMom("XX科技有限公司");Student student5 = new Student();//student5.setId("5");student5.setName("乙");student5.setPhone("13815698745");student5.setTime(new Date());student5.setMom("XX科技有限公司");list.add(student);list.add(student2);list.add(student3);list.add(student4);list.add(student5);return list;}
}

实体类

package com.wondersgroup.easyexceldome.model;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;import java.util.Date;@Data
public class Student {/*@ColumnWidth(10)@ExcelProperty(value = {"id"}, index = 0)private String id;*/@ColumnWidth(20)@ExcelProperty(value = {"名字"}, index = 0)private String name;@ColumnWidth(20)@ExcelProperty(value = {"手机号"}, index = 1)private String phone;@ColumnWidth(20)@ExcelProperty(value = {"工作日期"}, index = 2)private Date time;@ColumnWidth(20)@ExcelProperty(value = {"工作单位"}, index = 3)private String mom;
}

合并策略和样式

package com.wondersgroup.easyexceldome.dto;import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.wondersgroup.easyexceldome.model.Student;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @description: 合并策略和样式* @author* @param* @since 2020/11/20 17:24* @Modified By:* @return*/
public class BizMergeStrategy extends AbstractMergeStrategy {private Map<String, List<RowRangeDto>> strategyMap;private Sheet sheet;public BizMergeStrategy(Map<String, List<RowRangeDto>> strategyMap) {this.strategyMap = strategyMap;}@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {this.sheet = sheet;//如果没有标题,只有表头的话,这里的 cell.getRowIndex() == 1if (cell.getRowIndex() == 2 && cell.getColumnIndex() == 0) {/*** 保证每个cell被合并一次,如果不加上面的判断,因为是一个cell一个cell操作的,* 例如合并A2:A3,当cell为A2时,合并A2,A3,但是当cell为A3时,又是合并A2,A3,* 但此时A2,A3已经是合并的单元格了*/for (Map.Entry<String, List<RowRangeDto>> entry : strategyMap.entrySet()) {Integer columnIndex = Integer.valueOf(entry.getKey());entry.getValue().forEach(rowRange -> {//添加一个合并请求sheet.addMergedRegionUnsafe(new CellRangeAddress(rowRange.getStart(),rowRange.getEnd(), columnIndex, columnIndex));});}}}public static Map<String, List<RowRangeDto>> addAnnualMerStrategy(List<Student> projectDtoList) {Map<String, List<RowRangeDto>> strategyMap = new HashMap<>();Student preUser = null;for (int i = 0; i < projectDtoList.size(); i++) {Student curUser = projectDtoList.get(i);//如果名字一样,将名字合并(真正开发中一般不会通过名字这样字段,而是通过一些关联的唯一值,比如父id)if (preUser != null) {if (curUser.getName() == preUser.getName()){    // 名字相同则合并第一列
//                    BizMergeStrategy.fillStrategyMap(strategyMap, "0", i+1);//如果没有标题,只有表头的话,这里为 BizMergeStrategy.fillStrategyMap(strategyMap, "1", i);BizMergeStrategy.fillStrategyMap(strategyMap, "0", i+1);}}preUser = curUser;}return strategyMap;}/*** @description: 新增或修改合并策略map* @author* @param strategyMap* @param key* @param index* @since 2020/11/17 17:32* @Modified By:* @return*/private static void fillStrategyMap(Map<String, List<RowRangeDto>> strategyMap, String key, int index){List<RowRangeDto> rowRangeDtoList = strategyMap.get(key) == null ? new ArrayList<>() : strategyMap.get(key);boolean flag = false;for (RowRangeDto dto : rowRangeDtoList) {//分段list中是否有end索引是上一行索引的,如果有,则索引+1if (dto.getEnd() == index) {dto.setEnd(index + 1);flag = true;}}//如果没有,则新增分段if (!flag) {rowRangeDtoList.add(new RowRangeDto(index, index + 1));}strategyMap.put(key, rowRangeDtoList);}/*** @description: 表格样式* @author* @since 2020/11/20 9:40* @Modified By:* @return*/public static HorizontalCellStyleStrategy CellStyleStrategy(){WriteCellStyle headWriteCellStyle = new WriteCellStyle();//设置背景颜色headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());//设置头字体WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)13);headWriteFont.setBold(true);headWriteCellStyle.setWriteFont(headWriteFont);//设置头居中headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//内容策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();//设置 水平居中contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);return horizontalCellStyleStrategy;}
}

RowRangeDto

package com.wondersgroup.easyexceldome.dto;public class RowRangeDto {private int start;private int end;public RowRangeDto(int start,int end){this.start = start;this.end = end;}public int getStart() {return start;}public void setStart(int start) {this.start = start;}public int getEnd() {return end;}public void setEnd(int end) {this.end = end;}
}

TitleSheetWriteHandler

package com.wondersgroup.easyexceldome.dto;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;public class TitleSheetWriteHandler implements SheetWriteHandler {private String title;private int lastCol;public TitleSheetWriteHandler(String title,int lastCol){this.title = title;this.lastCol = lastCol;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Workbook workbook = writeWorkbookHolder.getWorkbook();Sheet sheet = workbook.getSheetAt(0);//设置标题Row row = sheet.createRow(0);row.setHeight((short) 800);Cell cell = row.createCell(0);cell.setCellValue(title);CellStyle cellStyle = workbook.createCellStyle();cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);cellStyle.setAlignment(HorizontalAlignment.CENTER);Font font = workbook.createFont();font.setBold(true);font.setFontHeight((short) 400);cellStyle.setFont(font);cell.setCellStyle(cellStyle);sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, lastCol));}
}

启动类

package com.wondersgroup.easyexceldome;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class EasyexceldomeApplication {public static void main(String[] args) {SpringApplication.run(EasyexceldomeApplication.class, args);}}

application.properties

server.port=9090

总结

新建个项目,直接拷贝代码运行即可。

easyExcel导出表格及合并单元格相关推荐

  1. 使用EasyExcel导出表格时合并单元格

    背景 现在需要将一个导出列表数据到Excel表格的功能进行改造,将指定列相同数据自动合并单元格. 如上图所示,指定A.B两列自动合并,如图所示(6.7),(8.9),(13.14.15)要自动合并单元 ...

  2. python xlsxwriter合并单元格_Python使用xlsxwriter导出表格并合并单元格

    之前使用csv导出表格,但是好像不支持合并单元格.后来发现了这个,试了一下. import xlsxwriter f = xlsxwriter.Workbook('9.xlsx') # 创建excel ...

  3. python csv合并单元格_Python使用xlsxwriter导出表格并合并单元格

    之前使用csv导出表格,但是好像不支持合并单元格.后来发现了这个,试了一下. import xlsxwriter f = xlsxwriter.Workbook('9.xlsx') # 创建excel ...

  4. easyexcel导出excel自定义合并单元格【动态表头和动态数据均可以自由合并】

    网上合并单元格的博客还是很多的,大家自行舍取吧.本文主要讲解固定与不固定的表头和内容如何合并 参考官网 https://easyexcel.opensource.alibaba.com/docs/cu ...

  5. java poi导出excel,合并单元格

    java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体:另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是 ...

  6. SpringBoot+Poi-tl根据Word模板动态生成word(含动态行表格、合并单元格)

    本编文章继SpringBoot+Poi-tl根据Word模板动态生成word(含动态行表格)文章之后 介绍Poi-tl导出word的延伸功能: 所需依赖以及word模板所属位置 见 SpringBoo ...

  7. xlsx-style使用(导出表格及修改单元格样式)

    xlsx-style使用(导出表格及修改单元格样式) 针对导出表格 需要与xlsx配合使用,通过xlsx的方法生成sheet对象然后在对象上修改样式 本文对xlsx-style 如何修改单元格样式做了 ...

  8. python合并word表格单元格_python docx模块读取word表格遇到合并单元格时的处理

    python docx模块读取word表格遇到合并单元格时的处理 python docx模块读取word表格遇到合并单元格时的处理 python docx模块读取word表 遇到合并单元格时的处理 通 ...

  9. java导出excel 边框不全_POI导出excel,合并单元格后没有边框

    导出的excel合并单元格有两种方法: 第一种: sheet.addMergedRegion(new CellRangeAddress(开始行, 结束行, 开始列, 结束列)); 这样就可以合并单元格 ...

最新文章

  1. 重磅!神策智能推荐获 2019 大数据“星河奖”
  2. 快速排序算法-php实现
  3. 联想拯救者y7000加内存条_关于2020款联想拯救者Y7000、R7000和Y7000P,r7000p选哪个好?看这里就对了...
  4. 【script】python 中文汉字与url的转换
  5. C++ 动态开辟二维数组的的方法
  6. 关于 IIS7.0下文件写入无权限的解决办法
  7. 初学者必学教程——JQuery的简介
  8. 二分查找时间复杂度分析
  9. 怎么接收xml报文_Benteler/本特勒 DESADV 报文生成过程
  10. C#.Net 扩展方法
  11. Java中Collection接口
  12. 笔记本辐射与日常电器辐射对比
  13. Android studio 手机扫描二维码功能
  14. 不谋一时不足以谋一域_“不谋万世者,不足谋一时。不谋全局者,不足谋一隅”出自哪里?是什么意思?...
  15. 电脑xls图标未正常显示
  16. 杂文 | 金沙江创投朱啸虎谈微信小程序
  17. 把随身WiFi的esim卡移植到SIM卡放到手机使用
  18. 向量的2-范数、矩阵的2-范数
  19. MDI窗体的优化---下
  20. 计算机load代表,什么是 Load ? 什么是 Load Average ?

热门文章

  1. 微信手气红包算法 php,微信随机生成红包金额算法php版
  2. Quick BI、帆软Fine BI等BI产品,优势详细介绍
  3. 机房综合布线施工主要是几个方面
  4. 通信专业实务(三)——接入网
  5. html 纯css设置转圈,CSS3 转圈彩色文字动画实例及animation-play-state属性规则
  6. Vscode 与服务器建立远程连接(ssh)
  7. oracle数据删了怎么恢复吗,oracle误删数据恢复方法总结
  8. android平板 视频输入,安卓平板电脑的新突破口:HDMI in 视频输入,取代便携显示器...
  9. Fiddler实现苹果手机APP抓包
  10. 营业执照注册编码 15与18位的java实现