You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Apache CSV读取Excel导出CSV文件及空字符问题排查

嘿,这个问题我太熟了!之前帮好几个朋友排查过类似的坑,大概率是字符编码不匹配搞的鬼,我给你拆解下:

问题根源

外部数据源导出的CSV文件,很大可能是用UTF-16编码保存的(Excel有时候会偷偷导出UTF-16 LE带BOM的格式,尤其是非英文环境下)。而你的代码里直接用InputStreamReader读取时,默认用的是当前系统的编码(一般是UTF-8),UTF-16每个字符占2字节,用UTF-8读就会把每个字符的高字节(空字节)当成独立的空字符,就出现了你看到的“每个字符之间被空字符分隔”的情况。

至于手动复制内容重新生成CSV后正常,是因为你复制粘贴的过程中,Excel已经把内容转成了UTF-8(或者你系统默认的兼容编码),所以读取就没问题了。

解决方案

  1. 先确认编码:用Notepad++这类文本编辑器打开原CSV文件,看一下编码菜单里的选项(比如「编码」→「UTF-16 小端序」是不是被选中),确认原文件的编码格式。
  2. 修改代码指定编码:在创建InputStreamReader的时候,明确指定原文件的编码,比如如果是UTF-16,就改成这样:
InputStream is = null;
Reader in = null;
try {
    is = new ByteArrayInputStream(excelCSVFileBytes);
    // 关键:指定正确的编码,比如UTF-16
    in = new InputStreamReader(is, StandardCharsets.UTF_16);
    // 用Excel兼容的格式解析
    CSVParser parser = CSVParser.parse(in, CSVFormat.EXCEL);
    
    // 后续处理逻辑,比如遍历行
    for (CSVRecord record : parser) {
        // 处理每一行数据
        String value = record.get(0);
        System.out.println(value);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    // 别忘了关闭流
    if (in != null) {
        try { in.close(); } catch (IOException ignored) {}
    }
    if (is != null) {
        try { is.close(); } catch (IOException ignored) {}
    }
}
  1. 如果是带BOM的编码:有些UTF-16文件开头会有BOM(字节顺序标记),如果指定编码后还是有问题,可以用BOMInputStream(来自Apache Commons IO库)来处理BOM:
// 先引入Apache Commons IO依赖,然后修改流的创建
is = new ByteArrayInputStream(excelCSVFileBytes);
BOMInputStream bomInputStream = new BOMInputStream(is);
// 获取实际编码,或者直接指定
Charset charset = bomInputStream.getBOM() == BOMInputStream.BOM.UTF_16LE ? StandardCharsets.UTF_16LE : StandardCharsets.UTF_8;
in = new InputStreamReader(bomInputStream, charset);

这样应该就能解决你的问题了,试试吧!

内容的提问来源于stack exchange,提问作者Pat's

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:34:03