开发后台管理系统的人,迟早都会碰到一个需求:附件在线预览。一开始看似简单——图片直接展示,PDF 接个 pdf.js,文本塞进代码编辑器,视频交给浏览器。
真正复杂的是后续:用户开始上传 doc、xls、pptx、wps、et,再混进压缩包、邮件、图纸、代码文件,原本一个小功能,很快就膨胀成一套独立系统。
Open File Viewer
目前已经支持原生 JavaScript、Vue、React、Svelte 四种技术栈,Office 方向也覆盖了 doc、docx、xls、xlsx、pptx 等常见格式。

文件预览最难的地方:失控
很多项目最早的预览代码大概是这样:
if (isPdf(file)) {
openPdf(file);
} else if (isImage(file)) {
openImage(file);
} else if (isOffice(file)) {
openOffice(file);
} else {
download(file);
}
刚开始没问题,等格式一多,业务就会慢慢失控:PDF 有一套工具栏,图片有一套缩放逻辑,Office 有一套加载状态,视频有自己的控制器,压缩包只能下载。各写各的,同一个预览功能在弹窗、详情页、审批流和附件中心不断复制。
最后项目里没有"文件预览能力",只有一堆散落的格式判断。
Open File Viewer 最先解决的就是这个问题:把所有文件预览统一收口到一个入口。业务层只负责传文件,格式识别、插件匹配、渲染、错误处理、下载兜底,全部交给 SDK。

一套 Core,支持四种技术栈
Open File Viewer 没有把能力绑死在某个框架里。它的核心结构分成几层:
JavaScript / Vue / React / Svelte
↓ Framework Adapter
↓ Open File Viewer Core
↓ Plugin System
↓ Renderer
底层 Core 负责:文件识别、插件调度、状态管理、容器生命周期、工具栏、主题、错误处理、Fallback。上层的 Vue、React、Svelte 只负责框架适配。不管项目用什么技术栈,底层走的都是同一套预览能力。
一个团队里可能同时存在老后台(原生 JS)、管理端(Vue)、新产品(React)、轻量页面(Svelte)。以前需要分别维护四套方案,现在共用一套插件和渲染逻辑。这也是我一开始就把它做成 SDK,而不是只做一个 Vue 组件的原因。
插件系统才是核心
文件格式太多,靠一个超级组件硬扛,后面一定会越来越重。所以 Open File Viewer 把不同格式拆成独立插件:
const plugins = [
officePlugin(),
pdfPlugin(),
imagePlugin(),
textPlugin()
];
文件传入后,内部流程大致是:读取文件信息 → 识别扩展名和 MIME → 匹配对应插件 → 创建 Renderer → 渲染到统一容器。
每个插件只处理自己负责的内容。officePlugin() 关注 Office,pdfPlugin() 处理 PDF,imagePlugin() 负责图片,后续还可扩展音视频、压缩包、CAD、GIS、3D 等能力。
这种结构有两个关键优势:
- 格式之间互不干扰:Office 插件出问题,不会影响图片和 PDF 的正常预览。
- 业务可以按需加载:项目只需要引入自己用到的插件,不需要的格式不会增加打包体积。
统一的状态管理
预览能力统一后,上层业务拿到的就是一套标准化的事件和状态。比如 loading、error、download 这些状态,业务层只需要监听一次,不用再为每种格式单独处理。

总结
Open File Viewer 的核心理念是:格式再多,入口只有一个。
通过插件化的架构,把文件预览从"散落的格式判断"变成"统一的能力模块"。不管你的技术栈是 Vue、React 还是原生 JS,都可以用同一套 SDK 解决文件预览问题。
-
官网地址:
https://open-file-viewer-workspace.void.app/ -
GitHub 地址:
https://github.com/xushanpei/open-file-viewer -
npm 地址:
https://www.npmjs.com/package/@open-file-viewer/core