暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Node.js 生成CSV文件以及Excel打开时的乱码问题

背井 2021-03-03
3775

节前最后一天,不让人省心的运营同学又出了个新需求:每天定时导出某某统计数据。

为了快速完成任务,决定用 Node.js 来写,csv 库用的则是 csv-writer 这个 npm 包。

大体要用的代码如下:

  1. 安装依赖
npm i csv-writer

  1. 从数据库取出数据,写入 csv 文件:
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const csvWriter = createCsvWriter({
    path'path/to/file.csv',
    header: [ // 表头
        { id'name'title'NAME' },
        { id'lang'title'LANGUAGE' },
    ],
});

// 数据库中取的数据
const records = [
    { name'Bob'lang'French, English' },
    { name'Mary'lang'English' },
];

// 写入文件
csvWriter.writeRecords(records).then(() => {
    console.log('...Done');
});

考虑到大家用的系统不同,所以对 Numbers 和 Excel 都做了测试。

运行上述代码,查看生成的效果:

Mac 下 Numbers 软件的打开效果:

Mac 下 Excel 软件的打开效果:

乍一看好像没什么问题,但当数据中出现中文时,区别就出来了:

// 带有中文的数据
const records = [
    { name'Bob'lang'French, English' },
    { name'Mary'lang'English' },
    { name'尤慕'lang'汉语' },
];

Numbers 仍然能正常显示:

Excel 则残了:

为什么 Excel 会乱码?通过搜索网络,在知乎上看到如下解答:

对于 CSV 文件,Excel 需要它有一个元信息来说明它的编码,那 CSV 是纯文本文件怎么设置元信息呢?微软就定义了一个自己的格式叫  BOM 头,这个 BOM 头在被其他的表格展示器(比如 Numbers 或者 Libre Office)打开的时候会被忽略,但对 Excel 就很关键了。([1])

作者所说的 BOM 头,就是在 csv 文件的头部,加入一个 \uFEFF
字符。

我们打开刚才程序生成的 csv 文件,可以看到如下内容:

NAME,LANGUAGE
Bob,"French, English"
Mary,English
尤慕,汉语

所以我们要做的,是在第一行的开头,加入\uFEFF
。程序改动如下:

const csvWriter = createCsvWriter({
    path'file.csv',
    header: [
        // 注意这里,NAME 前加了 BOM 头
        { id'name'title'\uFEFFNAME' },
        { id'lang'title'LANGUAGE' },
    ],
});

再次运行程序生成 csv,发现 Excel 软件也能正常显示了:

Numbers 打开也不受影响:

很神奇是不是?


好奇的同学可以用 less
命令查看新生成的 csv 文件的内容,在终端下可以发现那个神奇的字符:

可以设想,如果拿到的一个 csv 文件打开时有乱码,而文件又不是自己生成的,可以尝试如下方式来修复:

# 假设乱码的 csv 叫 a.csv
# 我们可以以它为基础
# 创建一个带有 BOM 头的 b.csv
echo -n '\uFEFF' > b.csv
cat a.csv >> b.csv
# 如此一来,b.csv 就能正常显示了

谢谢阅读,提前祝你春节快乐!

参考资料

[1]

csv 文件打开乱码,有哪些方法可以解决?: https://www.zhihu.com/question/21869078/answer/350728339

- END -


文章转载自背井,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论