Java读写CSV文件的几种方式
以下是三种常见的Java读写CSV文件的方法:

使用OpenCSV库(推荐)
添加Maven依赖
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.8</version>
</dependency>
读取CSV文件
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileReader;
import java.io.IOException;
public class ReadCSVWithOpenCSV {
public static void main(String[] args) {
String csvFile = "data.csv";
try (CSVReader reader = new CSVReader(new FileReader(csvFile))) {
String[] line;
while ((line = reader.readNext()) != null) {
// 处理每一行数据
for (String cell : line) {
System.out.print(cell + " | ");
}
System.out.println();
}
} catch (IOException | CsvValidationException e) {
e.printStackTrace();
}
}
}
写入CSV文件
import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;
public class WriteCSVWithOpenCSV {
public static void main(String[] args) {
String csvFile = "output.csv";
try (CSVWriter writer = new CSVWriter(new FileWriter(csvFile))) {
// 写入表头
String[] header = {"姓名", "年龄", "城市"};
writer.writeNext(header);
// 写入数据
String[] data1 = {"张三", "25", "北京"};
String[] data2 = {"李四", "30", "上海"};
String[] data3 = {"王五", "28", "广州"};
writer.writeNext(data1);
writer.writeNext(data2);
writer.writeNext(data3);
System.out.println("CSV文件写入成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Apache Commons CSV
添加Maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.10.0</version>
</dependency>
读取CSV文件
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class ReadCSVWithCommons {
public static void main(String[] args) {
try {
Reader reader = new FileReader("data.csv");
CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
.withFirstRecordAsHeader()
.withIgnoreHeaderCase()
.withTrim());
for (CSVRecord record : csvParser) {
// 通过列名访问数据
String name = record.get("姓名");
String age = record.get("年龄");
String city = record.get("城市");
System.out.println(name + " - " + age + " - " + city);
}
csvParser.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
写入CSV文件
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.FileWriter;
import java.io.IOException;
public class WriteCSVWithCommons {
public static void main(String[] args) {
String[] headers = {"姓名", "年龄", "城市"};
try {
FileWriter out = new FileWriter("output.csv");
CSVPrinter printer = new CSVPrinter(out, CSVFormat.DEFAULT
.withHeader(headers));
printer.printRecord("张三", 25, "北京");
printer.printRecord("李四", 30, "上海");
printer.printRecord("王五", 28, "广州");
printer.flush();
printer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Java原生NIO(不使用第三方库)
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class NativeCSVHandler {
// 读取CSV文件
public static List<String[]> readCSV(String filePath) throws IOException {
List<String[]> records = new ArrayList<>();
try (BufferedReader br = Files.newBufferedReader(Paths.get(filePath))) {
String line;
while ((line = br.readLine()) != null) {
// 处理引号内的逗号
String[] fields = parseCSVLine(line);
records.add(fields);
}
}
return records;
}
// 解析CSV行(处理引号)
private static String[] parseCSVLine(String line) {
List<String> fields = new ArrayList<>();
StringBuilder currentField = new StringBuilder();
boolean inQuotes = false;
for (char c : line.toCharArray()) {
if (c == '"') {
inQuotes = !inQuotes;
} else if (c == ',' && !inQuotes) {
fields.add(currentField.toString().trim());
currentField = new StringBuilder();
} else {
currentField.append(c);
}
}
fields.add(currentField.toString().trim());
return fields.toArray(new String[0]);
}
// 写入CSV文件
public static void writeCSV(String filePath, List<String[]> data) throws IOException {
try (BufferedWriter bw = Files.newBufferedWriter(Paths.get(filePath))) {
for (String[] row : data) {
StringBuilder line = new StringBuilder();
for (int i = 0; i < row.length; i++) {
if (i > 0) {
line.append(",");
}
// 如果包含逗号、引号或换行符,则用引号包裹
if (row[i].contains(",") || row[i].contains("\"") || row[i].contains("\n")) {
line.append("\"").append(row[i].replace("\"", "\"\"")).append("\"");
} else {
line.append(row[i]);
}
}
bw.write(line.toString());
bw.newLine();
}
}
}
}
// 使用示例
public class Main {
public static void main(String[] args) throws IOException {
// 准备数据
List<String[]> data = new ArrayList<>();
data.add(new String[]{"姓名", "年龄", "城市"});
data.add(new String[]{"张三", "25", "北京"});
data.add(new String[]{"李四", "30", "上海"});
data.add(new String[]{"王五", "28", "广州"});
// 写入CSV
NativeCSVHandler.writeCSV("output.csv", data);
// 读取CSV
List<String[]> readData = NativeCSVHandler.readCSV("output.csv");
for (String[] row : readData) {
System.out.println(Arrays.toString(row));
}
}
}
推荐方案
- 项目中使用:推荐使用 OpenCSV 或 Apache Commons CSV,它们处理了各种边界情况(如引号内的逗号、换行符等)
- 简单需求:可以使用Java原生方式,但需要自己处理特殊字符
- 大数据量:考虑使用流式处理方式,避免一次性加载全部数据到内存
注意事项
- 注意处理CSV中的特殊字符(逗号、引号、换行符)
- 考虑文件编码(建议使用UTF-8)
- 处理表头时注意大小写问题
- 大文件时注意内存使用