一、CSV和CSVBeans介绍
CSV:Comma Seperated Values;
描述:一行代表一个记录,并且一个记录有多个域(属性),每个属性用逗号(或其他符号)分隔。
CSVBeans开源项目:将CSV的每行数据转换成JavaBean的开源工具;
Download URL:http://sourceforge.net/projects/csvbeans/files/
当然解析csv不只有一个工具,还有apache的opencsv等;

读取csv程序:
依赖包在lib目录中,也要一并添加,包括:
commons-resources.jar
commons-logging.jar
commons-lang-2.1.jar
commons-digester-1.7.jar
commons-codec-1.3.jar
commons-beanutils-core.jar
commons-beanutils-bean-collections.jar
commons-beanutils.jar
二、项目缺陷解决
首先,这个项目我目前找出了两个小问题:
(1)csv文件数据之间不能够以\t分隔;
(2)写csv文件时,一定要带有startTag;
必须要有startTag的意思是:
Persons ---->这个就是startTag
aaa,20
aaa,20
aaa,20
不能没有startTag的意思是:
aaa,20
aaa,20
aaa,20
如果startTag设为null,则会有问题;
|
解决:
(1)对于第一个问题,如果存在一个csv文件以\t分隔,则我写了一个辅助类,可以用于将此csv文件重写成以逗号分隔的csv文件;
package com.xiazdong.csv;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.UUID;
public class CSVUtils {
/**
* 此函数用于辅助CSVBeans,由于此开源包有一个缺陷,就是不能解析以tab为分隔符的csv,因此此函数专门用于将tab转换成逗号,并覆盖原有文件
* @param fromFile 需要转换的文件
* @throws Exception
*/
public static void parseFromTabToComma(File fromFile)throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fromFile)));
File tmpFile = new File(UUID.randomUUID().toString()); //生成临时文件,不过最后不会存在
PrintWriter writer = new PrintWriter(tmpFile);
String line = null;
while((line=reader.readLine())!=null){
String ss[] = line.split("\\t"); //以tab分隔
for(int i=0;i<ss.length;i++){
writer.write(ss[i]);
if(i<(ss.length-1)){
writer.write(",");
}
}
writer.write("\n");
}
writer.close();
reader.close();
if(fromFile.exists()){
fromFile.delete();
tmpFile.renameTo(fromFile);
}
}
public static void main(String[] args) throws Exception {
parseFromTabToComma(new File("src/persons.csv"));
}
}
(2)对于第二个问题,就必须要修改源码了;
源码下载:http://sourceforge.net/projects/csvbeans/files/csvbeans/csvbeans-0.7.1/
csvbeans-0.7.1\src\java\org\csvbeans\builders\CSVBuilder.java
csvbeans-0.7.1\src\java\org\csvbeans\builders\CSVBuilder.java
addBeans函数改为:
public void addBeans(String tag, List beans) {
if (beans != null) {
this.beans.add(new Records(tag, beans));
}
}
writeBeans函数开头改为:
try {
if(tag!=null)
writer.writeLine(tag);
RecordSpecification record = getRecordSpecification(tag);
修改了源码后还需要用ant编译,ant package 就自动生成了csvbeans.jar;
三、前期准备
1.编写JavaBean表示一条CSV记录;
2.编写一个XML文件,内容为:
(1)一条CSV记录的属性,每个属性的name、maxLen等;
(2)每个属性之间的分隔符;
(3)JavaBean所在类;
(4)使用的Parser类、Builder类;
四、编写程序
目录结构:

首先说明,读取csv和写入csv的JavaBean和mapping.xml都是一样的;
1.读取csv
Person.java略
mapping.xml
<?xml version="1.0" ?>
<csvbeans>
<strategy>
<parser className="org.csvbeans.parsers.CSVParser" />
<builder className="org.csvbeans.builders.CSVBuilder" />
</strategy>
<property name="separator" value="," /> <!--分隔符 -->
<property name="noStartTag" value="true" /> <!--没有startTag -->
<record className="com.xiazdong.csv.domain.Person"> <!-- 一条记录-->
<field name="name" maxLen="100" required="true" />
<field name="age" maxLen="10" required="true"/>
</record>
</csvbeans>
读取csv程序:
private static void read() throws Exception, SpecificationsFileException,
FileNotFoundException, ParsingException {
File f = new File("src/persons.csv");
CSVUtils.parseFromTabToComma(f); //如果csv文件是以tab分隔,则需要使用这个函数
SpecificationsFileParser specsParser = new SpecificationsFileParser();
SpecificationsFile specs = specsParser.parse(new FileInputStream("src/mapping.xml"));
ParsingStrategy parser = specs.getParsingStrategy(); //获得mapping.xml中的CSVParser
parser.parse(new InputStreamLinesReader(new FileInputStream(f)));
List products = parser.getBeans(null); //没有头
for (Iterator it = products.iterator(); it.hasNext(); ) {
Person product = (Person) it.next();
System.out.println(product);
}
}
2.写入csv
private static void write() throws SpecificationsFileException,
FileNotFoundException, GenerationException {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("我", 20, 20));
persons.add(new Person("aaa", 20, 20));
persons.add(new Person("aaa", 20, 20));
SpecificationsFileParser specsParser = new SpecificationsFileParser();
SpecificationsFile specs = specsParser.parse(new FileInputStream("src/mapping.xml"));
BuildingStrategy builder = specs.getBuildingStrategy(); //获得mapping.xml中的CSVBuilder
CSVBuilder csvbuilder = (CSVBuilder)builder;
csvbuilder.addBeans(null, persons);
csvbuilder.build(new OutputStreamLinesWriter(new FileOutputStream("src/output.csv")));
}