乐于分享
好东西不私藏

使用EasyPOI对Excel导入导出

使用EasyPOI对Excel导入导出

Dream_sky

读完需要

10

分钟

速读仅需 5 分钟

一、Easypoi 简介

二、使用步骤

三、常用注解介绍

四、DTO/VO样例

五、导出Excel添加序号

六、多sheet导入

一、Easypoi 简介

Easypoi 是为了让开发者快速的实现Excel的导入导出,基于Apache poi基础上的一个工具包。

二、使用步骤

2.1 引入依赖

<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.1.0</version></dependency>

2.2 ExcelUtils工具类

import cn.afterturn.easypoi.excel.ExcelExportUtil;import cn.afterturn.easypoi.excel.ExcelImportUtil;import cn.afterturn.easypoi.excel.entity.ExportParams;import cn.afterturn.easypoi.excel.entity.ImportParams;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.word.WordExportUtil;import com.jb.base.constant.ExcelConstant;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xwpf.usermodel.XWPFDocument;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.net.URLEncoder;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.NoSuchElementException;/** * @description: excel导入导出工具类 * @author: wyk * @create: 2022-04-08 18:26 * @version: 1.0.0-SNAPSHOT */publicclassExcelUtils{/**     * excel 导出     *     * @param list 数据     * @param title 标题     * @param sheetName sheet名称     * @param pojoClass pojo类型     * @param fileName 文件名称     * @param isCreateHeader 是否创建表头     * @param response     */publicstaticvoidexportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,boolean isCreateHeader, HttpServletResponse response)throws IOException {        ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);        exportParams.setCreateHeadRows(isCreateHeader);        defaultExport(list, pojoClass, fileName, response, exportParams);    }/**     * excel 导出     *     * @param list 数据     * @param title 标题     * @param sheetName sheet名称     * @param pojoClass pojo类型     * @param fileName 文件名称     * @param response     */publicstaticvoidexportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,        HttpServletResponse response)throws IOException {        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName, ExcelType.XSSF));    }/**     * 生成Excel文件的字节数组     */publicstaticbyte[] generateExcel(String title, String sheetName, List<?> list, Class<?> pojoClass)throws IOException {        Workbook workbook =            ExcelExportUtil.exportExcel(new ExportParams(title, sheetName, ExcelType.XSSF), pojoClass, list);try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {            workbook.write(outputStream);return outputStream.toByteArray();        }    }/**     * 通过模板 word 导出     *     * @param url 模板地址     * @param map 填充数据     * @param response 返回     * @param fileName 文件名称     */publicstaticvoidexportWord(String url, Map<String, Object> map, HttpServletResponse response, String fileName)throws Exception {        XWPFDocument doc = WordExportUtil.exportWord07(url, map);// 导出 Word 文件        response.setCharacterEncoding("UTF-8");        response.setContentType("application/vnd.ms-word;charset=utf-8");        response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName + "." + ExcelTypeEnum.DOCX.getValue(), "UTF-8"));        response.setHeader("Cache-Control""no-store");        response.addHeader("Cache-Control""max-age=0");        OutputStream out = response.getOutputStream();        doc.write(out);        out.flush();        out.close();    }/**     *     * @author wzm     * @description 通过模板导出数据     * @date 9:03 2024/6/21     * @param url     * @param map     * @version:1.0.0-SNAPSHT     **/publicstaticvoidexportExcelByTemplate(String url, Map<String, Object> map, String fileName,        HttpServletResponse response)throws Exception {        TemplateExportParams templateExportParams = new TemplateExportParams(url);        Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, map);        downLoadExcel(fileName, response, workbook);    }/**     * excel 导出     *     * @param list 数据     * @param pojoClass pojo类型     * @param fileName 文件名称     * @param response     * @param exportParams 导出参数     */publicstaticvoidexportExcel(List<?> list, Class<?> pojoClass, String fileName, ExportParams exportParams,        HttpServletResponse response)throws IOException {        defaultExport(list, pojoClass, fileName, response, exportParams);    }/**     * excel 导出     *     * @param list 数据     * @param fileName 文件名称     * @param response     */publicstaticvoidexportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response)throws IOException {        defaultExport(list, fileName, response);    }/**     * 默认的 excel 导出     *     * @param list 数据     * @param pojoClass pojo类型     * @param fileName 文件名称     * @param response     * @param exportParams 导出参数     */privatestaticvoiddefaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response,        ExportParams exportParams)throws IOException {        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);        downLoadExcel(fileName, response, workbook);    }/**     * 动态列的 excel 导出     *     * @param list 数据     * @param title 头     * @param sheetName sheet页     * @param entityList 动态pojo类型     * @param fileName 文件名称     * @param response     */publicstaticvoiddynamicExport(List<?> list, String title, String sheetName, List<ExcelExportEntity> entityList,        String fileName, HttpServletResponse response)throws IOException {        ExportParams exportParams = new ExportParams(title, sheetName, ExcelType.XSSF);        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);        downLoadExcel(fileName, response, workbook);    }/**     * 默认的 excel 导出     *     * @param list 数据     * @param fileName 文件名称     * @param response     */privatestaticvoiddefaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response)throws IOException {        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);        downLoadExcel(fileName, response, workbook);    }privatestaticvoiddefaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response,        ExcelType excelType)throws IOException {        Workbook workbook = ExcelExportUtil.exportExcel(list, excelType);        downLoadExcel(fileName, response, workbook);    }/**     * 下载     *     * @param fileName 文件名称     * @param response     * @param workbook excel数据     */privatestaticvoiddownLoadExcel(String fileName, HttpServletResponse response, Workbook workbook)throws IOException {try {            response.setCharacterEncoding("UTF-8");            response.setHeader("content-Type""application/vnd.ms-excel");            response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName + "." + ExcelTypeEnum.XLSX.getValue(), "UTF-8"));            workbook.write(response.getOutputStream());        } catch (Exception e) {thrownew IOException(e.getMessage());        } finally {            workbook.close();        }    }publicstaticvoiddownLoadExcelByWorkBook(String fileName, HttpServletResponse response, Workbook workbook)throws IOException {        downLoadExcel(fileName, response, workbook);    }/**     * excel 导入     *     * @param filePath excel文件路径     * @param titleRows 标题行     * @param headerRows 表头行     * @param pojoClass pojo类型     * @param <T>     * @return     */publicstatic <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass)throws IOException {if (StringUtils.isBlank(filePath)) {returnnull;        }        ImportParams params = new ImportParams();        params.setTitleRows(titleRows);        params.setHeadRows(headerRows);        params.setNeedSave(true);        params.setSaveUrl("/excel/");try {return ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);        } catch (NoSuchElementException e) {thrownew IOException("模板不能为空");        } catch (Exception e) {thrownew IOException(e.getMessage());        }    }/**     * excel 导入     *     * @param file excel文件     * @param pojoClass pojo类型     * @param <T>     * @return     */publicstatic <T> List<T> importExcel(MultipartFile file, Class<T> pojoClass)throws IOException {return importExcel(file, 11, pojoClass);    }/**     * excel 导入     *     * @param file excel文件     * @param titleRows 标题行     * @param headerRows 表头行     * @param pojoClass pojo类型     * @param <T>     * @return     */publicstatic <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass)throws IOException {return importExcel(file, titleRows, headerRows, false, pojoClass);    }/**     * excel 导入     *     * @param file 上传的文件     * @param titleRows 标题行     * @param headerRows 表头行     * @param needVerfiy 是否检验excel内容     * @param pojoClass pojo类型     * @param <T>     * @return     */publicstatic <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, boolean needVerfiy,        Class<T> pojoClass)throws IOException {if (file == null) {returnnull;        }try {return importExcel(file.getInputStream(), titleRows, headerRows, needVerfiy, pojoClass);        } catch (Exception e) {thrownew IOException(e.getMessage());        }    }/**     * excel 导入     *     * @param inputStream 文件输入流     * @param titleRows 标题行     * @param headerRows 表头行     * @param needVerify 是否检验excel内容     * @param pojoClass pojo类型     * @param <T>     * @return     */publicstatic <T> List<T> importExcel(InputStream inputStream, Integer titleRows, Integer headerRows,boolean needVerify, Class<T> pojoClass)throws IOException {if (inputStream == null) {returnnull;        }        ImportParams params = new ImportParams();        params.setTitleRows(titleRows);        params.setHeadRows(headerRows);        params.setSaveUrl("excel/");        params.setNeedSave(true);        params.setNeedVerify(needVerify);try {return ExcelImportUtil.importExcel(inputStream, pojoClass, params);        } catch (NoSuchElementException e) {thrownew IOException("excel文件不能为空");        } catch (Exception e) {thrownew IOException(e.getMessage());        }    }/**     * 导出多个sheet页     *      * @param listMap     * @param     * @param response     */publicstaticvoidexportMoreSheetExcel(List<Map<String, Object>> listMap, String fileName,        HttpServletResponse response)throws IOException {        defaultExport(listMap, fileName, response, ExcelType.XSSF);    }publicstaticbooleanisExcel(BufferedInputStream inputStream){boolean result = false;try {            FileMagic fileMagic = FileMagic.valueOf(inputStream);if (Objects.equals(fileMagic, FileMagic.OLE2)                    || Objects.equals(fileMagic, FileMagic.OOXML)) {                result = true;            }        } catch (Exception e) {            e.printStackTrace();        }return result;    }publicstatic Workbook getWorkBook(MultipartFile file)throws IOException {        InputStream is = file.getInputStream();        Workbook hssfWorkbook = null;try {            hssfWorkbook = new HSSFWorkbook(is);        } catch (Exception ex) {            is =file.getInputStream();            hssfWorkbook = new XSSFWorkbook(is);        }return hssfWorkbook;    }/**     * Excel 类型枚举     */enum ExcelTypeEnum {        XLS("xls"), XLSX("xlsx"), DOCX("docx");private String value;        ExcelTypeEnum(String value) {this.value = value;        }public String getValue(){return value;        }publicvoidsetValue(String value){this.value = value;        }    }}

2.3 导入使用

2.3.1 controller

/**     * 导入     * @param file 入参     * @return CommonResponse<Boolean> 返回值     */@PostMapping("/import")public CommonResponse<Boolean> testImport(MultipartFile file){return CommonResponse.ok(this.testService.testImport(file));    }

2.3.2 service

/**     * 导入     * @param file 入参     * @return CommonResponse<Boolean> 返回值     */Boolean testImport(MultipartFile file);

2.3.3 Impl

/**     * 通行管理导入/覆盖     *     * @param file 入参     * @return CommonResponse<Boolean> 返回值     */@Override@Transactional(rollbackFor = Exception.class)publicBooleanvehiclePermitImport(MultipartFilefile{try(BufferedInputStream inputStream = new BufferedInputStream(file.getInputStream())) {if (!ExcelUtils.isExcel(inputStream)) {thrownew ParameterException("仅支持上传后缀为xlsx或者xls格式");            }// 1. 读取Excel数据            List<ImportDTO> importDataList = ExcelUtils.importExcel(file, 01, ImportDTO.class);// 2. 处理数据return Boolean.TRUE;        } catch (IOException e) {throw BusinessException.buildBusinessExceptionAlert("导入失败!" + e);        }    }
在这里插入图片描述

2.4 导出使用

2.4.1 controller

/**  * 导出  * @param dto  * @param response  */@PostMapping("/export")publicvoidtestExport(@RequestBody SelectDTO dto, HttpServletResponse response){  exportFileService.testExport(dto,response); }

2.4.2 service

/**     * 导出     * @param dto     * @param response     */voidtestExport(SelectDTO dto, HttpServletResponse response);

2.4.3 Impl

/**     * 导出     *     * @param dto     * @param response     */@OverridepublicvoidtestExport(SelectDTO dto, HttpServletResponse response){        List<ZnjProjectRequireExportVO2> znjProjectRequireVOS = null ;//导出数据try {            ExcelUtils.exportExcel(exportVOS, null"测试导出", ExportVO.class, "测试导出", trueresponse);        } catch (IOException e) {            log.error("导出失败: {}", e);        }    }
在这里插入图片描述

三、常用注解介绍

  • @Excel 作用到filed上面,是对Excel列的描述
  • @ExcelCollection 表示一个集合,主要针对一对多的导出
  • @ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段

@Excel 这个是必须使用的注解,如果需求简单只使用这一个注解也是可以的,涵盖了常用的Excel需求

在这里插入图片描述

@ExcelCollection 一对多的集合注解

@ExcelEntity 标记是不是导出excel 标记为 实体类 ,一般是一个内部属性类,标记是否 继续穿透

四、DTO/VO样例

只为满足常用的注解使用参考,可能不是一个完整的Excel字段

4.1 导入DTO

/** * 导入DTO * @description * @version: 1.0.0-SNAPSHT **/@DatapublicclassImportDTOimplementsSerializable{privatestaticfinallong serialVersionUID = 605469180573673969L;@Excel(name = "外协单位", fixedIndex = 0)private String deptName;@Excel(name = "创建时间",format = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8",fixedIndex = 1)private LocalDateTime createdTime;@Excel(needMerge = true, name = "项目名称",fixedIndex = 2)private String projectName;@Excel(name = "专业类型", replace = {"粮油_1""蔬菜_2"},fixedIndex = 3)private String specializedParentId;@Schema(description = "实施主体")@ExcelEntityprivate ImportTestDTO testDTO;@ExcelCollection(name = "子项目")private List<ImportSubDTO> subjectList;}

4.2 导出VO

/** * 导出DTO * @description * @version: 1.0.0-SNAPSHT **/@DatapublicclassExportDTOimplementsSerializable{privatestaticfinallong serialVersionUID = 605469180573673969L;@Excel(name = "序号", orderNum = "0", width = 5,format = "isAddIndex")private Integer index;@Excel(name = "类别", orderNum = "1", width = 20)private String classification;@Excel(name = "承担单位名称", orderNum = "2", width = 30)private String unitName;@Excel(name = "产业", orderNum = "2",width = 10 ,replace = {"粮油_96""蔬菜_97"})private String type;@Excel(name = "实施单位", orderNum = "3", mergeVertical = true, width = 30)private String subjectName;@Excel(name = "主持单位", orderNum = "4", needMerge = true,width = 20)private String mainName;}

五、导出Excel添加序号

在导出的bean对象添加一个Integer 数据 ,字段字段命名,添加easypoi的@Excel注解,最主要是的这个注解里面的format属性要设置成isAddIndex,导出即可带出自增的序号

在这里插入图片描述

六、多sheet导入

 Workbook workBook = ExcelUtils.getWorkBook(file);//支持多sheetint sheetNum = workBook.getNumberOfSheets(); ImportParams params = new ImportParams(); params.setSheetNum(sheetNum); List<ImportDTO> importVoList = ExcelImportUtil.importExcel(file.getInputStream(), ImportDTO.classparams);

公众号|程序员总结文档

CSDN|Dream_sky分享