Excel下载(easyExcel)

 2023-09-15 阅读 33 评论 0

摘要:​ 目录一 框架及版本二 数据准备三 基础下载​四 单元格样式设置五 单元格行合并1 合并统计2 合并策略类3 注册合并策略六 行高设置1 非动态设置行高2 动态设置行高 一 框架及版本 springboot: 2.1.3.RELEASEhutool工具easyExcel <dependency><groupId>com.aliba


目录

    • 一 框架及版本
    • 二 数据准备
    • 三 基础下载
    • ​四 单元格样式设置
    • 五 单元格行合并
      • 1 合并统计
      • 2 合并策略类
      • 3 注册合并策略
    • 六 行高设置
      • 1 非动态设置行高
      • 2 动态设置行高



一 框架及版本

  • springboot: 2.1.3.RELEASE
  • hutool工具
  • easyExcel
 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.4</version></dependency>

二 数据准备

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {@ExcelProperty(value = {"年级"}, index = 0)private String grade;@ExcelProperty(value = {"姓名"}, index = 1)private String name;@ExcelProperty(value = {"年龄"}, index = 2)private Integer age;@ExcelProperty(value = {"性别"}, index = 3)private String sex;@ExcelProperty(value = {"综合素质评价"}, index = 4)@ColumnWidth(50)private String evaluate;@ExcelProperty(value = {"综合评分"}, index = 5)@ColumnWidth(20)private String score;}
public class DataReady {public static List<Student> listStudent() {// 综合素质评价List<String> evaluateList = evaluateList();List<Student> students = new ArrayList<>();students.add(new Student("三年一班", "小东", 12, "男", evaluateList.get(0), "优"));students.add(new Student("三年一班", "小南", 12, "男", evaluateList.get(1), "优"));students.add(new Student("三年二班", "小西", 13, "男",evaluateList.get(2), "优"));students.add(new Student("三年二班", "小北", 12, "男",evaluateList.get(3), "优"));students.add(new Student("三年二班", "小红", 12, "女",evaluateList.get(4), "优"));students.add(new Student("三年三班", "小独", 12, "男",evaluateList.get(5), "优"));return students;}private static List<String> evaluateList() {List<String> strings = new ArrayList<>();strings.add("你活泼乐观,自信心强,尊敬老师,是你的最大优点,作业能按时完成,有强烈的好奇心,可惜的是你上课管不住自己,不守纪律,老师提出问题不经过深思熟虑");strings.add("该生在校期间学习态度端正,成绩优良");strings.add("积极参与各项实践活动,全面的锻炼自己。");strings.add("你是个天性好动的男孩。想到你,浮现在老师眼前的是你积极劳动、礼貌待人的身影。");strings.add("热情活泼,全面发展,对于自己喜欢的工作,能投入极大的热情去做,哪怕再苦再累,也不计较。");strings.add("好");return strings;}
}

三 基础下载

效果
在这里插入图片描述


EasyExcelController

@GetMapping("/download")
public void download(HttpServletResponse response) throws IOException {service.download(response);
}

手机EXCEL?EasyExcelService

/*** 基础下载*/
void download(HttpServletResponse response) throws IOException;

EasyExcelServiceImpl

/*** 基础下载*/
@Override
public void download(HttpServletResponse response) throws IOException {String message = "下载文件失败";String filename = "学生信息.xlsx";try {// 设置响应头response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));response.setContentType("application/octet-stream;charset=UTF-8"); // 类型response.setCharacterEncoding("utf-8");// 获取导出数据List<Student> students = DataReady.listStudent();// 数据导出EasyExcel.write(response.getOutputStream(), Student.class).sheet("Sheet1").doWrite(students);} catch (Exception e) {e.printStackTrace();// 重置responseresponse.reset();response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().println(JsonUtil.writeValueAsString(message));}
}

测试
浏览器访问: http://localhost:8060/easyExcel/download 下载Excel


​四 单元格样式设置

目标

  • 单元格字体居中
  • 超出单元格部分,自适应高度显示

效果
在这里插入图片描述


surf下载、自定义样式

public class ExcelUtils {/*** 单元格水平样式策略*/public static HorizontalCellStyleStrategy setHorizontalCellStyleStrategy(){// 头部样式WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 内容样式WriteCellStyle contentWriteCellStyle = new WriteCellStyle();contentWriteCellStyle.setWrapped(true); // 数据超出换行contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 水平居中// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);}}

注册自定义样式
在这里插入图片描述


五 单元格行合并

目标

  • 将同一年级的行进行合并

效果
在这里插入图片描述

1 合并统计

统计“指定列“ 的“哪几行”需要进行合并


表格软件电脑版。使用Map集合进行统计

Map<String, List<RowRange>> merStrategyMap 
  • key: 需要合并的列
  • value: 指定列中需要合并的行

每一个列有多个 rowRange, 每个rowRange表示这个列合并行的开始和结束的位置

在这里插入图片描述

RowRange

/*** 用于记录 Excel某一列, 某一类型的* 合并的开始和结束位置*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class RowRange {/*** 行合并开始位置*/private int start;/*** 行合并结束位置*/private int end;
}

EasyExcelServiceImpl

/*** 添加合并策略*/
private Map<String, List<RowRange>> addMerStrategy(List<Student> students) {// key: 表示需要合并的列  value: 表示该列需要合并的行集合Map<String, List<RowRange>> strategyMap = new HashMap<>();// 前一条数据。 (用于判断是否需要合并)Student preStudent = null;for (int i = 0; i < students.size(); i++) {Student student = students.get(i);if (preStudent != null) {// 年级合并if (student.getGrade().equals(preStudent.getGrade())) {fillStrategyMap(strategyMap, "0", i);}}preStudent = student;}return strategyMap;
}
/*** 计算需要合并的行**/
public static void fillStrategyMap(Map<String, List<RowRange>> strategyMap, String key, int index) {List<RowRange> rowRangeList = strategyMap.get(key) == null ? new ArrayList<>() : strategyMap.get(key);// 判断是否新增分段boolean flag = false;for (RowRange dto : rowRangeList) {//分段list中是否有end索引是上一行索引的,如果有,则索引+1if (dto.getEnd() == index) {dto.setEnd(index + 1);flag = true;}}//如果没有,则新增分段if (!flag) {rowRangeList.add(new RowRange(index, index + 1));}strategyMap.put(key, rowRangeList);
}

2 合并策略类

在上一步已经统计出了,哪些列的行需要进行合并, 具体的合并工作在这个类完成

/*** 合并类*/
public class MergeStrategy  extends AbstractMergeStrategy {// Map<列, 要进行合并的行>private Map<String, List<RowRange>> strategyMap;public MergeStrategy(Map<String, List<RowRange>> strategyMap) {this.strategyMap = strategyMap;}/*** 每一个单元格都会进入到该方法*    第一个单元格进入到该方法时就进行合并操作,其余单元格进入到该方法时不进行合并操作*/@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {int rowIndex = cell.getRowIndex();int columnIndex1 = cell.getColumnIndex();if (rowIndex == 1 && columnIndex1 == 0) {for (Map.Entry<String, List<RowRange>> entry : strategyMap.entrySet()) {// 哪一列的行需要进行合并int columnIndex = Integer.parseInt(entry.getKey());entry.getValue().forEach(rowRange -> {// 对行进行合并(四个参数: 行开始 行结束 列开始 列结束)sheet.addMergedRegionUnsafe(new CellRangeAddress(rowRange.getStart(), rowRange.getEnd(), columnIndex, columnIndex));});}}}
}

表格软件,关于 if (rowIndex == 1 && columnIndex1 == 0) 的说明
在这里插入图片描述

3 注册合并策略

EasyExcelServiceImpl
在这里插入图片描述


六 行高设置

1 非动态设置行高

效果 行高发生了变化
在这里插入图片描述


在实体中添加注解即可设置
在这里插入图片描述

注意
对超出单元格部分的数据不会自适应高度显示了。这是正常的,因为设置了行高将单元格的高度固定了。
在这里插入图片描述

2 动态设置行高

easyExcel如何使用。效果: 行高发生变化且超出单元格部分自适应高度显示
在这里插入图片描述

思路: 某一行中,如果某个单元格数据超出了单元格则不设置该行的行高,则该行的行高会根据 “四 单元格样式设置” 中的配置进行自适应高度显示


行高样式策略类

/*** 自定义行高* 注意: 实体类上不可加 @HeadRowHeight(value = 30) 注解,不然此方法失效(会进入到SimpleRowHeightStyleStrategy)*/
public class EvaSysRowHeightStyleStrategy extends AbstractRowHeightStyleStrategy {private Map<Integer, Integer> map = new HashMap<>();// 列数(用于判断当前行是否执行结束了)private  Integer cellNum;// 行高private static final Float height = 30f;// 需要设置行高的限制值(如果数据长度 < heightLimit 则需要设置行高,否则不需要)private  static  final Integer heightLimit = 40;public EvaSysRowHeightStyleStrategy(int cellNum) {this.cellNum = cellNum;}/*** 设置标题的行高*/@Overrideprotected void setHeadColumnHeight(Row row, int i) {row.setHeightInPoints((float)40);}@Overrideprotected void setContentColumnHeight(Row row, int i) {row.forEach(cell -> {// 设置行高和解决数据显示不完整问题// 当前行号int currentNum = cell.getRow().getRowNum();// 当前数据的长度Integer currentLength = getDataLength(cell);// 当前单元格列数int currentCellNum = cell.getColumnIndex()+1;// 如果已经是最后一列,则判断是否需要设置行高if (cellNum == currentCellNum) {// 如果数据最大长度 <= 20 则设置行高Integer max = map.get(currentNum);max = max > currentLength? max: currentLength;if(max <= heightLimit) {cell.getRow().setHeightInPoints(height);}} else {// 获取当前行最大的数据长度。因为可能是新的行,获取数据时可能为null,如果为null,我们就置max为0Integer max = map.get(currentNum) == null? 0: map.get(currentNum);// 比较获取最大的数据长度更新max的值max = max > currentLength? max: currentLength;map.put(currentNum, max);}});}/*** 获取数据长度*/private Integer getDataLength(Cell cell) {CellType type = cell.getCellTypeEnum();String data;switch (type) {case STRING: data = cell.getStringCellValue(); break;case FORMULA: data = cell.getCellFormula(); break;case NUMERIC: data = String.valueOf(cell.getNumericCellValue()); break;default: data = "";}return data.length();}
}

注: 实体类中不可加 @HeadRowHeight, 不然该策略类会失效(会使用 SimpleRowHeightStyleStrategy 进行行高的设置)


注册策略类
EasyExcelServiceImpl
在这里插入图片描述

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/64521.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息