JeeSite的Excel导入、导出、支持大数据量,使用annotation最小化配置

介绍 Apache POI 3.9 的封装方法,用于简化 Excel 的导出和导入操作。支持 xls 和 xlsx 格式,通过 Annotation 定义字段,自动处理字典类型数据。

介绍:

对Apache POI 3.9的简单封装,实现Excel的导出导入功能。使用Annotation定义导出导入字段。 http://jeesite.com

优点:

  1. 简单易用,支持大数量导出,配置简单,代码量少。
  2. 支持Excel 2003、2007、2010(xls、xlsx)格式。
  3. 支持简单格式设置,对齐方式,排序等
  4. 可导出字典类型数据,自定义数据字段类型(例如:部门关联对象,部门名称与部门编号互转)。
  5. 无需建立导入模板,系统自动生成。

缺点:

  1. 格式单一,无法导出格式比较复杂的表格。
  2. 不能使用模板进行导入,导出。

使用示例:

 

1、导出实体对象中的annotation的定义(ExcelField说明见:5、ExcelField定义说明):

  

Java代码    收藏代码
  1. @Entity  
  2. @Table(name = "sys_user")  
  3. public class User extends BaseEntity {  
  4.   
  5.     private Long id;        // 编号  
  6.     ...  
  7.     ...  
  8.     ...   
  9.     private List<Role> roleList = Lists.newArrayList(); // 拥有角色列表  
  10.       
  11.     @Id  
  12.     @ExcelField(title="ID", type=1, align=2, sort=1)  
  13.     public Long getId() {  
  14.         return id;  
  15.     }  
  16.     @ManyToOne  
  17.     @ExcelField(title="所属区域", align=2, sort=10)  
  18.     public Area getArea() {  
  19.         return area;  
  20.     }  
  21.     @ManyToOne  
  22.     @ExcelField(title="所属部门", align=2, sort=20)  
  23.     public Office getOffice() {  
  24.         return office;  
  25.     }  
  26.     @Length(min=1, max=100)  
  27.     @ExcelField(title="姓名", align=2, sort=40)  
  28.     public String getName() {  
  29.         return name;  
  30.     }  
  31.     @Length(min=0, max=100)  
  32.     @ExcelField(title="用户类型", align=2, sort=80, dictType="sys_user_type")  
  33.     public String getUserType() {  
  34.         return userType;  
  35.     }  
  36.     @ExcelField(title="创建时间", type=0, align=1, sort=90)  
  37.     public Date getCreateDate() {  
  38.         return createDate;  
  39.     }  
  40.     @ExcelField(title="最后登录日期", type=1, align=1, sort=110)  
  41.     public Date getLoginDate() {  
  42.         return loginDate;  
  43.     }  
  44.     @ManyToMany  
  45.     @ExcelField(title="拥有角色", align=1, sort=800, fieldType=RoleListType.class)  
  46.     public List<Role> getRoleList() {  
  47.         return roleList;  
  48.     }  
  49. }  
 

 2、Excel导出示例:

 

Java代码    收藏代码
  1. public String exportFile(User user) {  
  2.     try {  
  3.         String fileName = "用户数据"+DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";   
  4.                 // 查询数据  
  5.         Page<User> page = systemService.findUser(new Page<User>(request, response, -1), user);   
  6.                 // 1:创建Excel导出对象;2:设置数据;3:写入输出流;4:临时数据销毁  
  7.         new ExportExcel("用户数据", User.class)  
  8.                      .setDataList(page.getList())  
  9.                      .write(response, fileName)  
  10.                      .dispose();  
  11.         return null;  
  12.     } catch (Exception e) {  
  13.         addFlashMessage("导出用户失败!失败信息:"+e.getMessage());  
  14.     }  
  15.     return "redirect:"+BaseController.ADMIN_PATH+"/sys/user/?repage";  
  16. }  

 

3、Excel 导入示例:

 

