Clark.Pan 发表于 2024-9-9 11:22:10

GcExcel导出CSV特殊字符出现乱码问题

本帖最后由 Clark.Pan 于 2024-9-9 11:23 编辑

背景:


之前文章中有介绍GcExcel导出CSV乱码问题的解决方案。其中有说到设置编码为GBK后导出CSV。该方案适用于大多数场景,但是当文档中包含一些特殊符号时,例如人民币的“¥”符号。这个时候使用上述方案导出CSV 会发现“¥”符号变成了“?”,上述方案将不再适用。

原因:

这是因为当使用 ANSI 编码,例如 GB2312、GBK 或 GB18030,Excel 可能会将特性的一些内容显示成乱码,这是由 Excel 的编码检测引起的。解决方案是使用UTF-8-BOM这种编码格式。
UTF-8 BOM 与 UTF-8存在一些区别:
BOM (Byte Order Mark) 是一个特殊的字节序列,用来标记文本文件的字节序。

[*]UTF-8:标准的 UTF-8 编码,不包含字节顺序标记(BOM)。
[*]UTF-8 BOM:在文件开头带有字节顺序标记(0xEF 0xBB 0xBF),用于明确编码为 UTF-8。


加入了BOM相当于明确了编码,这就使得在中文Excel解析CSV的时候不会用默认的 ANSI 的编码去处理,而是会按照BOM上记载的编码使用UTF-8编码来处理。这就是为什么即使中文Excel默认的编码方式为 ANSI,但导入后仍然不会出现乱码的原因。


解决方案:
解决方案的思路就是,先利用GcExcel导出CSV的时候设置编码格式为UTF-8。
CsvSaveOptions options = new CsvSaveOptions();
options.setEncoding("UTF-8");之后通过下面的代码给UTF-8的文件开头添加BOM
private static void addBom(File fileInput) throws IOException {
    try (RandomAccessFile file = new RandomAccessFile(fileInput, "rws")) {
      byte[] text = new byte[(int) file.length()];
      file.readFully(text);
      file.seek(0);
      byte[] bom = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
      file.write(bom);
      file.write(text);
    }
}CsvSaveOptions options = new CsvSaveOptions();
options.setEncoding("UTF-8");
workbook.save("export.csv",options);
addBom(new File("export.csv"))

页: [1]
查看完整版本: GcExcel导出CSV特殊字符出现乱码问题