当前位置:首页 > VUE

vue实现文档下载

2026-02-19 09:37:56VUE

使用 <a> 标签下载

通过动态生成 <a> 标签并触发点击实现下载。适用于直接下载静态文件或后端返回的二进制流。

vue实现文档下载

// 方法1: 直接下载静态文件
const downloadByLink = (url, filename) => {
  const link = document.createElement('a')
  link.href = url
  link.download = filename || 'document'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

// 使用示例
downloadByLink('/files/report.pdf', '季度报告.pdf')

处理 Blob 数据下载

当后端返回二进制流(如 Blob 数据)时,需先转换为可下载的 URL。

vue实现文档下载

const downloadBlob = (blobData, fileName) => {
  const url = window.URL.createObjectURL(blobData)
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  link.click()
  window.URL.revokeObjectURL(url) // 释放内存
}

// 结合axios示例
axios.get('/api/download', {
  responseType: 'blob'
}).then(res => {
  downloadBlob(res.data, 'export.xlsx')
})

文件流下载处理

针对后端返回文件流的情况,需设置正确的响应类型和响应头解析。

axios({
  method: 'get',
  url: '/api/export',
  responseType: 'blob',
}).then(response => {
  const contentDisposition = response.headers['content-disposition']
  const fileName = decodeURIComponent(
    contentDisposition.match(/filename=(.*?)(;|$)/)[1]
  )

  const blob = new Blob([response.data])
  const downloadUrl = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = downloadUrl
  a.download = fileName
  a.click()
  URL.revokeObjectURL(downloadUrl)
})

封装为 Vue 指令

可复用逻辑可封装为全局指令,通过 v-download 调用。

// main.js 全局注册
Vue.directive('download', {
  bind(el, binding) {
    el.addEventListener('click', () => {
      const { url, filename } = binding.value
      const link = document.createElement('a')
      link.href = url
      link.download = filename || 'download'
      link.click()
    })
  }
})

// 组件中使用
<button v-download="{ url: '/file.doc', filename: '合同.doc' }">
  下载文档
</button>

注意事项

  • 跨域问题需确保服务器配置 Access-Control-Allow-Origin
  • 大文件下载建议显示进度条,可通过 axiosonDownloadProgress 实现
  • 后端应设置正确的 Content-Disposition 响应头
  • 移动端部分浏览器可能限制自动下载,需用户主动触发

完整组件示例

<template>
  <div>
    <button @click="handleDownload">下载PDF</button>
    <button @click="handleExport">导出Excel</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleDownload() {
      this.$axios.get('/file.pdf', {
        responseType: 'blob'
      }).then(res => {
        const blob = new Blob([res.data])
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = 'document.pdf'
        link.click()
      })
    },

    handleExport() {
      this.$axios.get('/api/export', {
        responseType: 'blob',
        onDownloadProgress: progressEvent => {
          const percent = Math.round(
            (progressEvent.loaded * 100) / progressEvent.total
          )
          console.log(`下载进度: ${percent}%`)
        }
      }).then(res => {
        const fileName = res.headers['content-disposition']
          .split('filename=')[1]
          .replace(/"/g, '')

        const url = window.URL.createObjectURL(res.data)
        const link = document.createElement('a')
        link.href = url
        link.download = fileName
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      })
    }
  }
}
</script>

标签: 文档vue
分享给朋友:

相关文章

vue 实现拖拽

vue 实现拖拽

Vue 实现拖拽功能 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。 <template> &l…

vue实现通讯

vue实现通讯

Vue 组件通讯方法 父子组件通讯 父组件向子组件传递数据通过 props,子组件向父组件传递数据通过 $emit 事件。 父组件模板: <child-component :message=…

vue实现树形

vue实现树形

Vue 实现树形组件 在 Vue 中实现树形结构通常需要递归组件和动态数据绑定。以下是实现树形组件的几种常见方法。 递归组件实现 递归组件是 Vue 中实现树形结构的核心方法。通过组件调用自身,可以…

vue最佳实现

vue最佳实现

Vue 最佳实践 组件设计 组件应遵循单一职责原则,每个组件只负责一个功能模块。命名采用 PascalCase(如 UserProfile.vue),模板中使用 kebab-case(如 <us…

vue实现页面

vue实现页面

Vue 实现页面的基本方法 创建 Vue 项目 使用 Vue CLI 快速初始化项目,运行以下命令安装并创建项目: npm install -g @vue/cli vue create my-pro…

vue 实现获取焦点

vue 实现获取焦点

实现获取焦点的方法 在 Vue 中实现获取焦点可以通过多种方式完成,以下是几种常见的方法: 使用 ref 和 focus 方法 通过 ref 属性获取 DOM 元素,并调用其 focus 方法实现焦…