Java导出数据到Excel文件

  • 前言
  • 如何导出
    • 导出的基本流程
  • 测试结果
    • 测试数据及结果
    • 测试代码
  • ExcelExportUtil.class
  • 遇到的问题
    • lombok的问题
      • 解决
    • Cell.setCellValue()的参数需要具体的类型
      • 解决方法
  • 总结

前言

通过上一篇文章: Java导入Excel文档到数据库
我们了解到了有关使用Java操作Excel文件的基本流程及相关的类
那么现在我们就要做一下将相关的数据导出成Excel文件给用户了。

如何导出

导入的流程我们已经清楚了:
读取Excel文件生成工作簿(Workbook)对象
获取表(Sheet)对象
遍历行所有的单元格(Cell)

获取一行数据(Row)
生成一个相应的对象
数据库存储

重复上述操作,直至遍历完所有的行
大致可以理解为将表里的所有Row变为一个List

那么导出的逻辑就很简单了,反过来就行了:
List变为表里面所有Row

导出的基本流程

1、数据库操作获取一个List
2、创建一个Workbook对象
3、由Workbook获取一个Sheet对象
4、遍历List集合

    为每一个对象创建一个Row对象遍历属性集合,为每一个属性值创建一个Cell将对象里的值设置进Cell中

测试结果

这里就不对使用到类再进行赘述了,前言里提到的Java导入Excel文档到数据库一文中,已经说过了。相关的类也在里面,代码部分我只放测试与工具类,其他的在导入里面。

测试数据及结果


导出结果 - 默认排序

指定顺序

测试代码

