我最近在 Java 专案中使用 Log4j2 做即时日誌并输出 CSV,输出完成后,文字编辑器打开一切正常,但以 Excel 开启时却出现乱码,明明是 UTF-8,怎么还会有乱码呢? 查资料后才发现原来 CSV 的档头没有带着 BOM (byte-order mark) 导致。本文介绍两种解决办法。
解法1. 用 shell 指令在档头加入 BOM
网路上大部分的解法都是像这样,以事后透过指令或程式手动在档头补上 BOM。如下所示,以下这段指令是先将 BOM 码写入一个空的档案内,再将 CSV 资料倒入这个档案中,这方法看似简单却又带有设计巧思。
#!/usr/bin/env bash#Add BOM to the new fileprintf '\xEF\xBB\xBF' > with_bom.csv# Append the content of the source file to the new filecat 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
栏位需加入
:
header="id,question,answer\n"
就是上述的 UTF-8 BOM,而此解法最大的优点在于: 利用 Log4j2 CsvParameterLayout
原有的 header 属性,借力使力,轻鬆解决 Excel 开启 CSV 中文乱码问题。
References
本文转录自我的部落格 https://kaisheng714.github.io/articles/log4j2-to-utf8-csv-for-excel