\r\n 或 \n, 分隔,含逗號/換行/引號的字段需雙引號包裹並轉義雙引號import java.io.*;
public class CsvCreator {
public static void main(String[] args) {
String path = "C:/data/export.csv";
try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"))) {
// 寫入表頭
pw.write("ID,Name,Email,Score\r\n");
// 寫入數據行
pw.write("1,張三,zhang@example.com,95\r\n");
pw.write("2,李四,\"li,si@example.com\",88\r\n"); // 含逗號字段加引號
pw.write("3,王五,\"He said \\\"Hi\\\"\",76\r\n"); // 含引號轉義
System.out.println("CSV 生成完成:" + path);
} catch (IOException e) {
e.printStackTrace();
}
}
}
手寫解析器易漏邊界情況(引號、換行、轉義),生產環境強烈建議使用成熟庫:
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.9</version>
</dependency>
import com.opencsv.CSVReader;
import java.io.*;
import java.util.List;
public class CsvParser {
public static void main(String[] args) {
String path = "C:/data/export.csv";
try (CSVReader reader = new CSVReader(new FileReader(path))) {
List rows = reader.readAll();
for (String[] row : rows) {
System.out.printf("ID=%s, Name=%s, Email=%s, Score=%s%n", row);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static List parseSimple(File file) throws IOException {
List result = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// 僅處理無引號、無轉義的簡單情況
result.add(line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"));
}
}
return result;
}
正則 ,(?=([^\"]*\"[^\"]*\")*[^\"]*$) 僅在引號外分割,但無法處理換行、轉義引號等複雜情況。
CSVReader.readNext() 逐行讀取,避免 OOM