Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

การทำงานกับไฟล์ CSV ใน Java

การอ่าน/เขียนไฟล์ CSV ใน Java ด้วย OpenCSV

Java ไม่มี Built-in CSV parser ต้องใช้ Library ยอดนิยมคือ OpenCSV หรือ Apache Commons CSV

การติดตั้ง OpenCSV (Maven)

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

Gradle

implementation 'com.opencsv:opencsv:5.9'

การอ่าน CSV แบบบรรทัดต่อบรรทัด

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class CsvReaderExample {
    public static void readLineByLine(String filePath) {
        try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
            String[] line;
            int lineNumber = 0;
            
            while ((line = reader.readNext()) != null) {
                lineNumber++;
                if (lineNumber == 1) {
                    System.out.println("Header: " + String.join(" | ", line));
                    continue;
                }
                System.out.println("Row " + lineNumber + ": " + String.join(" | ", line));
            }
        } catch (IOException | CsvException e) {
            System.err.println("Error reading CSV: " + e.getMessage());
        }
    }
    
    // อ่านทั้งหมดเป็น List
    public static List readAll(String filePath) {
        try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
            return reader.readAll();
        } catch (IOException | CsvException e) {
            throw new RuntimeException("Failed to read CSV", e);
        }
    }
}

การอ่าน CSV แมปเป็น Object (Bean Mapping)

import com.opencsv.bean.CsvToBeanBuilder;
import java.io.FileReader;
import java.util.List;

public class User {
    @CsvBindByName(column = "id")
    private int id;
    
    @CsvBindByName(column = "name")
    private String name;
    
    @CsvBindByName(column = "email")
    private String email;
    
    // getters, setters, toString()
}

public class CsvToBeanExample {
    public static List readUsers(String filePath) {
        try (FileReader reader = new FileReader(filePath)) {
            return new CsvToBeanBuilder(reader)
                .withType(User.class)
                .withIgnoreLeadingWhiteSpace(true)
                .build()
                .parse();
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse CSV to beans", e);
        }
    }
}

การเขียน CSV

import com.opencsv.CSVWriter;
import java.io.FileWriter;
import java.io.IOException;

public class CsvWriterExample {
    public static void writeCsv(String filePath, List data) {
        try (CSVWriter writer = new CSVWriter(new FileWriter(filePath))) {
            writer.writeAll(data);
        } catch (IOException e) {
            throw new RuntimeException("Failed to write CSV", e);
        }
    }
    
    // เขียนจาก Bean
    public static void writeBeans(String filePath, List users) {
        try (FileWriter writer = new FileWriter(filePath)) {
            new com.opencsv.bean.StatefulBeanToCsvBuilder(writer)
                .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
                .build()
                .write(users);
        } catch (Exception e) {
            throw new RuntimeException("Failed to write beans to CSV", e);
        }
    }
}

ตัวอย่าง CSV Input (users.csv)

id,name,email
1,John Doe,john@example.com
2,Jane Smith,jane@example.com
3,Bob Wilson,bob@example.com

ตัวเลือก Library อื่น

Library ข้อดี ข้อเสีย
OpenCSV Feature-rich, Bean mapping, RFC 4180 compliant Size ใหญ่กว่า
Apache Commons CSV Lightweight, Simple API, Apache License Bean mapping ต้องเขียนเอง
Jackson CSV Integration กับ Jackson JSON, Streaming Complex setup
UniVocity Parsers เร็วมาก, Memory efficient Commercial license (Free for open source)

การจัดการกรณีพิเศษ

  • Quote/Escape: OpenCSV จัดการอัตโนมัติ ตาม RFC 4180
  • Encoding: ระบุ UTF-8: new FileReader(file, StandardCharsets.UTF_8) (Java 11+)
  • Large files: ใช้ CSVReader แบบ Streaming (readNext) ไม่ใช่ readAll
  • Header mapping: ใช้ HeaderColumnNameMappingStrategy สำหรับ Bean mapping