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,再渲染到页面中,同时支持跳转新标签页打开完整预览。

相关推荐
天若有情6732 小时前
从零实现轻量级C++ Web框架:SimpleHttpServer入门指南
开发语言·前端·c++·后端·mvc·web应用
摇滚侠2 小时前
css,控制超出部分隐藏,显示... css,控制超出部分不隐藏,换行
前端·css
IT_陈寒2 小时前
Python 3.12 新特性实战:10个让你代码更优雅的隐藏技巧
前端·人工智能·后端
lyx_20162 小时前
PDF文档导出分页功能实现
react.js·typescript·pdf·react
一 乐2 小时前
海产品销售系统|海鲜商城购物|基于SprinBoot+vue的海鲜商城系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·后端
艾小码2 小时前
还在死磕模板语法?Vue渲染函数+JSX让你开发效率翻倍!
前端·javascript·vue.js
炒毛豆2 小时前
vue3 + antd + print-js 实现打印功能(含输出PDF)
前端·javascript·vue.js
天天向上10242 小时前
el-table动态添加行,删除行
前端·javascript·vue.js
puyaCheer2 小时前
Android 打开 在线 pdf 文件
android·pdf