Java案例如何读写CSV文件?

wen java案例 68

Java读写CSV文件的几种方式

以下是三种常见的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));
        }
    }
}

推荐方案

  1. 项目中使用:推荐使用 OpenCSVApache Commons CSV,它们处理了各种边界情况(如引号内的逗号、换行符等)
  2. 简单需求:可以使用Java原生方式,但需要自己处理特殊字符
  3. 大数据量:考虑使用流式处理方式,避免一次性加载全部数据到内存

注意事项

  • 注意处理CSV中的特殊字符(逗号、引号、换行符)
  • 考虑文件编码(建议使用UTF-8)
  • 处理表头时注意大小写问题
  • 大文件时注意内存使用

抱歉,评论功能暂时关闭!