
字节笔记本
2026年10月5日 · 约 10 分钟读完
Open File Viewer:容器内预览几十种文件格式
几乎每个业务系统都会遇到附件预览:ERP 要看合同 PDF,CRM 要看报价 Excel,设计平台要看 CAD 图纸,开发者工具要看代码文件。传统做法是每种格式接一个库,PDF 用 pdf.js,Office 用微软的在线预览服务,图片用 PhotoSwipe,视频用 Video.js。接了十几个库,每个都有自己的 API 和坑,长期维护是个噩梦。

一、它是什么
Open File Viewer 是一个面向现代 Web 产品的文件预览 SDK,MIT 协议开源,仓库地址是 https://github.com/xushanpei/open-file-viewer 。它把几十种文件格式放进同一个可控的 DOM 容器里渲染,不跳窗口、不打断业务页面,并提供原生 JavaScript、React、Vue、Svelte 四套接入方式,四者共用同一套 core 能力。
支持的格式覆盖面:
| 类别 | 格式 |
|---|---|
| 文档 | PDF、Word、Excel、PowerPoint |
| 图片 | JPG/PNG/GIF/WebP/SVG/BMP/HEIC |
| 音视频 | MP4/WebM/MP3/WAV/OGG/FLAC |
| 压缩包 | ZIP/RAR/7Z/TAR |
| 邮件 | .eml/.msg |
| 图纸 | CAD(DWG/DXF) |
| 3D | STL/OBJ/GLB/GLTF |
| GIS | GeoJSON/Shapefile |
| 代码 | JS/TS/Python/Go/Rust/SQL/YAML/JSON 等几十种 |
二、五个核心设计
1. 容器优先
所有内容渲染在你传入的 DOM 容器内。不弹新窗口、不跳页面、不打断用户的业务流程。这在企业系统里尤其重要:用户不想点个附件就被甩到新标签页,看完还要手动切回来。
2. 多框架兼容
一套 core,四个框架包,按技术栈选装:
pnpm add @open-file-viewer/core # 核心
pnpm add @open-file-viewer/react # React 适配
pnpm add @open-file-viewer/vue # Vue 适配
pnpm add @open-file-viewer/svelte # Svelte 适配3. 格式插件化
不同文件格式由独立插件负责,可以按需引入(比如只装 PDF 加图片),也可以全量安装,方便裁剪包体积。插件协议也足够简单:实现 match 判断文件是否归你管,实现 render 把内容写进 ctx.viewport 就行,需要响应容器变化就补一个 resize,需要清理事件和 Object URL 就实现 destroy。
import { createViewer, imagePlugin, videoPlugin, textPlugin } from '@open-file-viewer/core'
import '@open-file-viewer/core/style.css'
const viewer = createViewer({
container: '#viewer',
file: fileOrUrl,
fileName: 'report.pdf',
width: '100%',
height: '70vh',
plugins: [imagePlugin(), videoPlugin(), textPlugin()],
})4. 响应式预览
支持 px、%、vh、vw、rem、calc() 等 CSS 尺寸,容器变了预览自动跟着调整,不需要手动监听 resize 再重算布局。
5. 产品级状态
内置了真实产品需要的各种状态:loading、error、unsupported、下载兜底、工具栏、明暗主题切换、多文件队列。不是 demo 级别的“能打开就行”,而是产品级的“各种边缘情况都处理了”。工具栏还支持自定义文案、图标、顺序和业务按钮,比如直接加一个“审批”或“收藏”动作,不必重写整套预览器。

三、复杂格式的处理策略
浏览器能直接渲染的格式(图片、视频、文本)优先本地渲染。复杂格式(CAD、3D、Office)有两条路径:
| 路径 | 怎么做 | 适合 |
|---|---|---|
| WASM 本地解析 | 浏览器内用 WASM 解析,如 STL 3D、DWG 线稿 | 隐私敏感、离线场景 |
| 服务端转换 | 后端转成浏览器能渲染的格式 | 高保真、复杂格式(CAD/Office) |
值得称道的是它的边界设计:Office 插件默认不上传文件,只有业务显式配置 convert 钩子时,复杂 DOCX 和旧版 Office 才会走服务端转 PDF 的链路;CAD 插件则是两层能力,先用内置的 LibreDWG WASM 尽量在本地出线稿,不够再通过 binaryRenderer 接入自己的商用引擎或后端转换。整体设计哲学是“可进化”:第一版可以只支持 PDF 加图片,后续逐步加 WASM 解析器或服务端转换,不用一步到位。
四、和同类方案对比
| Open File Viewer | PDF.js | react-pdf | Office Web Viewer | react-preview | |
|---|---|---|---|---|---|
| 格式覆盖 | 几十种 | 仅 PDF | 仅 PDF | 仅 Office | 几种 |
| 框架 | JS/React/Vue/Svelte | 原生 | React | iframe | React |
| 容器内渲染 | 支持 | 支持 | 支持 | 否(iframe) | 支持 |
| 插件化 | 支持 | 否 | 否 | 否 | 否 |
| 响应式 | 支持 | 手动 | 手动 | 否 | 部分 |
| 产品级状态 | 支持 | 手动 | 手动 | 否 | 部分 |
| 开源协议 | MIT | Apache | MIT | 否 | MIT |
它的差异化可以概括成一句话:全格式、多框架、插件化、容器内渲染、产品级状态,五件事同时做到。其他方案要么只支持一种格式,要么不是容器内渲染,要么缺少产品级的错误处理和兜底。
五、谁该用
如果你在做下面这些事情,值得一试:
- 做企业系统(ERP/CRM/OA),有大量附件预览需求
- 做开发者工具,需要预览代码、PDF、图片
- 做内容平台,需要预览用户上传的多种文件
- 做设计或工程平台,需要预览 CAD、3D、GIS 文件
- 不想为每种格式单独接一个库
- 技术栈是 React、Vue、Svelte 任一框架,或者纯原生 JS
React 侧接入示例:
import { FileViewer } from '@open-file-viewer/react'
import { imagePlugin, pdfPlugin, textPlugin } from '@open-file-viewer/core'
import '@open-file-viewer/core/style.css'
import pdfWorkerSrc from 'pdfjs-dist/build/pdf.worker.mjs?url'
function App() {
return (
<FileViewer
file={file}
fileName={file.name}
width="100%"
height="600px"
fit="contain"
toolbar
theme="auto"
plugins={[imagePlugin(), pdfPlugin({ workerSrc: pdfWorkerSrc }), textPlugin()]}
/>
)
}注意 PDF 预览依赖 pdfjs-dist,装好包并把 worker 地址传给 pdfPlugin 即可。
六、小结
一句话总结:Open File Viewer 是一个全格式文件预览 SDK,PDF、Office、图片、音视频、压缩包、邮件、CAD、3D、GIS、代码,一个容器搞定,支持原生 JS、React、Vue、Svelte 四种接入方式,MIT 开源。如果你做的 Web 产品有附件预览需求,它能省掉你接十几个库的时间。
这种“一个 SDK 替代一堆库”的聚合思路,在用户引导库 driver.js、Mac 端工具合集 AnyDoor 身上也有体现,做技术选型时可以对照参考。
本文基于开源项目 Open File Viewer 的公开仓库与文档整理,MIT 协议。



