Skip to content

About

纯前端 Vue 3 组件:在浏览器中直接解析并渲染 Word .doc(OLE2/CFB)文件,零上传、零后端。Pure-frontend Vue 3 component that parses & renders legacy .doc in the browser — no server, no upload.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

224 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DOC Preview

npm version npm downloads npm downloads npm bundle size License: MIT TypeScript Vue 3

A pure-frontend Vue 3 component for previewing Microsoft Word .doc files (OLE2 / CFB / Compound File Binary format) in the browser. No server, no upload, no backend. Search, zoom, print, dark mode, Web Worker parsing.

A DOC file viewer / Word document previewer built entirely in the browser. A drop-in <DocPreview> Vue component for .doc (Word 97-2003) files. Useful when you need to display Word documents on a website without sending them to a server. Renders the original formatting (font size, bold, alignment, list type) and supports search, zoom, print, and dark mode.

在线预览地址 - 点击此处即可在线体验,上传您的 .doc 文件即可预览 Compare with other doc-preview packages on npm

关键词 / Keywords

doc, doc-preview, doc-viewer, docx, docx-preview, word, word-preview, word-viewer, microsoft word, ms word, vue, vue3, vue component, preview, viewer, ole2, cfb, compound file, document parser, word parser, binary parser, frontend, in-browser, no backend, pure frontend

Features / 简介 (English)

  • Pure frontend: parses and renders entirely in the browser — no upload, no server, no API key, no CDN dependency for parsing.
  • Vue 3 component: drop-in <DocPreview :source="file" /> for any Vue 3 app; works with file upload, URL, or in-memory File object.
  • Microsoft Word .doc (OLE2 / CFB): parses the legacy Word 97-2003 binary format directly, including UTF-16LE and 8-bit compressed text streams, FIB headers, with real CHP/PAP format recovery and heuristic fallback when needed.
  • DOCX is not supported by this package — for .docx (Open XML) files, use a dedicated DOCX parser. This package is the .doc specialist.
  • Web Worker parsing: files >1 MiB are parsed off the main thread when Workers are available, reducing main-thread parsing work. Rendering still uses the main thread.
  • Built-in UX: keyword search with highlighting, zoom (50%–200%), print (browser print to PDF), text copy, text download, document outline / TOC.
  • Accessibility: keyboard shortcuts, ARIA labels, skip-link, dark mode with localStorage persistence, mobile responsive.
  • Privacy: files never leave the browser — safe for confidential docs.

Use Cases

  • A web app that needs to preview user-uploaded Word documents
  • An intranet tool that displays .doc files in a browser without a server
  • A document preview component for a content management system
  • A privacy-first document viewer (no upload to third-party servers)

功能特性

  • 🚀 纯前端实现 - 不依赖任何后端服务,完全在浏览器中解析和渲染
  • 📦 自研解析器 - OLE/CFB 与 DOC 解析由本项目实现,不依赖第三方 DOC 解析引擎;预览 HTML 使用 DOMPurify 安全净化
  • 🎯 Vue 3 组件 - 提供开箱即用的 Vue 3 组件
  • 📄 格式保留 - 尽可能保留文档的原始格式(字体、对齐、段落等)
  • 🔒 隐私安全 - 文件仅在本地处理,不上传至任何服务器
  • 🌐 跨平台 - 支持所有现代浏览器
  • 🎨 暗色模式 - 支持亮色/暗色主题切换,自动持久化偏好
  • 🔍 文档搜索 - 支持关键词搜索和高亮定位
  • 🔎 缩放控制 - 支持页面缩放(50%~200%)
  • 🖨️ 打印支持 - 一键打印或导出为 PDF
  • 📋 列表检测 - 自动识别编号列表和符号列表
  • ⌨️ 键盘快捷键 - 完整的键盘操作支持

快速开始

在线使用

直接访问 在线预览地址,点击上传按钮选择您的 .doc 文件即可预览。

安装

npm install @zhenghy/doc-preview
# 或
pnpm add @zhenghy/doc-preview
yarn add @zhenghy/doc-preview

CDN(unpkg)

<link rel="stylesheet" href="https://unpkg.com/@zhenghy/doc-preview/dist/doc-preview.css" />
<script type="importmap">
  { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } }
</script>
<script type="module">
  import { DocPreview } from 'https://unpkg.com/@zhenghy/doc-preview/dist/doc-preview.js'
  // Use DocPreview in your Vue app.
