Java处理CSV类库:OpenCSV

news2025/1/18 8:42:38

一:CSV简介

Comma-Separated Values(CSV), 因分隔符没有严格指定规范标准,可以使用逗号,也可以使用其他字符(如制表符\t、分号;等),所以CSV也称为 逗号分隔值或者字符分隔值。csv文件是使用纯文本来存储表格数据(即只能存储文本,不能存储二进制数据)。CSV因没有严格的规范,所以变异的形式比较多。

二:CSV文件的组成和规则

组成:

  • csv文件由任意条数据的【记录】组成, 每条记录的最后一个字段也要使用分隔符,记录间一般使用换行符分隔\n,也可以指定其他字符串(比如”——”)
  • 每条记录由【字段】组成,字段间使用分隔符(逗号、制表符\t等)分隔。

规则:

  1. 开头是不留空,以行为单位。
  2. 可含或不含列名,含列名则居文件第一行。
  3. 一行数据不跨行,无空行。
  4. 以半角逗号(即,)作分隔符,列为空也要表达其存在。
  5. 列内容如存在半角引号(即”),替换成半角双引号(”“)转义,即用半角引号(即”“)将该字段值包含起来。
  6. 文件读写时引号,逗号操作规则互逆。
  7. 内码格式不限,可为 ASCII、Unicode 或者其他。
  8. 不支持特殊字符
  9. 如果值有特殊字符(逗号,双引号,换行符等)要使用引号(一般使用双引号,也可以指定单引号)括起来,比如分隔符是逗号,值中也出现逗号了
  10. 值中出现双引号,需要使用双引号来转义
"ID,Name,Age,Birthday,\n1,zhangsan,20,1990-08-08,\n2,lisi,21,1990-08-09,\n"

三、CSV和Excel的区别

csv文件可以被excel软件打开,csv只能用于存储纯文本内容,excel不仅支持纯文本内容还支持二进制数据,可以看做csv是excel的轻量级简单版的实现,excel比csv更加强大,csv文件一般用于表格数据的传输。

四、类库简介opencsv

官网: http://opencsv.sourceforge.net/
maven:https://mvnrepository.com/artifact/com.opencsv/opencsv 目前最新版本4.0,更新比较频繁,4.0版本还不够成熟。
支持注解(根据名称或者位置)
支持自定义转换器AbstractBeanField
支持跳跃行skipLine和数据过滤Filter

注解:

  • @CsvBindByName:根据CSV输入中该字段的标题名,将一个bean字段映射到CSV文件中的一个字段, 可以控制列名,按名字列名的先后顺序好像是按照字母排序的
  • @CsvBindByPosition:根据CSV输入中字段的数字位置,将一个bean字段映射到CSV文件中的一个字段@CsvBindByPosition(position = 0) 按位置好像不能写列名,但是可以控制列的顺序, 还不知道即可控制列名,又可以控制列的顺序的方法(通过String[]控制应该是最灵活的)
  • @CsvCustomBindByName:与CsvBindByName相同,但必须提供自己的数据转换类。
  • @CsvCustomBindByPosition:与CsvBindByPosition相同,但必须提供自己的数据转换类。
  • @CsvDate:必须应用于日期/时间类型的bean字段,以便自动转换工作,并且必须与前述四个注释中的一个一起使用。

API

CSVWriter
        public CSVWriter(Writer writer, char separator, char quotechar, char escapechar, String lineEnd);
        public void writeAll(List<String[]> allLines);
        public void writeNext(String[] nextLine);
        protected void writeColumnNames(ResultSet rs);
        public void flush();
        public void close();

CSVReader
        public CSVReader(Reader reader, char separator, char quotechar, char escape, int line, boolean strictQuotes, boolean ignoreLeadingWhiteSpace);
        public String[] readNext();
        public List<String[]> readAll();
        public void close();
Strategy
    ColumnPositionMappingStrategy
    HeaderColumnNameMappingStrategy
    HeaderColumnNameTranslateMappingStrategy

