文件预览服务:kkFileView、File Viewer
2026/8/2 20:18:44 网站建设 项目流程

概述

在企业级应用开发场景下,非常常见的一个需求就是多格式文档的预览,包括但不限于:TXT、CSV、PDF、Word、PPT、Excel等。通常情况下,这些文件会上传到MinIO、阿里云OSS或腾讯云COS。

根据个人知识所限,MinIO只能预览TXT、CSV、PDF,并不能预览Office三件套,更别谈其他各种各样的文件格式。

那商业化文件存储平台呢?

OSS

亲自尝试,阿里云OSS预览Word文档,需绑定IMM智能媒体项目

点击【绑定】

点击【授权】

可惜,OSS免费开通,IMM需付费使用;本着写技术博客的严谨精神,还是开通体验一下

点击桶(Bucket)内的.docx文件,自动下载线性代数.htm文件,浏览器打开此文件,加载几分钟还出来。

商业平台能力,就这样????

另外,再说一个很搞笑的Bug(非常明显的问题):

Bucket列表为空,创建一个preview-test的桶,结果提示我已存在,我他妈为啥要关心这个名称被其他用户占用???OSS作为SaaS应用,而SaaS最基本的概念就是多租户,不同用户创建相同的Bucket名称,有什么问题吗?

上面说到有2个方案,方案1是图片方案,猜测是基于截图来实现,限于时间因素,未经验证。有空补上。

关于IMM的介绍:可绑定智能媒体管理产品,来做数据分析预处理

  • 调用方式:OSS域名/sample_object?x-oss-process=imm/action,param_value
  • 接口实例:OSS域名/family.jpg?x-oss-process=imm/detectface

IMM基于x-oss-process推出全新的文档处理、音视频处理等能力,支持样式、异步任务、批处理、触发器等多种使用方式。

COS

上传文件后,有【预览】入口

点击预览,果不其然,也是收费服务

点击【开启服务】

预览效果

开源

商业化平台能力是ok的,但涉及到企业内部安全隐私,数据泄密等问题,最好还是使用本地化部署方案。本文收集几个基于浏览器的文件预览开源项目。

kkFileView

官网,一个基于Java+Spring Boot的万能文件预览开源(GitHub,14.4K Star,3.3K Fork)项目,允许用户在浏览器端实时查看文件内容。

支持的文件类型:

  1. 支持doc、docx、xls、xlsx、xlsm、ppt、pptx、csv、tsv、dotm、xlt、xltm、dot、dotx、xlam、xla等Office办公文档;
  2. 支持wps、dps、et、ett、wpt等国产WPS Office办公文档;
  3. 支持odt、ods、ots、odp、otp、six、ott、fodt、fods等Open Office、Libre Office办公文档;
  4. 支持vsd、vsdx等Visio流程图文件;
  5. 支持wmf、emf等Windows系统图像文件;
  6. 支持psd等Photoshop软件模型文件;
  7. 支持pdf、ofd、rtf等文档;
  8. 支持xmind软件模型文件;
  9. 支持bpmn工作流文件;
  10. 支持eml邮件文件;
  11. 支持epub图书文档;
  12. 支持obj、3ds、stl、ply、gltf、glb、off、3dm、fbx、dae、wrl、3mf、ifc、brep、step、iges、fcstd、bim等3D模型文件;
  13. 支持dwg、dxf等CAD模型文件;
  14. 支持txt、xml(渲染),md(渲染),java、php、py、js、css等所有纯文本;
  15. 支持zip、rar、jar、tar、gzip、7z等压缩包;
  16. 支持jpg、jpeg、png、gif、bmp、ico、jfif、webp等图片预览(翻转,缩放,镜像);
  17. 支持tif、tiff图信息模型文件;
  18. 支持tga图像格式文件;
  19. 支持svg矢量图像格式文件;
  20. 支持mp3、wav、mp4、flv等音视频格式文件;
  21. 支持avi、mov、rm、webm、ts、rm、mkv、mpeg、ogg、mpg、rmvb、wmv、3gp、ts、swf等视频格式转码预览;

极易上手,使用HTTP接口访问,不需要和应用集成,具有跨系统跨语言使用的特性。提供Windows/Linux版本发行包、自定义配置文件、和一键启动/停止脚本等,极大方便部署使用,官方提供Docker镜像。

因此仅需单独将kkFileView部署好后,文件交由minio存储和维护,然后提供文件的url地址既可实现在线预览,如下图所示:

部署