</script>

Vue 项目中使用

<template>
  <div>
    <input type="file" @change="handleFileChange" accept=".doc" />
    <DocPreview :source="currentFile" />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { DocPreview } from '@zhenghy/doc-preview'

const currentFile = ref(null)

const handleFileChange = (event) => {
  const file = event.target.files[0]
  if (file) {
    currentFile.value = file
  }
}
</script>

独立 HTML 页面使用

先运行 npm run build:lib 生成 dist。将下面示例保存为项目根目录中的 HTML 文件,并通过本地 HTTP 静态服务器打开;不要直接使用 file://,因为浏览器会限制原生 ES module 导入。

<!DOCTYPE html>
<html>
<head>
  <title>DOC Preview Demo</title>
  <link rel="stylesheet" href="./dist/doc-preview.css" />
  <script type="importmap">
    { "imports": { "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js" } }
  </script>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; }
    #preview-container { max-width: 800px; margin: 0 auto; }
  </style>
</head>
<body>
  <h1>DOC 文件预览</h1>
  
  <div id="preview-container"></div>

  <script type="module">
    import { createApp } from 'vue'
    import { DocPreview } from './dist/doc-preview.js'

    createApp({
      components: { DocPreview },
      data() {
        return {
          currentFile: null
        }
      },
      methods: {
        handleFileChange(event) {
          const file = event.target.files[0]
          if (file) {
            this.currentFile = file
          }
        }
      },
      template: `
        <div>
          <input type="file" @change="handleFileChange" accept=".doc" />
          <DocPreview :source="currentFile" />
        </div>
      `
    }).mount('#preview-container')
  </script>
</body>
</html>

键盘快捷键

快捷键 功能
Ctrl+F / Cmd+F 打开搜索栏
F3 / Ctrl+G 下一个匹配项
Shift+F3 / Ctrl+Shift+G 上一个匹配项
Esc 关闭搜索栏
Ctrl+P / Cmd+P 打印/导出 PDF
Ctrl+= / Ctrl++ 放大
Ctrl+- 缩小
Ctrl+0 重置缩放

API

Props

属性名 类型 必填 默认值 说明
source File | string | null 是 - 本地文件或通过 fetch() 加载的 URL;跨域地址需允许 CORS。null 表示当前无文档源。
useWebFont boolean 否 false 启用后会从 Google Fonts 加载字体;默认关闭,不产生该第三方请求。

事件

事件名 参数 说明
error (message: string) 解析出错时触发
loaded () 文档成功解析后触发
loading (isLoading: boolean) 加载开始/结束时触发

组件方法(通过 ref 暴露)

const previewRef = ref()

// 重新加载当前文档
previewRef.value?.reload()

// 获取解析后的纯文本
const text = previewRef.value?.getPlainText()

// 滚动并聚焦到文档内容
previewRef.value?.focusContent()

导出函数

函数名 说明
parseDocFile(file) 解析 .doc 文件,返回纯文本
parseDocFileWithFormat(file) 解析 .doc 文件,返回带格式的文档数据
parseDocFileFromBuffer(buffer) 从 ArrayBuffer 解析 .doc 文件(同步)
parseWithWorker(buffer, maxScanBytes?) 在 Web Worker 中解析(异步,大文件不阻塞 UI)
enableDebugMode() 启用调试日志输出
DocParser 解析器类(可自定义 maxScanBytes)

事件与方法示例

<template>
  <DocPreview 
    ref="previewRef"
    :source="currentFile"
    @error="handleError"
    @loaded="onLoaded"
    @loading="onLoading"
  />
  <button @click="previewRef?.reload()">重新加载</button>
</template>

<script setup>
import { ref } from 'vue'
import { DocPreview } from '@zhenghy/doc-preview'

const previewRef = ref()
const currentFile = ref()

function handleError(msg) { console.error('DOC 解析失败:', msg) }
function onLoaded() { console.log('文档已加载') }
function onLoading(isLoading) { console.log('加载中:', isLoading) }
</script>

自定义扫描上限

import { DocParser } from '@zhenghy/doc-preview'

const buffer = await file.arrayBuffer()
// 自定义扫描上限为 5 MiB(默认 10 MiB)
const parser = new DocParser(buffer, 5 * 1024 * 1024)
const result = parser.parseWithFormat()

Web Worker 解析

自动行为:DocPreview 组件内部会在 source 超过 1 MiB 时自动使用 Worker。 如果你在代码中直接使用 parseWithWorker,可以手动管理。

import { parseWithWorker } from '@zhenghy/doc-preview'

const buffer = await file.arrayBuffer()
const result = await parseWithWorker(buffer, 10 * 1024 * 1024)

if (result.success) {
  console.log('段落数:', result.document?.paragraphs.length)
} else {
  console.error('失败:', result.error)
}

工作原理

解析器在浏览器中读取 OLE/CFB 容器和 Word 二进制结构,提取文本、格式和可识别的嵌入内容,再由 Vue 组件渲染预览。完整功能项及实现状态见 FEATURES.md。

支持范围

  • .doc 和 .dot(OLE2/CFB;主要面向 Word 97-2003 二进制格式)
  • Unicode/UTF-16LE 和 8-bit 压缩文本
  • 文本、表格、常见字符/段落格式、分页与分节信息
  • 可识别的图片、页眉页脚、脚注/尾注、书签、超链接、修订标记及部分 OLE 对象
  • .docx(Open XML)不支持

格式还原取决于文件中的 Word 结构是否完整。解析器优先使用真实 CHP/PAP 格式表;缺少这些数据或遇到不常见变体时会使用启发式回退。复杂绘图、图表和公式并非完整的 Word 排版引擎,预览可能与 Microsoft Word 有差异。

替代方案对比 / Comparison

If you're evaluating doc-preview libraries for your project, here's how this package compares:

Package Format Framework Backend Notes
@zhenghy/doc-preview .doc (OLE2) Vue 3 None This package — pure OLE2/CFB parser, no server, Vue 3 only
@doc-preview/core .doc/.docx/.pdf Framework-neutral Optional Multi-format ecosystem
@doc-preview/react .doc/.docx/.pdf React 18/19 Optional React wrapper around the ecosystem
@doc-preview/angular .doc/.docx/.pdf Angular 19/20 Optional Angular standalone component
@doc-preview/js .doc/.docx/.pdf Vanilla JS Optional Plain JS API
vue-doc-preview .doc/.docx Vue 2/3 Server-based Pre-renders to HTML via remote service

When to choose this package:

  • You specifically need legacy .doc (Word 97-2003) parsing without a server
  • Your stack is Vue 3 and you want a small drop-in component
  • Privacy matters: files must never leave the browser
  • You want full control: this is a self-contained parser you can fork and extend

