1.一个常见的问题就是如何读取excel。

这里面有几个分支的问题,一个是如何使用poi读取excel,网上例子很多,但是这只解决了第一步。如何将excel读取入一定的数据结构这是第二个问题,还有就是读取到数据了以后如何存放,如何将其转换成我们希望的对象?这些问题一个比一个在应用的更高层级上,也就是说,如果excel是数据源,如何将数据源读取到的数据转换成我们喜爱的实体类,也就是ORM的思想,只是在读取excel这个事情上,我们的数据源是个文件,需要一定的驱动去读取,仅此而已。

2..破解问题

我们需要poi包的支持,这是世界java圈里公认的组件,不用再次发明轮子。我们需要用到json包,用alibaba出品的fastjson包,这个也非常好用。感谢zj的推荐。思考的过程是这样的,在我们现有的知识里面,已经有这样几个概念了,excel通过poi可以读取它的值,json包可以把string直接转换成pojo,那么我们将他们建立联系,从excel中读取行到json,再把json变成实体类,就可以达到我们预想的效果了。那么还有一个问题需要解决,就是如何指定类的属性与excel对应列的关系。仔细想了一阵子,还没想到好的解决办法,如果没有办法自动,那就可以用指定的方法,外部指定其实已经解耦了,只是没那么完美而已。

3.解决问题

第一步,我们建立pojo类属性与excel的对照关系,我们还是利用json作为中间传递的载体。
/**
* 创建用于翻译中文列名到英文变量名的对照字典。
* @param keys 中文或默认的excel列名称
* @param values 变量名
* @return
* @throws Exception
*/
public JSONObject genImportKyes(String[] keys,String[] values) throws Exception {
try {
JSONObject result = new JSONObject();
for (int i = 0; i < keys.length; i++) {
result.put(keys[i], values[i]);
}
return result;
}catch (Exception e){
e.printStackTrace();
throw e;
}
}
调用的时候比如excel有字段"序号", "数量", "日期", "小计", "备注",而我们的pojo对象的属性是"id","count","date","sum","memo",我们这样调用
JSONObject keys = eo.genImportKyes(new String[]{"序号", "数量", "日期", "小计", "备注"},new String[]{"id","count","date","sum","memo"} );
这样这个keys里面我们就建立了excel中的列名和我们实体类属性的对应关系了。
第二步,从excel的指定行去读取一行,来建立属性名和excel列的位置的对应关系。也就是我们需要知道我们的序号兑换成的id这个数据是放在excel的第几列里面的。
public JSONObject createRowIndex(Row row, JSONObject keys) {
int col_count = row.getLastCellNum();
JSONObject jsonObject = new JSONObject();
for (int i = 0; i < col_count; i++) {
String cv = row.getCell(i).getStringCellValue();
if (keys == null) {
jsonObject.put(cv, i);
} else {
String key = keys.getString(cv);
jsonObject.put(key, i);
}
}
return jsonObject;
}
通过读取excel的一个row放进这个函数,再加上我们第一步准备好的keys,我们就可以比较容易的做出对应关系来。因为第一步我们解决了excel列明与实体类属性的对照关系,在第二步我们解决了属性与excel的列的对应位置关系,接下来我们就可以去读取格子了,因为我们需要的信息都准备好了。也就是我们已经建立好了读取的规则。
第三步:读取excel的其他所有行,并按照第一步建立的关系创建出json对象来。这中间有一个需要注意的地方是我们队与excel中的特殊类型需要额外的关照一下,比如日期类型、数字类型等等。具体可以看源码public String parseCell(Cell cell) 这个函数的实现。我们通过每一行的读取来获得一个json的对象,接下来我们在使用json包转javaobject的能力把它变成对应的实体类。接近成功了。

4.最后我们来看看,假设我们有一个excel文件是这样的



我们希望读取出来以后的实体类是这样的。



是时候展示真正的实力啦。

@Test
public void test1() throws Exception {
excelOpterator eo = new excelOpterator().setHeadRowIndex(0);
JSONObject keys = eo.genImportKyes(new String[]{"序号", "数量", "日期", "小计", "备注"},new String[]{"id","count","date","sum","memo"} );
JSONArray rows = eo.readXls("C:/excel.xls", keys);
for(Object jo :rows){
testEntity to = JSON.toJavaObject((JSONObject)jo,testEntity.class );
System.out.println(to);
}
}

看到输出的时候总是很开心,但是回头看自己思考的过程,也会比较有意思,希望大家都能享受到这个轻松的结果。bingo

文末有福利

https://gitee.com/youliaoo/lutraExcelHelper

