在 Java 開發中,將資料匯出為 CSV 檔案是常見需求。然而,直接以 UTF-8 編碼寫入 CSV 時,Excel 開啟往往會出現亂碼,因為 Excel 預期 UTF-8 檔案開頭應包含 BOM (Byte Order Mark)。本文示範如何利用 Google Guava 函式庫,在寫入 CSV 時自動加入 UTF-8 BOM,確保 Excel 正確識別編碼。
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.google.common.primitives.Bytes;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class CsvHelper {
private static final String DELIMITER = ",";
private static final String LINE_END = "\r\n";
// UTF-8 BOM: EF BB BF
private static final byte[] UTF8_BOM = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
public static void writeCsv(List<List<String>> data) throws IOException {
StringBuilder sb = new StringBuilder();
for (List<String> row : data) {
sb.append(Joiner.on(DELIMITER).join(row)).append(LINE_END);
}
// 關鍵步驟:將 BOM 與內容位元組合併後寫入
Files.write(Bytes.concat(UTF8_BOM, sb.toString().getBytes(Charsets.UTF_8)), new File("d:/export.csv"));
}
}
0xEF, 0xBB, 0xBF 為 UTF-8 BOM 標準簽名,放在檔案最前端。Bytes.concat:將 BOM 與內容位元組無縫合併,避免手動操作 FileOutputStream 的繁瑣。Charsets.UTF_8:明確指定編碼,避免平台預設編碼差異導致問題。public static void main(String[] args) throws IOException {
List<List<String>> data = Lists.newArrayList();
data.add(Lists.newArrayList("測試標題1", "測試標題2"));
data.add(Lists.newArrayList("資料A", "資料B"));
writeCsv(data);
System.out.println("CSV 已產生至 d:/export.csv");
}
產出的檔案以 Excel 開啟,中文欄位將完美顯示,不再出現亂碼。
若專案未引入 Guava,亦可改用標準 java.nio.file.Files 配合 StandardOpenOption 手寫 BOM;但 Guava 的 Files.write 封裝了原子寫入與資源釋放,程式碼更簡潔安全。