找回密码
 立即注册

QQ登录

只需一步,快速开始

Clark.Pan 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2024-9-9 11:22  /   查看:351  /  回复:0
本帖最后由 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。
  1. CsvSaveOptions options = new CsvSaveOptions();
  2. options.setEncoding("UTF-8");
复制代码
之后通过下面的代码给UTF-8的文件开头添加BOM
  1. private static void addBom(File fileInput) throws IOException {
  2.     try (RandomAccessFile file = new RandomAccessFile(fileInput, "rws")) {
  3.         byte[] text = new byte[(int) file.length()];
  4.         file.readFully(text);
  5.         file.seek(0);
  6.         byte[] bom = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
  7.         file.write(bom);
  8.         file.write(text);
  9.     }
  10. }
复制代码
  1. CsvSaveOptions options = new CsvSaveOptions();
  2. options.setEncoding("UTF-8");
  3. workbook.save("export.csv",options);
  4. addBom(new File("export.csv"))
复制代码


0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部