我最近在 Java 專案中使用 Log4j2 做即時日誌並輸出 CSV,輸出完成後,文字編輯器打開一切正常,但以 Excel 開啟時卻出現亂碼,明明是 UTF-8,怎麼還會有亂碼呢? 查資料後才發現原來 CSV 的檔頭沒有帶著 BOM (byte-order mark) 導致。本文介紹兩種解決辦法。

log4j-to-utf8-csv-for-excel

解法1. 用 shell 指令在檔頭加入 BOM

網路上大部分的解法都是像這樣,以事後透過指令或程式手動在檔頭補上 BOM。如下所示,以下這段指令是先將 BOM 碼寫入一個空的檔案內,再將 CSV 資料倒入這個檔案中,這方法看似簡單卻又帶有設計巧思。

#!/usr/bin/env bash

#Add BOM to the new file
printf '\xEF\xBB\xBF' > with_bom.csv

# Append the content of the source file to the new file
cat source_file.csv >> with_bom.csv

雖然簡單,但這並不符合我的需求,這種解法需要多一個處理步驟,但我希望能使用 Log4j2 一氣呵成

在研究無果後,我只好在 Stackoverflow 上發問,所幸有一位熱心網友給了答案:

解法2. 在 header 裡加入 BOM (推薦)

CsvParameterLayout 是 Log4j2 推出的專門給 CSV 的 Layout 類型,只需要簡單的設定就能輸出成 CSV 檔。Log4j2 版本為 2.17.0,以下是我的 log4j2.xml 程式片段:

<RollingFile 
  name="Chat-Appender" 
  fileName="output.csv">
  <CsvParameterLayout 
      delimiter="," 
      format="Excel"
      header="id,question,answer\n"
      charset="UTF-8" />
</RollingFile>

至於如何解決 CSV 檔中文亂碼問題呢? 關鍵在於 header 欄位需加入 &#xFEFF;:

header="&#xFEFF;id,question,answer\n"

&#xFEFF; 就是上述的 UTF-8 BOM,而此解法最大的優點在於: 利用 Log4j2 CsvParameterLayout 原有的 header 屬性,借力使力,輕鬆解決 Excel 開啟 CSV 中文亂碼問題。


References

更多你可能會感興趣的文章

Java

view: