ofd文件预览
文件列表
<template><div><div class='file' v-if='$myUtils.coll.isNotEmpty(filesList)'><div class='file-view'><div class='file-view-item' :style='{justifyContent: align }' v-for='(item, index) in filesList' :key='index'><img class='file-view-item-icon' alt='':src='require(`@/assets/file/${getFileSuffix(item.fileSuffix)}.png`)' /><template v-if='isShowQuery(item)'><div class='file-view-item-info file-view-item-infoHover' @click='previewFile(item)'><a-tooltip placement='topLeft' :title='item.fileName + item.fileSuffix'>{{ item.fileName }}.{{ item.fileSuffix }}</a-tooltip></div></template><template v-else><div class='file-view-item-info'><a-tooltip placement='top' :title='item.fileName + item.fileSuffix'>{{ item.fileName }}.{{ item.fileSuffix }}</a-tooltip></div></template><img class='file-view-item-icon mr-5' alt='' @click="downloadFile(item)":src='require(`@/assets/file/down.png`)' /></div></div></div><div v-else class='not-file'>暂无文件</div><my-a ref='myA'></my-a></div>
</template><script>
import { filesApiGetListByIds, getPreviewFileUrl, getDownLoadFileUrl } from '@/api/system/files'
import MyA from '@/components/My/MyA'let fileMap = {image: ['png', 'jpeg', 'jpg'],word: ['doc', 'docx', 'wps'],pdf: ['pdf'],ofd: ['ofd'],excel: ['xls', 'xlsx'],zip: ['zip', 'rar'],pptx: ['ppt', 'pptx'],bin: ['bin'],txt: ['txt'],deb: ['deb']
}export default {name: 'MyFileListMinor',components: {MyA},props: {filesIds: [String, Array],emptyText: {type: String,default: '暂无文件'},align: {type: String,default: 'left'}},filters: {toKB(val) {return (Number(val) / 1024).toFixed(0)}},watch: {filesIds: {handler: function(filesIds) {if (filesIds != null&& (this.$myUtils.str.isNotEmpty(filesIds)|| this.$myUtils.coll.isNotEmpty(filesIds))) {this.getFilesList(filesIds)} else {this.filesList = []}},immediate: true}},data() {return {filesList: []}},methods: {getFileSuffix(suffix) {let result = ''if (fileMap.word.indexOf(suffix) !== -1) {result = 'word'} else if (fileMap.pdf.indexOf(suffix) !== -1) {result = 'pdf'} else if (fileMap.ofd.indexOf(suffix) !== -1) {result = 'ofd'} else if (fileMap.excel.indexOf(suffix) !== -1) {result = 'xlsx'} else if (fileMap.image.indexOf(suffix) !== -1) {result = 'image'} else if (fileMap.zip.indexOf(suffix) !== -1) {result = 'zip'} else if (fileMap.pptx.indexOf(suffix) !== -1) {result = 'ppt'} else if (fileMap.bin.indexOf(suffix) !== -1) {result = 'bin'} else if (fileMap.txt.indexOf(suffix) !== -1) {result = 'txt'} else {result = 'other'}return result},/*** 是否显示查看按钮* @param item* @returns {boolean}*/isShowQuery(item) {let show = falseif (item) {switch (item.fileSuffix) {case 'pdf':case 'doc':case 'docx':case 'ofd':case 'jpg':case 'png':case 'jpeg':show = true}}return show},/*** 文件预览* @param {*} files*/previewFile(files) {if ('ofd' === files.fileSuffix) {const routeData = this.$router.resolve({path: '/ofd/preview',query: {id: files.fileId}});window.open(routeData.href, "_blank");} else {const url = getPreviewFileUrl(files.fileId)this.$refs.myA.target(url)}},/*** 文件下载* @param {*} files*/downloadFile(files) {const url = getDownLoadFileUrl(files.fileId)this.$refs.myA.target(url)},getFilesList(filesIds) {let ids = ''if (filesIds.constructor == String) {ids = filesIds} else {ids = filesIds.join()}filesApiGetListByIds(ids).then(res => {this.filesList = res.data})}}
}
</script><style lang='less' scoped>
@themeColor: #409eff;.file {width: 100%;height: 100%;&-view {width: 100%;&-item {width: 100%;height: 100%;display: flex;align-items: center;box-sizing: border-box;&:not(:last-child) {margin-bottom: 3px;}&-icon {width: 20px;height: 20px;object-fit: cover;cursor: pointer;}&-info {font-family: "Arial Negreta", "Arial Normal", "Arial", sans-serif;font-size: 14px;text-align: left;margin-left: 5px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;cursor: pointer;}&-infoHover {color: @themeColor;&:hover {text-decoration: underline;}}}}
}.mr-5 {margin-left: 5px;
}.not-file {font-family: "Arial Negreta", "Arial Normal", "Arial", sans-serif;font-size: 14px;
}
</style>
文件预览为ofd时走ofd预览,否则走正常的预览文件接口
previewFile(files) {if ('ofd' === files.fileSuffix) {const routeData = this.$router.resolve({path: '/ofd/preview',query: {id: files.fileId}});window.open(routeData.href, "_blank");} else {const url = getPreviewFileUrl(files.fileId)this.$refs.myA.target(url)}},
ofd文件预览组件
<template><div class="main-section" id="content" ref="contentDiv" @mousewheel="scrool"></div>
</template><script>
import {parseOfdDocument, renderOfd, digestCheck, getPageScale} from '@/utils/ofd/ofd';
import {getPreviewFileUrl} from "@/api/system/files";
import axios from 'axios';export default {name: 'preview',data() {return {docleft: 0,//公章距离左侧文档边缘的距离leftMenu_width: 0,//左侧菜单宽度ofdBase64: null,loading: false,pageIndex: 1,pageCount: 0,scale: 0,ofdObj: null,screenWidth: document.body.clientWidth,}},mounted() {this.screenWidth = document.body.clientWidth - this.leftMenu_width;this.$refs.contentDiv.addEventListener('scroll', this.scrool);this.getOfd(this.$route.query.id)},methods: {getOfd(id) {axios({url: getPreviewFileUrl(id),responseType: 'blob'}).then(res => {const files = new window.File([res.data], "ofd", {type: 'application/ofd'});this.getOfdDocumentObj(files, this.screenWidth);})},scrool() {let scrolled = this.$refs.contentDiv.firstElementChild?.getBoundingClientRect()?.top - 60;let top = 0let index = 0;for (let i = 0; i < this.$refs.contentDiv.childElementCount; i++) {top += (Math.abs(this.$refs.contentDiv.children.item(i)?.style.height.replace('px', '')) + Math.abs(this.$refs.contentDiv.children.item(i)?.style.marginBottom.replace('px', '')));if (Math.abs(scrolled) < top) {index = i;break;}}this.pageIndex = index + 1;},getOfdDocumentObj(file, screenWidth) {let that = this;this.loading = true;parseOfdDocument({ofd: file,success(res) {that.ofdObj = res[0];that.pageCount = res[0].pages.length;const divs = renderOfd(screenWidth, res[0]);that.displayOfdDiv(divs);that.loading = false;},fail(error) {that.loading = false;that.$alert('OFD打开失败', error, {confirmButtonText: '确定',callback: action => {this.$message({type: 'info',message: `action: ${action}`});}});}});},displayOfdDiv(divs) {this.scale = getPageScale();let contentDiv = document.getElementById('content');contentDiv.innerHTML = '';for (const div of divs) {contentDiv.appendChild(div)}for (let ele of document.getElementsByName('seal_img_div')) {this.addEventOnSealDiv(ele, JSON.parse(ele.dataset.sesSignature), JSON.parse(ele.dataset.signedInfo));}},addEventOnSealDiv(div, SES_Signature, signedInfo) {try {global.HashRet = null;global.VerifyRet = signedInfo.VerifyRet;div.addEventListener("click", function () {document.getElementById('sealInfoDiv').hidden = false;document.getElementById('sealInfoDiv').setAttribute('style', 'display:flex;align-items: center;justify-content: center;');if (SES_Signature.realVersion < 4) {document.getElementById('spSigner').innerText = SES_Signature.toSign.cert['commonName'];document.getElementById('spProvider').innerText = signedInfo.Provider['@_ProviderName'];document.getElementById('spHashedValue').innerText = SES_Signature.toSign.dataHash.replace(/\n/g, '');document.getElementById('spSignedValue').innerText = SES_Signature.signature.replace(/\n/g, '');document.getElementById('spSignMethod').innerText = SES_Signature.toSign.signatureAlgorithm.replace(/\n/g, '');document.getElementById('spSealID').innerText = SES_Signature.toSign.eseal.esealInfo.esID;document.getElementById('spSealName').innerText = SES_Signature.toSign.eseal.esealInfo.property.name;document.getElementById('spSealType').innerText = SES_Signature.toSign.eseal.esealInfo.property.type;document.getElementById('spSealAuthTime').innerText = "从 " + SES_Signature.toSign.eseal.esealInfo.property.validStart + " 到 " + SES_Signature.toSign.eseal.esealInfo.property.validEnd;document.getElementById('spSealMakeTime').innerText = SES_Signature.toSign.eseal.esealInfo.property.createDate;document.getElementById('spSealVersion').innerText = SES_Signature.toSign.eseal.esealInfo.header.version;} else {document.getElementById('spSigner').innerText = SES_Signature.cert['commonName'];document.getElementById('spProvider').innerText = signedInfo.Provider['@_ProviderName'];document.getElementById('spHashedValue').innerText = SES_Signature.toSign.dataHash.replace(/\n/g, '');document.getElementById('spSignedValue').innerText = SES_Signature.signature.replace(/\n/g, '');document.getElementById('spSignMethod').innerText = SES_Signature.signatureAlgID.replace(/\n/g, '');document.getElementById('spSealID').innerText = SES_Signature.toSign.eseal.esealInfo.esID;document.getElementById('spSealName').innerText = SES_Signature.toSign.eseal.esealInfo.property.name;document.getElementById('spSealType').innerText = SES_Signature.toSign.eseal.esealInfo.property.type;document.getElementById('spSealAuthTime').innerText = "从 " + SES_Signature.toSign.eseal.esealInfo.property.validStart + " 到 " + SES_Signature.toSign.eseal.esealInfo.property.validEnd;document.getElementById('spSealMakeTime').innerText = SES_Signature.toSign.eseal.esealInfo.property.createDate;document.getElementById('spSealVersion').innerText = SES_Signature.toSign.eseal.esealInfo.header.version;}document.getElementById('spVersion').innerText = SES_Signature.toSign.version;document.getElementById('VerifyRet').innerText = "文件摘要值后台验证中,请稍等... " + (global.VerifyRet ? "签名值验证成功" : "签名值验证失败");if (global.HashRet == null || global.HashRet == undefined || Object.keys(global.HashRet).length <= 0) {setTimeout(function () {const signRetStr = global.VerifyRet ? "签名值验证成功" : "签名值验证失败";global.HashRet = digestCheck(global.toBeChecked.get(signedInfo.signatureID));const hashRetStr = global.HashRet ? "文件摘要值验证成功" : "文件摘要值验证失败";document.getElementById('VerifyRet').innerText = hashRetStr + " " + signRetStr;}, 1000);}});} catch (e) {console.log(e);}if (!global.VerifyRet) {div.setAttribute('class', 'gray');}}}
}
</script><style scoped>
.main-section {display: flex;flex-direction: column;align-items: center;justify-content: center;overflow: hidden;position: relative;margin: 10px auto 0;border: 1px solid #f7f7f7;box-shadow: 0 3px 10px 0 rgba(76, 101, 123, 0.12);
}
</style>
将文件引入到src下
资源在笔记里面找一下
相关文章:

ofd文件预览
文件列表 <template><div><div classfile v-if$myUtils.coll.isNotEmpty(filesList)><div classfile-view><div classfile-view-item :style{justifyContent: align } v-for(item, index) in filesList :keyindex><img classfile-view-item-…...
浅浅了解下Spring中生命周期函数(Spring6全攻略)
你好,这里是codetrend专栏“Spring6全攻略”。 Spring框架设计生命周期回调函数的主要目的是为了提供一种机制,使开发人员能够在对象创建、初始化和销毁等生命周期阶段执行特定的操作。这种机制可以帮助开发人员编写更加灵活和可维护的代码。 举个例子…...

建议收藏!亚马逊卖家必须知道的37个常用术语解释
运营亚马逊,经常会看到很多个专业术语,想必大部分新手卖家都比较陌生,熟悉这些常用术语的含义有助于你更好地运营亚马逊。下面为各位整理了37个在亚马逊跨境电商中常见的术语及其解释,建议收藏! 1、SKU Stock Keeping…...

黑苹果睡眠总是自动唤醒(RTC)
黑苹果睡眠总是自动唤醒【RTC】 1. 问题2. 解决方案2.1. 查看重启日志2.2. 配置Disable RTC wake scheduling补丁 3. 后续4. 参考 1. 问题 黑苹果EFI 更换后,总是在手动 睡眠后,间歇性重启,然后再次睡眠,然后再重启。原因归结为&…...
【代码随想录训练营】【Day 49+】【动态规划-8】| Leetcode 121, 122, 123
【代码随想录训练营】【Day 49】【动态规划-8】| Leetcode 121, 122, 123 需强化知识点 买卖股票系列 题目 121. 买卖股票的最佳时机 动态规划贪心:记录左侧的最小值 class Solution:def maxProfit(self, prices: List[int]) -> int:# n len(prices)# # 0…...

k8s metrics-server服务监控pod 的 cpu、内存
项目场景: 需要开启指标服务,依据pod 的 cpu、内存使用率进行自动的扩容或缩容 pod 的数量 解决方案: 下载 metrics-server 组件配置文件: wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/…...

电脑自带录屏在哪?电脑录屏,4个详细方法
在现代社会中,越来越多的人需要在电脑上录制视频,比如录制游戏操作、制作教学视频、演示文稿等等。因此,电脑录屏成为了一项非常重要的功能。那么电脑自带录屏在哪?本文将带领大家看看可以使用哪些方法进行录屏。 录屏方法一&…...

[Cloud Networking] Layer3 (Continue)
文章目录 1. DHCP Protocol1.1 DHCP 三种分配方式1.2 DHCP Relay (中继) 2. 路由协议 (Routing Protocol)2.1 RIP (Routing Information Protocol)2.2 OSPF Protocol2.2.1 OSPF Area2.2.2 Route ID / DR / BDR2.2.3 LSA / OSPF 邻居表 / LSDB / OSPF路由表 2.3 BGP Protocol2.4…...

missing authentication credentials for REST request
1、报错截图 2、解决办法 将elasticsearch的elasticsearch.yml的 xpack.security.enabled: true 改为 xpack.security.enabled: false...

Unity 从0开始编写一个技能编辑器_02_Buff系统的生命周期
工作也有一年了,对技能编辑器也有了一些自己的看法,从刚接触时的惊讶,到大量工作时觉得有一些设计的冗余,在到特殊需求的修改,运行效率低时的优化,技能编辑器在我眼中已经不再是神圣不可攀的存在的…...

计算机网络简答题
第一章 计算机网络 1.因特网是一个世界范围的计算机网络,记一个互联了遍及全世界的计算机设备的网络。 2.计算机网络将众多分散的、自治的(一台坏了不影响其他)计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。 3.计算机网络的组…...

探索Java 8 Stream API:现代数据处理的新纪元
Stream流 Stream初探:何方神圣? Stream流是一种处理集合数据的高效工具,它可以让你以声明性的方式处理数据集合。Stream不是存储数据的数据结构,而是对数据源(如集合、数组)的运算操作概念,支…...
vim 删除光标到最后一行的所有内容
在 Vim 中删除从光标所在位置到文件末尾的所有内容 删除从光标所在位置到文件末尾的所有内容使用 dG 命令 参考 删除从光标所在位置到文件末尾的所有内容 使用 dG 命令 确保你在正常模式下(按 Esc 键)。移动光标到你想要开始删除的位置。输入以下命令&…...

k8s之kubelet证书时间过期升级
1.查看当前证书时间 # kubeadm alpha certs renew kubelet Kubeadm experimental sub-commands kubeadm是一个用于引导Kubernetes集群的工具,它提供了许多命令和子命令来管理集群的一生周期。过去,某些功能被标记为实验性的,并通过kubeadm a…...

5G消息 x 文旅 | 一站式智慧文旅解决方案
5G消息 x 文旅 | 一站式智慧文旅解决方案 文旅 x 5G 消息将进一步强化资源整合,满足游客服务需求、企业营销需求、政府管理需求,推进文化旅游项目的智慧化、数字化,增强传播力、竞争力和可持续性。5G 消息的“原生入口”、“超强呈现”、“智…...

如何评估员工在新版FMEA培训后应用知识的效果?
随着制造业的快速发展,新版FMEA已成为企业提升产品质量、减少故障风险的关键一环。然而,培训只是第一步,如何有效评估员工在新版FMEA培训后应用知识的效果,才是确保培训成果转化的关键所在。 评估员工知识应用效果的首要步骤是制定…...
python脚本之解析命令参数
import requests import argparseprint(f"{__name__}:start")parser argparse.ArgumentParser(description使用方法) parser.add_argument(-p, --prefix, typestr, help域名) parser.add_argument(-t, --token, typestr, helptoken) parser.add_argument(-i, --queu…...

当JS遇上NLP:开启图片分析的奇幻之旅
前言 在当今科技飞速发展的时代,JavaScript(JS)作为广泛应用的编程语言,展现出了强大的活力与无限的可能性。与此同时,自然语言处理(NLP)领域也正在经历着深刻的变革与进步。 当这两者碰撞在一…...
trpc快速上手
tRPC (Type-safe Remote Procedure Call) 是一个用于构建类型安全的 API 的框架,它能够在前端和后端之间共享类型,确保类型安全性。这对于使用 TypeScript 的项目特别有用,因为它消除了前后端类型不一致的问题,提高了开发效率和代…...

知识图谱存在的挑战---隐私、安全和伦理相关和测试认证相关
文章目录 隐私、安全和伦理相关测试认证相关 隐私、安全和伦理相关 从部署拓扑结构而言,知识图谱技术以数据为核心、数据库为载体的方式来存储,有单机、云平台、集群及其组合的部署方式,结合大数据平台、云平台、业务系统、灾备、网络系统及其…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...