1. 项目概述

本项目基于 Vue3 和 VueOffice 系列组件,实现了一个简洁的文档在线预览功能。用户可以在前端直接预览本地服务器上的 PDF、Word、PPT、Excel 和 TXT 文件,无需下载或依赖外部服务。

核心特性:

  • 支持 PDF、DOCX、PPTX、XLSX、TXT 五种常见格式。
  • 使用 @vue-office 官方组件,渲染效果好。
  • 纯前端实现,文件需预先放置在服务器指定目录。
  • 路由跳转,结构清晰。

2. 项目目录结构

vue-project/
├── public/                    # 静态资源目录
│   └── files/                # 存放预览文件
│       ├── a.docx
│       ├── a.pptx
│       ├── a.xlsx
│       ├── a.txt
│       └── c.pdf
├── src/
│   ├── views/                # 页面组件
│   │   ├── HomeView.vue      # 首页
│   │   └── FilePreview.vue   # 预览页
│   ├── router/
│   │   └── index.js          # 路由配置
│   ├── App.vue               # 根组件
│   └── main.js               # 应用入口
├── index.html
├── package.json              # 项目依赖
└── vite.config.js            # Vite 配置

关键目录说明:

  • public/files/:所有用于预览的示例文件需放在此目录,Vite 开发服务器会将其映射到根路径 /files/
  • src/views/:两个页面组件,分别对应首页和预览页。
  • src/router/index.js:定义了两个路由:/(首页)和 /preview(预览页)。

3. 核心代码解析

3.1 路由配置 (src/router/index.js)

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import FilePreview from '../views/FilePreview.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/preview',
      name: 'preview',
      component: FilePreview
    }
  ]
})

export default router
  • 使用 createWebHistory 模式,URL 更友好。
  • 定义了两个路由,分别指向首页和预览页组件。

3.2 首页组件 (src/views/HomeView.vue)

<template>
  <div style="padding: 40px;">
    <h1>Vue3 文档预览演示</h1>
    <p>点击按钮进入预览页面:</p>
    <router-link to="/preview">
      <button style="padding: 10px 20px; font-size: 16px; cursor: pointer;">
        进入文档预览
      </button>
    </router-link>
  </div>
</template>
  • 一个简单的引导页,通过 <router-link> 跳转到 /preview

3.3 预览页组件 (src/views/FilePreview.vue)

这是核心功能页面,包含文件类型切换和预览区域。

<template>
  <div style="padding: 20px;">
    <h2>Vue3 文档在线预览(本地文件版)</h2>

    <div style="margin: 10px 0; flex-wrap: wrap; display: flex; gap: 10px;">
      <button @click="showPDF">预览 PDF</button>
      <button @click="showWord">预览 Word</button>
      <button @click="showPPT">预览 PPT</button>
      <button @click="showExcel">预览 Excel</button>
      <button @click="showTxt">预览 TXT</button>
    </div>

    <div style="border:1px solid #ccc; height: 700px; margin-top:20px; padding:10px; overflow:auto;">
      <!-- PDF -->
      <vue-office-pdf v-if="fileType === 'pdf'" :src="fileUrl" style="height:100%;" />

      <!-- Word -->
      <vue-office-docx v-else-if="fileType === 'docx'" :src="fileUrl" style="height:100%;" />

      <!-- PPT -->
      <vue-office-pptx v-else-if="fileType === 'pptx'" :src="fileUrl" style="height:100%;" />

      <!-- Excel -->
      <vue-office-excel v-else-if="fileType === 'xlsx'" :src="fileUrl" style="height:100%;" />

      <!-- TXT 文本预览 -->
      <pre v-else-if="fileType === 'txt'" style="margin:0; font-size:14px; white-space: pre-wrap;">{{ txtContent }}</pre>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// 引入组件
import VueOfficePdf from '@vue-office/pdf'
import VueOfficeDocx from '@vue-office/docx'
import VueOfficePptx from '@vue-office/pptx'
import VueOfficeExcel from '@vue-office/excel'

// 文件类型 & 地址
const fileType = ref('')
const fileUrl = ref('')
const txtContent = ref('') // TXT 内容
// track any blob URL we create so we can revoke it when switching files
let currentBlobUrl = null

