java实现数据的Excel导出, 自定义导出字段, 转换字典值

第一版代码:
基础功能跳转此文章java自定义Excel导出工具:

简介

新增功能:

  1. 添加自定义字段导出功能, 用户可以选择字段进行导出
  2. 将字典类型数据进行转换(如:0=女,1=男, 将0转换为女, 1转换为男)
  3. 添加表头格式
  4. 随机文件名称, 防止多次导出时文件覆盖问题
实现代码

Excel注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel {/*** 导出到Excel中的名字*/String name() default "";/*** 日期格式, 如: yyyy-MM-dd*/String dateFormat() default "";/*** 字典的key值*/String dictKey() default "";/*** 读取内容转表达式 (如: 0=男,1=女,2=未知)*/String dictExp() default "";
}

Excel的导出工具类

/*** Excel的工具类*/
public class ExcelUtil<T> {/*** 工作薄*/private Workbook wb;/*** 工作表*/private Sheet sheet;/*** 需要导出的数据*/private List<T> exportList;/*** 对象的class对象*/private Class<T> clazz;/*** 被选中需要导出的字段名称*/private Map<String, Object> checkedFieldsName;/*** 被选中需要导出的字段对象*/private List<Field> checkedFields;/*** 包含需要字典转换的字段对象*/private List<Field> fieldsContainDict;/*** 对象中的字典值*/private Map<String, Map<String, String>> dicts;private ExcelUtil(){}public ExcelUtil(Class<T> clazz){this.clazz = clazz;}/**** @param list* @param sheetName* @param fieldsName*/public void exportExcel(List<T> list, Map<String, Object> fieldsName, String sheetName){// 初始化数据init(list, sheetName, fieldsName);// 转换字典值try {convertDict();} catch (IllegalAccessException e) {e.printStackTrace();}// sheet第一行加入名称数据createTopRow();// sheet其他行,添加目标数据try {createOtherRow();} catch (IllegalAccessException e) {e.printStackTrace();}// 导出wbtry(OutputStream outFile = new FileOutputStream(generateFileName())){wb.write(outFile);} catch (IOException e) {e.printStackTrace();} finally {try {wb.close();} catch (IOException e) {e.printStackTrace();}}}/*** 添加导出数据*/private void createOtherRow() throws IllegalAccessException {for (int rowNum = 1; rowNum <= exportList.size(); rowNum++) {Row row = sheet.createRow(rowNum);T t = exportList.get(rowNum - 1);for (int colNum = 0; colNum < checkedFields.size(); colNum++) {Cell cell = row.createCell(colNum);Field field = checkedFields.get(colNum);field.setAccessible(true);// 单元格设置值addCell(cell, field, t);}}}/*** 单元格中添加数据** @param cell  单元格* @param field 字段* @param t     list中的一条数据*/private void addCell(Cell cell, Field field, T t) throws IllegalAccessException {Class<?> fieldType = field.getType();if (String.class == fieldType) {cell.setCellValue((String) field.get(t));} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {cell.setCellValue((Integer) field.get(t));} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {cell.setCellValue((Long) field.get(t));} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {cell.setCellValue((Double) field.get(t));} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {cell.setCellValue((Float) field.get(t));} else if (Date.class == fieldType) {String dateFormat = field.getAnnotation(Excel.class).dateFormat();cell.setCellValue(dateFormat((Date) field.get(t), dateFormat));}}/*** 时间格式转换* @param date 日期* @param dateFormat 日期格式* @return*/private String dateFormat(Date date, String dateFormat) {if (dateFormat == null || "".equals(dateFormat)) {dateFormat = "yyyy-MM-dd HH:mm:ss";}SimpleDateFormat df = new SimpleDateFormat(dateFormat);return df.format(date);}/*** sheet第一行加入名称数据*/private void createTopRow() {Row row = sheet.createRow(0);Map<String, CellStyle> styles = createStyles(wb);for (int index = 0; index < checkedFields.size(); index++) {Cell cell = row.createCell(index);cell.setCellValue(checkedFields.get(index).getAnnotation(Excel.class).name());System.out.println(styles.get("header"));cell.setCellStyle(styles.get("header"));}}/*** 转换字典值*     将数据中字典值转化为对应的值(注:字典值应为String格式)*/private void convertDict() throws IllegalAccessException {for (Field field : fieldsContainDict) {Excel annotation = field.getAnnotation(Excel.class);String dictKey = annotation.dictKey();field.setAccessible(true);for (T t : exportList) {// 获取字段值String o = (String) field.get(t);field.set(t, dicts.get(dictKey).get(o));}}}/*** 将数据导出Excel** @param list 需要导出的数据* @param sheetName 工作表名称*/public void exportExcel(List<T> list, String sheetName){exportExcel(list, null, sheetName);}/*** 将数据导出Excel** @param list 需要导出的数据*/public void exportExcel(List<T> list) {exportExcel(list, null, "sheet");}/*** 初始化*/public void init(List<T> list ,String sheetName,  Map<String, Object> fieldsName){this.checkedFieldsName = fieldsName;this.exportList = list;// 初始化导出数据initExportList();// 初始化工作薄initWorkbook();// 初始化工作表initSheet(sheetName);// 初始化checkedFields, fieldsContainDictinitFields();// 根据注解生成生成字典generateObjDict();}/*** 初始化导出数据*/private void initExportList(){// 防止导出过程中出现空指针if(Objects.isNull(this.exportList)) {this.exportList = new ArrayList<>();}}/*** 初始化工作簿*/private void initWorkbook(){this.wb = new SXSSFWorkbook();}/*** 初始化工作表*/private void initSheet(String sheetName){this.sheet = wb.createSheet(sheetName);}/*** 初始化checkedFields, fieldsContainDict*     fieldsContainDict含有字典表达式的字段*     checkedFields用户选中的字段*        1.如果checkedFieldsName没有定义(未自定义导出字段),所有字段全部导出*        2.如果checkedFieldsName进行了定义,根据定义字段进行导出*/private void initFields(){// 获取对象所有字段对象Field[] fields = clazz.getDeclaredFields();// 过滤出checkedFieldsthis.checkedFields = Arrays.asList(fields).stream().filter(item -> {if(!Objects.isNull(this.checkedFieldsName)) {if (item.isAnnotationPresent(Excel.class)) {return checkedFieldsName.containsKey(item.getName());}} else {return item.isAnnotationPresent(Excel.class);}return false;}).collect(Collectors.toList());// 过滤出fieldsContainDictfor (Field declaredField : clazz.getDeclaredFields()) {if(declaredField.getAnnotation(Excel.class) != null) {System.out.println(declaredField.getAnnotation(Excel.class).dictExp());}}this.fieldsContainDict = Arrays.asList(clazz.getDeclaredFields()).stream().filter(item -> !"".equals(item.getAnnotation(Excel.class) != null? item.getAnnotation(Excel.class).dictExp() : "")).collect(Collectors.toList());}/*** 通过扫描字段注解生成字典数据*/private void generateObjDict(){if(fieldsContainDict.size() == 0) {return;}if(dicts == null) {dicts = new HashMap<>(); //  Map<String, List<Map<String, String>>>}for (Field field : fieldsContainDict) {String dictKey = field.getAnnotation(Excel.class).dictKey();String exps = field.getAnnotation(Excel.class).dictExp();String[] exp = exps.split(",");Map<String, String> keyV = new HashMap<>();dicts.put(dictKey, keyV);for (String s : exp) {String[] out = s.split("=");keyV.put(out[0], out[1]);}System.out.println("字典值:"+ dicts);}}/*** 创建表格样式** @param wb 工作薄对象* @return 样式列表*/private Map<String, CellStyle> createStyles(Workbook wb){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);return styles;}/*** 生成随机名称,防止文件复写* @return*/private String generateFileName(){return "D:\\" + UUID.randomUUID().toString().replace("-", "") + ".xlsx";}
}
使用方法

将对象加上工具类需要的注解:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {@Excel(name = "姓名")private String name;@Excel(name = "年龄")private Integer age;@Excel(name = "出生日期", dateFormat = "yyyy-MM-dd")private Date birthday;@Excel(name = "性别", dictKey = "sex", dictExp = "1=男,2=女")private String sex;
}

测试字典转换

public static void main(String[] args) {ArrayList<Student> data = new ArrayList<>();Student student = new Student();student.setName("tom");student.setAge(19);student.setSex("1");student.setBirthday(new Date());data.add(student);ExcelUtil<Student> util = new ExcelUtil<>(Student.class);util.exportExcel(data, "人员信息表");
}

输出结果:


结果可以看出, 已将1转换为


测试选择字段导出:
若不自定义导出的字段, 工具将会把所有带有Excel注解的字段进行导出, 如上方所示。
当输入导出字段时,才能根据定义的字段进行导出,实现如下:

public static void main(String[] args) {ArrayList<Student> data = new ArrayList<>();Student student = new Student();student.setName("tom");student.setAge(19);student.setSex("1");student.setBirthday(new Date());data.add(student);// 需要导出字段的名称,放入map的key中即可(这里只导出姓名和性别)Map<String, Object> fieldsName = new HashMap<>();fieldsName.put("name", null);fieldsName.put("sex", null);ExcelUtil<Student> util = new ExcelUtil<>(Student.class);// 将fieldsName放入方法中util.exportExcel(data, fieldsName,"人员信息表");
}

java实现数据的Excel导出, 自定义导出字段, 转换字典值相关推荐

