前端做文件预览,最难搞的永远不是图片,也不是 PDF。
真正折磨人的,是 Office。
后台系统里随便一个附件中心,用户上传的文件可能是:
合同.doc报价.xls方案.pptx审批表.xlsx说明文档.docx历史资料.wps财务表.et演示稿.dps产品只会说一句:
“这里加个在线预览。”
听起来很简单,落到前端就开始爆炸。
PDF 还能靠 pdf.js 顶住,图片、视频浏览器原生就能处理,文本和代码也不算复杂。但 Word、Excel、PPT 完全是另一套难度。字体、分页、表格、合并单元格、图片浮动、页眉页脚、旧版二进制格式、WPS 兼容格式,每一个都可能让预览效果翻车。
更麻烦的是,真实业务里不可能只出现 docx、xlsx。
很多企业项目、政务项目、OA 系统、档案系统,里面存了大量历史文件,doc、xls 依然非常常见。很多所谓的 Office 预览库,看起来支持 Word 和 Excel,实际只支持新版 docx、xlsx。一旦碰到 doc、xls,直接打不开。
这个问题我自己在项目里也遇到过很多次。
所以我做了一个文件预览 SDK:
Open File Viewer。

这次最想说的重点是:
它已经支持 doc / xls 预览了。
这一下就不只是“能预览 Office”这么简单了。
它开始覆盖真实业务里最容易踩坑的那部分文件。
为什么我要做这个库?
因为前端文件预览这个需求,太容易被低估了。

很多人一开始会觉得:
PDF 用 pdf.js图片用 img视频用 video文本直接渲染Office 找个库不支持就下载听起来问题不大。
但项目一复杂,就会发现完全不是这么回事。
每一种文件类型都有自己的加载状态、错误状态、工具栏、下载逻辑、全屏逻辑、容器适配、fallback 逻辑。最后代码里全是判断,页面里到处复制。
比如:
if (isPdf(file)) { renderPdf(file);} elseif (isImage(file)) { renderImage(file);} elseif (isOffice(file)) { renderOffice(file);} else { download(file);}刚开始能跑,后面一定难维护。
弹窗里一套,详情页一套,审批页一套,附件中心一套。后面要加格式、改工具栏、补错误状态,维护成本非常高。
所以我想做的不是一个简单的预览组件,而是一个更通用的文件预览 SDK。
它要解决的不是某一个文件,而是一整类场景:
统一容器统一工具栏统一状态统一 fallback统一插件扩展这就是 Open File Viewer 的核心思路。
doc / xls 支持为什么关键?
很多人可能觉得:
doc 和 docx 不都是 Word 吗?
差别很大。
docx、xlsx 属于新版 Office 格式,本质上是基于 XML 的压缩包结构,解析路径相对清晰;而 doc、xls 是更早期的二进制格式,历史包袱更重,结构更复杂,浏览器端处理起来麻烦很多。
所以很多前端方案会选择性支持:
docx ✅xlsx ✅pptx ✅doc ❌xls ❌Demo 看起来没问题,真正接进业务系统就开始出事。
因为用户上传文件时不会考虑技术实现,他看到的只有:
Word 文件打不开Excel 文件打不开至于这个文件到底是 doc 还是 docx,是 xls 还是 xlsx,用户根本不关心。
这就是 doc / xls 支持的价值。
它不是锦上添花,而是决定一个文件预览组件能不能进入老系统、企业系统、政务系统、合同系统、档案系统的关键能力。
目前 Open File Viewer 在 Office 方向已经支持这些格式:
docdocxxlsxlsxpptxrtfodtcsvwpsetdps这里面最关键的就是:
docxls因为这两个格式,基本就是很多老业务系统的历史包袱。
比如一个 OA 审批系统,跑了十几年,里面的历史附件大概率不是清一色 docx。合同、制度、财务表、报价单,很可能就是 doc、xls。
如果预览器只支持新版 Office,接进去之后很快就会遇到投诉。
所以我这次把 doc / xls 支持加进来之后,整个库的实用性会明显上一个台阶。
它不只适合新项目,也适合给老系统补一套现代化附件预览能力。
Open File Viewer 的架构思路
Open File Viewer 的方案更像一个文件预览底座。

