vue中预览pdf文件

在 Vue 中实现 PDF 文件预览并跳转新标签页,需根据 PDF 的来源(本地静态文件、远程 URL、接口返回的文件流)选择不同方案,以下是常见场景的完整实现:

一、场景 1:预览本地静态 PDF 文件(放在 public 目录)

如果 PDF 是项目内的静态资源(如 public/docs/test.pdf),可直接通过文件路径打开新标签页预览。

实现代码
vue 复制代码
<template>
  <el-button @click="openLocalPdf">预览本地 PDF</el-button>
</template>

<script>
export default {
  methods: {
    openLocalPdf() {
      // public 目录下的文件可直接通过相对路径访问
      const pdfPath = '/docs/test.pdf' 
      // 跳转新标签页打开
      window.open(pdfPath, '_blank')
    }
  }
}
</script>
注意事项
  • 静态 PDF 文件必须放在 public 目录下(Vue CLI 项目),打包后会被复制到输出目录的根目录,可直接通过根路径访问。
  • 若路径错误,会导致新标签页显示 404,需检查文件路径是否正确。

二、场景 2:预览远程 URL 对应的 PDF(如服务器上的 PDF)

如果 PDF 已部署在服务器,有公开的访问 URL,直接通过 window.open 打开该 URL 即可,浏览器会自动解析预览。

实现代码
vue 复制代码
<template>
  <el-button @click="openRemotePdf">预览远程 PDF</el-button>
</template>

<script>
export default {
  methods: {
    openRemotePdf() {
      // 服务器上的 PDF 地址
      const remotePdfUrl = 'https://example.com/files/report.pdf'
      // 新标签页打开
      window.open(remotePdfUrl, '_blank')
    }
  }
}
</script>
注意事项
  • 确保远程 PDF URL 可访问(无跨域限制或权限拦截)。
  • 若 URL 需携带权限参数(如 token),可直接拼在 URL 后(如 remotePdfUrl + '?token=' + localStorage.getItem('token'))。

三、场景 3:预览接口返回的 PDF 文件流(需携带请求头,如 Token)

如果 PDF 需通过接口动态获取(如需要用户权限验证),接口返回 blob 类型的文件流,需先请求接口获取 Blob,再构造临时 URL 打开新标签页。

步骤 1:封装接口请求(结合之前的 axios 配置)

src/api/file.js 中添加获取 PDF 流的接口:

javascript 复制代码
import request from '@/utils/request'

export default {
  // 获取 PDF 文件流
  getPdfStream(params) {
    return request({
      url: '/api/file/export-pdf',
      method: 'get',
      params, // 接口参数(如报表 ID)
      responseType: 'blob', // 关键:指定响应类型为 blob
      headers: {
        // 若需权限验证,携带 Token(根据项目实际情况调整)
        Authorization: `Bearer ${localStorage.getItem('token')}`
      }
    })
  }
}
步骤 2:组件中调用并打开新标签页
vue 复制代码
<template>
  <el-button @click="openPdfStream">预览接口返回的 PDF</el-button>
</template>

<script>
import api from '@/api'

export default {
  methods: {
    async openPdfStream() {
      try {
        // 1. 请求接口获取 PDF 流
        const blob = await api.file.getPdfStream({ reportId: 123 })
        
        // 2. 构造 Blob URL
        const pdfUrl = URL.createObjectURL(
          new Blob([blob], { type: 'application/pdf' }) // 指定 MIME 类型为 PDF
        )
        
        // 3. 新标签页打开预览
        window.open(pdfUrl, '_blank')
        
        // 4. 可选:页面卸载时释放 Blob URL,避免内存泄漏
        this.$once('hook:beforeDestroy', () => {
          URL.revokeObjectURL(pdfUrl)
        })
      } catch (error) {
        console.error('获取 PDF 失败:', error)
        this.$message.error('预览 PDF 失败,请重试')
      }
    }
  }
}
</script>

四、场景 4:Electron + Vue 环境的特殊处理

由于你的项目是 Electron + Vue,Electron 渲染进程打开新窗口有两种方式,需注意窗口权限配置:

方式 1:用默认浏览器打开(推荐,避免 Electron 窗口兼容性问题)
javascript 复制代码
// 引入 Electron 的 shell 模块(渲染进程需开启 Node 集成)
const { shell } = require('electron')

// 替换 window.open 为 shell.openExternal
openPdfStream() {
  // ... 前面获取 pdfUrl 的逻辑不变
  shell.openExternal(pdfUrl) // 用系统默认浏览器打开 PDF,兼容性更好
}
方式 2:用 Electron 新窗口打开
javascript 复制代码
const { remote } = require('electron')
const BrowserWindow = remote.BrowserWindow

openPdfStream() {
  // ... 前面获取 pdfUrl 的逻辑不变
  // 创建新的 Electron 窗口
  const pdfWindow = new BrowserWindow({
    width: 1000,
    height: 800,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  })
  pdfWindow.loadURL(pdfUrl) // 加载 PDF 的 Blob URL
}

关键注意事项

  1. Blob URL 内存泄漏 :通过 URL.createObjectURL 生成的 URL 会占用内存,建议在组件卸载时用 URL.revokeObjectURL 释放。

  2. 浏览器兼容性 :大部分现代浏览器(Chrome、Edge、Firefox)支持直接预览 PDF,IE 需安装插件,若需兼容 IE 可使用 pdf.js 库增强。

  3. Electron 权限:若渲染进程无法使用electron模块,需检查background.js中是否开启 Node 集成:

    javascript 复制代码
    // background.js 中创建窗口时的配置
    new BrowserWindow({
      // ... 其他配置
      webPreferences: {
        nodeIntegration: true, // 开启 Node 集成
        contextIsolation: false // 关闭上下文隔离(Vue 2 项目常用)
      }
    })

扩展:使用 pdf.js 增强预览功能(可选)

如果需要更灵活的预览功能(如分页控制、批注),可集成 pdf.js 库,核心思路是通过 pdf.js 解析 Blob 或 URL,再渲染到页面中,同时支持跳转新标签页打开完整预览。

相关推荐
2501_9445255427 分钟前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐27 分钟前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
2601_9498574331 分钟前
Flutter for OpenHarmony Web开发助手App实战:快捷键参考
前端·flutter
wangdaoyin201038 分钟前
若依vue2前后端分离集成flowable
开发语言·前端·javascript
心柠1 小时前
vue3相关知识总结
前端·javascript·vue.js
Amumu121381 小时前
Vue Router(二)
java·前端
a1117762 小时前
图书借阅管理系统(FastAPI + Vue)
前端·vue.js·fastapi
常年游走在bug的边缘2 小时前
掌握JavaScript作用域:从函数作用域到块级作用域的演进与实践
开发语言·前端·javascript
极致♀雨3 小时前
vue2+elementUI table表格勾选行冻结/置顶
前端·javascript·vue.js·elementui
林shir3 小时前
3-15-前端Web实战(Vue工程化+ElementPlus)
前端·javascript·vue.js