2.自定义@Excel注解实现数据Excel形式导入导出

您所在的位置:网站首页 poi导出数据到excel模板 2.自定义@Excel注解实现数据Excel形式导入导出

2.自定义@Excel注解实现数据Excel形式导入导出

2023-04-11 14:40| 来源: 网络整理| 查看: 265

测试2 python-图灵-1 java-图灵-1 前言

  这几天在学习如何使用自定义注解实现Excel格式数据导入导出,参考的还是若依框架里面的代码,由于是初学,所以照猫画虎呗,但是难受的是需要复制并根据自己项目修改作者自定义的工具类以及导入这些工具类的依赖包。由于吃了这个苦,我决定把这个艰辛的CV操作通过一张逻辑图来表达,方便我以后复用。下面证实开始介绍这个功能的实现,但是由于对项目中的只是很不了解,我这里简单实现,并简单讲解,深层次的代码我会给出,后续会继续运用讲解。整篇博客分为两个部分,一部分是数据的导出,一部分是数据的导入。本文项目链接:WomPlus: 结合若依项目对原始工单项目内容进行增强 (gitee.com)

1.所需要的依赖

  在进行项目前,我们需要导入依赖才能引用具体的功能,因此第一步就是导入依赖了,这里除了Excel需要的依赖,一些工具类的依赖也需要导入,为什么呢?因为作者的项目写的很细致,比如在咋们的java中自带有StringUtils工具类,但是作者细致地自己写了一个,可见其基础功能之深呀!

org.apache.poi poi-ooxml 4.1.2 org.apache.commons commons-lang3 commons-io commons-io 2.11.0 org.springframework.boot spring-boot-configuration-processor true 所需依赖 2.修改配置文件

  引入依赖是第一步,修改配置文件就是我们的第二步了,在这里修改配置文件是因为在该功能的数据导入,作者是在自己自定义的RuoYiConfig中通过

@ConfigurationProperties(prefix = "wo")注解获取配置文件中profile属性值,即我们上传下载文件的地址。我这里使用的是properties为后缀的文件,配置文件为yaml的请根据自己文件类型修改 //添加自己的项目配置类WoConfig需要配置的项目名和导出Excel形式数据下载路径 #项目相关配置 wo.name=WO wo.profile=G:/Desktop/base_study/project/myself_springboot_project/wom-plus/uploadPath 3.数据以Excel格式导出的Controller层 @PostMapping("/export") @ResponseBody public AjaxResult export(@RequestParam(value = "name", required = false) String username){ List list = userDetailsService.getUserListByUsername(username); ExcelUtil util = new ExcelUtil(SysUser.class); return util.exportExcel(list, "用户数据"); }   在UserController的export()方法中,首先传入一个Class.class作为ExcelUtils类的参数来new一个ExcelUtils对象util,然后传递一个Class的list对象和表名称到util的exportExcel()方法中返回Class的Excel信息。 3.1 ExcelUtils的有参构造 //1.传入需要Excel导出类的Class.class,返回一个ExcelUtil对象 public ExcelUtil(Class clazz) { this.clazz = clazz; }

  这里就是传入一个Class类来创建该类的Excel对象,本篇博客围绕着SysUser类实现该功能的,因此这里传入SysUser.class

3.2 exportExcel(Listlist, String sheetName) public AjaxResult exportExcel(List list, String sheetName) { return exportExcel(list, sheetName, StringUtils.EMPTY); }

  在方法中,调用exportExcel(Listlist, String sheetName, String title)封装Excel格式数据导出

3.3 exportExcel(List list, String sheetName, String title) public AjaxResult exportExcel(List list, String sheetName, String title) { this.init(list, sheetName, title, Type.EXPORT); return exportExcel(); }

  本文方法首先初始化要创建的Excel表格,然后返回exportExcel()方法来讲要导出的数据写进前面的profile路径中