gitclone https://github.com/kekingcn/kkFileView.gitcdkkfileviewerdockerbuild-tkkfileview:v5.0.0.dockerrun-d-p8012:8012--namekkfileview kkfileview:v5.0.0

打开:http://localhost:8012,开始体验。

集成MinIO

添加依赖:implementation 'io.minio:minio:8.5.17'

application.yaml配置:

minio:endpoint:http://xxxxx:9000accessKey:xxxxsecretKey:xxxxxbucketName:test

MinIO配置类:

@ConfigurationpublicclassMinioConfig{@Value("${minio.endpoint}")privateStringendPoint;@Value("${minio.accessKey}")privateStringaccessKey;@Value("${minio.secretKey}")privateStringsecretKey;@Value("${minio.bucketName}")privateStringbucketName;@BeanprotectedMinioClientminioClient(){returnMinioClient.builder().endpoint(endPoint).credentials(accessKey,secretKey).build();}}

工具类:

@ComponentpublicclassMinioUtils{@Value("${minio.bucketName}")privateStringbucketName;@ResourceprivateMinioClientminioClient;publicApiResultuploadFile(MultipartFilefile)throwsAppException{StringfileName=System.currentTimeMillis()+file.getOriginalFilename();try(InputStreamfi=file.getInputStream()){PutObjectArgsputObjectArgs=PutObjectArgs.builder().bucket(bucketName).contentType(file.getContentType()).object(fileName).stream(fi,fi.available(),-1).build();minioClient.putObject(putObjectArgs);}catch(Exceptione){thrownewAppException("文件上传失败"+e.getMessage());}returnApiResult.ok(fileName);}publicApiResultgetPreviewUrl(StringobjectName)throwsAppException{try{GetPresignedObjectUrlArgsurlArgs=GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).method(Method.GET).build();returnApiResult.ok(minioClient.getPresignedObjectUrl(urlArgs));}catch(Exceptione){thrownewAppException("获取预览链接失败"+e.getMessage());}}}

controller接口类:

@RestController@RequestMapping("/file")publicclassFileOperationController{@ResourceprivateMinioUtilsminioUtils;@PostMapping("/upload")publicApiResultupload(MultipartFilefile)throwsAppException{returnminioUtils.uploadFile(file);}@GetMapping("/getPreviewUrl")publicApiResultgetPreviewUrl(StringfileName)throwsAppException{returnminioUtils.getPreviewUrl(fileName);}}

File Viewer

官网,全能、纯前端、开源(GitHub,1.8K Star,185 Fork)商用友好的文件预览器。基于浏览器运行,覆盖Office、PDF、OFD、Typst、CAD、3D、压缩包、邮件、绘图、电子书、Markdown、代码、图片、音频、视频等常见业务附件。官方文档,在线Demo。

功能价值
全能纯前端文件预览器文件在浏览器端完成解析和展示,业务系统可用一套组件覆盖绝大多数附件预览需求
完全开源,Apache-2.0协议商用友好,适合企业内部系统、SaaS产品、低代码平台和二开集成
覆盖几乎所有常见附件场景合同、档案、工单、知识库、工程图纸、邮箱附件、代码审阅、培训资料、压缩包归档都能进入统一预览体验
优质且高效的代码链路按文件类型异步加载重型依赖,PDF.js、CAD WASM、docx-preview、epub.jslibarchive等只在需要时进入页面
可扩展性完整清晰@file-viewer/core负责底层预览能力,Vue、React、纯Web、jQuery、Svelte等组件入口保持统一参数、事件和操作语义

适用场景

场景推荐能力组合
合同审阅Word/PDF/OFD+水印+打印+下载前置校验+文档比对
档案归档PDF/OFD/Office+生命周期回调+搜索定位+HTML导出
邮箱附件归档EML/MSG/MBOX+附件继续预览+原文下载
工程图纸DWG/DXF/DWF/DWFx/XPS+CAD WASM私有化+图层/结构面板
知识库Markdown/代码/PDF/Word+全文搜索+文本切片+来源定位
低代码平台Pure Web/Vue/React组件+统一options+动态文件源
SaaS中后台主题固定为light+权限前置操作+统一工具栏
内网部署静态资源自托管+Docker/静态目录+Worker/WASM路径配置

核心架构

架构设计对开发者的价值
@file-viewer/core作为纯TypeScript底座格式矩阵、渲染协议、生命周期、搜索、缩放、打印、导出、水印等能力集中沉淀,框架层更轻
多生态标准组件拆分Vue、React、纯Web、jQuery、Svelte等入口都只依赖core,参数和事件语义保持一致
渲染链路按需异步加载命中文件类型后才加载PDF.js、CAD WASM、docx-preview、epubjs、libarchive等重型依赖
Demo、文档、Release、静态部署体系完整官网、文档站、在线Demo、文档比对页、Docker/静态产物、npm包和Release下载物形成完整分发闭环

