您能推荐一个用于读取(并可能写入)CSV 文件的 Java 库吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/200609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can you recommend a Java library for reading (and possibly writing) CSV files?
提问by Vihung
Can you recommend a Java library for reading, parsing, validating and mapping rows in a comma separated value (CSV) file to Java value objects (JavaBeans)?
你能推荐一个 Java 库来读取、解析、验证和映射逗号分隔值 (CSV) 文件中的行到 Java 值对象 (JavaBeans) 吗?
采纳答案by Gary McWilliams
We have used http://opencsv.sourceforge.net/with good success
我们已经 成功地使用了 http://opencsv.sourceforge.net/
I also came across another question with good links: Java lib or app to convert CSV to XML file?
我还遇到了另一个带有良好链接的问题: Java lib or app to convert CSV to XML file?
回答by Steve Moyer
回答by Vihung
The CSV File to XML question asked previously seems to answer all my questions.
先前提出的 CSV File to XML 问题似乎回答了我所有的问题。
OpenCSV (http://opencsv.sourceforge.net/) also does binding to JavaBeans using a Column Position Mapping Strategy
OpenCSV ( http://opencsv.sourceforge.net/) 也使用列位置映射策略绑定到 JavaBeans
ColumnPositionMappingStrategy strat = new ColumnPositionMappingStrategy();
strat.setType(YourOrderBean.class);
String[] columns = new String[] {"name", "orderNumber", "id"}; // the fields to bind do in your JavaBean
strat.setColumnMapping(columns);
CsvToBean csv = new CsvToBean();
List list = csv.parse(strat, yourReader);
JSEFA (http://jsefa.sourceforge.net) also seems to do everything I need - particularly binding to Java objects - in addition to supporting FLR and XML
JSEFA ( http://jsefa.sourceforge.net) 除了支持 FLR 和 XML 之外,似乎还可以做我需要的一切 - 特别是绑定到 Java 对象
回答by ddimitrov
回答by kolrie
Hey, I have an open-source project for that: JFileHelpers. I think the main advantage is that it uses Java Annotations, take a look:
嘿,我有一个开源项目:JFileHelpers。我认为主要的优点是它使用了 Java Annotations,看看:
If you have this bean:
如果你有这个豆子:
@FixedLengthRecord()
public class Customer {
@FieldFixedLength(4)
public Integer custId;
@FieldAlign(alignMode=AlignMode.Right)
@FieldFixedLength(20)
public String name;
@FieldFixedLength(3)
public Integer rating;
@FieldTrim(trimMode=TrimMode.Right)
@FieldFixedLength(10)
@FieldConverter(converter = ConverterKind.Date,
format = "dd-MM-yyyy")
public Date addedDate;
@FieldFixedLength(3)
@FieldOptional
public String stockSimbol;
}
And wants to parse this file:
并想解析这个文件:
....|....1....|....2....|....3....|....4
1 Antonio Pereira 10012-12-1978ABC
2 Felipe Coury 201-01-2007
3 Anderson Polga 4212-11-2007DEF
All you have to do is this:
你所要做的就是:
FileHelperEngine<Customer> engine =
new FileHelperEngine<Customer>(Customer.class);
List<Customer> customers =
new ArrayList<Customer>();
customers = engine.readResource(
"/samples/customers-fixed.txt");
Also, it supports master-detail, date and format conversion, and a lot more. Let me know what you think!
此外,它还支持主从、日期和格式转换等等。让我知道你的想法!
Best regards!
此致!
回答by Domchi
回答by James Bassett
Super CSVis a great choice for reading/parsing, validating and mapping CSV files to POJOs!
Super CSV是读取/解析、验证和映射 CSV 文件到 POJO 的绝佳选择!
We (the Super CSV team) have just released a new version (you can downloadit from SourceForge or Maven).
我们(Super CSV 团队)刚刚发布了一个新版本(您可以从 SourceForge 或 Maven下载)。
Reading a CSV file
读取 CSV 文件
The following example uses CsvDozerBeanReader
(a new reader we've just released that uses Dozerfor bean mapping with deep mapping and index-based mapping support) - it's based on the example from our website. If you don't need the Dozer functionality (or you just want a simple standalone dependency), then you can use CsvBeanReader
instead (see this code example).
下面的示例使用CsvDozerBeanReader
(我们刚刚发布的一个新阅读器,它使用Dozer进行带有深度映射和基于索引的映射支持的 bean 映射)——它基于我们网站上的示例。如果您不需要 Dozer 功能(或者您只想要一个简单的独立依赖项),那么您可以CsvBeanReader
改用(请参阅此代码示例)。
Example CSV file
示例 CSV 文件
Here is an example CSV file that represents responses to a survey. It has a header and 3 rows of data, all with 8 columns.
这是一个示例 CSV 文件,它表示对调查的响应。它有一个标题和 3 行数据,全部有 8 列。
age,consentGiven,questionNo1,answer1,questionNo2,answer2,questionNo3,answer3
18,Y,1,Twelve,2,Albert Einstein,3,Big Bang Theory
,Y,1,Thirteen,2,Nikola Tesla,3,Stargate
42,N,1,,2,Carl Sagan,3,Star Wars
Defining the mapping from CSV to POJO
定义从 CSV 到 POJO 的映射
Each row of CSV will be read into a SurveyResponseclass, each of which has a List of Answers. In order for the mapping to work, your classes should be valid Javabeans (i.e have a default no-arg constructor and have getters/setters defined for each field).
CSV 的每一行都将被读入一个SurveyResponse类,每个类都有一个 List of Answer。为了使映射工作,您的类应该是有效的 Javabeans(即具有默认的无参数构造函数并为每个字段定义了 getter/setter)。
In Super CSV you define the mapping with a simple String array - each element of the array corresponds to a column in the CSV file.
在 Super CSV 中,您使用简单的 String 数组定义映射 - 数组的每个元素对应于 CSV 文件中的一列。
With CsvDozerBeanMapper
you can use:
有了CsvDozerBeanMapper
你可以使用:
simple field mappings (e.g.
firstName
)deep mappings (e.g.
address.country.code
)indexed mapping (e.g.
middleNames[1]
- zero-based index for arrays or Collections)deep + indexed mapping (e.g.
person.middleNames[1]
)
简单的字段映射(例如
firstName
)深度映射(例如
address.country.code
)索引映射(例如
middleNames[1]
- 数组或集合的从零开始的索引)深度 + 索引映射(例如
person.middleNames[1]
)
The following is the field mapping for this example - it uses a combination of these:
以下是此示例的字段映射 - 它使用了这些的组合:
private static final String[] FIELD_MAPPING = new String[] {
"age", // simple field mapping (like for CsvBeanReader)
"consentGiven", // as above
"answers[0].questionNo", // indexed (first element) + deep mapping
"answers[0].answer",
"answers[1].questionNo", // indexed (second element) + deep mapping
"answers[1].answer",
"answers[2].questionNo",
"answers[2].answer" };
Conversion and Validation
转换和验证
Super CSV has a useful library of cell processors, which can be used to convert the Strings from the CSV file to other data types (e.g. Date, Integer), or to do constraint validation (e.g. mandatory/optional, regex matching, range checking).
Super CSV 有一个有用的单元处理器库,可用于将字符串从 CSV 文件转换为其他数据类型(例如日期、整数),或进行约束验证(例如强制/可选、正则表达式匹配、范围检查) .
Using cell processors is entirely optional- without them each column of CSV will be a String, so each field must be a String also.
使用单元处理器是完全可选的——如果没有它们,CSV 的每一列都将是一个字符串,因此每个字段也必须是一个字符串。
The following is the cell processor configuration for the example. As with the field mapping, each element in the array represents a CSV column. It demonstrates how cell processors can transform the CSV data to the data type of your field, and how they can be chained together.
以下是示例的单元处理器配置。与字段映射一样,数组中的每个元素都代表一个 CSV 列。它演示了单元处理器如何将 CSV 数据转换为字段的数据类型,以及如何将它们链接在一起。
final CellProcessor[] processors = new CellProcessor[] {
new Optional(new ParseInt()), // age
new ParseBool(), // consent
new ParseInt(), // questionNo 1
new Optional(), // answer 1
new ParseInt(), // questionNo 2
new Optional(), // answer 2
new ParseInt(), // questionNo 3
new Optional() // answer 3
};
Reading
读
Reading with Super CSV is very flexible: you supply your own Reader
(so you can read from a file, the classpath, a zip file, etc), and the delimiter and quote character are configurable via preferences(of which there are a number of pre-defined configurations that cater for most usages).
使用 Super CSV 读取非常灵活:您提供自己的Reader
(因此您可以从文件、类路径、zip 文件等中读取),并且分隔符和引号字符可通过首选项进行配置(其中有许多预- 满足大多数用途的定义配置)。
The code below is pretty self-explanatory.
下面的代码是不言自明的。
Create the reader (with your
Reader
and preferences)(Optionally) read the header
Configure the bean mapping
Keep calling
read()
until you get anull
(end of file)Close the reader
创建阅读器(根据您的
Reader
喜好)(可选)读取标题
配置bean映射
继续打电话,
read()
直到你得到一个null
(文件结尾)关闭阅读器
Code:
代码:
ICsvDozerBeanReader beanReader = null;
try {
beanReader = new CsvDozerBeanReader(new FileReader(CSV_FILENAME),
CsvPreference.STANDARD_PREFERENCE);
beanReader.getHeader(true); // ignore the header
beanReader.configureBeanMapping(SurveyResponse.class, FIELD_MAPPING);
SurveyResponse surveyResponse;
while( (surveyResponse =
beanReader.read(SurveyResponse.class, processors)) != null ) {
System.out.println(
String.format("lineNo=%s, rowNo=%s, surveyResponse=%s",
beanReader.getLineNumber(), beanReader.getRowNumber(),
surveyResponse));
}
} finally {
if( beanReader != null ) {
beanReader.close();
}
}
Output:
输出:
lineNo=2, rowNo=2, surveyResponse=SurveyResponse [age=18, consentGiven=true, answers=[Answer [questionNo=1, answer=Twelve], Answer [questionNo=2, answer=Albert Einstein], Answer [questionNo=3, answer=Big Bang Theory]]]
lineNo=3, rowNo=3, surveyResponse=SurveyResponse [age=null, consentGiven=true, answers=[Answer [questionNo=1, answer=Thirteen], Answer [questionNo=2, answer=Nikola Tesla], Answer [questionNo=3, answer=Stargate]]]
lineNo=4, rowNo=4, surveyResponse=SurveyResponse [age=42, consentGiven=false, answers=[Answer [questionNo=1, answer=null], Answer [questionNo=2, answer=Carl Sagan], Answer [questionNo=3, answer=Star Wars]]]
More Information
更多信息
You can find a lot more information on the website!
您可以在网站上找到更多信息!