它把预览能力收敛到同一个容器里,再通过插件处理不同格式。
核心可以理解成三层:
OpenFileViewer统一容器 / 工具栏 / 状态 / fallbackPlugin System根据文件类型分发到不同插件RendererPDF / Office / Image / Text / Audio / Video 等具体渲染能力这套结构的好处很直接:
业务层不需要关心每种格式怎么渲染,只需要把文件交给预览器。
支持的格式走对应插件,不支持的格式走兜底下载。后续想增强某一种格式,也不需要推翻整个组件,只需要扩展插件。
这才是我认为更适合复杂后台系统的设计。
因为真实项目里,文件类型不会很干净。
一个详情页里可能同时出现:
合同.doc报价.xls说明.pdf截图.png日志.json压缩包.zip方案.pptx以前每一种格式都要单独处理,现在可以统一交给 Open File Viewer。
业务侧只需要封一个组件:
<FilePreview:file="currentFile" />底层统一走 SDK,上层只管业务。
这样附件预览能力就不会散在整个项目里。
Vue3 接入方式
在 Vue3 项目里接入很直接。
先安装核心包和 Vue 组件:
pnpm add @open-file-viewer/core @open-file-viewer/vue如果项目里还需要 PDF 预览,再安装:
pnpm add pdfjs-dist基础用法大概是这样:
<scriptsetuplang="ts">import { OpenFileViewer } from"@open-file-viewer/vue";import { imagePlugin, textPlugin, pdfPlugin, officePlugin} from"@open-file-viewer/core";import"@open-file-viewer/core/style.css";import pdfWorkerSrc from"pdfjs-dist/build/pdf.worker.mjs?url";defineProps<{file: File;}>();const plugins = [ imagePlugin(), textPlugin(), pdfPlugin({workerSrc: pdfWorkerSrc }), officePlugin()];</script><template><OpenFileViewer:file="file":file-name="file.name"width="100%"height="640px"fit="contain"toolbartheme="auto":plugins="plugins" /></template>核心就两个点:
OpenFileViewer:负责统一预览容器officePlugin():负责 Office 文件预览也就是说,Vue 页面里不需要到处写格式判断,也不需要给 Word、Excel、PPT 单独设计一套 UI。
你只要把文件传进去,后面交给插件系统处理。
弹窗里可以用,抽屉里可以用,详情页里可以用,审批流里也可以用。
对后台系统来说,这种接入方式会干净很多。
不只是 Office
虽然这次重点是 Vue3 Office 预览,但 Open File Viewer 本身不是只服务 Office。
它的定位是一个插件化文件预览 SDK。
除了 Office,它还可以覆盖更多文件类型:
PDF图片音频视频文本代码压缩包邮件OFDEPUBCAD3DGIS数据文件我更希望它成为一个“文件预览底座”。
以前项目里每一种文件都单独接一个库,后期一定会变得很碎。
更合理的方式应该是:
文件进入统一预览器预览器根据类型分发到插件插件负责具体渲染失败之后统一 fallback这样后续要加格式、改工具栏、做权限控制、接下载逻辑、加埋点,都可以统一处理。
这也是我做插件体系的原因。
工具栏和 fallback 很重要
很多文件预览组件只关注“能不能渲染”。
但真实项目里,预览只是第一步。
还要考虑这些问题:
加载中怎么展示?加载失败怎么办?格式不支持怎么办?用户要下载怎么办?需要全屏怎么办?多个附件怎么切换?暗色模式怎么适配?容器宽高怎么控制?这些能力看起来不炫,但非常影响落地体验。
尤其是后台系统里,文件经常来自接口、对象存储、临时链接、权限系统。文件太大、链接过期、格式异常、浏览器不支持,都很常见。
一个能落地的预览组件,必须有完整状态链路:
loadingpreviewerrorunsupporteddownload fallbackOpen File Viewer 的价值就在于,它没有把这些东西都甩给业务层,而是直接放进统一容器里处理。
这对工程维护非常友好。
Office 预览的边界也要讲清楚
这里必须说一个现实问题:
浏览器端 Office 预览,不可能 100% 复刻 Microsoft Office / WPS 的完整排版效果。
尤其是复杂 Word 文档:
特殊字体复杂页眉页脚文本框浮动图片嵌套表格批注修订模式宏旧版二进制结构这些东西浏览器端天然就很难完全还原。
Excel 也一样。
复杂公式、图表、合并单元格、筛选器、冻结窗格、超大表格,都可能影响预览效果。
所以企业级 Office 预览通常有两条路线:
轻量文件:前端直接预览复杂文件:服务端转 PDF,再由前端渲染 PDF这才是更稳的工程方案。
Open File Viewer 的好处是,它可以作为统一入口。普通 Office 文件直接预览,复杂文件可以走服务端转换,再把转换后的 PDF 交给同一个预览容器处理。
业务层不需要感知太多细节。
最终用户看到的还是同一个预览器。
官网已经可以在线体验
为了方便大家直接看效果,我也做了一个官网。
官网地址:https://open-file-viewer-workspace.void.app/
里面可以在线预览不同类型文件,也可以看具体接入方式和插件设计。
建议大家可以直接打开体验一下,尤其是正在做这些场景的朋友:
OA 附件中心ERP 单据预览CRM 合同预览审批系统知识库网盘系统低代码平台档案管理系统企业内部文档系统工程资料系统这些系统有一个共同点:
文件类型很杂。
如果每一种格式都单独接一个库,项目最后一定会变得很碎。
更好的方式,是把文件预览能力统一收口:
统一容器统一工具栏统一状态统一 fallback统一插件扩展这就是 Open File Viewer 更有价值的地方。
它不是只解决某一个文件格式,而是把文件预览做成了一套可扩展的前端基础设施。
最后,求个 Star
这个项目目前是完全免费开源的。
项目地址:
https://github.com/xushanpei/open-file-viewer我做它的初衷也很简单:
希望把自己在文件预览里踩过的坑,沉淀成一个更通用的 SDK,帮助到更多前端开发者。
文件预览这种库,其实做起来挺琐碎的。
每一种格式、每一种异常状态、每一个 fallback、每一次容器适配,背后都是实际业务里的细节。它不像一些炫酷项目那样一眼炸裂,但真正做过后台系统的人应该知道,这种基础能力一旦稳定下来,能少踩很多坑。
所以,如果你正在做 后台、附件中心、知识库、网盘、审批系统,或者刚好也被 Office 预览折磨过,可以试一下 Open File Viewer。
如果觉得这个项目对你有帮助,也希望大家能去 GitHub 给个 Star。
开源不易。
一个 Star 对开源项目来说真的很重要,也会给我继续维护下去很大的动力。
后面我也会继续优化更多格式、更多插件,以及更多真实业务场景里的细节。
官网地址:
https://open-file-viewer-workspace.void.app/GitHub 地址:
https://github.com/xushanpei/open-file-viewernpm 地址:
https://www.npmjs.com/package/@open-file-viewer/core
夜雨聆风