• 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;
        }
    
  • 相关阅读:
    【QQ空间转移】C/C++函数的调用约定
    【QQ空间转移】BIG Endian 和 Little Endian模式
    【QQ空间转移】友元函数
    【QQ空间转移】和室友争论所瞎想的
    【QQ空间转移】银行同业拆借
    【QQ空间转移】票据和债券
    js实现给数字加三位一逗号间隔的两种方法
    js获取上个月第一天
    获取所选月份指定时间范围
    PLSQL 11 注册码
  • 原文地址:https://www.cnblogs.com/joeblackzqq/p/12763422.html
Copyright © 2020-2023  润新知