当前位置: 首页 > news >正文

Spring轻量级文件预览的组件

File View 文件预览

一个轻量级文件预览的starter组件,支持多种文档和媒体格式的在线预览,采用模块化架构,易于扩展和定制。

Gitee
Github


支持的文件类型

  • office文件(docx,xlsx,xls,pptx)
  • 业务流程管理文件(bpmn,dmn,cmmn)
  • 图片文件
  • 视频文件
  • 音频文件
  • 文档文件(pdf,ofd,epub)
  • 文本文件/代码文件(sh,c,cpp,cs,css,diff,go,graphql,ini,java,js,json,kt,less,lua,mk,m,pl,php,phtml,txt,py,pyrepl,r,rb,rs,scss,sh,sql,swift,ts,vb,wasm,xml,yaml,yml)
  • Markdown文档文件
  • 3D模型文件(3dm,3ds,3mf,amf,bim,brep,dae,fbx,fcstd,gltf,ifc,iges,step,stl,obj,off,ply,wrl)
  • 思维导图文件(xmind)
  • 压缩文件(zip)

引入

增加 JitPack 仓库

<repositories><repository><id>jitpack.io</id><url>https://jitpack.io</url></repository>
</repositories>

Maven依赖

<dependency><groupId>com.gitee.wb04307201.file-view</groupId><artifactId>file-view-spring-boot-starter</artifactId><version>1.3.0</version>
</dependency>

配置文件

file:view:## 以下为默认的处理器,默认无需配置bpmn:enable: truedmn:enable: truecmmn:enable: truecode:enable: trueepub:enable: trueimage:enable: truemarkdown:enable: truepdf:enable: truexmind:enable: trueofd:enable: truedocx:enable: trueexcel:enable: truepptx:enable: trueo3d:enable: truezip:enable: true## 以下为默认的文件名和处理器匹配规则,默认无需配置strategies:- syntaxAndPattern: glob:*.bpmnserviceName: bpmn- syntaxAndPattern: glob:*.dmnserviceName: dmn- syntaxAndPattern: glob:*.cmmnserviceName: cmmn- syntaxAndPattern: glob:*.{sh,c,cpp,cs,css,diff,go,graphql,ini,java,js,json,kt,less,lua,mk,m,pl,php,phtml,html,txt,py,pyrepl,r,rb,rs,scss,sh,sql,swift,ts,vb,wasm,xml,yaml,yml}serviceName: code- syntaxAndPattern: glob:*.epubserviceName: epub- syntaxAndPattern: glob:*.{jpg,png,bmp,gif,tiff,webp,svg,raw,heic,cr2,nef,orf,sr2}serviceName: image- syntaxAndPattern: glob:*.mdserviceName: markdown- syntaxAndPattern: glob:*.pdfserviceName: pdf- syntaxAndPattern: glob:*.xmindserviceName: xmind- syntaxAndPattern: glob:*.ofdserviceName: ofd- syntaxAndPattern: glob:*.docxserviceName: docx- syntaxAndPattern: glob:*.{xlsx,xls}serviceName: excel- syntaxAndPattern: glob:*.pptxserviceName: pptx- syntaxAndPattern: glob:*.{3dm,3ds,3mf,amf,bim,brep,dae,fbx,fcstd,gltf,ifc,iges,step,stl,obj,off,ply,wrl}serviceName: o3d- syntaxAndPattern: glob:*.zipserviceName: zip

syntaxAndPattern通过指定语法(如 glob 或 regex)对文件名进行匹配

  • glob:*.txt
  • regex:(.*).txt

使用

静态资源库

部分文件类型使用内置渲染器,如:pdf、epub、xmind、zip、image、code、markdown、cmmn、dmn、bpmn等
使用的js库资源从jsDelivr加载,如无法从jsDelivr获取资源,可以添加file-view-static将js库本地化

        <dependency><groupId>com.gitee.wb04307201.file-view</groupId><artifactId>file-view-static</artifactId><version>1.3.0</version></dependency>

访问内置界面进行文件上传和预览

访问 http://localhost:8080/file/view
在这里插入图片描述

预览扩展

下面以OnlyOffice为例说明如何扩展预览

  1. 使用docker安装OnlyOffice文档开发者版,更详细内容请查看
docker run --name onlyoffice -i -t -d -p 80:80 -e JWT_ENABLED=false -e ALLOW_PRIVATE_IP_ADDRESS=true onlyoffice/documentserver-de
  1. 文件预览渲染器扩展
    编写IView.java接口的实现OnlyOfficeView.java
