@l1yp/file-viewer

In-browser file viewer for 60+ formats (office / archives / images / code / …) as a Vue 3 component. Bytes never leave the browser.
1,383
Install
npm install @l1yp/file-viewer
Latest Version:0.1.10
Vue:3
License:MIT
Last Updated:Jul 19, 2026
Links: GitHub  ·  npm
Maintainer: l1yp

@l1yp/file-viewer

浏览器内的多格式文件查看器,封装成一个 Vue 3 组件。给它一个文件,它自动识别类型并完全在浏览器里解析渲染——文件字节不经过任何服务器。支持 60+ 种格式:Office 文档、压缩包、图片、代码、音频、证书、数据库、3D 模型、电子书……

从 chat-share-proxy 抽取。完整设计见仓库 frontend/docs/file-viewer-package-design.md。

特性

  • 60+ 格式:docx/xlsx/pptx/pdf、zip/7z/rar/tar、png/tiff/psd/heic/dcm、csv/jsonl/sqlite、markdown/代码高亮、eml/mht/har、字体/证书/密钥库、epub/mob、drawio/dxf/dwg/dwf/dwfx/geojson、hprof/.class/.so/.dll、易语言 .e/.ec 等。
  • Word 内嵌文件:识别 DOCX 中被 docx-preview 跳过的嵌入包(含直接嵌入的 XLSX 与 OLE 包装的 PPTX),把可用的 Word/WPS 内容快照插回正文原位置;遇到浏览器不支持的 EMF 快照时,按需用 PPTX renderer 渲染第一页。点击正文预览即可打开完整文件,也可下载原始附件。
  • 终端日志还原:日志和纯文本可解释 ANSI SGR 前景色、背景色、16/256/真彩色及常见文字装饰;搜索、折叠、复制使用净化后的纯文本,其他终端控制命令不会在页面执行。
  • STEP 三维预览:.stp/.step 在独立 Worker 内解析,保留可用的零件/面颜色,支持旋转、缩放、平移与自动适配视口;可取消,切换文件和关闭预览会终止解析。
  • 三维查看模式:所有网格模型均支持「原色 / 白模 / 线框」切换。原色保留导入的材质、贴图及顶点/面颜色,白模使用统一浅色哑光材质,线框沿用模型原有的材质颜色、贴图及顶点/面颜色,显示包含背面及已有内部结构的三角网格。切换无需重新下载或解析,保持当前视角;线框展示的是离散后的三角边,不等同于 CAD 特征边或剖切面。
  • ZIP 网页预览:打开压缩包里的 HTML 时,自动解析并加载同包的 JS、CSS、图片、字体等相对依赖;源码保持原样,脚本仍需用户主动开启后才会在不透明源沙箱中运行。
  • 零后端:上游字节只在浏览器解析;HTML/SVG 走沙箱 iframe、下载端点无法内联执行。
  • 按需分包:每个查看器是独立的懒加载 chunk,打开 PDF 才拉 PDF 引擎;用不到的格式零成本。
  • 重型依赖可选:只装你需要的格式的引擎;明确缺少依赖时显示安装提示,网络、缓存或模块执行失败时显示真实错误与刷新入口。
  • 主题可定制:CSS 变量作用域限定在组件根,不污染宿主;theme prop 或覆盖变量即可换肤。

安装

npm i @l1yp/file-viewer vue

vue(>=3.5)是 peer 依赖。核心解析(代码高亮 / Markdown 数学 / frontmatter)依赖的 highlight.js / katex / js-yaml 会随包自动安装。

各重型格式的引擎是可选 peer 依赖——按需安装你要支持的格式:

格式 需额外安装
PDF pdfjs-dist
Word .docx docx-preview
Excel .xlsx exceljs numfmt
PowerPoint .pptx @aiden0z/pptx-renderer pdfjs-dist
SQLite .sqlite/.db sql.js
3D 模型 .stl/.obj/.glb/… three
STEP 模型 .stp/.step three occt-import-js
地图 .geojson/.kml/.kmz/.gpx maplibre-gl(KMZ 另用内置 jszip 解包)
Photoshop .psd ag-psd
TIFF .tif/.tiff utif2
HEIC/HEIF heic2any
EPUB epubjs
DICOM .dcm dicom-parser(JPEG2000/JPEG-LS 另需 @cornerstonejs/codec-openjpeg @cornerstonejs/codec-charls @cornerstonejs/codec-libjpeg-turbo-8bit)
RAR node-unrar-js
Brotli 归档 .br brotli-dec-wasm
微信/QQ 语音(SILK/AMR) silk-wasm @audio/decode-amr