3.3.1 init(list, sheetName, title, Type.EXPORT) public void init(List list, String sheetName, String title, Type type) { if (list == null) { list = new ArrayList(); } this.list = list; this.sheetName = sheetName; this.type = type; this.title = title; //根据要导出Excel的实体类的字段创建字段Class类所需要的Excel字段 createExcelField(); createWorkbook();//创建一个工作薄 createTitle();//创建Excel第一行标题 createSubHead();//创建对象子列表名称 } 3.3.2 exportExcel() public AjaxResult exportExcel() { OutputStream out = null; try { writeSheet();//写入数据到Sheet String filename = encodingFilename(sheetName);//编辑文件名 //getAbsoluteFile(filename)根据文件名称获取下载路径 //创建一个输出流 out = new FileOutputStream(getAbsoluteFile(filename)); wb.write(out);//写入Excel信息到该路径 return AjaxResult.success(filename);//返回导出成功信息 } catch (Exception e) { log.error("导出Excel异常{}", e.getMessage()); throw new UtilException("导出Excel失败,请联系网站管理员!"); } finally { IOUtils.closeQuietly(wb);//关闭工作薄对象输出流 IOUtils.closeQuietly(out);//关闭输出流 } } 导出数据库数据到指定路径 3.4 @Excel和@Excels注解 package com.ku.wo.framework.aspectj.lang.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.math.BigDecimal; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import com.ku.wo.common.utils.poi.ExcelHandlerAdapter; /** * 自定义导出Excel数据注解 * * @author ruoyi */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD)//作用在什么地方 public @interface Excel { /** * 导出时在excel中排序 */ public int sort() default Integer.MAX_VALUE; /** * 导出到Excel中的名字. */ public String name() default ""; /** * 日期格式, 如: yyyy-MM-dd */ public String dateFormat() default ""; /** * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) */ public String dictType() default ""; /** * 读取内容转表达式 (如: 0=男,1=女,2=未知) */ public String readConverterExp() default ""; /** * 分隔符,读取字符串组内容 */ public String separator() default ","; /** * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) */ public int scale() default -1; /** * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN */ public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; /** * 导出时在excel中每个列的高度 单位为字符 */ public double height() default 14; /** * 导出时在excel中每个列的宽 单位为字符 */ public double width() default 16; /** * 文字后缀,如% 90 变成90% */ public String suffix() default ""; /** * 当值为空时,字段的默认值 */ public String defaultValue() default ""; /** * 提示信息 */ public String prompt() default ""; /** * 设置只能选择不能输入的列内容. */ public String[] combo() default {}; /** * 是否需要纵向合并单元格,应对需求:含有list集合单元格) */ public boolean needMerge() default false; /** * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. */ public boolean isExport() default true; /** * 另一个类中的属性名称,支持多级获取,以小数点隔开 */ public String targetAttr() default ""; /** * 是否自动统计数据,在最后追加一行统计数据总和 */ public boolean isStatistics() default false; /** * 导出类型(0数字 1字符串 2图片) */ public ColumnType cellType() default ColumnType.STRING; /** * 导出列头背景颜色 */ public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; /** * 导出列头字体颜色 */ public IndexedColors headerColor() default IndexedColors.WHITE; /** * 导出单元格背景颜色 */ public IndexedColors backgroundColor() default IndexedColors.WHITE; /** * 导出单元格字体颜色 */ public IndexedColors color() default IndexedColors.BLACK; /** * 导出字段对齐方式 */ public HorizontalAlignment align() default HorizontalAlignment.CENTER; /** * 自定义数据处理器 */ public Class handler() default ExcelHandlerAdapter.class; /** * 自定义数据处理器参数 */ public String[] args() default {}; /** * 字段类型(0:导出导入;1:仅导出;2:仅导入) */ Type type() default Type.ALL; public enum Type { ALL(0), EXPORT(1), IMPORT(2); private final int value; Type(int value) { this.value = value; } public int value() { return this.value; } } public enum ColumnType { NUMERIC(0), STRING(1), IMAGE(2); private final int value; ColumnType(int value) { this.value = value; } public int value() { return this.value; } } } //@Excels package com.ku.wo.framework.aspectj.lang.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Excel注解集 * * @author ruoyi */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Excels { Excel[] value(); } @Excel和@Excels 3.5 运行结果

4.数据以Excel格式导出的Controller层 @PostMapping("/importData") @ResponseBody public AjaxResult importData(MultipartFile file) throws Exception { ExcelUtil util = new ExcelUtil(SysUser.class); List userList = util.importExcel(file.getInputStream()); String message = userDetailsService.importUser(userList); return AjaxResult.success(message); }   在UserController的importData()方法中,首先传入一个Class.class作为ExcelUtils类的参数来new一个ExcelUtils对象util,然后传入一个要导入的Excel形式的表格数据作为utils.importData()函数的输入流is,importData()方法根据is返回Excel表格数据中的Class类的list对象,接着传入一个Class的list对象和一个关于是否支持更新数据库已有数据的布尔变量到importUser()方法中,该方法根据这两个参数来返回插入成功或失败的信息message,最后传入message到AjaxResult.success()方法返回导入数据成功消息。 4.1 importExcel(InputStream) public List importExcel(InputStream is) throws Exception { return importExcel(is, 0); } public List importExcel(InputStream is, int titleNum) throws Exception { return importExcel(StringUtils.EMPTY, is, titleNum); } //核心实现代码 public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception { this.type = Type.IMPORT; this.wb = WorkbookFactory.create(is); List list = new ArrayList(); // 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0); if (sheet == null) { throw new IOException("文件sheet不存在"); } boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook); Map pictures; if (isXSSFWorkbook) { pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb); } else { pictures = getSheetPictures03((HSSFSheet) sheet, (HSSFWorkbook) wb); } // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1 int rows = sheet.getLastRowNum(); if (rows > 0) { // 定义一个map用于存放excel列的序号和field. Map cellMap = new HashMap(); // 获取表头 Row heard = sheet.getRow(titleNum); for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { Cell cell = heard.getCell(i); if (StringUtils.isNotNull(cell)) { String value = this.getCellValue(heard, i).toString(); cellMap.put(value, i); } else { cellMap.put(null, i); } } // 有数据时才处理 得到类的所有field. List fields = this.getFields(); Map fieldsMap = new HashMap(); for (Object[] objects : fields) { Excel attr = (Excel) objects[1]; Integer column = cellMap.get(attr.name()); if (column != null) { fieldsMap.put(column, objects); } } for (int i = titleNum + 1; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3