美文网首页NodeJS技术栈
基于NodeJS+Express实现文件上传下载

基于NodeJS+Express实现文件上传下载

作者: candice2cc | 来源:发表于2017-05-06 18:49 被阅读1175次

    需求描述

    1. 允许用户上传文件,服务端从请求中读取并且解析
    2. 允许用户下载文件,如报表导出功能,基于当前展示的表格数据,导出excel文件

    涉及到的技术点

    1. 文件读写
    2. 文件上传
    3. 文件下载

    文件上传与读取文件

    前端代码

    比较常见的场景是:在前端页面中会有一个表单,表单中会输入一些字段,同时上传文件。
    代码示例:

    <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();
                }
    
            });
        });
    })
    

    常见问题

    1. 写入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('中文');
    ...
    

    相关文章

      网友评论

        本文标题:基于NodeJS+Express实现文件上传下载

        本文链接:https://www.haomeiwen.com/subject/dmdhnttx.html