代码地址如下:
http://www.demodashi.com/demo/12062.html

程序员最大的毛病可能就是懒,因为懒所以做出了许许多多提高自己工作效率的工具.

起因于我是商业开发,既然是商业项目避免不了各种数据统计,虽然公司有专门的数据平台,但是应对一些临时性需求还是免不了开发人员去导出一些数据.每一次有需求来我都是写一个复杂的sql,然后放到DataGrip中执行,利用其功能导出cvs,然而越来越多的需求该功能无法满足,比如导出组合表,也就是一个excel中有多个sheet表.那么应该这个需求我写了一个为自己的工具.

我理想中的工具

1.简单模式使用sql查询直接导出

2.复杂模式可以定义一些复杂的bean,然后通过组合代码中自定义实现导出逻辑

3.可以自己定义表头,以及对应的数据处理,比如把时间戳转换为yyy-MM-dd hh:MM:ss这样的形式

4.支持一个excel中含有多个sheet

5.不需要很复杂的配置,因为自用,所以能约定俗成的地方就约定俗成.

语言的选择

这个很随意了,我是选择自己最熟悉的语言,也就是Java.

同事听说我用Java写这种工具,强烈推荐我用py,但天生动态语言无感,可以说是反感,所以放弃.

实现

环境: JDK8 Maven

IDE: IntelliJ IDEA / Eclipse

具体过程很简单,代码逻辑也很清晰,这里只说下主要流程,详细的可以参考源码Github地址,另外由于个人使用,所以没有太多的校验和异常考虑.

数据的获取

数据的获取其实就是DBUtils的使用方法,很简单执行Sql,然后使用对应的Handler转换成对应形式参数

//查询出结果,使用Map存储,当然dbUtils也支持bean存储
final List<Map<String, Object>> result = queryRunner.query(conn, "select * from user", new MapListHandler());

ResultSetHandler接口提供了一个单独的方法:Object handle(java.sql.ResultSet.rs)。

ResultSetHandler接口的实现类

1. ArrayHandler:把结果集中的第一行数据转换成对象数组。

2. ArrayListHandler:把结果集中的每一行数据都转换成一个对象数组,再存放到List中。

3. BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。

4. BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。

5. MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。

6. MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List。

7. ColumnListHandler:将结果集中某一列的数据存放到List中。

8. KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map里,其key为指定的列。

9. ......

表头的定义

表头是有序的,所以使用LinkedHashMap<String, ExcelHeader> header这种数据结构,其中ExcelHeader是我封装的一个类,如下,可以看到其功能是存储对应的表头展示名称,以及转换器

@Data
public class ExcelHeader {
/**
* 展示名称
*/
private String displayHeader;
/**
* 对应数据转换器
*/
private Function convert; private ExcelHeader(String displayHeader,Function convert){
this.displayHeader = displayHeader;
this.convert = convert;
} public static ExcelHeader create(String displayHeader){
return new ExcelHeader(displayHeader, Function.identity());
} public static ExcelHeader create(String displayHeader,Function convert){
return new ExcelHeader(displayHeader, convert);
}
}

那么其使用就很简单了

   //表格对应的表头,以及该表头的数据处理
LinkedHashMap<String, ExcelHeader> header = new LinkedHashMap<>();
header.put("id", ExcelHeader.create("用户id"));
header.put("username", ExcelHeader.create("用户名"));
header.put("email", ExcelHeader.create("用户邮箱"));
header.put("avatar", ExcelHeader.create("用户头像"));
//对于日期使用转换器,转换器为java8的Function函数实现
header.put("last_login_date", ExcelHeader.create("用户上次登录时间", FuncitionConvertUtil.date2String));
header.put("status", ExcelHeader.create("用户id"));
header.put("role", ExcelHeader.create("用户id"));
//对于日期使用转换器,转换器为java8的Function函数实现
header.put("gmt_create", ExcelHeader.create("用户id",FuncitionConvertUtil.date2String));

导出表

数据以及表头都有了,那么只剩下的导出操作也就是数据的组合.

    //导出表
/**
* 查出来的map直接导出表格
*/
ExcelExportUtil.fromMap(result)
.displayHeader(header)
.excelType(ExcelExportUtil.ExcelFileType.XLS)
.build("用户表")
.writeTo("/tmp/test1.xls");
/**
* 导出多张表
*/
ExcelExportUtil.fromMap(result)
.displayHeader(header)
.excelType(ExcelExportUtil.ExcelFileType.XLSX)
.build("用户表1")
.andFormMap(result)
.displayHeader(header)
.build("用户表2")
.writeTo("/tmp/test2.xlsx");

核心的导出逻辑为build()方法

  @SuppressWarnings("unchecked")
public ExcelExportUtil build(String sheetName) {
buildReady();
//创建表,如果已存在excelBook,那么新增表
Sheet sheet = sheetName == null ? workbook.createSheet() : workbook.createSheet(sheetName); //写表头
int rowNum = 0;
Row headerRow = sheet.createRow(rowNum++);
int[] tempCol = {0};
this.headerAndConvert.forEach((k,v) -> headerRow.createCell(tempCol[0]++).setCellValue(v.getDisplayHeader())); //写表数据
for (Map<String, Object> colData : this.mapData) {
Row row = sheet.createRow(rowNum++);
tempCol[0] = 0;
this.headerAndConvert.forEach((k,v) -> {
Cell cell = row.createCell(tempCol[0]++);
Object value = v.getConvert().apply(colData.get(k));
convertObjValue(cell, value);
});
}
return this;
}

