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 的项目特别有用,因为它消除了前后端类型不一致的问题,提高了开发效率和代…...

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

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...