CSVBeans:Java解析CSV

本文介绍了CSVBeans库在Java中解析CSV文件的应用,并详细讨论了解决项目中遇到的相关问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、CSV和CSVBeans介绍


CSV:Comma Seperated Values;
描述:一行代表一个记录,并且一个记录有多个域(属性),每个属性用逗号(或其他符号)分隔。
CSVBeans开源项目:将CSV的每行数据转换成JavaBean的开源工具;

当然解析csv不只有一个工具,还有apache的opencsv等;

依赖包在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
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")));
	}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值