前端下载文件的方法
方法1: 前端点击下载按钮后直接发送请求,后端输出文件流。
import React from 'react'; import { Button } from 'antd'; interface Props { /** 下载地址 */ url: string; text?: string; className?: string; iconClassName?: string; /** 默认get轻轻 */ method?: 'get' | 'post'; /** 只用于post请求,如果是get请求,请自行在url中组装参数 */ data?: { [key: string]: any }; } /** * 文件下载组件 */ export default function Download(props: Props) { function createInput() { if (!props.data) return ''; return Object.entries(props.data).map(([key, value]) => ( <input type="hidden" name={key} value={value ?? ''} /> )); } return ( <div style={{ display: 'inline-block' }} className={props.className ?? ''}> <form method={props.method ?? 'get'} action={props.url} target="_self"> {createInput()} <Button type="submit"> {props.text ?? '下载数据'} </Button> </form> </div> ); }
方法2: 使用ajax发送请求,体验比上面的好
function saveFile (resBlob, fileName, fileType = '.xls') { const blob = new Blob([resBlob], { type: 'application/vnd.ms-excel;charset=utf-8' }) if (window.navigator && window.navigator.msSaveOrOpenBlob) { // 兼容IE/Edge window.navigator.msSaveOrOpenBlob(blob, fileName + fileType) } else { const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.display = 'none' a.download = fileName + fileType document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url) // 释放URL 对象 } } (async function(){ const res = await axios.post({ url:'/api/download',data: {}, responseType: 'blob'}) saveFile(res.data, '文件下载') })()