上一篇的文章存在一定的问题, 没有把export接口做成Promise, 所以无法在那个接口完成后继续作一些事, 而且不支持取服务端中设定的文件名, 所以这次的更新做个优化, 解决这些问题!
客户端http.js:
import axios from 'axios'; import history from './history'; export const baseUrl = '/api'; const request = axios; // or axios.create({}) request.defaults.baseURL = baseUrl; request.interceptors.request.use(config => { // const { url, data } = config; // console.log(`send request[${url}]: ${JSON.stringify(data)}`); return config; }); request.interceptors.response.use( response => { const { // config: { url }, headers, data, } = response; if (headers['content-type'].indexOf('application/json') >= 0) { if (data instanceof Blob) return response; else return data; } else { return response; } }, error => { console.log(`receive response[${'url'}]: ${JSON.stringify(error)}`); return Promise.reject( error && error.response && error.response.data && error.response.data.message ? error.response.data.message : error, ); }, ); const method = { get: (url, data = {}) => { return request.get(url, { params: data }); }, post: (url, data = {}) => { return request.post(url, data); }, // 导出数据到excel文件 export: (url, data = {}, fileName = '') => { return new Promise((resolve, reject) => { if (typeof data === 'string') { fileName = data; // 第2个参数是文件名 data = {}; } request({ method: 'post', url, data, responseType: 'blob', }) .then(res => { const data = res.data; if (data.type === 'application/json') { const reader = new FileReader(); reader.onload = function() { try { const json = JSON.parse(this.result); reject(json); } catch (err) { console.log('fail: ', err); reject(err); } }; reader.onerror = function(error) { reject(error); }; reader.readAsText(data); return; } // 导出数据到文件 if (fileName === '') { fileName = res.headers['content-disposition'] .split(';')[1] .split('filename=')[1] .replace(/"/g, ''); fileName = decodeURIComponent(fileName); } const href = window.URL.createObjectURL(new Blob([data])); const link = document.createElement('a'); link.style.display = 'none'; link.href = href; link.setAttribute('download', fileName); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(href); resolve(); }) .catch(error => { console.log('文件导出失败: ', error); reject(error); }); }); }, all: (...https) => { return new Promise((resolve, reject) => { request .all(https) .then( axios.spread((...resList) => { // 多个请求都发送完毕,拿到返回的数据 resolve(resList); }), ) .catch(err => { reject(err); }); }); }, }; export const http = (url, data, success, fail) => { return new Promise((resolve, reject) => { method .post(url, data) .then(res => { const { code } = res; if (code === 101) { history.replace('/'); history.fail && fail(); reject(); } if (code === 100 || code === 102) { history.replace('/login'); fail && fail(); reject(); } else { success && success(res); resolve(res); } }) .catch(error => { fail && fail(error); reject(error); }); }); }; export default method;
调用示例:
import React from 'react'; import * as antd from 'antd'; import request from '@/common/http'; const { Button, message } = antd; class Wrapper extends React.Component { exportPaidUsers = () => { request .export('user/exportPaidUsers') // .export('user/exportPaidUsers', '付费用户列表.xlsx') .then(() => { message.info('文件导出成功'); }) .catch(err => { message.warn(err.msg); }); }; // 渲染 render() { return ( <div> <div style={{ marginBottom: 30 }}> <span> <Button type='primary' onClick={this.exportPaidUsers.bind(this)}> 导出所有付费用户 </Button> </span> </div> </div> ); } } export default Wrapper;
服务端php:
public static function download(PHPExcel $excel, String $fileName = 'download') { $ua = strtolower($_SERVER['HTTP_USER_AGENT']); if(preg_match('/msie/i', $ua) || preg_match('/edge/i', $ua) || preg_match('/trident/i', $ua) ) { $fileName = urlencode($fileName); } ob_end_clean(); header('Content-Type: application/vnd.ms-excel;charset=utf-8'); // header(sprintf('Content-Disposition: attachment;filename="%s.xlsx"', $fileName)); header(sprintf('Content-Disposition: attachment;filename="%s.xlsx"', urlencode($fileName))); // 编码下,解决中文乱码问题(客户端需要解码) header('Cache-Control: max-age=0'); $ta[] = microtime(true); $writer = \PHPExcel_IOFactory::createWriter($excel, 'Excel2007'); $writer->save('php://output'); $ta[] = microtime(true); log_message2('download: ', $ta); exit; }