import org.apache.poi.ss.usermodel.*;import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;/*** @author 三文鱼先生* @title* @description* @date 2022/8/11**/
public class TestForParseExcel {public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, IOException {Map<String , String> map = new HashMap<>();//表头与键值对的映射关系map.put("学号", "id");map.put("姓名" , "name");map.put("科目" , "subject");map.put("分数" , "grade");map.put("班级" , "className");map.put("任课教师" , "teacher");map.put("是否缺课" , "cutClass");List<Student> list = null;try(//这里面的对象会自动关闭InputStream in = new FileInputStream(new File("F:\\学习记录\\测试数据\\Student.xlsx"));//用流来构建工作簿对象Workbook workbook = ExcelImportSheet.getTypeFromExtends(in , "Student.xlsx")) {//根据名称获取单张表对象 也可以使用getSheetAt(int index)获取单张表的对象 获取第一张表Sheet sheet = workbook.getSheetAt(0);list = ExcelImportSheet.getListFromExcel(sheet , Student.class , map);for (Student student : list) {//底层数据库操作 insert什么的System.out.println(student.toString());}}catch(IOException exception) {exception.printStackTrace();} catch (Exception e) {e.printStackTrace();}finally {//写着好看的}Map<String , String> map1 = new HashMap<>();//表头与键值对的映射关系map1.put("id", "学号");map1.put("name" , "姓名");map1.put("subject" , "科目");map1.put("grade" , "分数");map1.put("className" , "班级");map1.put("teacher" , "任课老师");map1.put("cutClass" , "是否缺课");//这里是指定表头顺序 记得把方法参数的null改为orderList
//        List<String> orderList = new ArrayList<>();
//        orderList.add("id");
//        orderList.add("name");
//        orderList.add("subject");
//        orderList.add("grade");
//        orderList.add("className");
//        orderList.add("teacher");
//        orderList.add("cutClass");//导出逻辑 这里的list是从导入里面哪来的 map1与map不一样 orderList这里为空Workbook workbook = ExcelExportUtil.createWorkbook(list , map1 , 1 , "学生信息表" , null);System.out.println("导出文件位置为:" + ExcelExportUtil.store("F:\\学习记录\\测试数据\\导出excel测试" , workbook , 1));}}

ExcelExportUtil.class

导出工具类,这里值得注意的是:
Map的映射方式是 属性-表头名称
,而导入的映射方式是:表头名称 - 属性
Map中的Key是不一样的。

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author 三文鱼先生* @title* @description 用于导出数据* @date 2022/8/23**/
public class ExcelExportUtil {/*** @description 考虑到下载方式的不同 这里细化成只获取一个workBook 格式为默认 无格式* @author 三文鱼先生* @date 10:47 2022/8/26* @param list 需要存储为excel的对象集合* @param map 键值对映射 属性 - 表头字段  类似于: name - 姓名* @param type 生成workbook的类型* @param tableName 生成Sheet的名称* @param orderList 表头顺序对应的属性list* @return org.apache.poi.ss.usermodel.Workbook**/public static <T>Workbook createWorkbook(List<T> list , //数据库查询的返回ListMap<String , String> map , //表头映射Integer type , //生成workbook的类型 0 - xls 其他-xlsxString tableName , //表名List<String> orderList //排序的List 为空 则使用默认的顺序) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {//工作簿Workbook workbook = getWorkbookByType(type);//单个表Sheet sheet = workbook.createSheet(tableName);//orderList 表头顺序,可以为空if(orderList == null || orderList.size() == 0) {orderList = new ArrayList<>();//获取map映射的顺序for (Map.Entry<String, String> mapEntry : map.entrySet()) {orderList.add(mapEntry.getKey());}}//每列对应的属性参数List<Class> typeClassList = getParamsType(list.get(0).getClass(), orderList);//设置表头的值Row headRow = sheet.createRow(0);for (int i = 0; i < orderList.size(); i++) {Cell cell = headRow.createCell(i);//设置单元格的属性cell.setCellType(CellType.STRING);cell.setCellValue(map.get(orderList.get(i)));}int index = 1;//单元行Row dataRow = null;//单元格Cell dataCell = null;//遍历Listfor (T t : list) {//获取一行dataRow = sheet.createRow(index);//遍历表头对应属性,给一行数据设置值for (int j = 0; j < orderList.size(); j++) {//获取一个单元格dataCell = dataRow.createCell(j);//根据对应列的属性 设置对应的值类型及值setCellValueTypeAndValue(dataCell , typeClassList.get(j) ,t.getClass().getMethod(getGetterMethodName(orderList.get(j)) , new Class[]{}).invoke(t , new Class[]{}));}//行下标后移index++;}//设置值return workbook;}/*** @description  存储到对应的文件夹下* @author 三文鱼先生* @date 10:44 2022/8/26* @param path 文件夹路径* @param workbook 存储的工作簿对象* @param type 存储的类型* @return void**/public static String store(String path , Workbook workbook , Integer type) throws IOException {path = path +File.separator +getNowDate()+ workbook.getSheetName(0) + getExtensionByType(type);try(OutputStream outputStream = new FileOutputStream(new File(path))){workbook.write(outputStream);} catch (FileNotFoundException e) {e.printStackTrace();}catch (Exception e) {e.printStackTrace();} finally {workbook.close();}return path;}/*** @description 根据type获取对应文件后缀 0-xls 其他xlsx 默认为xls* @author 三文鱼先生* @date 10:43 2022/8/26* @param type 类型* @return java.lang.String**/public static String getExtensionByType(Integer type) {if(type == null || type == 0)return ".xls";elsereturn ".xlsx";}/*** @description 根据所给的type获取对应的工作簿 0-HSSFWorkbook 其他-XSSFWorkbook* @author 三文鱼先生* @date 10:41 2022/8/26* @param type 类型* @return org.apache.poi.ss.usermodel.Workbook**/public static Workbook getWorkbookByType(Integer type) {if(type == null || type == 0)return new HSSFWorkbook();elsereturn new XSSFWorkbook();}/*** @description 根据属性名称获取对应的get方法* @author 三文鱼先生* @date 10:38 2022/8/26* @param param 属性名称* @return java.lang.String**/public static String getGetterMethodName(String param) {char[] chars = param.toCharArray();//首字母大写if(Character.isLowerCase(chars[0])) {chars[0] -= 32;}//拼接get方法return "get" + new String(chars);}/*** @description 根据属性的List获取对应的类型List* @author 三文鱼先生* @date 10:37 2022/8/26* @param cs 对应的类* @param paramsList 对应的属性list* @return java.util.List<java.lang.Class>**/public static List<Class> getParamsType(Class cs , List<String> paramsList) {List<Class> typeClass = new ArrayList<>();//对象的所有属性Field[] fields = cs.getDeclaredFields();//临时的属性 - 类型映射Map<String , Class> map = new HashMap();//获取属性名称及类型for (Field field : fields) {map.put(field.getName(), field.getType());}//遍历属性List获取对应的类型Listfor (String s : paramsList) {typeClass.add(map.get(s));}return typeClass;}/*** @description 根据对应的类型 给单元格设置类型和值* @author 三文鱼先生* @date 10:32 2022/8/26* @param cell 单元格* @param cs 属性的类型* @param o get方法获取到的对象* @return void**/public static  void setCellValueTypeAndValue(Cell cell , Class cs , Object o) {//这里没有日期类型 需要的自己加就行了if(Boolean.class.equals(cs) || boolean.class.equals(cs)) {//boolean类型cell.setCellType(CellType.BOOLEAN);cell.setCellValue((Boolean) o);} else if (int.class.equals(cs) ||Integer.class.equals(cs)) {//int类型cell.setCellType(CellType.NUMERIC);cell.setCellValue((Integer) o);} else if(double.class.equals(cs)||Double.class.equals(cs)) {//浮点数类型 也可以是float类型什么的cell.setCellType(CellType.NUMERIC);cell.setCellValue((Double) o);} else {//默认为字符串类型cell.setCellType(CellType.STRING);cell.setCellValue((String) o);}}/*** @description 获取当前时间的字符串* @author 三文鱼先生* @date 17:06 2022/8/26* @return java.lang.String**/public static String getNowDate() {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss");return simpleDateFormat.format(new Date());}
}

遇到的问题

lombok的问题

boolean属性自动生成的get方法问题。自动生成的方法为:getIs属性名,而不是我以为的get属性名称

解决

自己写一个该属性的get方法即可

Cell.setCellValue()的参数需要具体的类型

cell.setCellValue()的方法是需要具体的类型的
没有cell.setCellValue(Object o)方法,而是需要具体的类型。

我没找到使用Class和Object,将一个对象强转为指定Class对象的方法

解决方法

将强转和设置单元格类型,放到一起。也就是这样

总结

也是不难,不过需要时间。上述需要最应该优化的地方应该是在,
设置单元格的风格
表头字体可能需要加粗,
字符串包括什么敏感字符,单元格需要标红,
又或者是数字类型的数据超过什么值,需要显示黄色等等
但是由于每个人风格不一样,
所以还是读取完数据,生成了workbook,再拿workbook对象来设置好了。

另一个点就是,没有存储图片文件。不过估计也不难。

Java导出数据到Excel文件相关推荐