加载器明确报告缺少某格式的引擎时,打开该文件会显示一张安装提示卡(含一键复制安装命令 + 下载原文件)。模块下载失败、开发缓存失效或模块执行异常会显示「预览暂时无法加载」、错误详情与刷新入口,不会误报需要安装依赖。

打包器提示:这些可选依赖在库构建里是 external。若你的打包器(Vite/webpack)对未安装的可选依赖在构建期报「无法解析」,把你不用的那几个加进 bundler 的 external / optimizeDeps.exclude 即可。

STEP / STP

<FileViewer :blob="file" name="part.step" />
<!-- 与其他附件一样支持下载 URL、鉴权 fetchConfig、load 和压缩包内的 Blob URL。 -->
<FileViewer :src="downloadUrl" name="assembly.stp" :size="fileSize" />

STEP 使用 occt-import-js(OpenCascade WASM)进行曲面离散,再交给现有 Three.js 查看器显示。解析器只在打开 STEP 时加载;其 JS/WASM 通过 Vite ?url 交由宿主打包成静态资源,不访问 CDN、不上传模型、不需要后端转换接口。发布的库内包含 Worker 启动代码,消费者无需复制 Worker 文件或配置固定资源路径;使用其他打包器时需支持这些资源 URL 导入。

部分多面体导出器只写 FACETED_BREP → FACE → POLY_LOOP 边界,没有面对应的平面,OCCT 可能返回空网格,也可能只显示文件中的其他面。查看器会在解析前检查并在 Worker 的内存副本中补出共面的 FACE_SURFACE/PLANE,保留孔洞、有效边界方向和原始单位;不修改原文件或下载内容。无法补全的多面体、未离散的面和无三角形的网格会触发「预览可能不完整」提示,缺失边界、退化或非共面多边形不会被擅自补面。

支持带 BOM 的 UTF-8、UTF-16 LE/BE 以及以 STEP 文件头开始的无 BOM UTF-16;兼容处理保留旧编码名称的原始字节。解析结果在转为 WebGL 的 Float32 顶点前先减去双精度中心,避免位于远处的小零件丢失细节;装配层级与原始位置会恢复。无效顶点、三角形索引和装配引用会明确报错;缺少装配归属的有效网格作为独立部分显示并提示。

支持范围仍取决于 OCCT:此查看器以三角曲面/实体为主,不提供完整 CAD 参数历史、PMI/GD&T、几何约束或工程精度测量;纯曲线/点没有曲面网格时不会显示,也不会自动补取单独存放的外部零件文件。不同导出器、AP203/AP214/AP242 写法及超大模型需使用实际文件验证,不能仅凭 .step/.stp 后缀保证完整显示。

超过 20 MiB 或大小未知的 STEP 文件需点击后再开始加载,解析任务最多 120 秒,可以主动取消;每次解析使用独立 Worker,成功、失败、取消及超时都会终止 Worker 并释放 WASM 内存。直接 URL 的自动下载按实际接收字节检查门槛,错误的大小声明不会导致无限缓冲;用户确认后再完整读取。小型 Blob/文本文件会使用实际字节大小,避免多余的未知大小提示。复杂装配体的耗时与内存还取决于几何复杂度,大小提示不是兼容性保证。

CATIA V5 CATPart

CATPart 文件会进入同一个 Three.js 模型查看器。浏览器端先校验 V5_CFV2 文件头,重组嵌套目录中最大的 MainDataStream 分片,再解码 mode 0/1 可视化坐标表,把 FBB trim handle 映射到真实 XYZ,展开独立三角形、triangle strip 和 triangle fan,并保留 FBB 面颜色;同时校验 SurfacicReps 的解析曲面载荷。Three.js 使用这些源三角形生成带法线的实体 shaded mesh,支持旋转、缩放、平移和自动取景。解析结果会显示顶点、面记录、trim 三角形和曲面载荷数量。

CATIA V5 的参数特征树和部分 CGM 曲面载荷属于私有表示。当前支持的标准嵌套/FBB 布局会使用文件自身的可视化坐标和 trim 索引生成完整源面网格;不满足坐标表、handle 范围或面绑定完整性校验的其它布局会明确报错并保留原文件下载入口。

