nodejs调用后端接口返回excel文件流,nodejs再转发前端实现下载excel

今天在项目上遇到了一个问题,就是后端接口返回excel文件流,然后前端实现下载excel,前端下载的excel文件居然无法打开!

92d14d22ec5b460f9a2280319e781e94.png

在网上搜索了很多对应的资料,也尝试了很多办法,还是没能解决,最后在这篇文章上面找到了解决的办法:http://t.csdn.cn/0u4aC  ,然后我也总结了一下,希望能帮助到有希望的人!

        我这个项目在客户端和后端之间还隔着一层node层,下面简单介绍一下后端返回文件流,前端实现下载excel的整体流程:

adb5c28a4fc044abb21dd17962f22fa0.png

下面介绍主要的实现代码:

前端代码:

	  axios.post('/api/manage/downloadDataRecords', {}, { responseType: 'arraybuffer' }).then(res => {
	        const blob = new Blob(
				[res.data],
				{
					type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
				},
			)
		   const objUrl = URL.createObjectURL(blob);
	   
		   const eleLink = document.createElement('a');
		   eleLink.download = '报表数据-${new Date().getTime()}.xlsx';
		   eleLink.style.display = 'none';
		   eleLink.href = objUrl;
		   document.body.appendChild(eleLink);
		   eleLink.click();
		   document.body.removeChild(eleLink);
	})

注意:一定要设置responseType的值为arraybuffer

node层的代码:

// 下载
router.all('/data/download(.*)', async (ctx, next) => {
  const body = ctx.request.body;
  const method = ctx.request.method;
  const path = ctx.request.url;

  try {
    let res;
    if (method === 'GET') {
      res = await axios.get(`${remoteUrl}${path}`, {
        headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        },
        responseType: 'arraybuffer',
        timeout: 6000,
      });
    } else if (method === 'POST') {
      res = await axios.post(`${remoteUrl}${path}`, body, {
        headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        },
        responseType: 'arraybuffer',
        timeout: 6000,
      });
    }
    /**
     * 可以在这里打印一下,看看后端接口返回的content-type是否是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
     * 如果不是则会导致下载的excel文件无法正常打开
     * 
     */
    // console.log('====headers', res.headers); 
    ctx.res.writeHead(200, {
      // 注意:后端接口响应头中的内容类型content-type必须是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8,否则下载的文件无法正常打开
      'Content-Type': res.headers['content-type'],
      'Content-Disposition': res.headers['content-disposition'], // 后端接口返回的文件名称
    });
    // ctx.body = res.data;
    ctx.res.end(res.data, 'binary');
  } catch (e) {
    ctx.body = e?.response?.data || e.code;
  }
});

 注意:一定要设置responseType的值为arraybuffer

上面就是具体实现的代码了,主要的地方就是设置axios的responseType的值为arraybuffer,还有就是需要注意一下后端接口响应体中的content-type是否是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8,否则下载的excel文件无法打开或者乱码。如果有什么问题疑问,欢迎在下方留言一起讨论!

猜你喜欢

转载自blog.csdn.net/m0_37873510/article/details/125266126