axios请求导出数据到excel文件(二)

上一篇的文章存在一定的问题, 没有把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;
    }

 

posted on 2020-04-23 20:45  清清飞扬  阅读(651)  评论(0编辑  收藏  举报