在开发过程中经常需要处理csv文件,我一般是实现一个CSVHelper,封装一些对csv文件的基本操作,代码中直接使用封装好的CSVHelper来读写csv文件就可以了。今天就来记录一下如何通过Java实现封装的csv文件的读写。对于C#实现csv的读写,数据结构可以使用DataTable,但是Java没有这种对象,我用的嵌套List存储数据。
在看具体的代码之前,先来了解一下csv文件是什么,长什么样子。
1. 什么是csv文件?
逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。所有记录都有完全相同的字段序列。
2.csv文件长什么样子
csv文件的扩展名是*.csv,可以通过Excel直接打开,或者通过Notepad++等文本编辑器打开。打开后的文件内容大致类似于如下样子:
IssueId,ProjectId
1111,m1811
2222,m1852
3.代码实现封装的CSVHelper
(1)读取csv文件
/**
* 读取CSV文件
* @param filePath 文件路径(包括文件名)
* @param hasTitle 是否有标题行
* @return
*/
public static List<List<String>> readCSV(String filePath, boolean hasTitle){
List<List<String>> data=new ArrayList<>();
String line=null;
try {
//BufferedReader bufferedReader=new BufferedReader(new FileReader(filePath));
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"utf-8"));
if (hasTitle){
//第一行信息,为标题信息
line = bufferedReader.readLine();
String[] items=line.split(",");
data.add(Arrays.asList(items));
System.out.println("标题行:"+line);
}
int i=0;
while((line=bufferedReader.readLine())!=null){
i++;
//数据行
String[] items=line.split(",");
data.add(Arrays.asList(items));
System.out.println("第"+i+"行:"+line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
测试以上代码:前提需要准备一个有数据的csv文件,然后调用上述readCSV()方法即可,如下:
(2)向csv文件中写数据
/**
* 写CSV文件
* @param data 数据
* @param filePath 文件路径
* @param fileName 文件名
* @param hasTitle 是否有标题行
*/
public static void writeCSV(List<List<String>> data, String filePath,String fileName,boolean hasTitle){
File csvFile=new File(filePath+"/"+fileName);
BufferedWriter bufferedWriter=null;
String line=null;
try {
// bufferedWriter=new BufferedWriter(new FileWriter(csvFile,true));
bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(csvFile),"utf-8"));
for (int i=0;i<data.size();i++){
line=null;
if (hasTitle){
line=getLine(data.get(i));
}
System.out.println(line.toString());
bufferedWriter.write(line.toString());
bufferedWriter.newLine();
}
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
有一些小伙伴在问getLine的方法,其实这个方法很简单。csv每行其实是由csv分割符组成的一个字符串,getLine就是通过List<String>拼成符合csv格式的字符串返回的。
/**
* 获取一行数据的csv格式的字符串
* @param items
* @return
*/
private static String getLine(List<String> items){
StringBuilder line=new StringBuilder();
for (int i=0;i<items.size();i++){
line.append(items.get(i));
if (i<(items.size()-1)){
line.append(",");
}
}
return line.toString();
}
测试以上写入代码:需要准备要写入的数据,然后调用上述的writeCSV方法,如下:
Github: CSVHelper的源码和测试类