开源项目-CSV导入导出工具类_opencsv官网-程序员宅基地

技术标签: java27岁了  JAVA进阶知识  univocity  opencsv  common-csv  csv导入导出  



  • 个人网站: IT知识小屋
  • 版权: 本文由【IT学习日记】原创、在CSDN首发、需要转载请联系博主
  • 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦


前言

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

  上一次通过文章跟读者分享了自己写的轮子《摸鱼轮子》,读者的反馈还不错。趁热打铁,赶紧推出的摸鱼轮子第二版-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,对一些使用低版本的用户不是很友好。

image-20220518223211876

三、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导入轮子

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

/**
     *
     * @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导出轮子

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


 /**
     * 导出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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40891009/article/details/124874311

智能推荐

centos7离线安装mysql_centos7 离线安装mysql-程序员宅基地

文章浏览阅读3.8k次,点赞5次,收藏26次。1.下载mysql安装包:地址:https://dev.mysql.com/downloads/mysql/点击archives,查看历史版本选择版本和OS,然后点击download2.解压刚刚下载的tar包到 /home/mysql/下,得到rpm包:[root@localhost ~]# tar -xf mysql-5.7.19-1.el7.x86_64.rpm-bundle.tar -C /home/mysql/3.查询并卸载系统自带的Mariadb:rpm -.._centos7 离线安装mysql

对口升学计算机网络网络试题,中职对口升学计算机网络检测试题一-程序员宅基地

文章浏览阅读631次。习题1. 填空题1)计算机网络主要有2)TCP的汉语意思是IP的汉语意思是。3)计算机网络中的共享资源指的是硬件、软件和4)计算机通信采用的交换技术主要有交换和电路交换两种,前者比后者实时性差,线路的利用率高。5)在计算机网络中,通信双方必须共同遵守的规则或约定称为6)在计算机网络中,人们通常用来描述数据传输速率的符号是7)在信号的接受与发送两站点进行之间进行的数据传输只建立一条通信线路,每次只传..._中职对口高考计算机试题真题

strcmp( )函数-程序员宅基地

文章浏览阅读10w+次,点赞53次,收藏201次。strcmp的用法所在头文件:string.h功能:比较字符串s1和s2。一般形式:strcmp(字符串1,字符串2)说明:当s1&lt;s2时,返回为负数 注意不是-1当s1==s2时,返回值= 0当s1&gt;s2时,返回正数 注意不是1即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:"A"&lt;"B" "a"&gt;"A" "_strcmp

【前端学习 Vue (9) Vue路由】_vue3 window.history.replacestate(null, null, locat-程序员宅基地

文章浏览阅读191次。Vue路由_vue3 window.history.replacestate(null, null, location.origin + '/#/home')

安卓截屏技术+附带悬浮窗自动存储功能-程序员宅基地

文章浏览阅读730次,点赞18次,收藏21次。通过百度查询之后,发现是权限问题,首先我们要检查AndroidManifest.xml中是否有添加权限,在文章的一开头我们已经添加了,继续查阅发现Android 6.0 的权限是一套新的授权机制,所以在用法上也格外的不同,我们需要在运行时实施获取权限,也就是每次对文件进行R/W之前,我们都要获取一次权限。可以看到在界面的中右方向有一个悬浮窗,悬浮窗中有一个Button,点击这个Button,会弹出已经截屏的响应窗口。这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

索引越位:String index out of range: 1-程序员宅基地

文章浏览阅读3.9k次。报错原因:因为我循环使用的是字母“j”,但是我写成了“i”从而获取不到值导致报索引越位bug。出现这种问题的原因,是因为字符串的索引越位。注:细心、细心、再细心。_string index out of range: 1

随便推点

超微主板升级bios_超微主板bios升级大盘点-程序员宅基地

文章浏览阅读3.9k次。如今,电子设备已越来越普及,开始走进千家万户,空调、冰箱、微波炉、电视、音箱、数码相机、随身听几乎家家都有,汽车上装有无线导航,电话、手机等通讯产品必不可少,各种数控设备、仪器、仪表、电线电缆更是在工业中屡见不鲜。而作为先进的电子设备——电脑由于它高端的工作能力和娱乐方式也越来越受欢迎。用电脑的人越来越多,懂电脑的人越来越多,电脑也随着人们的开发不断更新,超微主板BIOS大家应该都听说过吧!它是..._超微的bios主板都差不多嘛

时间序列_python自相关系数(ACF)绘图_acf_corr 的算法流程图-程序员宅基地

文章浏览阅读1w次,点赞10次,收藏56次。一、概述自相关函数,用来度量同一事件在不同时期之间的相关程度,或者说是一个信号经过类似于反射、折射等其它情况的延时后的副本信号与原信号的相似程度。R(τ)=E[(Xt−μ)(Xt−τ−μ)]σ2R(\tau) = \frac{E[(X_t - \mu)(X_{t-\tau} - \mu)]}{\sigma ^ 2}R(τ)=σ2E[(Xt​−μ)(Xt−τ​−μ)]​简单讲就是比较不同时间延迟两个序列的相似程度,就好比下图蓝色框内序列和红色框内序列之间的相关性。二、python实现&s_acf_corr 的算法流程图

【语言处理与Python】6.4决策树/6.5朴素贝叶斯分类器/6.6最大熵分类器-程序员宅基地

文章浏览阅读85次。6.4决策树 决策树是一个简单的为输入值选择标签的流程图。这个流程图由检查特征值的决策节点 和分配标签的叶节点组成。为输入值选择标签,我们以流程图的初始决策节点(称为其根节点)开始。 熵和信息增益在决策树桩确定上的应用(可以自行查找相关资料阅读) 可以参考:http://blog.csdn.net/athenaer/article/details/8425479 决策树的一些..._朴素贝叶斯与最大熵方法

王下邀月熊_Chevalier的前端每周清单系列文章索引-程序员宅基地

文章浏览阅读173次。感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引。王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具体内容看这里:前端每周清单年度总结与盘点。前端每周清单第 56 期:D3 5.0,深入 React 事件系统,SketchCode 界面..._王下邀月

《软件登记测试报告》可以作为软件第三方检测报告使用吗_软件登记测评报告是否可用于投标产品功能鉴定评测?-程序员宅基地

文章浏览阅读802次。《软件登记测试报告》本身属于第三方软件检测报告,但是从软件登记测试与其他软件检测类型来看,测试内容和测试强度是不同的,并且测试报告使用目的还是有所不同的。软件登记测试内容1、功能性:系统安装卸载、功能模块挂接、功能模块实现2、安全可靠性:软件容错性、安全保密性、稳定性3、用户界面:界面输入、界面显示、界面文字4、中文特性:界面中文符合性、软件提示中文符合性、字库中文符合性、产品包装盒说明本地化5、用户文档:完备性、正确性、一致性主要是检测软件是否达到了需求要求的“基本”实现,_软件登记测评报告是否可用于投标产品功能鉴定评测?

jquery Select2 学习笔记之中文提示 - 程序员宅基地-程序员宅基地

文章浏览阅读199次。首先学习这个东西呢,还是看官网比较全面select2官网例子要select2中文显示:必须要引入中文包,且一定要放在select2.js之后[javascript]view plaincopy<linktype="text/css"rel="stylesheet"href="/css/select2.css">..._select2 中文提示

推荐文章

热门文章

相关标签