package cn.wubo.file.view.test;import cn.wubo.file.view.preview.IView;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;import java.net.URI;@Service
public class OnlyOfficeView implements IView {@Overridepublic String getServiceName() {return "onlyoffice";}@Overridepublic ServerResponse handle(ServerRequest request) {String id = request.pathVariable("id");return ServerResponse.temporaryRedirect(URI.create(String.format("/onlyoffice.html?id=%s",id))).build();}
}

编写页面onlyoffice.html

<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script src="/static/common.js"></script><script type="text/javascript" src="http://localhost/web-apps/apps/api/documents/api.js"></script><title>onlyoffice</title><style>html, body {height: 100%;padding: 0;margin: 0;}</style>
</head>
<body>
<div id="placeholder"></div>
<script>document.addEventListener('DOMContentLoaded', function () {const id = getUrlParam('id');fetch(`/wopi/files/${id}`).then(response => response.json()).then(data => {const fileName = data.BaseFileName;const fileType = data.BaseFileName.substring(data.BaseFileName.lastIndexOf('.') + 1);let documentType;if (fileType === 'docx' || fileType === 'doc') documentType = 'word';if (fileType === 'xlsx' || fileType === 'xls') documentType = 'cell';if (fileType === 'pptx' || fileType === 'ppt') documentType = 'slide';const config = {"type": "desktop","width": "100%","height": "100%","documentType": `${documentType}`,"document": {"fileType": `${fileType}`,"key": `${data.id}`,"title": `${fileName}`,"url": `http://192.168.31.197:8080/wopi/files/${data.id}/contents`,},"editorConfig": {"mode": "view","lang": "zh"},};console.log('config',config)const docEditor = new DocsAPI.DocEditor("placeholder", config);});});
</script>
</body>
</html>
  1. 修改配置,关闭重复的渲染器,重定义文件匹配规则application.yml
file:view:docx:enable: falseexcel:enable: falsepptx:enable: falsestrategies:- syntaxAndPattern: glob:*.bpmnserviceName: bpmn- syntaxAndPattern: glob:*.dmnserviceName: dmn- syntaxAndPattern: glob:*.cmmnserviceName: cmmn- syntaxAndPattern: glob:*.{sh,c,cpp,cs,css,diff,go,graphql,ini,java,js,json,kt,less,lua,mk,m,pl,php,phtml,html,txt,py,pyrepl,r,rb,rs,scss,sh,sql,swift,ts,vb,wasm,xml,yaml,yml}serviceName: code- syntaxAndPattern: glob:*.epubserviceName: epub- syntaxAndPattern: glob:*.{jpg,png,bmp,gif,tiff,webp,svg,raw,heic,cr2,nef,orf,sr2}serviceName: image- syntaxAndPattern: glob:*.mdserviceName: markdown- syntaxAndPattern: glob:*.pdfserviceName: pdf- syntaxAndPattern: glob:*.xmindserviceName: xmind- syntaxAndPattern: glob:*.ofdserviceName: ofd
#      - syntaxAndPattern: glob:*.docx
#        serviceName: docx
#      - syntaxAndPattern: glob:*.{xlsx,xls}
#        serviceName: excel
#      - syntaxAndPattern: glob:*.pptx
#        serviceName: pptx- syntaxAndPattern: glob:*.{3dm,3ds,3mf,amf,bim,brep,dae,fbx,fcstd,gltf,ifc,iges,step,stl,obj,off,ply,wrl}serviceName: o3d- syntaxAndPattern: glob:*.zipserviceName: zip- syntaxAndPattern: glob:*.{docx,doc,xlsx,xls,pptx,ppt}serviceName: onlyoffice
  1. 预览效果如下
    在这里插入图片描述

文件存储扩展

下面以MinIO为例说明如何扩展文件存储

  1. 使用docker安装MinIO
docker run -p 9000:9000 -p 9001:9001 --name minio -e "MINIO_ROOT_USER=ROOTUSER" -e "MINIO_ROOT_PASSWORD=CHANGEME123" quay.io/minio/minio server /data --console-address ":9001"
  1. 添加MinIO依赖
        <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.6.0</version></dependency>
  1. 实现自定义存储
  2. 编写接口IFileStorage.java的实现MinioFileStorageImpl.java