三维取景同时考虑横向和纵向视角,窄侧栏及窗口尺寸变化时会重新适配,也可点击「适应窗口」重新居中。切换模型会释放几何体、材质、贴图与图像位图,模式切换仍保持当前模型和视角。

宿主若配置了严格 CSP,需允许 Blob Worker(worker-src blob:)、自托管解析器脚本及 WASM 执行;不依赖 SharedArrayBuffer 或 COOP/COEP。occt-import-js 为可选外部依赖,使用其 LGPL-2.1 许可,与本包自身的 MIT 许可分开。

使用

import { FileViewer } from '@l1yp/file-viewer'
import '@l1yp/file-viewer/style.css' // 必需:查看器的样式在这里
<!-- 最简:URL + 文件名 -->
<FileViewer :src="url" name="report.csv" />

<!-- 内存字节(拖拽 / 上传的 File 直接喂) -->
<FileViewer :blob="file" :name="file.name" />

<!-- 需要鉴权的 URL:附加 fetch 配置,或用 load 完全自定义取字节 -->
<FileViewer
  :input="{
    src,
    name,
    mime,
    size,
    fetchConfig: { headers: { Authorization: `Bearer ${token}` } },
  }"
  theme="dark"
  @loaded="onText"
  @error="onError"
/>

数据源(写在 input 上,或用同名简写 props)——四选一,优先级 text > blob > load > src:

字段 说明
src 可直接 fetch 的 URL(最常用)
blob 内存字节(Blob/File)
text 已解码文本(文本型查看器免网络)
fetchConfig 附加到 fetch(src, …):headers/credentials/mode …(会触发一次性预取到 blob)
load (signal?: AbortSignal) => Promise<Blob | ArrayBuffer>,自己拉字节(签名换取 / SDK);原来的无参数函数也兼容

更底层的出口

文件准备阶段可取消。切换文件或卸载组件会中止鉴权预取,并丢弃旧任务的迟到结果、释放 Blob URL;自定义 load 可把传入的 signal 继续交给 fetch 或 SDK 实现实际中止,不处理信号的旧函数也不会覆盖新文件。resolveInput(input, signal?) 同样支持可选取消信号。三维加载失败会通过 FileViewer 的 error 事件上报。

import {
  FileViewer, // ① 完整面板(含头部、下载、主题),ViewerInput 驱动
  FileViewerBody, // ② 只有内容区,塞进你自己的外壳
  classifyViewerFile, // 纯函数:文件 → 用哪个查看器,自己路由
  isTextFile,
  fileExt, // 类型判定辅助
  resolveInput, // 把 ViewerInput 归一化成可 fetch 的源
} from '@l1yp/file-viewer'

主题 / 样式

所有样式的 CSS 变量作用域限定在组件根 .fv-root,不碰宿主全局样式。三种定制方式:

  1. theme prop:theme="light | dark | system | inherit"。FileViewer 默认 system,跟随系统偏好并实时响应切换;显式 light / dark 只控制当前实例,可在同一页面并排使用。inherit 不声明配色与字体变量,直接继承最近宿主或父查看器的变量及 color-scheme。
  2. 覆盖 CSS 变量:在你自己的 .fv-root 规则里改,例如
    .fv-root {
      --accent: #2563eb;
      --font-mono: 'JetBrains Mono', monospace;
    }
    
  3. 复制 dist 里的令牌整套替换。

数学公式:如需 Markdown 里的数学公式正常显示,宿主需自行 import 'katex/dist/katex.min.css'。

FileViewerPanel 同样带 .fv-root 并接受上述 theme prop,默认 inherit 以延续宿主页面主题。单独使用侧栏且宿主未定义变量时,传 theme="system"。只用 FileViewerBody 时,可在外层添加 <div class="fv-root" data-theme="system">,或提供自己的变量。

<!-- 宿主维护 light / dark / system 时,直接绑定,主题切换不会重新读取文件。 -->
<FileViewer :blob="file" :name="file.name" :theme="appTheme" />

<!-- 宿主已有完整配色变量时:字体、配色和原生控件都继承宿主。 -->
<FileViewer :src="url" name="report.csv" theme="inherit" />

使用 inherit 的宿主应同步设置 color-scheme: light / dark(跟随系统时为 light dark),让滚动条、下拉框等原生控件与 CSS 配色一致。代码高亮与 ANSI 基础色随包内样式提供,不再依赖宿主额外导入高亮样式。HTML 全屏工具栏保留来源查看器的主题和自定义变量,并在打开期间响应主题切换。

