一、GET接口获取资源下载
这种方式最简单,直接 拼接好下载接口路径和参数,然后跳页访问即可
二、POST接口返回文件流下载
- 如果接口是From Data格式直接创建form表单下载
/**
* 根据接口获取文件并下载
* @param action 接口路径
* @param params 接口请求参数
* @param method 接口请求方式
* @param parent 生成form父级元素
*/
export const formDataDownFile = (action: string, params: any, method: string = 'post', parent: string = 'app') => {
const App = document.getElementById(parent)
const form = document.createElement("form")
// 可结合iframe标签,处理成不跳页的方式
const iframe = document.createElement("iframe")
iframe.id = "downloadBox"
iframe.name = "downloadBox"
iframe.style.display = "none"
form.method = `${
method}`
form.target = "downloadBox"
form.action = action
for (const key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
let element = params[key]
if (typeof element !== 'string') {
element = JSON.stringify(element)
}
// 将该输入框插入到 form 中
form.appendChild(createInputElement(key, element))
}
}
App?.appendChild(form)
App?.appendChild(iframe)
form.submit()
App?.removeChild(form)
App?.removeChild(iframe)
}
// 创建Input标签
export const createInputElement = (name: string, value: string, type: string = 'text' ) => {
// 创建一个输入
const input = document.createElement("input");
// 设置相应参数
input.name = name;
input.value = value;
input.type = type;
return input
}
- 不是From data提交,只是post请求获取文件流
需要在请求接口是设置responseType: 'blob'
// js
axios({
method: 请求方式,
url: 接口路径,
data: 接口参数,
dataType: 'json',
responseType: 'blob',
})
// ts
export const postFile = <U = unknown, T = unknown>(
url: string,
params?: U,
config: AxiosRequestConfig = {
responseType: 'blob' },
) => axios.post<T, ResCommonType<T>>(url, {
...params }, config);
然后根据获取的文件流创建a
标签下载
/**
* 文件流下文件
* @param file
* @param fileName
*/
export const downloadFile = (file: string, fileName?: string) => {
const blob = new Blob([file]);
const fileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.onload = (e) => {
console.log('teste', e)
const a = document.createElement("a");
a.download = fileName || '0123456.PNG';
a.href = e.target?.result as string;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
}
三、导出Html页面内容为Excel表格
需要先安装 xlsx
插件 npm i xlsx -S
import * as xlsx from 'xlsx'
/**
* 导出excel内容
* @param fileName 文件名称
* @param pageName 工作表名称
*/
export const exportExcel = (fileName: string = "demo", pageName: string = "Sheet1") => {
const table = getHtmlTableData()
const fieldName = arrToObj(table.ths)
const tableData = table.trs.map((tr) => {
return arrToObjTwo(tr, table.ths)
})
const list = changeTableHead(tableData, fieldName);
// 创建工作表
const data = xlsx.utils.json_to_sheet(list);
// 创建工作簿
const wb = xlsx.utils.book_new();
// 将工作表放入工作簿中
xlsx.utils.book_append_sheet(wb, data, pageName);
// 生成文件并下载
xlsx.writeFile(wb, `${
fileName}.xlsx`);
};
/**
* 获取页面表格内容
* @returns
*/
export const getHtmlTableData = () => {
const table__header = document.getElementsByClassName("el-table__header") // 获取表头
const table__body = document.getElementsByClassName("el-table__body")[0] // 获取tbody
const ths: string[] = table__header[0].innerText.split('\n\t\n')
const trss = table__body.getElementsByTagName("tr")
let trs = []
for (let i = 0, l = trss.length; i < l; i++) {
trs.push([])
trs[i] = trss[i].innerText.split('\n\t\n')
}
return {
ths,
trs
}
}
/**
* 数组转换对象(当前值作为key)
* @param arr
* @returns
*/
export const arrToObj = (arr: Array<string>) =>{
let obj = {
} as OBJ_STRING
arr.forEach(item => {
obj[item] = item
})
return obj
}
/**
* 数组转对象(指定顺序对应的key)
* @param arr 需转换的数组
* @param arr2 需转换的数组对应的key列表
* @returns
*/
export const arrToObjTwo = (arr: Array<string>, arr2: Array<string> ) =>{
let obj = {
} as OBJ_STRING
arr.forEach((item, index) => {
obj[arr2[index]] = item
})
return obj
}
export interface OBJ_STRING {
[key: string]: string;
}
//表头数据切换
export const changeTableHead = (tableData: Array<OBJ_STRING>, fieldName: OBJ_STRING) => {
const list = tableData.map((item) => {
const obj = {
} as OBJ_STRING
for (const k in item) {
if (fieldName[k]) {
obj[fieldName[k]] = item[k]
}
}
return obj
})
return list
}
四、导出Html页面内容为CSV表格
export const downloadTableToCSV = (fileName: string) => {
// const fileName = Date.now() + ".csv" // 使用当前时间戳作为文件名
const columnDelimiter = "," //列分割符
const lineDelimiter = "\n\t" //行分割符
let result = "" // 最终结果的字符串
const table = getHtmlTableData()
for (let i = 0, l = table.ths.length; i < l; i++) {
result += transferred('"' + table.ths[i] + '"') + columnDelimiter // 每一列用逗号分隔
}
result += lineDelimiter // 每一行使用"rn"分隔
for (let i = 0, l = table.trs.length; i < l; i++) {
let spandata = table.trs[i]
for (let i = 0, l = spandata.length; i < l; i++) {
result += transferred('"' + spandata[i] + '"') + columnDelimiter
}
result += lineDelimiter
}
// uFEFF
const blob = new Blob([result], {
type: "text/csv" }) // 记得将编码格式设置一下,避免最终下载的文件出现乱码
blobFileDown(blob, fileName)
}
/**
* 获取页面表格内容
* @returns
*/
export const getHtmlTableData = () => {
const table__header = document.getElementsByClassName("el-table__header") // 获取表头
const table__body = document.getElementsByClassName("el-table__body")[0] // 获取tbody
const ths: string[] = table__header[0].innerText.split('\n\t\n')
const trss = table__body.getElementsByTagName("tr")
let trs = []
for (let i = 0, l = trss.length; i < l; i++) {
trs.push([])
trs[i] = trss[i].innerText.split('\n\t\n')
}
return {
ths,
trs
}
}
// 转义br和>
export const transferred = (data: string) => {
return data.replace(/<br>/g, "rn").replace(/>/g, ">");
}
export const blobFileDown = (blob: Blob, fileName: string) => {
const url = URL.createObjectURL(blob);
const downloadLink = document.createElement("a")
downloadLink.href = url
downloadLink.download = fileName
downloadLink.hidden = true
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
}