怎么解决数据保存到csv文件乱码问题
发布于 11 年前 作者 zjshop 55522 次浏览 最后一次编辑是 8 年前

我要将用户查询的结果信息保存到csv或者execl(由于没有找到合适的execl库,所以采用csv库保存)中, 结果用execl打开csv文件发现乱码,通过google找到iconv-lite,可结果还是不行 。代码如下: fs.open(config.UP_PATH+’/csv/’+troopId+year+month+’.csv’,‘a’); var csvData = ‘“序号”,“检查人”,“检查日期”,“省”,“城市”,“系统”,“售点”,“地址”,“门店类型”,’+shopnames; var b = Iconv.encode(csvData,‘GBK’); csv().from.string(b).to(config.UP_PATH+"/csv/"+troopId+year+month+’.csv’);

shopnames:是一个中文字符串变量

26 回复

用csv处理汉字没有问题:

var csv = require('csv');
var data = [ 
    ['john', 23, '城市'],
    ['john2', 123, 'male'],
    ['john3', 234, 'female']
];
csv()
.from.array(data)
.to.path('sample2.csv');


$ cat sample2.csv 
john,23,城市
john2,123,male
john3,234,female

你没理解我的意思 我的意思是将数据写入csv里面 然后用excel打开中文乱码

@zjshop

http://www.csser.com/question/505ae0066f1f5a9d610004dd 由于node.js 只支持‘ascii’ 、‘utf8’、‘base64’、‘binary’ 编码方式,不支持MS 的 utf-8 + BOM 格式。所以 excel 打开中文乱码。

我是这么解决的:nodejs 生成的 csv 文件先用 Open Office 或 Libre Office 打开,存成 Office Excel 格式。这样就可以用 Excel 打开,中文没有乱码。

@leapon 我也是这样的,我就想有没有更简洁的方法

@leapon 现在就是这个问题撒 只要是这个csv文件是供用户下载看的

@zjshop 根据 @leapon 的回复,解决方法已经很明显了,既然excel需要BOM,每次写入数据前先加入一个BOM就可以了嘛。utf-8对应的BOM是 EF BB BF,稍微改动下1楼代码:

var csv = require('csv'),fs=require('fs');
var data = [ 
    ['john', 23, '城市'],
    ['john2', 123, 'male'],
    ['john3', 234, 'female']
];
var fout=fs.createWriteStream('sample2.csv');
fout.write(new Buffer('\xEF\xBB\xBF','binary'));//add utf-8 bom
csv() .from.array(data) .to(fout);

如此,excel直接打开文件也不会乱码了,转码GBK是不需要的,保持本身utf-8即可。

@shiedman 还是会乱码的呀;代码如下: var csvData = ‘“序号”,“检查人”,“检查日期”,“省”,“城市”,“系统”,“售点”,“地址”,“门店类型”’; csvData = csvData.split(’,’); var fout=fs.createWriteStream(config.UP_PATH+’/csv/aaa.csv’); fout.write(new Buffer(’\xEF\xBB\xBF’,‘binary’)); csv().from.array(csvData ).to(fout); excel打开如下:enter image description here

@shiedman 图片放不上来 附文字好了

“搴忓彿”,“妫€鏌ヤ汉”,“妫€鏌ユ棩鏈?”,“鐪?”",“鍩庡競” …后面的就不附上了,总之全是谢乱码

@zjshop to.stream(fout)试试

@cathcn 依然乱码

@zjshop 搴忓彿的GBK字节=序号的utf8字节,excel把cvs文件当gbk来处理了,也就是说很大的可能,BOMEFBB BF并没有加上去,请检查文件的头3个字节是什么。 附上我机子上的运行结果:excel 2003,生成文件大小87字节,头3字节EF BB BF http://i.imgur.com/IPZfUKo.png

@zjshop 我复制你的代码,结果正常 ps:win7系统

@shiedman 按照你的方法做了,头三字节是EF BB BF没错,在excel2013打开正常,但是excel2003就是乱码了

@shiedman EF BB BF 6A 6F 68 6E 2C 32 33 2C E5 9F 8E E5 B8 82 0A 6A 6F 68 6E 32 2C 31 32 33 2C 6D 61 6C 65 0A 6A 6F 68 6E 33 2C 32 33 34 2C 66 65 6D 61 6C 65