When to choose alternatives:

  • You need .docx (Open XML) support — use the @doc-preview/* ecosystem
  • You're not on Vue 3 — use the React / Angular / JS / vanilla variants from the ecosystem
  • You prefer a managed service — use vue-doc-preview

浏览器支持

浏览器 最低版本 Web Worker 备注
Chrome 111+ ✅ 推荐
Edge 111+ ✅ Chromium 内核
Firefox 114+ ✅ 支持 Worker
Safari 16.4+ ✅ macOS 13+/iOS 16.4+
IE 11 ❌ ❌ 不支持

生产包使用 Vite 8 默认的 baseline-widely-available 目标;最低版本随该目标更新,详见 Vite build.target 文档。不满足目标的浏览器可能无法解析生成的 JavaScript。

性能

  • <1 MiB 文件: 同步解析(主线程)
  • ≥1 MiB 文件: Web Worker 解析(自动)
  • 默认扫描上限: 10 MiB(可配置 maxScanBytes)
  • 解析耗时参考(仅解析阶段,随设备和文档结构变化):
    • 小型 (<100KB): 通常 <50ms
    • 约 1 MiB: 典型样本约 200ms
    • 1 MiB: 支持 Worker 时在后台线程解析;页面渲染仍在主线程执行

功能清单

完整的 .doc 文件功能支持状态请参阅 FEATURES.md,按 14 大类列出 119 项功能的实现状态(115 项已实现,4 项不支持)。

限制

  • 单个 .doc / .dot 文件最大支持 50 MiB;本地文件和远程 URL 都受此限制,远程响应会在超过限制时停止读取。
  • 不解析 .docx、加密/密码保护的文档,也不执行 VBA 宏。
  • 图片、修订、脚注/尾注和批注 story 等可识别内容会尝试提取和展示;不保证支持每一种 Word 变体或完整还原定位与排版。
  • 格式恢复使用 CHP/PAP 表解析,并在相关结构缺失时回退到启发式;复杂图形、图表、公式的呈现可能与 Word 不同。
  • 少数由 macOS textutil 生成的文件可能缺少标准 FIB 偏移,解析结果会受源文件结构影响。

开发

详细的架构说明请参阅 docs/ARCHITECTURE.md。

安装依赖

npm install

开发模式

npm run dev

访问 http://localhost:5173 查看开发服务器。

单元测试

npm test

监听模式测试

npm run test:watch

类型检查

npx vue-tsc --noEmit

构建库版本

npm run build:lib

构建后的文件将输出到 dist 目录,含 ES + UMD 双格式和 .d.ts 类型声明。

构建文档预览版本

npm run build

技术栈

  • Vue 3 - 前端框架
  • TypeScript - 类型安全
  • Vite - 构建工具
  • OLE/CFB - Microsoft Office 文档格式

AI Coding 介绍

本项目是 AI 辅助编程的典型实践案例,大量使用 AI 工具进行开发和优化:

开发过程中的 AI 应用

  • 代码编写 - AI 辅助实现 OLE/CFB 复合文档格式解析器
  • 问题调试 - AI 帮助定位和修复各种解析问题(乱码、格式错误、边界情况)
  • 架构设计 - AI 参与项目架构和模块划分
  • 文档完善 - AI 辅助编写 API 文档和使用示例
  • 部署优化 - AI 帮助解决 GitHub Pages 和 npm 发布问题

AI 工具使用

  • 代码补全与生成 - 快速实现复杂的二进制解析逻辑
  • 错误诊断 - 定位解析过程中的各种边界问题
  • 优化建议 - 提供性能优化和代码改进建议
  • 测试用例 - 辅助设计测试场景和边界条件

项目亮点

本项目展示了如何在 AI 辅助下,从 0 到 1 实现一个复杂的文件格式解析器,包括:

  • 深入理解 Microsoft OLE/CFB 二进制格式规范
  • 实现完整的 DOC 文件解析流程
  • 处理各种编码和格式兼容性问题
  • 发布高质量的 npm 包和在线演示

这是 AI 编程时代的一个典型项目案例,展示了 AI 如何大幅提升开发效率。

项目结构

doc-preview/
├── src/
│   ├── components/
│   │   └── DocPreview.vue           # 主预览组件(工具栏/搜索/缩放/打印/大纲)
│   ├── utils/
│   │   ├── logger.ts                # 日志工具
│   │   ├── oleParser.ts             # OLE2/CFB 复合文档结构解析
│   │   ├── fibParser.ts             # FIB (File Information Block) 解析
│   │   ├── docParser.ts             # 文本提取 + 格式推断 + 公开 API
│   │   ├── docParser.worker.ts      # Web Worker 入口
│   │   ├── parseWithWorker.ts       # Worker 封装 + 主线程降级
│   │   └── docFormat.ts             # 类型定义
│   ├── App.vue                      # 应用入口(上传/拖拽/URL 加载)
│   ├── index.ts                     # 库导出入口
│   ├── main.ts                      # 开发模式入口
│   ├── vite-env.d.ts                # Vite 类型声明
│   └── style.css                    # 全局样式 / CSS 变量 / 暗色主题
├── public/
│   ├── favicon.svg                  # 自定义图标
│   └── 404.html                     # GitHub Pages SPA 路由
├── tests/                           # Vitest parser, fixture, Worker and component regressions
│   ├── docParser.test.ts             # Parser API and format regressions
│   ├── realDocs.test.ts              # Real-world DOC fixtures
│   ├── parseWithWorker.test.ts       # Worker protocol and failure paths
│   └── components/                   # Component lifecycle and security tests
├── .github/workflows/deploy.yml     # CI: audit + tests + app/library/package builds + deploy
├── LICENSE                          # MIT 许可证
├── package.json
├── vite.config.ts
└── vitest.config.ts

贡献

欢迎提交 Issue 和 Pull Request!

许可证

MIT License - 详见 LICENSE 文件

GitHub

在线演示

立即体验 DOC Preview

点击上方的链接即可打开在线演示页面,无需安装任何软件,直接上传您的 .doc 文件即可预览效果。

About

纯前端 Vue 3 组件:在浏览器中直接解析并渲染 Word .doc(OLE2/CFB)文件,零上传、零后端。Pure-frontend Vue 3 component that parses & renders legacy .doc in the browser — no server, no upload.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages