Java案例如何导入CSV数据?

wen java案例 71

本文目录导读:

Java案例如何导入CSV数据?

  1. 使用OpenCSV库(推荐)
  2. 使用Apache Commons CSV
  3. 手动解析CSV(无需第三方库)
  4. 使用Spring Batch(适合大数据量)
  5. 推荐选择

在Java中导入CSV数据有多种方式,我来介绍几种常用的方法:

使用OpenCSV库(推荐)

添加依赖(Maven)

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.8</version>
</dependency>

基本用法

import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class CSVImporter {
    public static void main(String[] args) {
        String csvFile = "data.csv";
        try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvFile))
                .withSkipLines(1)  // 跳过标题行
                .build()) {
            List<String[]> records = reader.readAll();
            for (String[] record : records) {
                for (String field : record) {
                    System.out.print(field + " | ");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}

映射到Java对象

import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import java.io.FileReader;
import java.util.List;
public class CSVToObject {
    public static void main(String[] args) {
        String csvFile = "employees.csv";
        try (FileReader reader = new FileReader(csvFile)) {
            CsvToBean<Employee> csvToBean = new CsvToBeanBuilder<Employee>(reader)
                    .withType(Employee.class)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build();
            List<Employee> employees = csvToBean.parse();
            employees.forEach(System.out::println);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
// Employee类
public class Employee {
    @CsvBindByName(column = "ID")
    private int id;
    @CsvBindByName(column = "姓名")
    private String name;
    @CsvBindByName(column = "年龄")
    private int age;
    @CsvBindByName(column = "部门")
    private String department;
    // getter和setter方法
    // toString方法
}

使用Apache Commons CSV

添加依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.10.0</version>
</dependency>

基本用法

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.FileReader;
import java.io.Reader;
public class CommonsCSVExample {
    public static void main(String[] args) {
        try (Reader reader = new FileReader("data.csv")) {
            Iterable<CSVRecord> records = CSVFormat.DEFAULT
                    .withFirstRecordAsHeader()  // 第一行为标题
                    .parse(reader);
            for (CSVRecord record : records) {
                String name = record.get("姓名");
                String age = record.get("年龄");
                String department = record.get("部门");
                System.out.printf("姓名: %s, 年龄: %s, 部门: %s%n", 
                    name, age, department);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

手动解析CSV(无需第三方库)

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ManualCSVParser {
    public static void main(String[] args) {
        String csvFile = "data.csv";
        List<String[]> rows = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            String line;
            boolean isFirstLine = true;
            while ((line = br.readLine()) != null) {
                // 跳过标题行
                if (isFirstLine) {
                    isFirstLine = false;
                    continue;
                }
                // 简单分割CSV行
                String[] fields = parseCSVLine(line);
                rows.add(fields);
            }
            // 输出数据
            for (String[] row : rows) {
                System.out.println(String.join(" | ", row));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 简单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]);
    }
}

使用Spring Batch(适合大数据量)

@Configuration
@EnableBatchProcessing
public class BatchCSVImport {
    @Bean
    public FlatFileItemReader<Employee> reader() {
        return new FlatFileItemReaderBuilder<Employee>()
                .name("employeeItemReader")
                .resource(new FileSystemResource("employees.csv"))
                .delimited()
                .names(new String[]{"id", "name", "age", "department"})
                .fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{
                    setTargetType(Employee.class);
                }})
                .build();
    }
    @Bean
    public JdbcBatchItemWriter<Employee> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Employee>()
                .itemSqlParameterSourceProvider(
                    new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql("INSERT INTO employee (id, name, age, department) " +
                     "VALUES (:id, :name, :age, :department)")
                .dataSource(dataSource)
                .build();
    }
}

推荐选择

  1. 小型项目/简单需求:使用OpenCSV,功能完善,使用简单
  2. 需要处理复杂CSV格式:使用Apache Commons CSV,支持更多格式选项
  3. 避免第三方依赖:使用手动解析,但要考虑各种边界情况
  4. 大数据量处理:使用Spring Batch或流式读取

选择哪个方案主要取决于你的具体需求和项目规模。

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