需求描述
- 允许用户上传文件,服务端从请求中读取并且解析
- 允许用户下载文件,如报表导出功能,基于当前展示的表格数据,导出excel文件
涉及到的技术点
- 文件读写
- 文件上传
- 文件下载
文件上传与读取文件
前端代码
比较常见的场景是:在前端页面中会有一个表单,表单中会输入一些字段,同时上传文件。
代码示例:
<form method="POST" action="/apps/rel" encType="multipart/form-data" name="form">
<input id="inputFile" type="file"
accept="application/vnd.ms-excel|xls"
name="inputFile" onChange={this.handleFileChange}/>
<button onClick={this.handleSubmit}>点击提交</button>
</form>
表单提交一般通过js代码提交:首先做数据合法性校验,然后执行form.submit()执行提交。如果不想页面跳转,则将表单target设置为一个隐藏的iframe。
服务端代码
服务端处理上传文件使用multer npm包。
代码示例:
//先引入multer
var multer = require('multer');
var upload = multer();
//从upload中获取文件
router.post('/rel', upload.fields([{name: 'inputFile', maxCount: 1}]),function(req,res,next){
var inputFiles = req.files; //未传时为undefined
...
//读取文件内容
var content = inputFiles['inputFile'][0].buffer.toString();
})
multer的更多使用请参考官方文档。
文件下载
文件下载比较典型的例子是报表导出:通过数据库数据查询,写入到csv文件中,然后支持浏览器下载。
代码示例:
router.get('/export',(req,res,next)=>{
//查询数据库
...
let realPath = path.join(TMP_PATH, fileName);
let writeStream = fs.createWriteStream(realPath);
let bom = new Buffer('\xEF\xBB\xBF', 'binary');
writeStream.write(bom);
//写入数据内容
...
writeStream.end();
writeStream.on('finish', ()=> {
res.download(realPath, outName, (err)=> {
fs.unlink(realPath, (err2)=> {
if (err2) {
logger.error('删除文件失败,err=' + err);
}
});
if (err) {
logger.error(err);
res.status(404).end();
}
});
});
})
常见问题
- 写入csv中文乱码问题
由于 NodeJS只支持 ascii、utf8、base64、binary 编码方式, 不支持 MS 的 utf-8 + BOM 格式, 所以 excel 打开中文乱码。
解决方法:既然excel需要BOM,写入数据前先加入一个BOM。utf-8对应的BOM是EF BB BF
let writeStream = fs.createWriteStream(realPath);
let bom = new Buffer('\xEF\xBB\xBF', 'binary');
writeStream.write(bom);
writeStream.write('hello');
writeStream.write('继续测试');
writeStream.end('中文');
...
网友评论