赞
踩
文章目录
该文章主要是介绍如何快速实现导入与导出功能
引用官方的说明:EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
pom.xml引入jar依赖包:
- <!-- EasyExcel -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>2.2.6</version>
- </dependency>
@ExcelProperty该注解的value是对应excle表格的列名称,index对应的是excel列的下标
- @Data
- public class ImportModel {
-
- /**
- * 树根
- */
- @ExcelProperty(value = "名称", index = 0)
- private String ;
-
- /**
- * 树根标题
- */
- @ExcelProperty(value = "编码", index = 1)
- private String code;
- }
- /**
- * 导入
- */
- @ApiOperation("导入")
- @PostMapping("/importTree")
- public R importTree(@RequestParam("file") MultipartFile file) {
- /** 根据自己的业务自行选择在哪处理 */
- /** 直接在controllerr处理 */
- // EasyExcel.read(file.getInputStream(), BigTreeImportCommand.class, new ExcelListener(urbanFacilityManageService)).sheet().doRead();
- /** 在service实现类处理 */
- Boolean flag = treeService.importTree(file, tenantId);
- return R.ok("导入成功");
- }
- @Override
- public Boolean importTree(MultipartFile file) {
-
- try {
- /** 处理数据的监听器,有参构造,根据自己的业务决定 */
- TreeExcelListener excelListener = new TreeExcelListener(importService,tenantId);
-
- // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
- //EasyExcel.read(文件流,对应的Model实体类,监听器).sheet(那张sheet表,可以使用下标或者使用sheet名字).head(表头对应的实体类).headRowNumber(表头占几行).registerReadListener(处理数据的监听器类).doRead()
- EasyExcel.read(file.getInputStream(), ImportModel.class, excelListener).sheet(0).head(ImportModel.class).headRowNumber(1).doRead();
- return true;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- import com.alibaba.excel.context.AnalysisContext;
- import com.alibaba.excel.event.AnalysisEventListener;
- import com.ieds.back.interfaces.sys.web.command.BigTreeImportModel;
-
- /**
- * @Author: ChenFB
- * @CreateTime: 2023-04-23 17:18
- * @Description: 导入监听器
- */
- public class ImportListener extends AnalysisEventListener<BigTreeImportModel> {
-
-
- private ImportService importService;
-
- private String tenantId;
-
- /** 有参构造,建议将serverjie接口以参数的方式参进来,方便数据入库处理,这个参数自行界定 */
- public ImportListener(ImportService importService, String tenantId) {
- this.importService = importService;
- this.tenantId = tenantId;
- }
-
- /** 读取每一行数据都会进入该方法,数据处理与校验可以在该方法进行处理 */
- @Override
- public void invoke(BigTreeImportModel data, AnalysisContext context) {
-
- }
-
- /** 所有数据读取完毕后,最终会执行这个方法,所以建议数据处理完后,批量在该方法进行入库处理 */
- @Override
- public void doAfterAllAnalysed(AnalysisContext context) {
-
- }
- }
- /**
- * 导出
- */
- @ApiOperation("导出")
- @GetMapping("/exportTree")
- public void exportTree(HttpServletResponse response, @RequestParam("tenantId") String tenantId) {
- treeService.exportTree(response,tenantId);
- }
- @Override
- public void exportTree(HttpServletResponse response, String tenantId) {
- ExcelWriter writer = null;
- try {
- response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //设置响应内容类型
- response.setCharacterEncoding("utf-8");//编码
- // 设置文件名, ps:把字符串中所有的'+'替换成'%20',在URL中%20代表空格
- String fileName = URLEncoder.encode("文件名,根据业务决定", "UTF-8").replaceAll("\\+", "%20");
- response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");//设置响应头
- response.setHeader("fileName", fileName + ".xlsx");//设置响应头
- /** 导出的数据集合 */
- List<ExportModel> modelList = new ArrayList<>();
- /** registerWriteHandler(合并行数,那些列需要合并) */
- writer = EasyExcel.write(response.getOutputStream(), BigTreeImportModel.class).registerWriteHandler(new MergeStrategy(modelList.size(), 0, 1, 2, 7, 8, 10, 11)).build();//获取写出流
- WriteSheet sheet = EasyExcel.writerSheet("sheet名称,自行决定").build();//创建表格,设置表格页名称
- writer.write(modelList, sheet);//读出
-
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- if (null != writer) {
- writer.finish();//关闭流
- }
- }
- }
-
-
- import com.alibaba.excel.metadata.Head;
- import com.alibaba.excel.write.merge.AbstractMergeStrategy;
- import org.apache.commons.collections.map.HashedMap;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.util.CellRangeAddress;
-
- import java.util.*;
-
- /**
- * @Author: ChenFB
- * @CreateTime: 2023-04-20 10:56
- * @Description: Excel单元格合并工具类
- */
- public class MergeStrategy extends AbstractMergeStrategy {
-
- // 合并的列编号,从0开始,指定的index或自己按字段顺序数
- private Set<Integer> mergeCellIndex = new HashSet<>();
-
- // 数据集大小,用于区别结束行位置
- private Integer maxRow = 0;
-
- // 禁止无参声明
- private MergeStrategy() {
- }
-
- public MergeStrategy(Integer maxRow, int... mergeCellIndex) {
- Arrays.stream(mergeCellIndex).forEach(item -> {
- this.mergeCellIndex.add(item);
- });
- this.maxRow = maxRow;
- }
-
- // 记录上一次合并的信息
- private Map<Integer, MergeRange> lastRow = new HashedMap();
-
- // 每行每列都会进入,绝对不要在这写循环
- @Override
- protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
- int currentCellIndex = cell.getColumnIndex();
- // 判断该行是否需要合并
- if (mergeCellIndex.contains(currentCellIndex)) {
- String currentCellValue = cell.getStringCellValue();
- int currentRowIndex = cell.getRowIndex();
- if (!lastRow.containsKey(currentCellIndex)) {
- // 记录首行起始位置
- lastRow.put(currentCellIndex, new MergeRange(currentCellValue, currentRowIndex, currentRowIndex, currentCellIndex, currentCellIndex));
- return;
- }
- //有上行这列的值了,拿来对比.
- MergeRange mergeRange = lastRow.get(currentCellIndex);
- if (!(mergeRange.lastValue != null && mergeRange.lastValue.equals(currentCellValue))) {
- // 结束的位置触发下合并.
- // 同行同列不能合并,会抛异常
- if (mergeRange.startRow != mergeRange.endRow || mergeRange.startCell != mergeRange.endCell) {
- sheet.addMergedRegionUnsafe(new CellRangeAddress(mergeRange.startRow, mergeRange.endRow, mergeRange.startCell, mergeRange.endCell));
- }
- // 更新当前列起始位置
- lastRow.put(currentCellIndex, new MergeRange(currentCellValue, currentRowIndex, currentRowIndex, currentCellIndex, currentCellIndex));
- }
- // 合并行 + 1
- mergeRange.endRow += 1;
- // 结束的位置触发下最后一次没完成的合并
- if (relativeRowIndex.equals(maxRow - 1)) {
- MergeRange lastMergeRange = lastRow.get(currentCellIndex);
- // 同行同列不能合并,会抛异常
- if (lastMergeRange.startRow != lastMergeRange.endRow || lastMergeRange.startCell != lastMergeRange.endCell) {
- sheet.addMergedRegionUnsafe(new CellRangeAddress(lastMergeRange.startRow-1, lastMergeRange.endRow, lastMergeRange.startCell, lastMergeRange.endCell));
- }
- }
- }
- }
- }
-
- class MergeRange {
- public int startRow;
- public int endRow;
- public int startCell;
- public int endCell;
- public String lastValue;
-
- public MergeRange(String lastValue, int startRow, int endRow, int startCell, int endCell) {
- this.startRow = startRow;
- this.endRow = endRow;
- this.startCell = startCell;
- this.endCell = endCell;
- this.lastValue = lastValue;
- }
- }
以上就是使用EasyExcel时限导入与导出功能的实现步骤,鄙人才疏学浅,本文章仅供参考,有不对之处,还望各位大佬提醒与指教.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。