主题覆盖查看器外壳、导航、工具栏及状态提示。XLSX 的默认表格、行列标题、冻结区域、选区和图表也跟随主题;自动文字色与未调色的 Office 默认文字色(theme: 1)随背景切换。文件明确指定的字体色和填充色保持原样,这些单元格缺省的一侧沿用原稿的黑字/白底,避免深色背景与原稿字体冲突;图表中明确指定的数据系列颜色同样保留。

DOCX 的黑白正文页会自动适配纸张、文字和表格线,切换主题无需重新解析;图片像素保留原样,透明部分保留原白纸底色。检测到彩色文字、底纹、复杂绘图或生成内容的页面会整页保留原稿,避免局部改色造成黑底黑字或丢失颜色含义。

PDF、PPTX、DOCX 的自实现目录、页面导航、页码、选中状态、缩略图容器及外围区域都跟随主题。PDF 和 PPTX 正文及缩略图保留原稿:PDF 的页面配色接口会对整页画布施加滤镜,PPTX 的文件主题与版式配色也不能可靠地当作界面主题替换。RTF 纸张、图片、视频和沙箱网页同样保留原稿配色。

开发

pnpm -C packages/file-viewer type-check   # vue-tsc 类型检查
pnpm -C packages/file-viewer build        # vp build(JS 分包 + style.css)+ 产物冒烟 + vue-tsc(.d.ts)

构建与 prepack 会直接运行易语言解析器的 JS 产物,检查按模块分包后的依赖是否完整,并覆盖源码/模块元数据、GBK 解码和异常类型。也可额外传入本地 .e / .ec 文件验证(文件仅在本机读取):

node packages/file-viewer/scripts/epl-build-smoke.mjs /path/to/example.e

在本仓库中,STEP 浏览器回归页会用自生成的带面颜色立方体运行真实 OCCT/WASM,覆盖类型识别、毫米尺寸、面颜色、Worker 取消/超时、文件切换与 WebGL 卸载。先构建组件库,再启动 pnpm dev 并打开 /scripts/step-smoke.html。验证消费者生产打包(包括相对 base 下的 Worker/JS/WASM 地址):

pnpm exec vp build --config scripts/step-smoke.config.ts
pnpm exec vp preview --config scripts/step-smoke.config.ts --port 4174
# 打开 http://localhost:4174/scripts/step-smoke.html,等待 STEP smoke PASSED。

pnpm smoke 同时验证缺少平面的多面体 STEP:包含通孔、反向边界、面积、不可变源文件、字符串/注释中的伪记录及无效几何。可设置 STEP_SAMPLE_PATH 为本地 STEP 路径,再运行 pnpm exec vite-node --config packages/file-viewer/vite.config.ts scripts/step-facets-smoke.ts 验证实际文件;文件仅在本机读取。

发布

npm pack --dry-run   # 预览将发布的文件(dist + README + LICENSE)
npm login --registry=https://registry.npmjs.org/
npm publish --registry=https://registry.npmjs.org/          # publishConfig.access=public,已配好公开发布

prepack 脚本会在打包/发布前自动重新构建。发布前记得在 package.json 补上 repository / homepage 字段。 构建产物会同时生成并发布 dist/**/*.js.map,其中包含原始 Vue / TypeScript 源码,使用者的构建工具和浏览器开发者工具可据此还原异常堆栈。

License

MIT

Related Packages

@work-zhanguo/light-file-preview

Lightweight file preview component for Vue 3, Vue 2, and standalone usage / 轻量...

2,580
@icjia/pdf-search-index

Full-text PDF, DOCX, PPTX, XLSX search for static sites — Apache Solr for client...

3,487 0
@file-viewer/preset-office

Office renderer preset for File Viewer with PDF, Word, spreadsheet, presentation...

136,007 2,584
sa-file-previewer

集成VueOffice的文件预览组件

1,265
@flyfish-group/file-viewer3

Historical Vue 3 alias package for @file-viewer/vue3

30,120 2,598

Version History

Version Released Vue License
0.1.10 ^3.5.0 MIT
0.1.9 ^3.5.0 MIT
0.1.8 ^3.5.0 MIT
0.1.6 ^3.5.0 MIT
0.1.5 ^3.5.0 MIT