package cn.wubo.file.view.test;import cn.wubo.file.view.exception.LocalFileStorageException;
import cn.wubo.file.view.storage.IFileStorage;
import cn.wubo.file.view.storage.dto.FileStorageInfo;
import cn.wubo.file.view.utils.VersionUtls;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import org.springframework.stereotype.Service;import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;@Service
public class MinioFileStorageImpl implements IFileStorage {private final MinioClient minioClient;private static final String BUCKET_NAME = "temp";private static List<FileStorageInfo> fileStorageInfos = new ArrayList<>();public MinioFileStorageImpl() {this.minioClient = new MinioClient.Builder().endpoint("http://127.0.0.1:9000").credentials("ROOTUSER", "12345678").build();}@Overridepublic FileStorageInfo upload(String fileName, byte[] content, String mimeType) {try {String id = UUID.randomUUID().toString();String version = VersionUtls.generateContentVersion(content, id);Path filePath = Paths.get(version, fileName);minioClient.putObject(PutObjectArgs.builder().bucket(BUCKET_NAME).object(filePath.toString()).stream(new ByteArrayInputStream(content), content.length, -1).contentType(mimeType).build());FileStorageInfo fpi = new FileStorageInfo(id, fileName, content.length, mimeType, filePath.toString(), version);fileStorageInfos.add(fpi);return fpi;} catch (NoSuchAlgorithmException | IOException | ServerException | InsufficientDataException |InvalidKeyException | ErrorResponseException | InvalidResponseException | XmlParserException |InternalException e) {throw new LocalFileStorageException(e.getMessage(), e);}}@Overridepublic FileStorageInfo findById(String id) {return fileStorageInfos.stream().filter(fpi -> fpi.getId().equals(id)).findAny().orElseThrow(() -> new LocalFileStorageException("File info not found for id: " + id));}@Overridepublic List<FileStorageInfo> list() {return fileStorageInfos;}@Overridepublic byte[] getContentByLocation(String location) {try {InputStream is = minioClient.getObject(GetObjectArgs.builder().bucket(BUCKET_NAME).object(location).build());return is.readAllBytes();} catch (IOException | ErrorResponseException | InsufficientDataException | InternalException |InvalidKeyException | InvalidResponseException | NoSuchAlgorithmException | ServerException |XmlParserException e) {throw new LocalFileStorageException(e.getMessage(), e);}}@Overridepublic Boolean deleteById(String id) {FileStorageInfo fsi = findById(id);if (fsi != null) {try {minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(fsi.getLocation()).build());fileStorageInfos.remove(fsi);} catch (IOException | ErrorResponseException | InsufficientDataException | InternalException |InvalidKeyException | InvalidResponseException | NoSuchAlgorithmException | ServerException |XmlParserException e) {throw new LocalFileStorageException(e.getMessage(), e);}}return true;}
}

使用的第三方库

文件类型第三方库
office文件vue-office
业务流程管理文件bpmn-io
图片文件viewerjs
文档文件(pdf)pdfobject
文档文件(ofd)ofd.js
文档文件(epub)epub.js
文本文件/代码文件highlight.js
Markdown文档文件vditor
3D模型文件Online3DViewer
思维导图文件xmind-embed-viewer
压缩文件jszip
http://www.dtcms.com/a/475878.html

相关文章:

  • 网站建设与管理课程实训杭州西湖区抖音seo哪里找
  • 做团购网站商品从哪里找做内容的网站
  • 有哪些好的ps素材网站做爰全过程免费网站可以看
  • 网站自助制作公司网站设计要求
  • 苏州市吴江区住房和城乡建设局网站网站建设与网页设计 视频
  • 东莞官方网站 优帮云有实力的网站建设公司
  • 装饰公司手机网站云海建设工程有限公司网站
  • 如何建学校网站wordpress云建站教程
  • 在网站上做远程教育系统多少钱wordpress置顶精华图标
  • 怎么给网站备案网站制作开票几个点
  • 产品发布网站自己制作上传图片的网站怎么做
  • 龙岩做网站哪家最好专做蔬菜大棚的网站
  • 网站开发+语音泽库县公司网站建设
  • Ultralytics代码库深度解读【二】: TensorRT 引擎文件的构建与序列化
  • 广东网站建设哪家中国外贸网站
  • 做个卖东西的网站myeclipse做网站
  • 学生做网站的工作室网站建设有哪些荣誉
  • 字画价格网站建设方案无锡大型网站建设
  • 什么网站做家具出口做网络营销推广的公司
  • 外包网站怎么做seo响应式网站不加载图片
  • 河北建设网站公司wordpress postgre
  • 青岛网站建设青岛新思维做dapp开发广州
  • 【前缀和】| LeetCode 974题解 和可被K整除的子数组
  • 阿克苏建设租房信息阿克苏租房网站网站改版思路
  • 电商网站开发框架网站推广怎么做
  • 微信网站建设报价单应用商店软件
  • 开发php网站开发沈阳网势科技有限公司怎么样
  • 临沂网站公众号建设重庆企业型网站建设
  • 天津网站设计公司价格网页设计图片位置怎么设置
  • 云网站功能html网页设计代码教程