×

前端又一个 “全家桶” 出现了!

独孤求败 独孤求败 发表于2026-07-13 14:36:59 浏览15 评论0

抢沙发发表评论

做后台系统的人,迟早都会碰到一个需求:

附件在线预览。

一开始看着很简单,图片直接展示,PDF 接个 pdf.js,文本塞进代码编辑器,视频交给浏览器。

真正麻烦的是后面。

用户开始上传 docxlspptxwpset,再混进压缩包、邮件、图纸、代码文件,原本一个小功能,很快就变成一套独立系统。

我自己也被这个问题折腾过很多次。

所以我做了一个文件预览 SDK

Open File Viewer。

图片

目前已经支持原生 JavaScriptVueReactSvelte,Office 方向也覆盖了 docdocxxlsxlsxpptx 等常见格式。

图片

这篇文章不讲概念,直接聊它解决了什么,以及这套 SDK 是怎么设计的。

文件预览最难的地方,是失控

很多项目最早的预览代码,大概都是这样:

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

上层的 VueReactSvelte 只负责框架适配。

所以不管项目用什么技术栈,底层走的都是同一套预览能力。

一个团队里完全可能同时存在:

老后台:原生 JavaScript
管理端: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。

第二,业务可以按需加载。项目只需要 PDF 和 Office,就只注册这两个插件,不必把所有能力全部打进包里。

doc / xls 支持,才是真正进入业务系统

很多 Office 预览方案都会写一句:

支持 Word、Excel、PPT。

真正点进去一看,支持的是:

docx
xlsx
pptx

碰到 docxls 就没了。

但在真实项目里,老版 Office 文件根本绕不开。

特别是这些系统:

OA
档案管理
合同系统
财务系统
政企项目
内部知识库

历史数据里往往有大量 doc 和 xls

用户不会区分 doc 和 docx,也不会关心二进制格式和 XML 格式的区别。他只知道这个文件明明是 Word,为什么点不开。

所以这次我把 docxls 也补了进来。

目前 Office 方向覆盖:

doc
docx
xls
xlsx
pptx
rtf
odt
csv
wps
et
dps

对国内业务来说,wpsetdps 同样很重要。

文件格式从来不会按照开发者最舒服的方式出现,预览组件能不能处理这些“脏数据”,直接决定了它能不能落地。

四种技术栈,接入方式保持一致

原生 JavaScript

import {
  OpenFileViewer,
  officePlugin,
  pdfPlugin,
  imagePlugin
from"@open-file-viewer/core";

const viewer = new OpenFileViewer({
  container: document.querySelector("#viewer"),
  plugins: [
    officePlugin(),
    pdfPlugin(),
    imagePlugin()
  ]
});

viewer.open(file);

原生项目、老后台、WebView、低代码平台都可以直接使用,不需要额外引入框架。

Vue

<OpenFileViewer
  :file="file"
  :file-name="file.name"
  :plugins="plugins"
  width="100%"
  height="640px"
  toolbar
/>

React

<OpenFileViewer
  file={file}
  fileName={file.name}
  plugins={plugins}
  width="100%"
  height="640px"
  toolbar
/>

Svelte

<OpenFileViewer
  {file}
  fileName={file.name}
  {plugins}
  width="100%"
  height="640px"
  toolbar
/>

四套写法看起来不同,底层调用的是同一个 Core

这意味着格式支持、工具栏、异常状态、插件能力都不会因为框架不同而割裂。

真正难做的,还有失败状态

文件预览不可能永远成功。

真实项目里经常会碰到:

文件链接过期
对象存储跨域
文件体积过大
格式伪装
文件损坏
浏览器能力不足
插件加载失败

所以一套能落地的预览 SDK,必须把完整状态链路处理掉:

loading
preview
error
unsupported
download fallback

Open File Viewer 把这些状态统一放进容器里。

业务层不用给每一种格式重复写加载动画、错误提示和下载按钮。

预览成功,就进入 Renderer。

预览失败,就进入 Fallback。

格式不支持,也可以直接提示下载,或者接入服务端转换。

Office 高保真预览,必须保留服务端路线

浏览器端预览 Office 有天然边界。

复杂 Word 里可能有:

特殊字体
页眉页脚
浮动图片
文本框
修订记录
嵌套表格

Excel 里也会出现复杂公式、图表、冻结窗格和大数据量。

前端可以完成基础预览,但很难百分之百复刻 Microsoft Office 或 WPS 的排版结果。

所以更稳的工程方案通常是:

普通文件
前端直接预览

复杂文件
服务端转换为 PDF
前端继续预览

Open File Viewer 可以把两条路线统一起来。

前端能直接处理的,交给 Office 插件;需要高保真的,服务端转成 PDF,再交给 PDF 插件。

用户看到的仍然是同一个预览容器,业务页面也不用维护两套 UI。

官网已经可以在线体验

我做了一个在线官网,可以直接体验:https://open-file-viewer-workspace.void.app/

里面可以查看不同格式的预览效果,也可以了解插件体系和接入方式。

正在做这些项目的朋友,可以重点试一下:

附件中心
OA 审批
ERP 单据
CRM 合同
知识库
网盘
低代码平台
档案系统
企业文档平台

这些系统看起来完全不同,底层碰到的问题却高度一致:

文件类型杂,预览逻辑乱,后期维护成本高。

Open File Viewer 想做的,就是把这部分能力统一沉淀下来。

完全免费开源,求个 Star

项目目前完全免费开源。

GitHub 地址:

https://github.com/xushanpei/open-file-viewer

我开发这个项目的原因很简单:

希望把自己踩过的坑做成一套通用能力,帮助更多开发者少重复造轮子。

文件预览这种项目,表面上没有多复杂,真正做起来全是细节。

每一种格式、每一种异常状态、每一个浏览器差异、每一条 Fallback 路径,都需要一点点补齐。

如果你正在做文件预览,欢迎直接拿去试。

觉得项目有用,也希望能顺手给个 Star

开源不易,一个 Star,真的会成为我继续维护下去的动力。

  • 官网地址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


群贤毕至

访客