Java代码    收藏代码
  1. public String importFile(MultipartFile file) {  
  2.     try {  
  3.         int successNum = 0;  
  4.         int failureNum = 0;  
  5.         StringBuilder failureMsg = new StringBuilder();  
  6.                 // 创建导入Excel对象  
  7.         ImportExcel ei = new ImportExcel(file, 10);  
  8.                 // 获取传入Excel文件的数据,根据传入参数类型,自动转换为对象  
  9.         List<User> list = ei.getDataList(User.class);  
  10.                 // 遍历数据,保存数据  
  11.         for (User user : list){  
  12.             try{  
  13.                 if ("true".equals(checkLoginName("", user.getLoginName()))){  
  14.                     user.setPassword(SystemService.entryptPassword("123456"));  
  15.                     BeanValidators.validateWithException(validator, user);  
  16.                     systemService.saveUser(user);  
  17.                     successNum++;  
  18.                 }else{  
  19.                     failureMsg.append("<br/>登录名 "+user.getLoginName()+" 已存在; ");  
  20.                     failureNum++;  
  21.                 }  
  22.             }catch(ConstraintViolationException ex){  
  23.                 failureMsg.append("<br/>登录名 "+user.getLoginName()+" 导入失败:");  
  24.                 List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");  
  25.                 for (String message : messageList){  
  26.                     failureMsg.append(message+"; ");  
  27.                     failureNum++;  
  28.                 }  
  29.             }catch (Exception ex) {  
  30.                 failureMsg.append("<br/>登录名 "+user.getLoginName()+" 导入失败:"+ex.getMessage());  
  31.             }  
  32.         }  
  33.         if (failureNum>0){  
  34.             failureMsg.insert(0",失败 "+failureNum+" 条用户,导入信息如下:");  
  35.         }  
  36.         addFlashMessage("已成功导入 "+successNum+" 条用户"+failureMsg);  
  37.     } catch (Exception e) {  
  38.         addFlashMessage("导入用户失败!失败信息:"+e.getMessage());  
  39.     }  
  40.     return "redirect:"+BaseController.ADMIN_PATH+"/sys/user/?repage";  
  41. }  

 

4、Excel 导入模板下载示例

 

Java代码    收藏代码
  1. public String importFileTemplate() {  
  2.     try {  
  3.                 String fileName = "用户数据导入模板.xlsx";  
  4.         List<User> list = Lists.newArrayList(); list.add(UserUtils.getUser(true));  
  5.                 // 第三个参数设置为“2”表示输出为导入模板(1:导出数据;2:导入模板)  
  6.         new ExportExcel("用户数据", User.class2).setDataList(list).write(response, fileName).dispose();  
  7.         return null;  
  8.     } catch (Exception e) {  
  9.         addFlashMessage("导出用户失败!失败信息:"+e.getMessage());  
  10.     }  
  11.     return "redirect:"+BaseController.ADMIN_PATH+"/sys/user/?repage";  
  12. }  

 

  

5、ExcelField定义说明:

 

 

Java代码    收藏代码
  1. /** 
  2.  * Copyright &copy; 2012-2013 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved. 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  */  
  6. package com.thinkgem.jeesite.common.utils.excel.annotation;  
  7.   
  8. import java.lang.annotation.ElementType;  
  9. import java.lang.annotation.Retention;  
  10. import java.lang.annotation.RetentionPolicy;  
  11. import java.lang.annotation.Target;  
  12.   
  13. /** 
  14.  * Excel注解定义 
  15.  * @author ThinkGem 
  16.  * @version 2013-03-10 
  17.  */  
  18. @Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})  
  19. @Retention(RetentionPolicy.RUNTIME)  
  20. public @interface ExcelField {  
  21.   
  22.     /** 
  23.      * 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”) 
  24.      */  
  25.     String value() default "";  
  26.       
  27.     /** 
  28.      * 导出字段标题 
  29.      */  
  30.     String title();  
  31.       
  32.     /** 
  33.      * 字段类型(0:导出导入;1:仅导出;2:仅导入) 
  34.      */  
  35.     int type() default 0;  
  36.   
  37.     /** 
  38.      * 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右) 
  39.      */  
  40.     int align() default 0;  
  41.       
  42.     /** 
  43.      * 导出字段字段排序(升序) 
  44.      */  
  45.     int sort() default 0;  
  46.   
  47.     /** 
  48.      * 如果是字典类型,请设置字典的type值 
  49.      */  
  50.     String dictType() default "";  
  51.       
  52.     /** 
  53.      * 反射类型 
  54.      */  
  55.     Class<?> fieldType() default Class.class;  
  56.       
  57. }  
 

 

 

 

 