导出表格展示

test1.xls

test2.xlsx

下载Demo如何运行?

环境具备后,那么只需要对应的代码导出IDE,然后查看QueryAndExportByH2这个单元测试类,执行里面的testQueryAndExport()方法即可,注意导出表的时候需要指定路径名

项目结构截图

总结

本文的主要目的是表达迷茫的时候不知道自己该做什么,那么就从自己身边的需求开始,分析自己所遇到的痛点,然后用你喜欢的方式去解决这个痛点,那么这个过程就是你的进步.

最后给出github地址,如果你有能力则直接看源代码即可,如果你从此网站下载了Demo,那么有问题可以随时与我交流,邮件为 niudear@foxmail.com

由需求而产生的一款db导出excel的工具

代码地址如下:
http://www.demodashi.com/demo/12062.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

由需求而产生的一款db导出excel的工具的更多相关文章

  1. 个人推荐的两款vue导出EXCEL插件

    个人认为前端VUE项目中导出EXCEL比较好的两种方法,均不是我个人原创,我只是收录简单说明,原创地址在下面. 下面推荐两种方法,个人推荐第一种,第二种不做详细讲解,因为作者已经写过博客了,你们可以点 ...

  2. Linux下四款Web服务器压力测试工具(http_load、webbench、ab、siege)介绍

    一.http_load程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把 ...

  3. 简化工作流程,10款必备的HTML5开发工具

    利用HTML5工具不仅可以帮助设计师和开发者创建更具吸引力的网站,还能增加网站的可用性和可访问性.本文收集了10款HTML5开发工具让你在网页中搭建特效.动画.视频.音频等诸多功能,为你节省更多开发时 ...

  4. 15款最佳的MySQL管理工具和应用程序

    工欲善其事,必先利其器.几乎每个开发人员都有最钟爱的 MySQL 管理工具,它帮助开发人员在许多方面支持包括 PostgreSQL,MySQL,SQLite,Redis,MongoDB 等在内的多种数 ...

  5. 简化工作流程 10款必备的HTML5开发工具

    利用HTML5工具不仅可以帮助设计师和开发者创建更具吸引力的网站,还能增加网站的可用性和可访问性.本文收集了10款HTML5开发工具让你在网页中搭建特效.动画.视频.音频等诸多功能,为你节省更多开发时 ...

  6. 七款做好DevOps的强大工具

    原文链接: 7 cool tools for doing devops right 传统把开发和运营割裂开的做法,实则不适合现代产品和服务开发的需求,如今把开发和运营作为整体来看待的DevOps工程思 ...

  7. Python导出Excel为Lua/Json/Xml实例教程(三):终极需求

    相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 Python导出E ...

  8. pylot是一款开源的web性能测试工具

    pylot是一款开源的web性能测试工具,http://www.pylot.org/ 参考文档:http://www.pylot.org/gettingstarted.html很容易上手 使用分为以下 ...

  9. 给你推荐10款优秀的 HTML5 动画工具

    HTML5 在过去三年快速增长,已经成为 Web 开发人员最喜欢的编程语言之一.强大的编程语言拥有开发更好的网页应用的能力. HTML5 中引入的新技术都非常好,像 Chrome.Firefox.Sa ...

随机推荐

  1. Android SQLite使用

    1. 介绍 SQLite是一款轻型的数据库, 是遵守ACID的关系型数据库管理系统, Android系统已经在框架中适配接口供用户使用. 2. 数据类型 SQLite采用的是动态数据类型, 会根据存入 ...

  2. 在Centos中使用goaccess查看Nginx日志

    在Nginx的配置文件中配置一下access日志: log_format access ‘$remote_addr – $remote_user [$time_local] “$request” ‘‘ ...

  3. Java屌炸天学习路线图

            第一阶段:Java基础篇 编号 课程 课程目录 打包下载地址 讲师 01 J2SE(40课时) http://www.java1234.com/zy001.html http://pa ...

  4. kibana-metric

    1. Visualize 新建图形 2. 选择图形类型 3. 选择索引 4. 设置metric参数 4.1 count 4.2 unique count 5. 保存图形

  5. 【bzoj1951】【古代猪文】Lucas定理+欧拉定理+孙子定理

    (上不了p站我要死了,当然是游戏原画啊) Description (题面倒是很有趣,就是太长了) 题意: 一个朝代流传的猪文文字恰好为N的k分之一,其中k是N的一个正约数(可以是1和N).不过具体是哪 ...

  6. Java Web实现跨域

    import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import ja ...

  7. 记录在Spring-Boot中使用Fegin调用RESTfull的PATCH方法设置

    使用了ZooKeeper,设置 spring.cloud.zookeeper.dependency.headers.enabled=false 参考: https://github.com/sprin ...

  8. Orchard EventBus 事件总线及 IEventHandler作用

    事件总线接口定义: public interface IEventBus : IDependency { IEnumerable Notify(string messageName, IDiction ...

  9. Quartz配置CronTrigger

    CronTrigger 构造器 String name, //触发器名称 String group, //触发器的组名 String jobName, //job名称 String jobGroup, ...

  10. JavaScript indexOf() 方法,获取元素的位置;Object.keys()获取对象的所有key的数组

    定义和用法 indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置. 语法 stringObject.indexOf(searchvalue,fromindex) 参数 描述 sea ...