以ORM的思路来从Excel文件中读取JSON数据列表的更多相关文章

  1. 记新人从 excel 文件中读取字典数据踩的一个坑

    原本是打算今天分享一下最近学习接口自动化的心得体会,然而在我写模板的时候,却被一个坑拦我大半天,心得体会不得不 延期再分享了.在我无数次调试无数次看log,终于发现并解决这个问题了.下面记录一下踩的坑 ...

  2. 条形码的应用三-----------从Excel文件中读取条形码

    条形码的应用三------从Excel文件中读取条形码 介绍 上一篇文章,我向大家展示了生成多个条形码并存储到Excel文件中的一个方法.后来我又有了个想法:既然条码插入到excel中了,我可不可以从 ...

  3. 从Excel文件中读取内容

    从Excel文件中读取内容 global::System.Web.HttpPostedFileBase file = Request.Files["txtFile"]; strin ...

  4. go从文件中读取json字符串并转换

    go从文件中读取json字符串并转换 将要读取的文件的一部分 [ { "children": [ { "children": [ { "code&qu ...

  5. vue-cli项目 build后请求本地static文件中的 json数据,路径不对,报错404处理方法

    vue-cli 项目 build  出错点: 1,build生成dist 放在tomcat上 报错,不显示内容  解决办法: config>index.js===>assetsPublic ...

  6. java读取url中json文件中的json数据

    有时候需要远程从其他接口中获取json数据,如果遇到返回的json数据是一个文件而不直接是数据,那么可以通过以下方法进行读取: /** * 从数据接口获取到数据 * @return * @throws ...

  7. easyui datagrid 加载静态文件中的json数据

    本文主要介绍easyui datagrid 怎么加载静态文件里的json数据,开发环境vs2012, 一.json文件所处的位置 二.json文件内容 {"total":28,&q ...

  8. springMVC从上传的Excel文件中读取数据

    示例:导入客户文件(Excle文件) 一.编辑customer.xlsx 二.在spring的xml文件设置上传文件大小 <!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1 ...

  9. 从文件中读取数组数据————Java

    自己总结一下Java文件的读取类似数组数据的方法,自己可以快速查看. 一.规整化数据: 对于数组数据是一一对应的情况 ArrayList<String> arrayList = new A ...

随机推荐

  1. 索引视图DEMO2

    use tempdb ----在创建视图和所有底层表时,必须打开ANSI_NULLS以及QUOTED_IDENTIFIER选项 --SET ANSI_NULLS ON --GO --SET QUOTE ...

  2. 【mock】后端不来过夜半,闲敲mock落灯花 (mockjs+Vuex+Vue实战)

      mock的由来[假]   赵师秀:南宋时期的一位前端工程师 诗词背景:在一个梅雨纷纷的夜晚,正处于项目编码阶段,书童却带来消息:写后端的李秀才在几个时辰前就赶往临安度假去了,!此时手头仅有一个简单 ...

  3. IO模型 IO多路复用

    阻塞IO 用socket 一定会用到accept recv recvfrom这些方法正常情况下 accept recv recvfrom都是阻塞的 非阻塞IO 如果setblocking(False) ...

  4. 面向对象三大特性编写面向对象程序,self到底是谁

    一.函数式编程和面向对象的对比 面向过程:根据业务逻辑从上到下写垒代码: 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可: 面向对象:对函数进行分类和封装,让开发“更快更好更强. ...

  5. Postgres 的 JSON / JSONB 类型

    从 MySQL 5.7.8 开始,MySQL 支持原生的 JSON 数据类型. 一.介绍 json是对输入的完整拷贝,使用时再去解析,所以它会保留输入的空格,重复键以及顺序等.而jsonb是解析输入后 ...

  6. 爬虫 解码gb1312类型

    今天我爬虫的时候竟然遇见了网页编码为gb1312类型的网站  , 不是平常的utf-8 遇到这种类型的时候忽视它是最好的办法 ① respond.content.decode('gb18030','i ...

  7. NVIDIA GRID 和 NICE DCV 技术用于实现 Linux 和 Windows® 图形加速虚拟桌面

    NVIDIA GRID 和 NICE DCV 技术用于实现 Linux 和 Windows® 图形加速虚拟桌面. NICE DCV: 满足 LINUX 和 WINDOWS 的远程 3D 通过 NICE ...

  8. Python数据结构:栈 队列

    栈,队列的特性: 1.栈(stacks)是一种只能通过访问其一端来实现数据存储与检索的线性数据结构,具有后进先出(last in first out,LIFO)的特征 2.队列(queue)是一种具有 ...

  9. ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT allowed in this context

    封装Redis发布订阅时,SUB时,又想探测具体Channel的状态,于是执行PUBSUB CHNNALES命令,报 ERR only (P)SUBSCRIBE / (P)UNSUBSCRIBE / ...

  10. 通俗易懂详解Java代理及代码实战

    一.概述 代理模式是Java常用的设计模式之一,实现代理模式要求代理类和委托类(被代理的类)具有相同的方法(提供相同的服务),代理类对象自身并不实现真正的核心逻辑,而是通过调用委托类对象的相关方法来处 ...