由于 poi 本身只是针对于 excel 等office软件的一个工具包,在一些常规的 excel 导入导出时,还需要再做一次精简的封装,简化代码耦合。

一、现状

本人经历过几家公司的代码封装,导入导出一般存在下面的情况。

1.1 导入

  1. 传入文件地址,返回 Sheet 对象,在业务代码中进行循环遍历,做相对应的类型转换,业务处理(二零零几年的代码框架)
  2. 传入文件地址,返回 List<String, Object> 的对象,外部直接做强转
  3. 传入文件地址,返回 List<String, String> 的对象,外部将字符串对象转换为对应的类型

总结:如果只有上述的选择,本人是比较倾向于第二种,毕竟对外层是非常友好的

1.2 导出

  1. 直接在逻辑代码中进行遍历封装sheet,传入到生成file的方法中(二零零几年的代码框架)
  2. 先循环遍历 List<Model> 对象,转换为 List<Map<String, String>> 对象,带上 fieldName 传入到封装好excel生成的方法中,内部则使用 map.get() 方法操作
  3. 直接将 List<Model> 对象带上 fieldName 传入到封装好excel生成的方法中,内部将 Model 对象转换为 JSONObject,然后使用 jsonObj.get() 方法操作
  4. 先将 List<Model> 转换为 JSONArray ,带上 fieldName 传入到封装好excel生成的方法中,内部将 Model 对象转换为 JSONObject,然后使用 jsonObj.get() 方法操作。(使用这种做法,据分析应该是为了执行 jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor(“yyyy-MM-dd HH:mm:ss”)); 这行代码,可能是为了解决日期类型格式问题)

总结:如果只有上述的选择,本人是比较倾向于第三种,第三种只遍历一次,并且外部未做处理。但是按第四种模式来看,那么第三种模式还是会存在日期格式问题,这个我们后续再分析如何处理。

二、导入

2.1 方法定义

/**
* excel导入
* @param keys       字段名称数组,如  ["id", "name", ... ]
* @param filePath   文件物理地址
* @return
* @author yzChen
* @date 2016年12月18日 下午2:46:51
*/
public static List&lt;Map&lt;String, Object&gt;&gt; imp(String filePath, String[] keys)throws Exception {}

2.2 循环处理模块

// 遍历该行所有列
for (short j = 0; j &lt; cols; j++) {cell = row.getCell(j);if(null == cell) continue;  // 为空时,下一列// 根据poi返回的类型,做相应的get处理if(Cell.CELL_TYPE_STRING == cell.getCellType()) {value = cell.getStringCellValue();} else if(Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {value = cell.getNumericCellValue();// 由于日期类型格式也被认为是数值型,此处判断是否是日期的格式,若时,则读取为日期类型if(cell.getCellStyle().getDataFormat() &gt; 0)  {value = cell.getDateCellValue();}} else if(Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {value = cell.getBooleanCellValue();} else if(Cell.CELL_TYPE_BLANK == cell.getCellType()) {value = cell.getDateCellValue();} else {throw new Exception("At row: %s, col: %s, can not discriminate type!");}map.put(keys[j], value);
}

2.3 使用

String filePath = "E:/order.xls";
String[] keys = new String[]{"id","brand"};List&lt;Map&lt;String, Object&gt;&gt; impList;
try {impList = ExcelUtil.imp(filePath, keys);for (Map&lt;String, Object&gt; map : impList) {System.out.println(map.get("brand"));}
} catch (Exception e) {e.printStackTrace();
}

2.4 分析

  1. 入口只需要传入文件名称,以及外部需要读取的key即可
  2. 内部处理,则针对 数值型、日期类型、字符串 类型已经做了对应处理,外部则直接进行强转对应的类型即可

三、导出

3.1 方法定义

/**
* excel导出
* @param fileNamePath   导出的文件名称
* @param sheetName  导出的sheet名称
* @param list       数据集合
* @param titles     第一行表头
* @param fieldNames 字段名称数组
* @return
* @throws Exception
* @author yzChen
* @date 2017年5月6日 下午3:53:47
*/
public static &lt;T&gt; File export(String fileNamePath, String sheetName, List&lt;T&gt; list, String[] titles, String[] fieldNames) throws Exception {}

3.2 循环处理模块

