Newer
Older
xc-business-system / src / utils / download.ts
import { ElLoading, ElMessage } from 'element-plus'
import { getPhotoUrl } from '@/api/file'
declare const window: Window & {
  createObjectURL: any
  webkitURL: any
  URL: any
}
/**
 * 下载本地图片 href为 127.0.0.1/xxxx
 * @param href 图片地址
 * @param name 图片名称
 */
export function downloadImg(href: string, name: string) {
  const eleLink = document.createElement('a')
  eleLink.download = name
  eleLink.href = href
  eleLink.click()
  eleLink.remove()
}

/**
 * 下载文件
 * @param file 文件对象
 * @param name 图片名称
 */
export function downloadFile(file: File, name: string) {
  console.log(new Blob([file]), 'new Blob([file])')
  const objectUrl = URL.createObjectURL(new Blob([file]))
  const link = document.createElement('a')
  link.download = name
  link.href = objectUrl
  link.click()
  link.remove()
  window.URL.revokeObjectURL(link.href)
}
// 各种文件类型的type
export const fileType: { [key: string]: string } = {
  pdf: 'application/pdf',
  doc: 'application/doc',
  docx: 'application/docx',
  excel: 'application/excel',
  ppt: 'application/vnd.ms-powerpoint',
  dir: 'application/x-director',
  js: 'application/x-javascript',
  swf: 'application/x-shockwave-flash',
  xhtml: 'application/xhtml+xml',
  xht: 'application/xhtml+xml',
  zip: 'application/zip',
  mid: 'audio/midi',
  midi: 'audio/midi',
  mp3: 'audio/mpeg',
  rm: 'audio/x-pn-realaudio',
  rpm: 'audio/x-pn-realaudio-plugin',
  wav: 'audio/x-wav',
  bmp: 'image/bmp',
  gif: 'image/gif',
  jpeg: 'image/jpeg',
  jpg: 'image/jpeg',
  png: 'image/png',
  css: 'text/css',
  html: 'text/html',
  htm: 'text/html',
  txt: 'text/plain',
  xsl: 'text/xml',
  xml: 'text/xml',
  mpeg: 'video/mpeg',
  mpg: 'video/mpeg',
  avi: 'video/x-msvideo',
  movie: 'video/x-sgi-movie',
}
/**
 * 将网络文件地址转化为文件对象
 * @param url 文件地址
 * @param fileName 文件名称
 */
export function getFileFromUrl(url: string, fileName: string) {
  return new Promise((resolve, reject) => {
    var blob = null
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    const urlFileType = url.split('.')[url.split('.').length - 1]
    xhr.setRequestHeader('Accept', fileType[urlFileType])
    xhr.responseType = 'blob'
    // 加载时处理
    xhr.onload = () => {
      // 获取返回结果
      blob = xhr.response
      const file = new File([blob], fileName, { type: fileType[urlFileType] })
      // 返回结果
      resolve(file)
    }
    xhr.onerror = (e) => {
      reject(e)
    }
    // 发送
    xhr.send()
  })
}
/**
 * 将网络地址转化为 blob地址 并下载
 * @param url 文件地址
 * @param fileName 文件名称
 */
export function urlToBlob(url: string, name: string) {
  const xhr = new XMLHttpRequest()
  xhr.open('get', url)
  xhr.responseType = 'blob' // ""|"text"-字符串 "blob"-Blob对象 "arraybuffer"-ArrayBuffer对象
  xhr.onload = function () {
    const path = URL.createObjectURL(xhr.response)
    const link = document.createElement('a')
    link.download = name
    link.href = path
    link.click()
    link.remove()
    window.URL.revokeObjectURL(link.href)
  }
  xhr.send()
}

/**
 * 下载文件 各种文件
 * @param url 网络文件地址
 * @param name  文件名
 */