package com.ruoyi.asset.utils; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excels; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.exception.BusinessException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.reflect.ReflectUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFDataValidation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.*; import java.util.stream.Collectors; import com.ruoyi.common.utils.StringUtils; /** * Copyright (C), CICDI-2021 * FileName: ExcelUtils * Author: wmy * Date: 2021/1/22 9:38 * Description: 智能资产-excel处理工具类 */ public class ExcelUtils<T> { private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); /** * Excel sheet最大行数,默认65536 */ public static final int sheetSize = 65536; /** * 工作表名称 */ private String sheetName; /** * 导出类型(EXPORT:导出数据;IMPORT:导入模板) */ private Excel.Type type; /** * 工作薄对象 */ private Workbook wb; /** * 工作表对象 */ private Sheet sheet; /** * 样式列表 */ private Map<String, CellStyle> styles; /** * 导入导出数据列表 */ private List<T> list; /** * 注解列表 */ private List<Object[]> fields; /** * 统计列表 */ private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); /** * 数字格式 */ private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); /** * 实体对象 */ public Class<T> clazz; public ExcelUtils(Class<T> clazz) { this.clazz = clazz; } public void init(List<T> list, String sheetName, Excel.Type type) { if (list == null) { list = new ArrayList<T>(); } this.list = list; this.sheetName = sheetName; this.type = type; createExcelField(); createWorkbook(); } /** * 对excel表单默认第一个索引名转换成list * * @param is 输入流 * @return 转换后集合 */ public List<T> importExcel(InputStream is) throws Exception { return importExcel(StringUtils.EMPTY, is); } /** * 对excel表单指定表格索引名转换成list * * @param sheetName 表格索引名 * @param is 输入流 * @return 转换后集合 */ public List<T> importExcel(String sheetName, InputStream is) throws Exception { this.type = Excel.Type.IMPORT; this.wb = WorkbookFactory.create(is); List<T> list = new ArrayList<T>(); Sheet sheet = null; if (StringUtils.isNotEmpty(sheetName)) { // 如果指定sheet名,则取指定sheet中的内容. sheet = wb.getSheet(sheetName); } else { // 如果传入的sheet名不存在则默认指向第1个sheet. sheet = wb.getSheetAt(0); } if (sheet == null) { throw new IOException("文件sheet不存在"); } int rows = sheet.getPhysicalNumberOfRows(); if (rows > 0) { // 定义一个map用于存放excel列的序号和field. Map<String, Integer> cellMap = new HashMap<String, Integer>(); // 获取表头 Row heard = sheet.getRow(1); 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. Field[] allFields = clazz.getDeclaredFields(); // 定义一个map用于存放列的序号和field. Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>(); for (int col = 0; col < allFields.length; col++) { Field field = allFields[col]; Excel attr = field.getAnnotation(Excel.class); if (attr != null && (attr.type() == Excel.Type.ALL || attr.type() == type)) { // 设置类的私有字段属性可访问. field.setAccessible(true); Integer column = cellMap.get(attr.name()); fieldsMap.put(column, field); } } for (int i = 2; i < rows; i++) { // 从第2行开始取数据,默认第一行是表头. Row row = sheet.getRow(i); T entity = null; for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet()) { Object val = this.getCellValue(row, entry.getKey()); // 如果不存在实例则新建. entity = (entity == null ? clazz.newInstance() : entity); // 从map中得到对应列的field. Field field = fieldsMap.get(entry.getKey()); // 取得类型,并根据对象类型设置值. Class<?> fieldType = field.getType(); if (String.class == fieldType) { String s = Convert.toStr(val); if (StringUtils.endsWith(s, ".0")) { val = StringUtils.substringBefore(s, ".0"); } else { String dateFormat = field.getAnnotation(Excel.class).dateFormat(); if (StringUtils.isNotEmpty(dateFormat)) { val = DateUtils.parseDateToStr(dateFormat, (Date) val); } else { val = Convert.toStr(val); } } } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) { val = Convert.toInt(val); } else if (Long.TYPE == fieldType || Long.class == fieldType) { val = Convert.toLong(val); } else if (Double.TYPE == fieldType || Double.class == fieldType) { val = Convert.toDouble(val); } else if (Float.TYPE == fieldType || Float.class == fieldType) { val = Convert.toFloat(val); } else if (BigDecimal.class == fieldType) { val = Convert.toBigDecimal(val); } else if (Date.class == fieldType) { if (val instanceof String) { val = DateUtils.parseDate(val); } else if (val instanceof Double) { val = DateUtil.getJavaDate((Double) val); } } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) { val = Convert.toBool(val, false); } if (StringUtils.isNotNull(fieldType)) { Excel attr = field.getAnnotation(Excel.class); String propertyName = field.getName(); if (StringUtils.isNotEmpty(attr.targetAttr())) { propertyName = field.getName() + "." + attr.targetAttr(); } else if (StringUtils.isNotEmpty(attr.readConverterExp())) { val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); } else if (StringUtils.isNotEmpty(attr.dictType())) { val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); } ReflectUtils.invokeSetter(entity, propertyName, val); } } list.add(entity); } } return list; } /** * 对list数据源将其里面的数据导入excel表单 * * @param list 导出数据集合 * @param sheetName 工作表的名称 * @return 结果 */ public AjaxResult exportExcel(List<T> list, String sheetName) { this.init(list, sheetName, Excel.Type.EXPORT); return exportExcel(); } /** * 对list数据源将其里面的数据导入excel表单 * * @param sheetName 工作表的名称 * @return 结果 */ public AjaxResult importTemplateExcel(String sheetName) { this.init(null, sheetName, Excel.Type.IMPORT); return exportExcel(); } /** * 对list数据源将其里面的数据导入excel表单 * * @return 结果 */ public AjaxResult exportExcel() { OutputStream out = null; try { // 取出一共有多少个sheet. double sheetNo = Math.ceil(list.size() / sheetSize); for (int index = 0; index <= sheetNo; index++) { createSheet(sheetNo, index); // 产生一行 Row row = sheet.createRow(0); int column = 0; // 写入各个字段的列头名称 for (Object[] os : fields) { Excel excel = (Excel) os[1]; this.createCell(excel, row, column++); } if (Excel.Type.EXPORT.equals(type)) { fillExcelData(index, row); addStatisticsRow(); } } String filename = encodingFilename(sheetName); out = new FileOutputStream(getAbsoluteFile(filename)); wb.write(out); return AjaxResult.success(filename); } catch (Exception e) { log.error("导出Excel异常{}", e.getMessage()); throw new BusinessException("导出Excel失败,请联系网站管理员!"); } finally { if (wb != null) { try { wb.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e1) { e1.printStackTrace(); } } } } /** * 填充excel数据 * * @param index 序号 * @param row 单元格行 */ public void fillExcelData(int index, Row row) { int startNo = index * sheetSize; int endNo = Math.min(startNo + sheetSize, list.size()); for (int i = startNo; i < endNo; i++) { row = sheet.createRow(i + 1 - startNo); // 得到导出对象. T vo = (T) list.get(i); int column = 0; for (Object[] os : fields) { Field field = (Field) os[0]; Excel excel = (Excel) os[1]; // 设置实体类私有属性可访问 field.setAccessible(true); this.addCell(excel, row, vo, field, column++); } } } /** * 创建表格样式 * * @param wb 工作薄对象 * @return 样式列表 */ private Map<String, CellStyle> createStyles(Workbook wb) { // 写入各条记录,每条记录对应excel表中的一行 Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); CellStyle style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setBorderRight(BorderStyle.THIN); style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBorderLeft(BorderStyle.THIN); style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBorderTop(BorderStyle.THIN); style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBorderBottom(BorderStyle.THIN); style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); Font dataFont = wb.createFont(); dataFont.setFontName("Arial"); dataFont.setFontHeightInPoints((short) 10); style.setFont(dataFont); styles.put("data", style); style = wb.createCellStyle(); style.cloneStyleFrom(styles.get("data")); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); Font headerFont = wb.createFont(); headerFont.setFontName("Arial"); headerFont.setFontHeightInPoints((short) 10); headerFont.setBold(true); headerFont.setColor(IndexedColors.WHITE.getIndex()); style.setFont(headerFont); styles.put("header", style); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); Font totalFont = wb.createFont(); totalFont.setFontName("Arial"); totalFont.setFontHeightInPoints((short) 10); style.setFont(totalFont); styles.put("total", style); style = wb.createCellStyle(); style.cloneStyleFrom(styles.get("data")); style.setAlignment(HorizontalAlignment.LEFT); styles.put("data1", style); style = wb.createCellStyle(); style.cloneStyleFrom(styles.get("data")); style.setAlignment(HorizontalAlignment.CENTER); styles.put("data2", style); style = wb.createCellStyle(); style.cloneStyleFrom(styles.get("data")); style.setAlignment(HorizontalAlignment.RIGHT); styles.put("data3", style); return styles; } /** * 创建单元格 */ public Cell createCell(Excel attr, Row row, int column) { // 创建列 Cell cell = row.createCell(column); // 写入列信息 cell.setCellValue(attr.name()); setDataValidation(attr, row, column); cell.setCellStyle(styles.get("header")); return cell; } /** * 设置单元格信息 * * @param value 单元格值 * @param attr 注解相关 * @param cell 单元格信息 */ public void setCellVo(Object value, Excel attr, Cell cell) { if (Excel.ColumnType.STRING == attr.cellType()) { cell.setCellValue(StringUtils.isNull(value) ? attr.defaultValue() : value + attr.suffix()); } else if (Excel.ColumnType.NUMERIC == attr.cellType()) { cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); } } /** * 创建表格样式 */ public void setDataValidation(Excel attr, Row row, int column) { if (attr.name().indexOf("注:") >= 0) { sheet.setColumnWidth(column, 6000); } else { // 设置列宽 sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); row.setHeight((short) (attr.height() * 20)); } // 如果设置了提示信息则鼠标放上去提示. if (StringUtils.isNotEmpty(attr.prompt())) { // 这里默认设了2-101列提示. setXSSFPrompt(sheet, "", attr.prompt(), 1, 100, column, column); } // 如果设置了combo属性则本列只能选择不能输入 if (attr.combo().length > 0) { // 这里默认设了2-101列只能选择不能输入. setXSSFValidation(sheet, attr.combo(), 1, 100, column, column); } } /** * 添加单元格 */ public Cell addCell(Excel attr, Row row, T vo, Field field, int column) { Cell cell = null; try { // 设置行高 row.setHeight((short) (attr.height() * 20)); // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. if (attr.isExport()) { // 创建cell cell = row.createCell(column); int align = attr.align().value(); cell.setCellStyle(styles.get("data" + (align >= 1 && align <= 3 ? align : ""))); // 用于读取对象中的属性 Object value = getTargetValue(vo, field, attr); String dateFormat = attr.dateFormat(); String readConverterExp = attr.readConverterExp(); String separator = attr.separator(); String dictType = attr.dictType(); if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) { cell.setCellValue(DateUtils.parseDateToStr(dateFormat, (Date) value)); } else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) { cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); } else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) { cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator)); } else if (value instanceof BigDecimal && -1 != attr.scale()) { cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString()); } else { // 设置列类型 setCellVo(value, attr, cell); } addStatisticsData(column, Convert.toStr(value), attr); } } catch (Exception e) { log.error("导出Excel失败{}", e); } return cell; } /** * 设置 POI XSSFSheet 单元格提示 * * @param sheet 表单 * @param promptTitle 提示标题 * @param promptContent 提示内容 * @param firstRow 开始行 * @param endRow 结束行 * @param firstCol 开始列 * @param endCol 结束列 */ public void setXSSFPrompt(Sheet sheet, String promptTitle, String promptContent, int firstRow, int endRow, int firstCol, int endCol) { DataValidationHelper helper = sheet.getDataValidationHelper(); DataValidationConstraint constraint = helper.createCustomConstraint("DD1"); CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); DataValidation dataValidation = helper.createValidation(constraint, regions); dataValidation.createPromptBox(promptTitle, promptContent); dataValidation.setShowPromptBox(true); sheet.addValidationData(dataValidation); } /** * 设置某些列的值只能输入预制的数据,显示下拉框. * * @param sheet 要设置的sheet. * @param textlist 下拉框显示的内容 * @param firstRow 开始行 * @param endRow 结束行 * @param firstCol 开始列 * @param endCol 结束列 * @return 设置好的sheet. */ public void setXSSFValidation(Sheet sheet, String[] textlist, int firstRow, int endRow, int firstCol, int endCol) { DataValidationHelper helper = sheet.getDataValidationHelper(); // 加载下拉列表内容 DataValidationConstraint constraint = helper.createExplicitListConstraint(textlist); // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); // 数据有效性对象 DataValidation dataValidation = helper.createValidation(constraint, regions); // 处理Excel兼容性问题 if (dataValidation instanceof XSSFDataValidation) { dataValidation.setSuppressDropDownArrow(true); dataValidation.setShowErrorBox(true); } else { dataValidation.setSuppressDropDownArrow(false); } sheet.addValidationData(dataValidation); } /** * 解析导出值 0=男,1=女,2=未知 * * @param propertyValue 参数值 * @param converterExp 翻译注解 * @param separator 分隔符 * @return 解析后值 * @throws Exception */ public static String convertByExp(String propertyValue, String converterExp, String separator) throws Exception { StringBuilder propertyString = new StringBuilder(); try { String[] convertSource = converterExp.split(","); for (String item : convertSource) { String[] itemArray = item.split("="); if (StringUtils.containsAny(separator, propertyValue)) { for (String value : propertyValue.split(separator)) { if (itemArray[0].equals(value)) { propertyString.append(itemArray[1] + separator); break; } } } else { if (itemArray[0].equals(propertyValue)) { return itemArray[1]; } } } } catch (Exception e) { throw e; } return StringUtils.stripEnd(propertyString.toString(), separator); } /** * 反向解析值 男=0,女=1,未知=2 * * @param propertyValue 参数值 * @param converterExp 翻译注解 * @param separator 分隔符 * @return 解析后值 * @throws Exception */ public static String reverseByExp(String propertyValue, String converterExp, String separator) throws Exception { StringBuilder propertyString = new StringBuilder(); String[] convertSource = converterExp.split(","); for (String item : convertSource) { String[] itemArray = item.split("="); if (StringUtils.containsAny(separator, propertyValue)) { for (String value : propertyValue.split(separator)) { if (itemArray[1].equals(value)) { propertyString.append(itemArray[0] + separator); break; } } } else { if (itemArray[1].equals(propertyValue)) { return itemArray[0]; } } } return StringUtils.stripEnd(propertyString.toString(), separator); } /** * 解析字典值 * * @param dictValue 字典值 * @param dictType 字典类型 * @param separator 分隔符 * @return 字典标签 */ public static String convertDictByExp(String dictValue, String dictType, String separator) throws Exception { return DictUtils.getDictLabel(dictType, dictValue, separator); } /** * 反向解析值字典值 * * @param dictLabel 字典标签 * @param dictType 字典类型 * @param separator 分隔符 * @return 字典值 */ public static String reverseDictByExp(String dictLabel, String dictType, String separator) throws Exception { return DictUtils.getDictValue(dictType, dictLabel, separator); } /** * 合计统计信息 */ private void addStatisticsData(Integer index, String text, Excel entity) { if (entity != null && entity.isStatistics()) { Double temp = 0D; if (!statistics.containsKey(index)) { statistics.put(index, temp); } try { temp = Double.valueOf(text); } catch (NumberFormatException e) { } statistics.put(index, statistics.get(index) + temp); } } /** * 创建统计行 */ public void addStatisticsRow() { if (statistics.size() > 0) { Cell cell = null; Row row = sheet.createRow(sheet.getLastRowNum() + 1); Set<Integer> keys = statistics.keySet(); cell = row.createCell(0); cell.setCellStyle(styles.get("total")); cell.setCellValue("合计"); for (Integer key : keys) { cell = row.createCell(key); cell.setCellStyle(styles.get("total")); cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); } statistics.clear(); } } /** * 编码文件名 */ public String encodingFilename(String filename) { filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx"; return filename; } /** * 获取下载路径 * * @param filename 文件名称 */ public String getAbsoluteFile(String filename) { String downloadPath = RuoYiConfig.getDownloadPath() + filename; File desc = new File(downloadPath); if (!desc.getParentFile().exists()) { desc.getParentFile().mkdirs(); } return downloadPath; } /** * 获取bean中的属性值 * * @param vo 实体对象 * @param field 字段 * @param excel 注解 * @return 最终的属性值 * @throws Exception */ private Object getTargetValue(T vo, Field field, Excel excel) throws Exception { Object o = field.get(vo); if (StringUtils.isNotEmpty(excel.targetAttr())) { String target = excel.targetAttr(); if (target.indexOf(".") > -1) { String[] targets = target.split("[.]"); for (String name : targets) { o = getValue(o, name); } } else { o = getValue(o, target); } } return o; } /** * 以类的属性的get方法方法形式获取值 * * @param o * @param name * @return value * @throws Exception */ private Object getValue(Object o, String name) throws Exception { if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) { Class<?> clazz = o.getClass(); Field field = clazz.getDeclaredField(name); field.setAccessible(true); o = field.get(o); } return o; } /** * 得到所有定义字段 */ private void createExcelField() { this.fields = new ArrayList<Object[]>(); List<Field> tempFields = new ArrayList<>(); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); for (Field field : tempFields) { // 单注解 if (field.isAnnotationPresent(Excel.class)) { putToField(field, field.getAnnotation(Excel.class)); } // 多注解 if (field.isAnnotationPresent(Excels.class)) { Excels attrs = field.getAnnotation(Excels.class); Excel[] excels = attrs.value(); for (Excel excel : excels) { putToField(field, excel); } } } this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); } /** * 放到字段集合中 */ private void putToField(Field field, Excel attr) { if (attr != null && (attr.type() == Excel.Type.ALL || attr.type() == type)) { this.fields.add(new Object[] { field, attr }); } } /** * 创建一个工作簿 */ public void createWorkbook() { this.wb = new SXSSFWorkbook(500); } /** * 创建工作表 * * @param sheetNo sheet数量 * @param index 序号 */ public void createSheet(double sheetNo, int index) { this.sheet = wb.createSheet(); this.styles = createStyles(wb); // 设置工作表的名称. if (sheetNo == 0) { wb.setSheetName(index, sheetName); } else { wb.setSheetName(index, sheetName + index); } } /** * 获取单元格值 * * @param row 获取的行 * @param column 获取单元格列号 * @return 单元格值 */ public Object getCellValue(Row row, int column) { if (row == null) { return row; } Object val = ""; try { Cell cell = row.getCell(column); if (StringUtils.isNotNull(cell)) { if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) { val = cell.getNumericCellValue(); if (DateUtil.isCellDateFormatted(cell)) { val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 } else { if ((Double) val % 1 > 0) { val = new BigDecimal(val.toString()); } else { val = new DecimalFormat("0").format(val); } } } else if (cell.getCellType() == CellType.STRING) { val = cell.getStringCellValue(); } else if (cell.getCellType() == CellType.BOOLEAN) { val = cell.getBooleanCellValue(); } else if (cell.getCellType() == CellType.ERROR) { val = cell.getErrorCellValue(); } } } catch (Exception e) { return val; } return val; } } 我该怎么修改
最新发布
11-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值