  1. vue+elementui表格前端导出excel以及自定义导出样式

    vue+elementui表格前端导出excel以及自定义导出样式 项目遇到前端自己导出表格,我自己把后端给我的数据处理了一波,合并重复列啊,以及表头合并啊.可没想到导出竟然也要前端自己来弄,于是乎请 ...

  2. java poi-ooxml 3.17 excel通用导入导出

    java 使用poi-ooxml 3.17 excel的通用导入导出,导出的样式未做处理,可自行处理 可以在csdn下载或者在gitHub( https://github.com/aojd/excel ...

  3. PHP 利用PHPExcel到处数据到Excel;还有导出数据乱码的解决方案。

    PHP 利用PHPExcel到处数据到Excel:还有导出数据乱码的解决方案. 参考文章: (1)PHP 利用PHPExcel到处数据到Excel:还有导出数据乱码的解决方案. (2)https:// ...

  4. Java将数据写入Excel

    引入Maven依赖: <dependency><groupId>org.apache.poi</groupId><artifactId>poi</ ...

  5. java代码_Java:java五行代码实现Excel的快速导出

    通过Java进行excel导出,听着似乎有那么一点点的意思,也貌似很简单的样子(实事也很简单),究竟该怎么操作呢?但是如何进行操作呢,先看代码 再看效果 EasyExcel 本案例用到的框架是阿里推出 ...

  6. java导数据到Excel

    侵删.不足之处请谅解. 1,Excel导出工具类 package cn.ljs.util;import org.apache.poi.hssf.usermodel.HSSFCell; import o ...

  7. java table数据转excel,excel将数据转化成表格-如何将java数据转换成Excel表格

    excel 怎么把三列数据转换成一张表? 1.打开 OCR识别软然后单击"打开图像/PDF-"按钮 2弹出的"打开图窗口中,选择需要的扫描文件, 3.然后单击" ...

  8. java txt数据导入excel,java导入excle文件《如何用java 将txt数据导入excel》

    如何用java 将txt数据导入excel 代码如下: import java.io.*; import jxl.*; import jxl.write.*; public class CreateX ...

  9. java Clob转CLOB_Java获取Oracle中CLOB字段转换成String

    Java获取Oracle中CLOB字段转换成String : try {PreparedStatement stmt = session.connection().prepareStatement(s ...

最新文章

  1. 关于二叉树的链表表示的一个问题
  2. pytorch 之手写数字生成网络
  3. syslog介绍-CS架构来采集系统日志
  4. mysql like_MySQL LIKE:模糊查询
  5. 小程序 onReachBottom 事件快速滑动时不触发的bug
  6. php模式设计之 观察者模式
  7. srt乱码字幕中文显示解决办法
  8. WKWebview的内存问题
  9. javascript学习心得
  10. 抖音小程序开发教程之 02 创建第一个hello world 小程序(教程含源码)
  11. 如何把项目上传到Gitee(全网最细)
  12. SPI应用——W25Q128串行FLASH
  13. 操作系统课程设计-二级文件系统,Linux平台版本,c语言
  14. 使用Ajax传用户信息数据到后端
  15. 20计算机数电实验四--编译器的门级建模
  16. [容斥 状压DP] HDU4997. Biconnected
  17. arcgis10.8深度学习介绍课程梳理
  18. 呕血整理JavaScript知识重点(面试复习必备)
  19. Windows 7RTM综合评述
  20. iOS接入网易易盾并实现

热门文章

  1. 女人最让男人伤心的10句话
  2. GeoTrellis 尝试(springboot + swagger + spark + GeoTrellis)
  3. 模式识别边肇祺第二章(一)
  4. 内部视频放送 |《Python安全攻防:渗透测试实战指南》知识星球
  5. 网页通过iframe嵌入百度地图API时自适应屏幕
  6. 2023 QS世界大学学科排名:中国大陆高校有32个学科进入世界前20,材料科学、化学、生物科学等表现优异 | 美通社头条...
  7. android 录像
  8. python DBSCAN聚类算法
  9. 如何解决超薄笔记本电脑的音频挑战?
  10. web前端-JavaScript构造函数创建对象