【Apache POI】Excel操作(八):Excel工具类的封装(终极版)
恋爱最珍贵的纪念品,从来就不是那些你送我的手表和项链,甚至也不是那些甜蜜的短信和合照。是你留在我身上的,如同河流留给山川的,那些你对我造成的改变。
有目录,不迷路
- 前言
- 代码开整
- 环境准备
- 正式开整
- 实体类集合本地导出excel
- 实体类集合浏览器导出excel
- 将excel读取成实体类集合
- 完整工具类代码
- 往期回顾
前言
在我的 《Excel读写》 专栏的往期关于excel如何读取和写入的系列博客中,分别给大家介绍了如何运用实体类集合生成一张excel表格、如何在本地导出excel表格、如何在浏览器端导出excel表格以及如何将excel表格中的数据读取成实体类集合。
但是,缺点在于代码量比较多。今天我们来统一将重复的逻辑抽成一个工具类方法,争取将以前几十行代码实现的功能几行来实现!!!
代码开整
环境准备
所需依赖:
<!-- xls(03) --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><!-- xlsx(07) --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version></dependency><!-- 日期格式化工具 --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10.1</version></dependency><!-- 测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
所需实体类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** @ClassName BookList* @Description 书单实体类* @Author 古阙月* @Date 2020/11/23 22:11* @Version 1.0*/
//lombok插件的注解
@Data // 若未使用lombok插件,请自行生成getter、setter以及toString方法
@AllArgsConstructor // 若未使用lombok插件,请自行生成有参构造方法
@NoArgsConstructor // 若未使用lombok插件,请自行生成无参构造方法
@Accessors(chain = true) // 开启链式编程
public class Book {/*** 书名*/private String bookName;/*** 作者*/private String author;/*** 时间*/private String dateTime;}
生成实体类集合的方法:
/*** 数据部分*/private List<Book> getData() {List<Book> list = new ArrayList<Book>();for (int i = 0; i < 10; i++) {Book book = new Book();book.setAuthor("路遥").setBookName("平凡的世界" + (i+1)).setDateTime(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));list.add(book);}return list;}
生成excel表格的列名数组:
/*** 列名部分*/private static final String[] rowNameArray = {"书名", "作者", "时间"};
用于写入和读取excel文件的路径:
/*** 需要写入excel的路径*/private static final String PATH = "D:\\IdeaProjects\\my_study_demo\\src\\main\\java\\excel\\all";
用于写入和读取excel文件的名称:
/*** 需要写入excel的文件名称*/private static final String FILENAME = "古阙月的书单03.xls";
正式开整
实体类集合本地导出excel
在这期博客【Apache POI】Excel操作(二):Excel本地写入基本操作的实现(进阶版)中已经很详细的介绍了如何运用实体类集合在本地导出excel文件,但可惜用了五十多行代码。
我们试着来用一下工具类方法:
/*** 用实体类集合生成Excel*/@Testpublic void writeExcelTest() throws Exception {// 生成一张工作簿Workbook workbook = ExcelUtil.getWorkBook(new HSSFWorkbook(), FILENAME, rowNameArray, getData());// 生成ExcelUtil.exportExcelLocal(workbook, PATH, FILENAME);System.out.println(FILENAME + "生成完毕!!!");}
运行得:
成功生成:
将几十行代码简化成几行代码,这就是造轮子的魅力!!!
完整的工具方法代码在最后!!!
实体类集合浏览器导出excel
在这期博客【Apache POI】Excel操作(三):Excel在浏览器端即Web端写入操作的实现中已经很详细的介绍了如何运用实体类集合在浏览器端导出excel文件,但是代码量也比较多竟然用了六七十行代码!!!
我们也来使用一下工具方法:
/*** 在浏览器导出excel*/@GetMapping("/exportExcel")public void exportExcelTest(HttpServletResponse response) {try {// 生成一张工作簿Workbook workbook = ExcelUtil.getWorkBook(new HSSFWorkbook(), FILENAME, rowNameArray, getData());// 导出ExcelUtil.exportExcelWeb(response, workbook, FILENAME);} catch (Exception e) {e.printStackTrace();}}
浏览器访问:
点开得:
如此的简洁,是不是很舒服?
当然,Web工程环境的搭建可以参照我这篇博客:
【Apache POI】Excel操作(一):Excel本地写入基本操作的实现
中<前期准备>章节给出的博客链接,此处就不多加赘述!
完整的工具方法代码在最后!!!
将excel读取成实体类集合
在这期博客【Apache POI】Excel操作(七):Excel数据的读取(进阶版)中已经很详细的介绍了如何将excel文件读取陈实体类集合,但是竟然用了八十多行代码,要是以后每次读取都用个八十多行代码还得了!
同样的,我们来使用一下工具方法:
/*** 读取excel成实体类集合*/@Testpublic void readExcelTest() throws Exception {/*** 获取excel工作簿*/FileInputStream fileInputStream = new FileInputStream(PATH + File.separator + FILENAME);Workbook workbook = new HSSFWorkbook(fileInputStream);// 得到实体类集合List<Object> entityListFromExcel = ExcelUtil.getEntityListFromExcel(new Book(), workbook);// 输出实体类集合entityListFromExcel.forEach(book -> {System.out.println(book);});}
运行:
读取成功,同样的八十多行代码竟用短短的几行代码就完成了!!!
完整的工具方法代码在最后!!!
完整工具类代码
此处免费给出完整的工具类代码:
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.joda.time.DateTime;import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** @ClassName ExcelUtil* @Description Excel工具类* @Author 古阙月* @Date 2020/11/20* @Version 1.0*/
public class ExcelUtil {/*** 生成一张Excel工作簿 - 注意列名数组和实体类集合中实体类的属性名称顺序一一对应* @param workbook 用以返回的Excel工作簿对象* @param sheetName 工作表名称* @param columnNameArray 列名数组* @param entityList 实体类集合* @return*/public static Workbook getWorkBook(Workbook workbook, String sheetName, String[] columnNameArray, List<?> entityList) throws Exception {// 创建工作表Sheet sheet = workbook.createSheet(sheetName);if (sheet != null) {/*** 列名部分*/Row columnNameRow = sheet.createRow(0); // 生成列名的这一行,也就是第一行if (columnNameRow != null) {for (int i = 0; i < columnNameArray.length; i++) {// 按顺序依次填值Cell cell = columnNameRow.createCell(i);if (cell != null) {cell.setCellValue(columnNameArray[i]);}}}/*** 数据部分*/for (int i = 0; i < entityList.size(); i++) {// 生成第 i+2 行,因为第一行是列名,所以是i+1,而不是iRow row = sheet.createRow(i + 1);if (row != null) {// 获取当前遍历得到的实体类Object entity = entityList.get(i);// 获取实体类的所有属性集合Field[] fields = entity.getClass().getDeclaredFields();// 遍历属性集合for (int j = 0; j < fields.length; j++) {// 私有属性访问授权fields[j].setAccessible(true);//填值Cell cell = row.createCell(j);if (cell != null) {cell.setCellValue(((String)fields[j].get(entity)));}}}}}return workbook;}/*** 本地根据路径和名称导出excel* @param workbook excel工作簿对象* @param path 路径* @param fileName 文件名*/public static void exportExcelLocal(Workbook workbook, String path, String fileName) throws Exception {FileOutputStream outputStream = new FileOutputStream(path + File.separator + fileName);workbook.write(outputStream);// 关流outputStream.close();}/*** 在浏览器端导出excel* @param response* @param workbook* @param fileName*/public static void exportExcelWeb(HttpServletResponse response, Workbook workbook, String fileName) {response.reset();response.setContentType("application/ms-excel;charset=UTF-8");try {response.addHeader("Content-Disposition", "attachment;filename=\""+ new String((fileName).getBytes("GBK"),"ISO8859_1") + "\"");OutputStream out = response.getOutputStream();// 写入workbook.write(out);out.flush();out.close();} catch (Exception e) {e.printStackTrace();}}/*** 读取excel获取到相应的实体类集合* @param object 需要转化成的对象* @param workbook 工作簿对象* @return*/public static List<Object> getEntityListFromExcel(Object object, Workbook workbook) throws Exception {// 用于返回数据的实体类集合List<Object> entityList = new ArrayList<>();// 获取反射对象Class<?> clazz = object.getClass();if (workbook != null) {// 获取工作表Sheet sheet = workbook.getSheetAt(0);if (sheet != null) {// 获取行数int rowNum = sheet.getPhysicalNumberOfRows();if (rowNum > 1) { // 第一行是列名for (int i = 1; i < rowNum; i++) { // 从第二行,也就是数据部分开始// 获取行Row row = sheet.getRow(i);if (row != null) {// 获取列数int cellNum = row.getPhysicalNumberOfCells();// 生成对象Object obj = clazz.newInstance();// 获取属性集合Field[] fields = clazz.getDeclaredFields();for (int j = 0; j < cellNum; j++) {// 获取列Cell cell = row.getCell(j);String cellValue = "";// 获取列对应的数据类型int cellType = cell.getCellType();switch (cellType) {case HSSFCell.CELL_TYPE_STRING: // 字符串类型cellValue = cell.getStringCellValue();break;case HSSFCell.CELL_TYPE_BLANK: // 空break;case HSSFCell.CELL_TYPE_BOOLEAN: // 布尔类型cellValue = String.valueOf(cell.getBooleanCellValue());break;case HSSFCell.CELL_TYPE_NUMERIC: // 数字if (HSSFDateUtil.isCellDateFormatted(cell)) { // 日期类型Date dateCellValue = cell.getDateCellValue();cellValue = new DateTime(dateCellValue).toString("yyyy-MM-dd HH:mm:ss");
// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// cellValue = format.format(dateCellValue);}else { // 普通数字// 转化成字符串,防止数字过长无法显示cell.setCellType(HSSFCell.CELL_TYPE_STRING);cellValue = String.valueOf(cell);
// cellValue = cell.getNumericCellValue();}break;case HSSFCell.CELL_TYPE_ERROR: // 类型错误throw new RuntimeException("类型错误!");}// 私有属性访问授权fields[j].setAccessible(true);// 往对象中放值fields[j].set(obj, cellValue);}// 添加entityList.add(obj);}}}}}return entityList;}
}
时间飞逝,关于Apache POI
对于Excel的操作就告一段落。下期博客将给大家带来Alibaba
提供的工具EasyExcel
,使用起来更加的方便,给大家打开新世界的大门,敬请期待哦!!!
往期回顾
以下是往期Excel操作的回顾:
【Apache POI】Excel操作(一):Excel本地写入基本操作的实现
【Apache POI】Excel操作(二):Excel本地写入基本操作的实现(进阶版)
【Apache POI】Excel操作(三):Excel在浏览器端即Web端写入操作的实现
【Apache POI】Excel操作(四):Excel大数据量的写入
【Apache POI】Excel操作(五):Excel数据的读取
【Apache POI】Excel操作(六):Excel计算公式的读取和使用
【Apache POI】Excel操作(七):Excel数据的读取(进阶版)
【Apache POI】Excel操作(八):Excel工具类的封装(终极版)相关推荐
- POI导出表格到浏览器工具类,poi工具类
POI导出表格到浏览器工具类 要封装的实体bean类 public class Question {private String id; //题目IDprivate String companyId; ...
- Apache POI组件操作Excel,制作报表(四)
Apache POI组件操作Excel,制作报表(四) 博客分类: 探索实践 ExcelApacheSpringMVCServlet 上一篇我们介绍了如何制作复杂报表的分析和设计,本篇结合Sprin ...
- Java操作大数据量Excel导入导出万能工具类(完整版)
Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...
- 利用若依@Excel注解导出PDF工具类
利用若依@Excel注解导出PDF工具类 1.pom依赖 <!--PDF导出--><dependency><groupId>com.itextpdf</gro ...
- Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布
Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布 摘要: jeasypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导 ...
- JEasyPoi 2.1.4 (Jeecg订制) 版本发布,Excel 和 Word 简易工具类
JEasyPoi 2.1.4 (jeecg订制)版本发布,EasyPoi Excel 和 Word 简易工具类 easypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 ...
- [实用][更新中]Java Apache POI 打印Word文档工具(含文本替换,动态表格功能)
[实用][更新中]Java Apache POI 打印Word文档工具(含文本替换,动态表格功能) 基于Apache POI对Word进行操作 一.基于Apache POI封装的word文档工具V1. ...
- 解决修改properties 属性文件存在缓存问题,附带操作properties文件工具类
2019独角兽企业重金招聘Python工程师标准>>> 在做项目的时候有些数据不一定需要在数据库管理,例如数据库连接,定时任务等等的配置..有时候需要动态修改这些数据,但在修改完后, ...
- java redis remove_最全的Java操作Redis的工具类
RedisUtil 当前版本:1.1 增加更全的方法,对以前的部分方法进行了规范命名,请放心替换成新版本. 介绍 最全的Java操作Redis的工具类,使用StringRedisTemplate实现, ...
- Java——Arrays类操作数组的工具类
JDK中提供了一个专门用于操作数组的工具类,即 Arrays 类,位于 Java.util 包中.该类提供了一系列方法来操作数组,如排序.复制.比较.填充等,用户直接调用这些方法即可,不需要自己编码实 ...
最新文章
- Matlab学习笔记——文件的打开与关闭
- javascript代码解释执行过程
- lfcp——PB使用
- 川农计算机网络题库,川农网院20秋《计算机网络》期末机考
- LeetCode 第 207 场周赛(245/4115,前5.95%)
- 心态很容易受别人影响_女人生宝宝也看年龄?这3个影响生育能力的因素,你得了解清楚...
- python代码注释规范-Python编程规范之注释
- adb shell 之 screenrecord
- python打包成exe
- 汇编语言 王爽 第四版 实验4
- 结合LayoutIt学习Bootstrap的探索
- 貂蝉待你玩转Java王者荣耀
- 呼吸灯在哪里设置苹果_苹果前呼吸灯在哪里设置
- 个人计算机更新主要基于,计算机基础知练识习题.doc
- 通信教程 | 常见串行通信基础原理
- OpenStack云计算平台部署 单节点
- 有关积分的不等式证明
- 【秋招纪实录】一篇特别正经的【无领导小组讨论】经验分享
- ribbon 远程调用工具(Spring Cloud)
- 横版1:2500万标准中国地图