自定义的符号:

  • char separator: 分隔符, 默认使用逗号
  • char quotechar: 引号字符,双引号或者单引号,默认双引号,每个值都使用指定的引号包围起来,即使数据类型是int类型也会用引号引起来
  • char escapechar:转义字符, 默认是双引号
  • String lineEnd:行结束符,默认\n 或者 \r\n

五、基本使用

方式一:使用String[]方式

// CSVWriter 写
@Test
public void testWriteByStringArray() throws Exception{
    OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:\\test.csv"), Charset.forName("UTF-8"));
    CSVWriter csvWriter = new CSVWriter(out, ',');

    String[] record0 = {"id", "name", "age", "birthday"};
    csvWriter.writeNext(record0);

    String[] record1 = {"1", "张三", "20", "1990-08-08"};
    String[] record2 = {"2", "lisi", "21", "1991-08-08"};
    String[] record3 = {"3", "wangwu", "22", "1992-08-08"};
    List<String[]> allLines = new ArrayList<String[]>();
    allLines.add(record1);
    allLines.add(record2);
    allLines.add(record3);
    csvWriter.writeAll(allLines);
    csvWriter.close();
}

在这里插入图片描述

// CSVReader 读
@Test
public void testRead() throws Exception{
   InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\test.csv"), Charset.forName("UTF-8"));
   CSVReader reader = new CSVReader(in, ',');
   List<String[]> allRecords = reader.readAll();
   for (String[] records : allRecords) {
       for (String filed : records) {
           System.out.print(filed + " ");
       }
       System.out.println();
   }
   reader.close();
}

在这里插入图片描述

方式二:使用注解Bean方式

package com.mengday.csv;

import com.opencsv.bean.*;

import com.opencsv.bean.customconverter.ConvertSplitOnWhitespace;

import java.util.Date;
import java.util.List;


public class User {
    @CsvBindByName(required = true)
    private Long id;

    @CsvBindByName(column = "User Name")
    private String name;

    private int age;

    @CsvBindByName
    @CsvDate("yyyy-MM-dd hh:mm:ss")
    private Date birthday;

    @CsvCustomBindByName(converter = ConvertSplitOnWhitespace.class)
    private List<String> tags;

    @CsvBindByName
    private boolean vip;


    public User(){

    }

    public User(Long id, String name, int age, Date birthday, List<String> tags, boolean vip) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
        this.tags = tags;
        this.vip = vip;
    }

    // Getter && Setter && toString()
}
@Test
 public void testCSVWriteByAnnotation() throws Exception{
     List<User> users = new ArrayList<User>();
     users.add(new User(1L, "张'三'", 20, new Date(), Arrays.asList("eat", "drink", "girl"), true));
     users.add(new User(2L, "李,四", 21, new Date(), Arrays.asList("mm", "money"), false));
     users.add(new User(3L, "王\n五", 22, new Date(), Arrays.asList("girl", "$"), true));

     OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("D:\\test.csv"), Charset.forName("UTF-8"));
     StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer).withSeparator('\t').withQuotechar('\'').build();

     beanToCsv.write(users);
     writer.close();
 }

在这里插入图片描述