export function download(url: string, name: string) {
  // 下载图片
  const photo = ['jpg', 'jpeg', 'png']
  const fileType = url.split('.')[url.split('.').length - 1]
  console.log(fileType, 'fileType')
  if (photo.includes(fileType)) {
    // 图片 将服务器图片地址转化成本地地址
    const image = new Image()
    image.setAttribute('crossOrigin', 'anonymous')
    image.src = url
    image.onload = () => {
      const canvas = document.createElement('canvas')
      canvas.width = image.width
      canvas.height = image.height
      const ctx = canvas.getContext('2d')
      ;(ctx as CanvasRenderingContext2D).drawImage(
        image,
        0,
        0,
        image.width,
        image.height,
      )
      canvas.toBlob((blob) => {
        const url = URL.createObjectURL(blob as Blob)
        downloadImg(url, name)
        // 用完释放URL对象
        URL.revokeObjectURL(url)
      })
    }
  }
  else {
    // 预览一般都是用的a标签,文件下载用的window.open
    // 1.pdf文件路径放到window.open里面,点击是进行在线预览
    // 2.word文件和excel文件通过a标签打开时,是直接下载了
    // 将网络地址转化为 blob地址 并下载
    urlToBlob(url, name)
  }
}
//  将blob转为url
export function getObjectURL(data: any) {
  var url = null
  if (window.createObjectURL !== undefined) {
    // basic
    url = window.createObjectURL(data)
  }
  else if (window.webkitURL !== undefined) {
    // webkit or chrome
    try {
      url = window.webkitURL.createObjectURL(data)
    }
    catch (error) {
      console.log(error)
    }
  }
  else if (window.URL !== undefined) {
    // mozilla(firefox)
    try {
      url = window.URL.createObjectURL(data)
    }
    catch (error) {
      console.log(error)
    }
  }
  return url
}

// 二进制流转blob
export function getFiles(res: any, type: any) {
  // 创建blob对象,解析流数据
  const blob = new Blob([res], {
    // 如何后端没返回下载文件类型,则需要手动设置:type: 'application/pdf;chartset=UTF-8' 表示下载文档为pdf,如果是word则设置为		  msword,excel为excel
    type,
  })
  return blob
}

// 将二进制流转为base64
export function getBase64(data: any) {
  const blob = new Blob([data], { type: 'image/jpg' })
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(blob)
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
  })
}
// 将base64转为 文件对象
export function base64toFile(base: any, filename: string, suffix: string) {
  var arr = base.split(',')
  var mime = arr[0].match(/:(.*?);/)[1]
  var bstr = atob(arr[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], `${filename}.${suffix}`, { type: mime })
}
export function base64ToBlob(base64: any) {
  var arr = base64.split(',')
  var mime = arr[0].match(/:(.*?);/)[1]
  var bstr = atob(arr[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

// 文件名下载
export function downloadFileName(fileName: string) {
  const loading = ElLoading.service({
    lock: true,
    text: '下载中,请稍后',
    background: 'rgba(255, 255, 255, 0.6)',
  })
  if (fileName) {
    getPhotoUrl(fileName)
      .then((res) => {
        download(res.data, fileName)
        loading.close()
      })
      .catch(() => {
        loading.close()
        ElMessage.error('下载失败')
      })
  }
  else {
    loading.close()
    ElMessage('无可下载内容')
  }
}
// 下载echarts图片到本地
export const exportCharts = (dom: any, fileName: string) => {
  if (dom) {
    const chartsCanvas = dom
    const mime = 'image/png'
    if (chartsCanvas) {
      const imageUrl = chartsCanvas && chartsCanvas.toDataURL(mime)

      if (navigator.userAgent.includes('Trident')) {
        // IE11
        const arr = imageUrl.split(',')
        // atob() 函数对已经使用base64编码编码的数据字符串进行解码
        const bstr = atob(arr[1])
        let bstrLen = bstr.length
        // Uint8Array, 开辟 8 位无符号整数值的类型化数组。内容将初始化为 0
        const u8arr = new Uint8Array(bstrLen)
        while (bstrLen--) {
          // charCodeAt() 方法可返回指定位置的字符的 Unicode 编码
          u8arr[bstrLen] = bstr.charCodeAt(bstrLen)
        }
        //  msSaveOrOpenBlob 方法允许用户在客户端上保存文件,方法如同从 Internet 下载文件,这是此类文件保存到“下载”文件夹的原因
        window.navigator.msSaveOrOpenBlob(
          new Blob([u8arr], { type: mime }),
          `${fileName}.png`,
        )
      }
      else {
        // 其他浏览器
        const $a = document.createElement('a')
        $a.setAttribute('href', imageUrl)
        $a.setAttribute('download', fileName)
        $a.click()
      }
    }
  }
}

// 获取echarts图片文件
export const getChartsFile = (dom: any) => {
  let file = ''
  if (dom) {
    const chartsCanvas = dom
    const mime = 'image/png'
    if (chartsCanvas) {
      file = chartsCanvas && chartsCanvas.toDataURL(mime)
    }
  }
  return file
}