请问楼主解决了吗 我也遇到这个问题了.

@紫胤: 一个内部的终极解决方案

nodejs文件下载服务

踩到的几个坑:

1.Excel2007 打开utf-8编码的csv文件默认乱码

相关信息:http://www.docin.com/p-31710590.html

2.文件名中含中文,下载会乱码。各浏览器表现不同

相关信息:http://www.phpv.net/html/1675.html

解决方法:

iconv转码,utf-8 -> gbk

转完后为buffer对象,内容直接res.end(buffer), header中的filename则由buffer.toString(‘binary’);

http://127.0.0.1:22222/down

var http = require('http');
var url = require('url');
var Iconv = require('iconv').Iconv;
var crypto = require('crypto');
var server = http.createServer(function(req, res){
  var path = url.parse(req.url).pathname;

  if(path == '/favicon.ico'){
    res.end('');
  }else{
    var filename = '2012-06-01 至 2012-06-01 数据报表.csv';
    var content = "序号,日期,成交商品数,客单价,关注次数,搜索次数,收藏人数\n1, 2012-06-01, 1, 1, 1, 1, 1\n1, 2012-06-02, 1, 1, 1, 1, 1";
    //excel2007默认不支持utf-8编码的csv文件
    var iconv = new Iconv('UTF-8', 'GBK//IGNORE');
    content = iconv.convert(content);
    res.setHeader('Pragma', 'public');
    res.setHeader('Expires', '0');
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
//    res.setHeader('Cache-Control', 'pre-check=0, post-check=0, max-age=0');
//    res.setHeader('Content-Transfer-Encoding', 'none');
    res.setHeader('Content-Type', 'text/csv; charset=GBK');
    filename = iconv.convert(filename).toString('binary');
    res.setHeader('Content-Disposition', 'attachment;filename="'+ filename +'"');
    res.setHeader('Content-Length', content.length);
    res.end(content);
  }
}).listen(22222);

用 gbk。输出就好了

我也来挖坟了,今天也碰到这个问题,其实解决起来很简单,相关代码如下:

var iconv = new Iconv('UTF-8', 'GBK');
... //获取你的json
json2csv({data: result, fields: Object.keys(result[0] || {})}, function(err, csv) {
//将json转为csv格式的buf
//在写文件之前,转一下编码
	var buf = iconv.convert(csv)
//然后保存到文件中,在win7 office 2010 打开没问题
	fs.writeFile(xlsPath, buf, function (err) {
				  if (err) throw err;
				  console.log('It\'s saved!');
		});
})

-. - 最近怎么辣么多挖坟的?

@DoubleSpout 从上到下,还是大兄弟你的方法好使 (供以后人参考)上面的方法能够解决excel较新版(2016)乱码的问题,但是mac的excel2011不好使,然后用了iconv,就都可以了

这两天也是在处理乱码问题 最终发现 json2csv 模块有个 withBOM 参数可以很方便解决问题 记录一下 image.png const opts = { withBOM: true };
加上withBOM 参数就ok

时隔多年,继续挖坟。。。 另一方面,挖坟的多。。也说明这个坑。。。有点深啊。。

参考自 http://imziv.com/blog/article/read.htm?id=55


解决文件名乱码的问题。。。多是IE11、edge导致。。。

const { Iconv } = require('iconv');
const iconv = new Iconv('UTF-8', 'GBK//IGNORE'); // 定义buffer的转码器
const userAgent = (req.headers['user-agent'] || '').toLowerCase();
if (userAgent.indexOf('msie') >= 0 || userAgent.indexOf('edge') >= 0) {
    res.setHeader('Content-Disposition', 'attachment;filename=' + encodeURIComponent(filename));
} else if (userAgent.indexOf('firefox') >= 0) {
    res.setHeader('Content-Disposition', 'attachment;filename*="utf8*\'\'' + encodeURIComponent(filename) + '"');
} else {
    filename = iconv.convert(filename).toString('binary');
    res.setHeader('Content-Disposition', 'attachment;filename=' + filename);
}

@occultskyrong 挖坟同方案,今天帮同事解决了同样的坑。。。只不过这个只需要在第一次写文件的时候加这个var dataBuffer = Buffer.concat([new Buffer(’\xEF\xBB\xBF’, ‘binary’), new Buffer(data)]);如果是继续追加文件,直接用Buffer就行了。

回到顶部