ByteNoteByteNote
Open File Viewer:容器内预览几十种文件格式
字

字节笔记本

2026年10月5日 · 约 10 分钟读完

Open File Viewer:容器内预览几十种文件格式

API中转
¥120

几乎每个业务系统都会遇到附件预览:ERP 要看合同 PDF,CRM 要看报价 Excel,设计平台要看 CAD 图纸,开发者工具要看代码文件。传统做法是每种格式接一个库,PDF 用 pdf.js,Office 用微软的在线预览服务,图片用 PhotoSwipe,视频用 Video.js。接了十几个库,每个都有自己的 API 和坑,长期维护是个噩梦。

Open File Viewer 预览界面

一、它是什么

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)
3DSTL/OBJ/GLB/GLTF
GISGeoJSON/Shapefile
代码JS/TS/Python/Go/Rust/SQL/YAML/JSON 等几十种

二、五个核心设计

1. 容器优先

所有内容渲染在你传入的 DOM 容器内。不弹新窗口、不跳页面、不打断用户的业务流程。这在企业系统里尤其重要:用户不想点个附件就被甩到新标签页,看完还要手动切回来。

2. 多框架兼容

一套 core,四个框架包,按技术栈选装:

bash
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。

ts
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 级别的“能打开就行”,而是产品级的“各种边缘情况都处理了”。工具栏还支持自定义文案、图标、顺序和业务按钮,比如直接加一个“审批”或“收藏”动作,不必重写整套预览器。

Open File Viewer 预览管线示意图

三、复杂格式的处理策略

浏览器能直接渲染的格式(图片、视频、文本)优先本地渲染。复杂格式(CAD、3D、Office)有两条路径:

路径怎么做适合
WASM 本地解析浏览器内用 WASM 解析,如 STL 3D、DWG 线稿隐私敏感、离线场景
服务端转换后端转成浏览器能渲染的格式高保真、复杂格式(CAD/Office)

值得称道的是它的边界设计:Office 插件默认不上传文件,只有业务显式配置 convert 钩子时,复杂 DOCX 和旧版 Office 才会走服务端转 PDF 的链路;CAD 插件则是两层能力,先用内置的 LibreDWG WASM 尽量在本地出线稿,不够再通过 binaryRenderer 接入自己的商用引擎或后端转换。整体设计哲学是“可进化”:第一版可以只支持 PDF 加图片,后续逐步加 WASM 解析器或服务端转换,不用一步到位。

四、和同类方案对比

Open File ViewerPDF.jsreact-pdfOffice Web Viewerreact-preview
格式覆盖几十种仅 PDF仅 PDF仅 Office几种
框架JS/React/Vue/Svelte原生ReactiframeReact
容器内渲染支持支持支持否(iframe)支持
插件化支持否否否否
响应式支持手动手动否部分
产品级状态支持手动手动否部分
开源协议MITApacheMIT否MIT

它的差异化可以概括成一句话:全格式、多框架、插件化、容器内渲染、产品级状态,五件事同时做到。其他方案要么只支持一种格式,要么不是容器内渲染,要么缺少产品级的错误处理和兜底。

五、谁该用

如果你在做下面这些事情,值得一试:

  • 做企业系统(ERP/CRM/OA),有大量附件预览需求
  • 做开发者工具,需要预览代码、PDF、图片
  • 做内容平台,需要预览用户上传的多种文件
  • 做设计或工程平台,需要预览 CAD、3D、GIS 文件
  • 不想为每种格式单独接一个库
  • 技术栈是 React、Vue、Svelte 任一框架,或者纯原生 JS

React 侧接入示例:

tsx
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 协议。

相关文章

分享: