前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >5月20日送给单身狗的礼物-《自己写轮子之CSV轮子》

5月20日送给单身狗的礼物-《自己写轮子之CSV轮子》

作者头像
IT学习日记
发布2022-09-13 15:23:16
1.1K0
发布2022-09-13 15:23:16
举报
文章被收录于专栏:IT知识进阶学习

前言

  又是一年虐狗日,身为一名经验丰富的单身狗,虽然不能给读者分配"女朋友",但是也希望给大家费分享一些能够提高效率的轮子,帮助大家抽出更多时间摸鱼。

  上一次通过文章跟读者分享了自己写的轮子《摸鱼轮子》,读者的反馈还不错。趁热打铁,赶紧推出的摸鱼轮子第二版-CSV轮子,希望能够帮助更多人节省开发时间,提高摸鱼效率。

  本篇文章会对《轮子之王》开源项目中集成的轮子进行详解介绍,从功能集成从技术选项再到技术实现,帮助大家更好理解轮子是否适用于自己的业务。

项目地址

Gitee地址: https://gitee.com/it-learning-diary/it-wheels-king

Github地址: https://github.com/it-learning-diary/it-wheels-king

CSV轮子

  CSV(Comma Separated Values)逗号分隔值,也可以称为字符分隔符,因为分隔字符也可以不是逗号,以纯文本方式存储表格数据(数字和文本)。

  与excel等文件相比,excel文件中会包含许多格式信息,占用的空间会更大,CSV是以纯文本的方式存储,故体积会更小,适合存放结构化的信息,如数据导出、流量统计等。

集成目的

在日常的开发工作中,导入导出是非常常见的业务,通常来讲,CSV以纯文本方式存储数据,占用的存储空间比excel更少,同时在window环境下默认是使用excel方式打开CSV文件的,因为它本质上是一个文本文件,因此CSV文件的导入导出功能非常常用,故特意在轮子之王项目中集成CSV轮子。

技术架构选择

  JAVA语言中,操作CSV文件相关的框架比较多,常见的有以下几种:

一、Javacsv

官方地址: https://sourceforge.net/projects/javacsv/

简介: 它是一个小型的快速开源java库,用于读取和写入CSV和普通分隔文本文件。所有类型的CSV文件都可以处理,txt,Excel格式化,等等。

特点: 轻量,且快速,但是已经停止维护许久了,不推荐使用

二、Opencsv

官方地址: http://opencsv.sourceforge.net/#quick_start

简介: JAVA中易于使用的CSV解析依赖库,设计出来的目的是因为当时CSV解析器没有商业友好的许可证,最低支持JAVA8。

特点: 该项目已被Apache基金会收录,可以免费用于商业应用程序中,有较全的官网文档和Apache基金会进行维护,但是最低支持的JAVA版本为8,对一些使用低版本的用户不是很友好。

三、Apache-common-csv

官方地址: https://commons.apache.org/proper/commons-csv/

简介: 创建目的是为了在ASL许可证下构架一个通用的、简单的读取和写入CSV的接口,作者希望通过common-csv替换掉之前与csv相关的一些框架如opencsv、skife csv等。

特点: 被Apache收录,持续维护更新,有较全的官方文档。

四、Univocity-parsers(推荐使用)

官方地址: https://www.univocity.com/pages/univocity_parsers_tutorial

简介: JAVA语言编写,号称你能发现的最快的关于CSV文件的JAVA解析器,同时支持固定宽度格式文件和TSV文件,开源、已经被Apache收录了

特点: 支持CSV、TSV、固定宽度格式文件解析,有完整的官方文档、被Apache收录,持续在更新迭代。


经过对常用的CSV操作框架对比,考虑到性能、后续拓展性、以及官方文档完整性等方面因素,最终决定使用:Univocity-parser来处理CSV文件。


源码解析

  理论千遍不如实践一遍,下面一起来看看封装的CSV轮子源码吧!

CSV导入轮子

  部分源码如下,详细源请到文章末尾领取:

代码语言:javascript
复制
/**
     *
     * @param inputStream
     * @param errorList
     * @param rowDto
     * @param rowAction
     * @param <T>
     */
    public static <T extends Object> void importCsvWithString(InputStream inputStream, List<String> errorList, Class rowDto, ThrowingConsumer<List<String[]>> rowAction) {
        // 定义bean解析者:用于将csv中数据绑定到实体属性中,然后存储带list集合上
        RowListProcessor rowListProcessor = new RowListProcessor();
        CsvParserSettings setting = getDefaultSetting(errorList);
        setting.setProcessor(rowListProcessor);
        // 创建csv文件解析
        CsvParser csvParser = new CsvParser(setting);
        csvParser.parse(inputStream);
        // 获取数据映射后的集合
        List<String[]> rowDataList = rowListProcessor.getRows();
        // 执行数据持久化
        persistentStringDataToDb(rowDataList, rowAction);
    }

    /**
     * 将数据持久化到数据库中
     * 具体数据落库的业务逻辑方法:此处的逻辑是将数据从csv中读取出来后,然后进行自己的业务处理,最后进行落库操作
     * 不懂的可以参考:UserServiceImpl下的uploadUserListWithCsv方法案例
     *
     * @param data
     * @param persistentActionMethod
     */
    private static <T> void persistentStringDataToDb(List<String[]> data, ThrowingConsumer<List<String[]>> persistentActionMethod) {
        // 对数据分组,批量插入
        List<List<String[]>> dataList = ListUtil.split(data, ImportConstant.MAX_INSERT_COUNT);
        dataList.stream().forEach(persistentActionMethod);
    }

CSV导出轮子

  部分源码如下,详细源请到文章末尾领取:

代码语言:javascript
复制
 /**
     * 导出csv文件(表头和数据都以字符串的形式)
     *
     * @param response
     * @param head
     * @param rowDataList
     */
    public static <T> void exportCsvWithString(HttpServletResponse response, String fileName, List<T> head, List<List<T>> rowDataList) {
        CsvWriter writer = null;
        try {
            response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);
            response.setCharacterEncoding(ExportConstant.UTF_8);
            response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.CSV_SUFFIX);
            CsvWriterSettings setting = getDefaultWriteSetting();
            writer = new CsvWriter(response.getOutputStream(), setting);
            writer.writeHeaders(head);
            writer.writeStringRows(rowDataList);
            writer.flush();
        } catch (Exception e) {
            log.error("CsvExportUtil exportCsv in error:{}", e);
        } finally {
            if (Objects.nonNull(writer)) {
                writer.close();
            }
        }
    }

    /**
     * 导出csv文件(表头和行都以实体的方式)
     *
     * @param response
     * @param head
     * @param rowDataList
     */
    public static <T> void exportCsvWithBean(HttpServletResponse response, String fileName, T head, List<T> rowDataList) {
        CsvWriter writer = null;
        try {
            // 设置响应头格式
            response.setContentType(ExportConstant.EXCEL_CONTENT_TYPE);
            response.setCharacterEncoding(ExportConstant.UTF_8);
            response.setHeader(ExportConstant.CONTENT_DISPOSITION, ExportConstant.ATTACHMENT_FILENAME + fileName + ExportConstant.CSV_SUFFIX);

            // 设置导出格式
            CsvWriterSettings setting = getDefaultWriteSetting();
            // 创见bean处理器,用于处理写入数据
            BeanWriterProcessor<?> beanWriter = new BeanWriterProcessor<>(head.getClass());
            setting.setRowWriterProcessor(beanWriter);

            // 导出数据
            writer = new CsvWriter(response.getOutputStream(), setting);
            writer.processRecords(rowDataList);
            writer.flush();
        } catch (Exception e) {
            log.error("CsvExportUtil exportCsvWithBean in error:{}", e);
        } finally {
            if (Objects.nonNull(writer)) {
                writer.close();
            }
        }
    }

下一迭代

  下一迭代预计添加如下功能:

  • PDF轮子
  • FTP上传下载轮子
  • 更多功能期待读者提出issue或者私信

写在最后

  5月20号这天 ,希望博主的分享能够给你带来一些帮助 ,更多轮子功能集成,欢迎到下面地址了解

Gitee地址: https://gitee.com/it-learning-diary/it-wheels-king

Github地址: https://github.com/it-learning-diary/it-wheels-king

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/05/20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 项目地址
  • CSV轮子
    • 集成目的
      • 技术架构选择
        • 一、Javacsv
        • 二、Opencsv
        • 三、Apache-common-csv
        • 四、Univocity-parsers(推荐使用)
    • 源码解析
      • CSV导入轮子
        • CSV导出轮子
        • 下一迭代
        • 写在最后
        相关产品与服务
        文件存储
        文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档