Nodejs中怎么解决数据保存到csv文件乱码问题

Nodejs中怎么解决数据保存到csv文件乱码问题

我要将用户查询的结果信息保存到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:是一个中文字符串变量


12 回复

要解决Node.js中数据保存到CSV文件时出现的乱码问题,可以使用iconv-lite库来处理字符编码。以下是一个详细的解决方案,包括示例代码和解释。

解决方案

  1. 安装必要的依赖
    • iconv-lite: 用于字符编码转换。
    • fast-csv: 一个快速处理CSV的库。
npm install iconv-lite fast-csv
  1. 修改代码以正确处理字符编码
const fs = require('fs');
const path = require('path');
const iconv = require('iconv-lite');
const fastCsv = require('fast-csv');

// 配置文件路径
const config = {
    UP_PATH: '/path/to/your/upload/directory'
};

// 用户查询的结果信息
const troopId = 'someTroopId';
const year = '2023';
const month = '10';
const shopnames = '一些中文字符串';

// 定义CSV数据
const csvData = [
    ["序号", "检查人", "检查日期", "省", "城市", "系统", "售点", "地址", "门店类型", ...shopnames.split(',')]
];

// 将数据写入CSV文件
const filePath = path.join(config.UP_PATH, 'csv', `${troopId}${year}${month}.csv`);

// 创建可写流,并设置编码为GBK
const writeStream = fs.createWriteStream(filePath, { encoding: 'binary' });

// 使用fast-csv格式化数据并写入文件
fastCsv
    .writeStream(csvData, { headers: true })
    .on('finish', () => console.log(`CSV file successfully written to ${filePath}`))
    .pipe(iconv.encodeStream('GBK'))
    .pipe(writeStream);

解释

  1. 安装依赖

    • iconv-lite:用于处理字符编码转换。
    • fast-csv:用于方便地读取和写入CSV数据。
  2. 配置文件路径

    • config.UP_PATH:定义文件存储路径。
  3. 定义CSV数据

    • csvData:包含CSV文件中的列名和数据。
  4. 创建可写流

    • fs.createWriteStream:创建一个可写流,设置编码为binary,以便后续处理。
  5. 使用fast-csv写入数据

    • fastCsv.writeStream:将数据写入CSV文件。
    • .pipe(iconv.encodeStream('GBK')):将输出流转换为GBK编码。
    • .pipe(writeStream):将转换后的数据写入文件。

通过这种方式,可以确保生成的CSV文件不会出现乱码问题。


用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打开中文乱码

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

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

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!');
		});
})

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

哈哈 👍啊

这两天也是在处理乱码问题 最终发现 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);
}

在Node.js中处理CSV文件时遇到乱码问题,通常是因为字符编码不一致导致的。使用iconv-lite库可以很好地解决这个问题。你的代码有一些小问题,比如使用了不正确的字符串连接方法以及csv()模块的方法不正确。下面是一个改进后的示例,展示如何正确地将数据保存为CSV文件,并且避免乱码。

改进后的代码

首先确保安装了必要的库:

npm install iconv-lite csv-writer

然后你可以使用以下代码来生成CSV文件:

const fs = require('fs');
const path = require('path');
const iconv = require('iconv-lite');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;

// 假设这些是从数据库或其他地方获取的数据
const troopId = '12345';
const year = '2023';
const month = '10';
const shopnames = '店名';

// 数据准备
const data = [
    { 序号: 1, 检查人: '张三', 检查日期: new Date(), 省: '江苏', 城市: '南京', 系统: '系统A', 售点: '售点A', 地址: '地址A', 门店类型: '类型A' },
    // 更多数据...
];

// 定义CSV文件路径
const filePath = path.join(config.UP_PATH, '/csv/', `${troopId}${year}${month}.csv`);

// 创建CSV写入器
const csvWriter = createCsvWriter({
    path: filePath,
    header: [
        { id: '序号', title: '序号' },
        { id: '检查人', title: '检查人' },
        { id: '检查日期', title: '检查日期' },
        { id: '省', title: '省' },
        { id: '城市', title: '城市' },
        { id: '系统', title: '系统' },
        { id: '售点', title: '售点' },
        { id: '地址', title: '地址' },
        { id: '门店类型', title: '门店类型' },
    ],
});

// 写入数据
csvWriter.writeRecords(data)
    .then(() => {
        console.log(`数据已成功保存至 ${filePath}`);
    })
    .catch(err => {
        console.error('写入CSV文件失败:', err);
    });

解释

  1. 编码问题:通过使用csv-writer库直接以UTF-8编码写入文件,避免了手动编码转换的复杂性。
  2. 数据结构:将数据组织成数组形式,每个元素是一个对象,对应CSV文件的一行。
  3. 文件路径:使用path.join构建文件路径,确保跨平台兼容性。
  4. 错误处理:添加了错误处理逻辑,确保如果写入过程中出现错误能够被捕获并输出。

通过这种方式,你可以确保CSV文件在不同环境下正确显示中文内容,避免乱码问题。

回到顶部