// NOTE: Do NOT keep sensitive tokens in front-end code. Use a backend proxy that adds the Authorization header.

function setFile(type, url, isBlob = false) {
  // revoke previous blob URL if any
  if (currentBlobUrl && currentBlobUrl !== url) {
    try { URL.revokeObjectURL(currentBlobUrl) } catch (e) { /* ignore */ }
    currentBlobUrl = null
  }
  fileType.value = type
  fileUrl.value = url
  if (isBlob) currentBlobUrl = url
}

// 预览 PDF
const showPDF = () => {
  setFile('pdf', '/files/test.pdf')
}

// 预览 Word
// Fetch the DOCX via a local backend proxy which injects the Authorization header.
// Run a proxy (example: http://localhost:3000/proxy?url=<remoteUrl>) that holds the token.
const showWord = async () => {'/files/docx.pptx')
}

// 预览 PPT
const showPPT = () => {
  setFile('pptx', '/files/test.pptx')
}

// 预览 Excel
const showExcel = () => {
  setFile('xlsx', '/files/test.xlsx')
}

// 预览 TXT
const showTxt = async () => {
  fileType.value = 'txt'
  try {
    const res = await fetch('/files/test.txt')
    txtContent.value = await res.text()
  } catch (e) {
    txtContent.value = 'TXT 文件加载失败'
  }
}
</script>
  1. 预览方法:每个按钮对应一个方法,设置 fileTypefileUrl。TXT 文件额外使用 fetch 获取文本内容。

3.4 根组件 (src/App.vue)

<template>
  <router-view />
</template>
  • 仅作为路由视图的容器。

4. 依赖配置 (package.json)

完整的 package.json 配置文件如下:

{
  "name": "vue-project",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test:unit": "vitest",
    "format": "oxfmt src/"
  },
  "dependencies": {
    "@vue-office/docx": "^1.6.3",
    "@vue-office/excel": "^1.7.14",
    "@vue-office/pdf": "^2.0.10",
    "@vue-office/pptx": "^1.0.1",
    "jszip": "^3.10.1",
    "mammoth": "^1.12.0",
    "vue": "^3.5.32",
    "vue-router": "^5.0.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^6.0.6",
    "@vue/test-utils": "^2.4.6",
    "jsdom": "^29.0.2",
    "oxfmt": "^0.45.0",
    "vite": "^8.0.8",
    "vite-plugin-vue-devtools": "^8.1.1",
    "vitest": "^4.1.4"
  },
  "engines": {
    "node": "^20.19.0 || >=22.12.0"
  }
}

关键依赖说明:

  • "@vue-office/docx": "^1.6.3":Word 文档预览组件。
  • "@vue-office/excel": "^1.7.14":Excel 预览组件。
  • "@vue-office/pdf": "^2.0.10":PDF 预览组件。
  • "@vue-office/pptx": "^1.0.1":PPT 预览组件。
  • "vue": "^3.5.32":Vue3 核心。
  • "vue-router": "^5.0.4":路由管理。
  • "jszip": "^3.10.1""mammoth": "^1.12.0":VueOffice 内部处理 Office 文件所需。
  • 开发依赖:包含 Vite、Vue 插件、测试工具等,用于构建和开发。
  • Node 版本:要求 Node.js 20.19.0 或 >=22.12.0。

5. 运行与部署

5.1 本地开发

  1. 安装依赖:npm install
  2. 启动开发服务器:npm run dev
  3. 访问 http://localhost:5173(默认端口)。

5.2 文件准备

将你的示例文件(如 a.docx, c.pdf 等)放入 public/files/ 目录。代码中通过 /files/ 路径访问。

5.3 构建生产版本

运行 npm run build,生成的文件在 dist 目录。需要确保服务器能正确提供 dist/files/ 下的静态文件。

6. 注意事项

  1. 文件路径fileUrl 使用 /files/xxx 形式,对应 public/files/xxx。生产环境需根据实际部署调整。
  2. 文件大小:VueOffice 组件在前端解析文件,过大文件可能导致浏览器内存不足或加载缓慢。
  3. 浏览器兼容:部分格式(如 PPTX)依赖较新的浏览器 API。
  4. 安全:本项目仅预览本地静态文件,不支持用户上传。如需上传预览,需自行实现文件上传和服务器端安全校验。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