OpenCSV là thư viện phổ biến, dễ dùng để parse/ghi CSV trong Java. Xử lý tự động quote, escape, delimiter, header mapping.
Dependency (Maven/Gradle)
implementation 'com.opencsv:opencsv:5.8' com.opencsv opencsv 5.8
1. Đọc CSV dòng per dòng (Streaming, tiết kiệm memory)
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class CsvReadDemo {
public static void readLineByLine(String filePath) {
try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
String[] line;
int lineNum = 0;
while ((line = reader.readNext()) != null) {
lineNum++;
if (lineNum == 1) {
System.out.println("Header: " + String.join(" | ", line));
continue;
}
System.out.printf("Row %d: %s%n", lineNum, String.join(" | ", line));
}
} catch (IOException | CsvException e) {
e.printStackTrace();
}
}
// Đọc tất cả vào List (chỉ file nhỏ)
public static List readAll(String filePath) {
try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
return reader.readAll();
} catch (IOException | CsvException e) {
throw new RuntimeException(e);
}
}
}
2. Đọc CSV mapping trực tiếp vào Bean (POJO) – Khuyên dùng
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import java.io.FileReader;
import java.util.List;
// POJO với annotation mapping
public class Employee {
@CsvBindByName(column = "id")
private int id;
@CsvBindByName(column = "name")
private String name;
@CsvBindByName(column = "department")
private String department;
@CsvBindByName(column = "salary")
private double salary;
// getters, setters, toString
}
// Đọc
public class CsvBeanDemo {
public static List readEmployees(String filePath) {
try (FileReader reader = new FileReader(filePath)) {
return new CsvToBeanBuilder(reader)
.withType(Employee.class)
.withIgnoreLeadingWhiteSpace(true)
.withThrowExceptions(false)
.build()
.parse();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3. Ghi CSV từ Bean
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
import java.io.FileWriter;
import java.util.List;
public class CsvWriteDemo {
public static void writeEmployees(List employees, String filePath) {
try (FileWriter writer = new FileWriter(filePath)) {
StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
.withSeparator(CSVWriter.DEFAULT_SEPARATOR)
.withOrderedResults(true)
.build();
beanToCsv.write(employees);
} catch (IOException | CsvDataTypeMismatchException | CsvRequiredFieldEmptyException e) {
throw new RuntimeException(e);
}
}
}
4. Cấu hình nâng cao
CSVReader reader = new CSVReaderBuilder(new FileReader(file))
.withSkipLines(1) // Bỏ qua N dòng đầu
.withCSVParser(new CSVParserBuilder()
.withSeparator(';') // Delimiter tùy chỉnh (mặc định ',')
.withQuoteChar('"')
.withEscapeChar('\\')
.build())
.build();
CSVWriter writer = new CSVWriter(new FileWriter(file),
CSVWriter.DEFAULT_SEPARATOR,
CSVWriter.NO_QUOTE_CHARACTER, // Không quote
CSVWriter.DEFAULT_ESCAPE_CHARACTER,
CSVWriter.DEFAULT_LINE_END);
5. Xử lý file lớn (Streaming + Parallel)
// Java 8+ Stream từ CSVReader (OpenCSV 5.2+)
try (CSVReader reader = new CSVReader(new FileReader(largeFile))) {
reader.stream() // Stream
.skip(1) // Bỏ header
.parallel() // Xử lý song song
.forEach(row -> processRow(row));
}
Lưu ý & Best Practices
- Luôn dùng
try-with-resourcesđể tự đóng reader/writer. - File lớn: đọc dòng per dòng (streaming), KHÔNG
readAll(). - Encoding: Mặc định platform encoding. Chỉ định:
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8). - Header mapping: Dùng
@CsvBindByName(header name) hoặc@CsvBindByPosition(index). - Type conversion: OpenCV tự convert String → primitive/wrapper. Custom converter: implement
Converter. - Error handling:
withThrowExceptions(false)+CsvToBean.getCapturedExceptions()để collect lỗi từng dòng.
Thay thế nhẹ: Jackson CSV
Nếu đã dùng Jackson JSON, có thể dùng jackson-dataformat-csv – API nhất quán, ít dependency hơn.