  1. java导出为excel文件_java导出数据到excel文件

    有的时候,将一些有用的数据导出到excel是很有必要的.比如说,我现在在做一个学校的在线教学平台,有一个需求是:将学生成绩导出到excel文件中去. 那怎样实现用java导出数据到excel文件呢?? ...

  2. java导出文件到excel文件怎么打开_Java导出数据到Excel文件

    Java导出数据到Excel文件需要的jar包:easypoi-0.1.3.jar, poi-3.7-20101029 package com.sais.inkaNet.reportStatistic ...

  3. java 从excel中读取数据_在Java中读取Excel文件的内容和导出数据到Excel文件中

    转自www.chianjavaworld.net 原作者:SonyMusic 读:rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr 在Java ...

  4. python输出数据到excel-python如何导出数据到excel文件

    python导出数据到excel文件的方法: 1.调用Workbook()对象中的add_sheet()方法wb = xlwt.Workbook() ws = wb.add_sheet('A Test ...

  5. php上传和导出excel文件,(进阶篇)使用PHP导入Excel和导出数据为Excel文件

    有时需要将Excel表格的数据导入到mysql数据库中,我们使用PHP的一个开源项目PHP-ExcelReader可以轻松实现Excel的导入. 1.导入XLS PHP-ExcelReader这是一个 ...

  6. PHP导出数据为excel文件

    在项目中开发后台时经常会遇到导出数据为excel文件的需求,这里以Thinkphp5框架作为基础封装了一个导出excel文件的函数,其他框架可以在此基础上做对应修改.适用于PHP5.6+. /*** ...

  7. php 数据导出到excel文件,PHP导出数据到excel文件

    下面介绍一个很另类的php导出数据到xls文件的方法,用到的函数有pack,iconv //上面三个自定义函数很重要,大家自行揣摩 function xlsBOF() { echo pack(&quo ...

  8. java导出数据到excel表格的最简单实现

    导出excel整理 开发中难免会遇到要导出数据到excel的,网上有很多方法,但是看起来都很复杂的样子,写得又非常多代码,让人望而止步.我做一个简单的导出excel表格功能.这是我在工作上用到的. 1 ...

  9. java 前端导出exvel_java导出数据到Excel文件 前端进行下载

    /** * 导出宿舍人员信息 Excel文件 * @param type * @param id * @param request * @param response * @return * @thr ...

最新文章

  1. LRU(Least Recently Used)算法的理解
  2. windows-DLL注入
  3. Matlab图片改颜色通道不改名存储
  4. 【Tensorflow】打印输出tensor张量和变量的方法
  5. python命名实体识别工具_Day14:使用斯坦福 NER 软件包实现你自己的命名实体识别器(Named Entity Recognition,NER)...
  6. from_子句-内连接-左连接-右连接
  7. apk改之理 java源码_ApkIDE改之理最新版+环境包下载
  8. 酒店返现应用评测: 企鹅竟然没有模仿?
  9. 优质数据平台如何打造?从网易云音乐看内容生态的运营法则
  10. win10设置计算机关机时间,win10怎样固定时间关机_win10怎样设置电脑关机时间设置...
  11. 电脑桌面的快捷方式的字体有背景颜色,怎么修改?
  12. 你的数据库到底应该如何存储密码?
  13. 什么是AT指令,AT指令是什么
  14. 视频号主页,实现一键添加个人微信功能,留客更方便,真香
  15. NLP(七):前馈神经网络基础回顾(NN模型及其正则化,dropout,各种梯度求解算法等模型优化策略)
  16. JAVA:【基础三】split忽略中英文的符号区别
  17. 使用gcc的-E -P选项展开源代码中的宏
  18. Access 2003之控件使用
  19. Automa实现PowerBI大屏滚动播放
  20. linux服务器log日志通过python统计生成图表(LOG日志统计一)

热门文章

  1. python计算十年平均录取率_如何在Python中使用Pandas计算多年平均值
  2. HD44780http://blog.sina.com.cn/s/blog_61b6e08b01016xif.html
  3. 解决ViVO 手机安装APP失败问题
  4. 使用vscode remote ssh功能远程连接服务器或树莓派时,报错Setting up SSH tunnel的终极解决办法,全网仅此一份
  5. 安卓虚拟机_VMOS虚拟大师-独立的安卓虚拟机系统(已ROOT)「安卓」
  6. og协议-有利于SNS网站分享
  7. echarts饼图圆环图数据为0时字体重叠
  8. 【教程】百度地图AK申请指南(PM2.5指导版)
  9. dnf一直接收服务器信息失败怎么办,dnf接收频道信息失败
  10. JS数字区间比较大小的写法