你可以推荐一个Java库来阅读(也可能写入)CSV文件吗?

您能否推荐一个Java库来读取,parsing,validation和将逗号分隔值(CSV)文件中的行映射到Java值对象(JavaBeans)?

我们用http://opencsv.sourceforge.net/取得了很好的成功;

我也遇到了很好的链接的另一个问题: Java库或应用程序将CSV转换为XML文件?

Super CSV是读取/parsing,validation和将CSV文件映射到POJO的绝佳select!

我们(超级CSV小组)刚刚发布了一个新版本(可以从SourceForge或Maven 下载 )。

读取一个CSV文件

下面的例子使用CsvDozerBeanReader (我们刚刚发布的一个新的读者,它使用Dozer进行bean映射,具有深度映射和基于索引的映射支持) – 它基于我们网站的示例。 如果你不需要Dozerfunction(或者你只是想要一个简单的独立依赖),那么你可以使用CsvBeanReader (参见这个代码示例 )。

示例CSV文件

以下是一个表示对调查答复的示例CSV文件。 它有一个头和三行数据,全部有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 

定义从CSV到POJO的映射

每行CSV将被读入一个SurveyResponse类,每个类都有一个答案列表。 为了使映射工作,你的类应该是有效的JavaBeans(即有一个默认的无参数构造函数,并为每个字段定义getter / setter)。

在超级CSV中,您可以使用简单的string数组定义映射 – 数组中的每个元素都对应于CSV文件中的一列。

使用CsvDozerBeanMapper您可以使用:

  • 简单的字段映射(例如firstName

  • 深层映射(如address.country.code

  • 索引映射(例如, middleNames[1] – 数组或集合的从零开始的索引)

  • 深度+索引映射(例如, person.middleNames[1]

以下是这个例子的字段映射 – 它使用这些的组合:

 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" }; 

转换和validation

Super CSV具有一个有用的单元处理器库,可以用来将string从CSV文件转换为其他数据types(例如Date,Integer),或者进行约束validation(例如强制/可选,正则expression式匹配,范围检查) 。

使用单元处理器是完全可选的 – 没有CSV的每一列都将是一个string,所以每个字段也必须是一个string。

以下是该示例的单元处理器configuration。 与字段映射一样,数组中的每个元素都表示一个CSV列。 它演示了单元处理器如何将CSV数据转换为字段的数据types,以及如何将它们链接在一起。

 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 }; 

使用Super CSV阅读是非常灵活的:你提供自己的Reader (所以你可以读取文件,类path,zip文件等),分隔符和引号字符可以通过首选项configuration(其中有一些预定义的configuration,以满足大多数用途)。

下面的代码是不言自明的。

  1. 创build阅读器(使用您的Reader和首选项)

  2. (可选)读取标题

  3. configurationbean映射

  4. 保持调用read()直到你得到一个null (文件结束)

  5. closures阅读器

码:

 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(); } } 

输出:

 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]]] 

更多信息

你可以在网站上find更多的信息!

我可以推荐SuperCSV 。 简单易用,做了我所需要的一切。

嘿,我有一个开源项目: JFileHelpers 。 我认为主要的好处是它使用Java Annotations,看看:

如果你有这个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; } 

并想parsing这个文件:

 ....|....1....|....2....|....3....|....4 1 Antonio Pereira 10012-12-1978ABC 2 Felipe Coury 201-01-2007 3 Anderson Polga 4212-11-2007DEF 

所有你需要做的是这样的:

 FileHelperEngine<Customer> engine = new FileHelperEngine<Customer>(Customer.class); List<Customer> customers = new ArrayList<Customer>(); customers = engine.readResource( "/samples/customers-fixed.txt"); 

此外,它支持主细节,date和格式转换,以及更多。 让我知道你的想法!

最好的祝福!

我发现Flatpack处理奇怪的CSV文件(转义,引号,坏logging等)

以前问的CSV文件到XML问题似乎回答了我所有的问题。

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); 

除了支持FLR和XML之外,JSEFA( http://jsefa.sourceforge.net )也可以做我所需要的一切,尤其是绑定到Java对象

我用OpenCSV从Javaparsing和编写CSV文件取得了很好的成功。 如果你想读取或写入与Java兼容的Excel电子表格,Apache的POI库是最好的select。

参见CVSBeans