开发者可从最小组件开始接入,再逐步打开水印、搜索、打印、权限前置校验、WASM私有化、文档比对和AI溯源等能力。

扩展名支持参考packages/core/src/formats.ts,并由pnpm verify:format-support校验:194个扩展名映射,23条预览链路。不包含内部错误兜底处理器。

类别扩展名示例渲染链路适合场景与边界
Word/模板docxdocmdotxdotmdocdotdocx-previewmsdoc-viewer合同、制度、报告、历史Word附件。复杂版式优先保持页面阅读效果
Excel/表格xlsxxlsmxlsbxlscsvodsfodsnumbersstyled-exceljs
+虚拟表格
业务台账、导出报表、多sheet文件。表格链路以交互查看为主
PowerPointpptxpptmpotxppsx@aiden0z/pptx-renderer课件、方案、汇报材料。浏览器近似渲染,复杂动画建议转PDF留档
PDFpdfPDF.js合同、归档件、说明书。支持页导航、目录、缩放、搜索、打印和HTML导出
OFDofdDLTech21/ofd.js发票、政企归档。按需加载OFD解析链路
TypsttyptypstTypst WASM+SVG直接预览Typst源文件,适合技术文档和排版稿
CAD/图纸dwgdxfdwfdwfxxps@flyfish-dev/cad-viewer+WASM/Worker工程图纸、设备图、DWF/DWFx/XPS审阅。私有部署需配置WASM/Worker路径
3D模型glbgltfobjstlplyfbxdae3mfusdThree.js产品模型、工程资产、简单三维附件。复杂CAD/BIM可先转换
压缩包zip7zrartargzxzisojarapkcbzlibarchive.jsWorker+兼容降级查看压缩包目录,按需解压内部文档并继续预览
邮件emlmsgmboxpostal-mimemsgreader邮件归档、客服工单、附件审阅。正文隔离渲染,附件可继续预览
绘图excalidrawdrawiodio官方Excalidraw/diagrams.net链路流程图、草图、架构图,只读预览
电子书epubumdepubjs、UMD parser内部手册、电子书、历史移动阅读文件
Markdown/代码mdjsonjststsxvuepyjavasqllogMarkdown+highlight.js知识库、配置、源码、日志,安全地按源码展示
图片/设计资产pngjpgsvgwebpheicpsdaieps浏览器图片、按需解析器品牌素材、截图、设计附件。AI/EPS做安全摘要或PDF-backed预览
音视频mp3oggflacmidimp4webmm3u8原生媒体、hls.js、MIDIparser通话录音、培训视频、媒体附件
数据资产sqliteparquetavrowasmwebarchive、字体文件sql.js、hyparquet、avsc、FontFace快速查看结构、表、schema、导入导出信息

组件生态围绕core提供多条生产可用入口。新项目推荐优先使用标准包名,历史包名继续保持兼容。

技术栈

技术栈推荐包名兼容包名适合场景
Core@file-viewer/core自研组件、底层能力、格式识别、生命周期和操作API
Vue 3@file-viewer/vue3@flyfish-group/file-viewer3file-viewer3Vue3中后台、知识库、合同系统
Vue 2.7@file-viewer/vue2.7@flyfish-group/file-viewer存量Vue2.7项目
Vue 2.6@file-viewer/vue2.6老Vue2.6项目
React 18/19@file-viewer/react@flyfish-group/file-viewer-reactReact中后台、SaaS、设计系统
React 16.8/17@file-viewer/react-legacy老React项目
纯Web/JS@file-viewer/web@flyfish-group/file-viewer-web原生页面、Web Components外壳、微前端、script标签
jQuery@file-viewer/jquery老后台、CMS、传统页面
Svelte@file-viewer/svelteSvelte应用和组件库

对于独立静态预览站,可把自托管Demo页面放入业务iframe做隔离展示。新业务集成建议优先使用上面的原生组件或mountViewer,调试体验和事件回调会更直接。

实战

安装:

pnpmadd@file-viewer/vue3# React、纯Web、jQuery、Svelte分别安装对应包pnpmadd@file-viewer/reactpnpmadd@file-viewer/webpnpmadd@file-viewer/jquerypnpmadd@file-viewer/svelte

Vue3示例:

<script setup lang="ts">importFileViewerfrom'@file-viewer/vue3'</script><template><div style="height: 100vh"><FileViewer url="/files/demo.pdf"/></div></template>

Vue组件会自动带上样式,父容器需要明确高度,这是所有预览器最容易被忽略的基础条件。

React示例:

importFileViewerfrom'@file-viewer/react'exportfunctionPreview(){return(<div style={{height:'100vh'}}><FileViewer url="/files/contract.docx"/></div>)}

纯JS/Script标签:

import{mountViewer}from'@file-viewer/web'constcontroller=mountViewer(document.getElementById('viewer')!,{url:'/files/demo.pdf',options:{theme:'light'}})

传统页面也可使用IIFE产物,通过file-viewer-copy-assetsviewer assets发布到自己的静态目录,再用全局对象挂载。

URL最简单,适合文件地址能被浏览器直接访问的场景:

<FileViewer url="https://cdn.example.com/report.pdf"/>

本地上传、鉴权下载和SDK返回二进制时,推荐传File

constfile=newFile([blob],'contract.pdf',{type:blob.type})

ArrayBuffer也建议先包装成带扩展名的File

constbuffer=awaitsdk.downloadAttachment(id)constfile=newFile([buffer],'report.xlsx')

文件名很关键,预览器会根据扩展名选择渲染链路。遇到/download?id=123这种无后缀地址,推荐业务侧先下载,再补一个准确文件名。

鉴权文件下载推荐方式

constresponse=awaitfetch('/api/files/123/preview',{credentials:'include',headers:{Authorization:`Bearer${token}`}})constblob=awaitresponse.blob()constfile=newFile([blob],'sealed-contract.ofd',{type:blob.type})

这样权限仍然由业务系统控制,预览器只负责浏览器端解析和展示。

CAD、压缩包、PDF、Typst、SQLite、DOCX Worker等链路会按需使用Worker或WASM。内网、CSP严格、CDN子路径部署时,可显式配置资源地址:

constoptions={pdf:{workerUrl:'/file-viewer/vendor/pdf/pdf.worker.mjs',streaming:'same-origin',rangeChunkSize:64*1024},cad:{wasmPath:'/file-viewer/wasm/cad/',workerUrl:'/file-viewer/wasm/cad/dwg-worker.js',dwfWasmUrl:'/file-viewer/wasm/cad/dwfv-render.wasm'},archive:{workerUrl:'/file-viewer/vendor/libarchive/worker-bundle.js',workerTimeoutMs:30000,cache:true},typst:{compilerWasmUrl:'/file-viewer/wasm/typst/typst_ts_web_compiler_bg.wasm',rendererWasmUrl:'/file-viewer/wasm/typst/typst_ts_renderer_bg.wasm'},data:{sqlWasmUrl:'/file-viewer/wasm/sql/sql-wasm.wasm'}}

加载、卸载、打印、下载、导出、缩放都可接入业务审计和权限控制。

constoptions={hooks:{onLoadStart(ctx){console.log('开始加载',ctx.type,ctx.filename)},onLoadComplete(ctx){console.log('加载完成',ctx.duration)},onUnloadStart(ctx){console.log('开始卸载',ctx.reason)},onUnloadComplete(ctx){console.log('卸载完成',ctx.filename)}},asyncbeforeOperation(ctx){if(ctx.operation==='print'){returnawaitcheckPrintPermission(ctx.filename)}returntrue}}

水印、打印、下载、导出HTML

constoptions={theme:'light',toolbar:{position:'bottom-right',download:true,print:true,exportHtml:true,zoom:true},watermark:{text:'内部资料',opacity:0.16,rotate:-24,color:'#0f766e'}}

打印会尽量只输出主体文档,不带Demo外壳。PDF和Word会按页面尺寸处理;Excel等虚拟表格链路会根据能力动态隐藏打印按钮,避免输出只有当前视口。

预览器提供searchDocument()nextSearchResult()previousSearchResult()collectDocumentAnchors()scrollToLine()scrollToAnchor()getDocumentTextChunks()等能力。

业务侧可把文本切片写入自己的向量库或审计系统,再通过锚点回到原文位置。File Viewer 本身只提供结构、定位和高亮能力,不绑定任何云端模型。

文档比对是独立页面,适合合同版本、PDF与源文件、PPTX版本差异、Markdown与导出稿对照:https://demo.file-viewer.app/compare.html

可预置左右文件:

/compare.html?left=/example/pdf.pdf&right=/example/word.docx

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询