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

代码地址如下:
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大师代发,拒绝转载,转载需要作者授权

posted on   demo例子集  阅读(285)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示