// 遍历生成数据行,通过反射获取字段的get方法
for (int i = 0; i &lt; list.size(); i++) {t = list.get(i);HSSFRow row = sheet.createRow(i+1);Class&lt;? extends Object&gt; clazz = t.getClass();for(int j = 0; j &lt; fieldNames.length; j++){methodName = "get" + capitalize(fieldNames[j]);try {method = clazz.getDeclaredMethod(methodName);} catch (java.lang.NoSuchMethodException e) {   //  不存在该方法,查看父类是否存在。此处只支持一级父类,若想支持更多,建议使用while循环if(null != clazz.getSuperclass()) {method = clazz.getSuperclass().getDeclaredMethod(methodName);}}if(null == method) {throw new Exception(clazz.getName() + " don't have menthod --&gt; " + methodName);}ret = method.invoke(t);setCellGBKValue(row.createCell(j), ret + "");}
}

3.3 使用

String[] titles = new String[]{"Id", "Brand"};
String[] fieldNames = new String[]{"id", "brand"};
List&lt;Order&gt; expList = new ArrayList&lt;Order&gt;();
Order order = new Order();
order.setId(1L);
order.setBrand("第三方手动阀");
expList.add(order);
order = new Order();
order.setId(2L);
order.setBrand("scsdsad");
expList.add(order);String fileNamePath = "E:/order.xls";
try {ExcelUtil.export(fileNamePath, "订单", expList, titles, fieldNames);
} catch (Exception e) {e.printStackTrace();
}

3.4 总结

  1. 入口主要是需要传入 List<Model> 数据集合,以及 fieldNames 字段名称
  2. 内部处理,是直接通过反射获得 get 方法的返回值,进行强转为字符串进行导出
  3. 为了兼容继承父类的一些共有字段的设计,则加上了一层父类的方法读取

四、关于日期类型导出处理

1.1 日期字段导出指定格式内容

  1. 建议在 Model 类中,新增一个扩展字段,并封装一个 get 方法,内容则只是对原字段进行转换,导出时,fieldName 则传递扩展字段即可。如 createTime,示例如下:

    private Date createTime;
    private String createTimeStr;   // 扩展字段
    

public Date getCreateTime() {

return createTime;

}

public void setCreateTime(Date createTime) {

this.createTime = createTime;

}

public String getCreateTimeStr() {

createTimeStr = DateUtil.formatDatetime(this.createTime);
return createTimeStr;

}

## 五、Demo下载
[GJP-Example-ExcelUtil 代码下载](https://pan.baidu.com/s/1jIzFFPO)


转载:基于 POI 封装 ExcelUtil 精简的 Excel 导入导出

基于 POI 封装 ExcelUtil 精简的 Excel 导入导出相关推荐

  1. Excel导入导出工具类

    目录 1.mavn jar 2 工具类代码 2.1 ExcelUtil 2.2 引用自写类 2.2.1 ExcelMsg 2.2.2 CellDataType 2.2.3 SaxReadExcelUt ...

  2. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  3. Java poi 实现excel导入导出工具类

    最近项目上又要大量的涉及excel导入导出,网上各种导入导出的方式层出不穷,我是比较青睐官方的poi,但是要自己去操作工作簿对象自己一行一行的读取,会有很多的重复代码,重复劳动,也极为不美观,基于合成 ...

  4. SpringBoot实现Excel导入导出,好用到爆,POI可以扔掉了!

    在我们平时工作中经常会遇到要操作Excel的功能,比如导出个用户信息或者订单信息的Excel报表.你肯定听说过POI这个东西,可以实现.但是POI实现的API确实很麻烦,它需要写那种逐行解析的代码(类 ...

  5. excel 导入导出使用poi自定义注解

    excel导入导出使用poi自定义注解 最近在做一个数据导入导出的模块 在网上找了一些例子 在这里整理一下 这里就不再贴原作者的地址  (以下代码来自网上非原创 稍作简单修改)  首先引入pom.xm ...

  6. Excel 导入导出、样式设计、Excel各种工具类整合,FileUtil、ExcelUtil

    2022-12-09 今天整理一下最近的excel导入导出经验,整理出了几个工具类,放心使用,可应付8成需求 excel导入导出现实需求可能很复杂,但基本都可以通过原生和easyexcel配合实现,开 ...

  7. Java POI Excel导入导出

    Java POI Excel导入导出 1.maven引入依赖 2.导入Excel 3.导出Excel 1.maven引入依赖 <!-- POI Excel 操作 --> <depen ...

  8. excel winform 导入 导出_强大的 Excel 导入导出工具 hutool

    " 最近项目上需要用到 Excel 的导入导出功能,想着之前使用的都有点麻烦,所以结合多方资料,终于找到了这个还算不错的 Excel 处理工具,一起来看" 今日安利好物名为 Hut ...

  9. SpringBoot集成EasyPoi实现Excel导入导出

    作者介绍: 本人Java特工,代号:Cris Li : 中文名:克瑞斯理 简书地址: 消失的码农 - 简书 CSDN地址: https://blog.csdn.net/jianli95 个人纯洁版博客 ...

最新文章

  1. android 判断是否正在扫描蓝牙_判断蓝牙是否连接
  2. 实战项目---模拟商品采购中心信息平台
  3. Bootstrap4+MySQL前后端综合实训-Day06-AM【eclipse详细配置Tomcat、开发web项目、servlet、连接MySQL8.0数据库、用户登录界面的编写与验证、分页查询】
  4. HarmonyOS之设备定位的使用与地理编码的转化
  5. Spring Reactive已经过时了吗? 螺纹连接反转
  6. 禁用应用中Android系统的导航栏(特别是平板)
  7. oracle创建job一年执行,Oracle快速创建定时job执行批量转储过程脚本参考案例
  8. 怕死吗?研究人员推出可模拟“灵魂出窍”的VR系统
  9. 详解策略分析师的日常是怎么样的?策略数据代码篇
  10. 深入浅出Docker(六):像谷歌一样部署你的应用
  11. mysql 中间表的好处_MySql 使用中间表来提高统计查询速度
  12. 仿新浪微盾客户端项目简介一
  13. Javascript网页设计作业: HTML班级网页设计 基于HTML+CSS+JS制作我们的班级网页(web前端学生网页设计作品)
  14. c++操作打印机那些事
  15. 微信支付接口详细步骤
  16. 微型四旋翼飞行器的设计与制作
  17. 腾讯社交广告大赛总结
  18. 深度技术 Windows7 旗舰五周年纪念版
  19. 手机内置摄像头接线图解_坚果R2 手机官方壁纸
  20. 存储、计算、分布式知识点思维导图(收集整理适合小白)

热门文章

  1. 使用lvs实现负载均衡(V2.0)
  2. shell 学习之case语句
  3. navmesh思路的A*寻路算法优化
  4. Scala学习笔记总结
  5. 车联网中如何应用大数据
  6. 5G对于数据中心的影响有哪些
  7. 大数据的分析手段有哪几种
  8. html加图形验证码,canvas基础之图形验证码的示例
  9. java 选取topn_取Oracle中实现TOPN,选取前几条记录
  10. php $path_info,PHP $_SERVER['PATH_INFO'] 无法获取到内容怎么办?