Excel文件下载方式集合


一、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(/&gt;/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)
}

猜你喜欢

转载自blog.csdn.net/weiCong_Ling/article/details/130890527