@Test
public void testCSVReadByAnnotation() throws Exception{
    InputStreamReader in = new InputStreamReader(new FileInputStream("D:\\test.csv"), Charset.forName("UTF-8"));
    HeaderColumnNameMappingStrategy strategy = new HeaderColumnNameMappingStrategy();
    strategy.setType(User.class);

    CsvToBean csvToBean = new CsvToBeanBuilder<User>(in).withSeparator('\t').withQuoteChar('\'').withMappingStrategy(strategy).build();
    List<User> users = csvToBean.parse();
    for(User user: users) {
        System.out.println(user);
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1603137.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】为什么要添加一个与业务无关的主键?

关注获取更多&#xff1a; 你是否想过&#xff0c;为什么mysql要设置一个自增的主键&#xff0c;或者使用uuid生成一个和业务无关的主键id&#xff0c;在数据库设计中&#xff0c;主键是用来唯一标识每一行数据的关键。通常情况下&#xff0c;我们会选择与业务相关的字段作为…

CMEF | 澳鹏Appen精彩亮相第89届中国国际医疗器械博览会

4月14日&#xff0c;为期四天的第89届中国国际医疗器械博览会&#xff08;CMEF&#xff09;盛大收官。如今&#xff0c;人们的健康需求在人口老龄化等一系列因素的影响下持续增长&#xff0c;这意味着卫生系统也面对着更多具有复杂健康需求的患者。信息化、数字化、智能化已经成…

Zynq学习笔记--数字视频帧以及同步信号

目录 1. 介绍 2. 重要概念 3. 仿真测试 4. 总结 1. 介绍 Zynq芯片&#xff0c;作为一款集成了高性能FPGA和ARM处理器的系统级芯片(SoC)&#xff0c;为视频处理提供了强大的硬件支持。该芯片内置的丰富视频方面的IP模块&#xff0c;使得从事视频处理项目的开发者能够高效、…

PHP 使用 PHPMailer 发送电子邮件

1. PHPMailer 介绍 phpMailer 是一个非常强大的 php 发送邮件扩展包&#xff0c;可以设定发送邮件地址、回复地址、邮件主题、html邮件内容和上传附件等&#xff0c;使用起来非常方便。它目前有着有近 4 千万的下载量&#xff0c;是 PHP 开发者实现邮件发送功能的首选扩展包 它…

阅读小程序|基于微信阅读网站小程序的系统设计与实现(源码+数据库+文档)

目录 基于微信阅读网站小程序 一、前言 二、系统设计 三、系统功能设计 小程序端&#xff1a; 后台 管理员进入指定功能操作区之后可以管理图书订单。其页面见下图。管理员审核订单&#xff0c;查看订单是否支付&#xff0c;为购买图书的用户推送对应的章节。 管理员进…

西瓜书学习——第一、二章笔记

[] 什么是机器学习? 研究关于“学习算法”(一类能从数据中学习出其背后潜在规律的算法)的一门学科。 PS:深度学习指的是神经网络那一类学习算法&#xff0c;因此是机器学习的子集。 假设空间和版本空间 举个栗子:假设现已收集到某地区近几年的房价和学校数量数据&#xf…

【基础物理实验】【AFM虚拟实验】基于AFM的物质表面微观结构及力学性质表征仿真实验(下)【北京航空航天大学】

本次实验&#xff08;上&#xff09;见博客&#xff1a;【基础物理实验】【AFM虚拟实验】基于AFM的物质表面微观结构及力学性质表征仿真实验&#xff08;上&#xff09;【北京航空航天大学】 本次实验&#xff08;中&#xff09;见博客&#xff1a;【基础物理实验】【AFM虚拟实…

『哈哥赠书 - 51期』-『数字风控体系:设计与实践』

⭐️ 赠书 - 《数字风控体系&#xff1a;设计与实践》 ⭐️ 数字风控概述 从2007年开始到2014年左右&#xff0c;高速移动网络和智能手机迅速在大众中普及&#xff0c;开启了移动互联网时代。在这个背景下&#xff0c;企业的产品与服务也出现了两个重要的趋势。 第一个趋势是…

(十三)C++自制植物大战僵尸游戏多用户存档实现(二)

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs UserData.h 在头文件中定义了枚举类型openUserDataReturnType&#xff0c;用于表示打开用户数据文件的返回状态。FileExistError表示文件存在但是打开错误&#xff0c;FileExistCorrect表示文件在且正确&#xff0…

活动理论的散点图

import pandas as pd import matplotlib.pyplot as plt# 假设您已经有一个名为 data.xlsx 的 Excel 文件 # 您可以使用以下代码读取数据# 读取 Excel 文件 try:data pd.read_excel(data.xlsx) except Exception as e:print(f"Error: {e}")# 假设您的数据包含以下列:…

2024 OceanBase开发者大会:专场论坛亮点抢先看

4 月 20 日&#xff0c;2024 OceanBase 开发者大会将在上海闵行区漕宝路 3199 号宝龙艾美酒店召开。 此次盛会专为开发者们量身打造&#xff0c;OceanBase诚挚邀请了来自不同行业的最佳实践用户、业界享有盛誉的技术专家&#xff0c;以及OceanBase数据库领域的精英们齐聚一堂。…

线程池学习(通俗易懂)

线程池 线程池是什么ThreadPoolExecutor模拟实现线程池结语 线程池是什么 假设我们要频繁的创建线程和销毁线程,但是创建线程和销毁线程是有成本的. 所以我们可以提前创建一批线程,后面需要使用的时候,直接拿就可以了,这就是线程池. 当线程不再使用的时候,就归还到池子里.为什…

软考131-上午题-【软件工程】-软件可靠性、可用性、可维护性

可靠性、可用性和可维护性是软件的质量属性&#xff0c;软件工程中&#xff0c;用 0-1 之间的数来度量。 0.66 66% 1、 可靠性 可靠性是指一个系统对于给定的时间间隔内、在给定条件下无失效运作的概率。 可以用 MTTF/ (1MTTF) 来度量&#xff0c;其中 MTTF 为平均无故障时间…

算法练习第18天|111.二叉树的最小深度

111.二叉树的最小深度 111. 二叉树的最小深度 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/ 题目描述&#xff1a; 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最…

vue3 vueUse 连接蓝牙

目录 vueuse安装&#xff1a; useBluetooth: 调用蓝牙API 扫描周期设备 选择设备配对 连接成功 vue3的网页项目连接电脑或者手机上的蓝牙设备&#xff0c;使用vueUse库&#xff0c;可以快速检查连接蓝牙设备。 vueUse库使用参考&#xff1a; VueUse工具库 常用api-CSDN…

【代码】Python3|Requests 库怎么继承 Selenium 的 Headers (2024,Chrome)

本文使用的版本&#xff1a; Chrome 124Python 12Selenium 4.19.0 版本过旧可能会出现问题&#xff0c;但只要别差异太大&#xff0c;就可以看本文&#xff0c;因为本文对新老版本都有讲解。 文章目录 1 难点解析和具体思路2 注意事项2.1 PDF 资源获取时注意事项2.2 Capabiliti…

接口防盗刷的方法有哪些?

在工作中&#xff0c;曾经遇到过一个手机号一天发送上百次验证码得情况&#xff0c;这种明显是出问题了&#xff0c;那怎么解决和防范呢&#xff1f; 这是一个非常有意思的问题&#xff0c;防范措施挺多的。今天这篇文章专门跟大家一起聊聊&#xff0c;希望对你会有所帮助。 1…

固定测斜仪:工程观测的精密利器

在工程观测测量领域&#xff0c;固定测斜仪扮演着至关重要的角色。固定测斜仪&#xff0c;凭借其耐冲击型倾斜传感器、出色的可靠性、快速稳定的特点&#xff0c;以及简洁的安装和智能识别功能&#xff0c;已成为行业内重要工具。其输出信号为RS485数字量&#xff0c;可直接显示…

进行接口测试时,连接数据库,对数据源进行备份、还原、验证操作

进行接口测试时&#xff0c;我们需要连接到数据库中&#xff0c;对数据源进行备份、还原、验证等操作。 一、Python连接数据库常见模块 MysqlDBpython2时代最火的驱动库。基于C开发&#xff0c;对windows平台不友好。现在已经进入python3时代&#xff0c;基本不再使用MysqlCl…

OPC-UA是这样在食品和饮料中应用的

什么是 OPC-UA OPC Unified Architecture&#xff0c;即 OPC-UA&#xff0c;是一种基于 TCP/IP 的协议&#xff0c;用于自动化工程师实时、高可靠性、高效性地在控制系统级别共享数据。 OPC-UA 的特点 安全通信: OPC-UA 使用先进的加密方法和严格的访问控制&#xff0c;确保数…