【总结】前端JQuery获取Java后端文件流实现常规附件预览功能

前端JQuery获取Java后端文件流实现常规附件预览功能

  • 项目背景
  • 1. Java后端处理附件
    • 1.1 将word文档转换为pdf格式
    • 1.2 将文件流返回前端
  • 2. 前端处理附件预览(JQuery)
    • 2.1 预览pdf文件
    • 2.2 预览ofd文件
    • 2.3 预览图片、txt文档
  • 共勉。

项目背景

目前维护的项目是个远古的SpringMVC项目,前端使用的是JQuery和HTML,与Vue相比维护比较复杂,功能实现上没有那么丰富。在做附件预览的需求时,考虑不借助第三方预览服务,通过开源组件实现,需要借助以下服务依赖:
1)Java:引入aspose.words依赖(支持将word文档转换为pdf格式)
注意:需要引入license

1. Java后端处理附件

1.1 将word文档转换为pdf格式

1)在resource下新增license.xml

<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

2)word转pdf工具类

/*** @program: Mickey* @description: pdf工具类**/
public class WordToPdfUtil {public static byte[] toPdfBytes(HttpServletRequest req, InputStream inputstream) throws IOException {ByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] b = null;try {//认证aspose-word,否则转换的pdf会有水印if (!getWordLicense(req)) {return null;}LoadOptions options = new LoadOptions();options.setLoadFormat(LoadFormat.DOC);Document doc = new Document(inputstream, options);doc.save(bos, SaveFormat.PDF);b = bos.toByteArray();} catch (Exception e) {e.printStackTrace();throw new RuntimeException("word转换pdf出错!");} finally {bos.close();}return b;}/*** 获取aspose-word授权** @return*/public static boolean getWordLicense(HttpServletRequest req) {boolean result = false;InputStream is = null;try {//获取认证文件,并转为输入流is = new FileInputStream(req.getSession().getServletContext().getRealPath("") + File.separator + "downFile/pdfFile" + File.separator + "license.xml");//创建密钥认证对象License aposeLic = new License();//进行认证ssaposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}return result;}
}

1.2 将文件流返回前端

try (InputStream in = new FileInputStream(new File("文件路径"))) {// 预览附件类型白名单List<String> whiteFileTypeList = Arrays.asList(DOC_SUFFIX, DOCX_SUFFIX, PDF_SUFFIX, TXT_SUFFIX, OFD_SUFFIX, PNG_SUFFIX, JPG_SUFFIX, JPEG_SUFFIX);// 不支持附件预览的类型if (StringUtils.isNotBlank(suffix) && !whiteFileTypeList.contains(suffix)) {throw new RuntimeException("不支持的附件预览类型,请下载后查看!");}String fileName = "预览附件名称";byte[] toPdfBytes;// word文档类型进行格式转换if (StringUtils.equals(DOC_SUFFIX, suffix) || StringUtils.equals(DOCX_SUFFIX, suffix)) {toPdfBytes = WordToPdfUtil.toPdfBytes(request, in);} else {toPdfBytes = readInputStream(in);if (StringUtils.equals(PNG_SUFFIX, suffix) || StringUtils.equals(JPG_SUFFIX, suffix) || StringUtils.equals(JPEG_SUFFIX, suffix)) {String base64Str = Base64Utils.encodeToString(toPdfBytes);model.put("base64Str", base64Str);}if (StringUtils.equals(TXT_SUFFIX, suffix)) {model.put("txtView", toPdfBytes);}}if (toPdfBytes != null) {try {String contextPath = request.getContextPath();String basePath = request.getSession().getServletContext().getRealPath(File.separator);File outFile = new File(basePath + File.separator + "temp" + File.separator + "fileView");if (!outFile.isDirectory()) {if (!outFile.exists()) {boolean b = outFile.mkdirs();}}FileOutputStream fo = new FileOutputStream(outFile + File.separator + "附件id" + ".pdf");BufferedOutputStream out = new BufferedOutputStream(fo);out.write(toPdfBytes, 0, toPdfBytes.length);out.flush();out.close();return contextPath + File.separator + "temp" + File.separator + "fileView" + File.separator + "附件id" + ".pdf";} catch (IOException e) {e.printStackTrace();}}
} catch (IOException e) {log.error("附件处理异常", e);
} 

2. 前端处理附件预览(JQuery)

2.1 预览pdf文件

引入PDFView组件

<iframe id="pdfFrame" src="${base}/pdfView/web/viewer.html?file=${viewFilePath}" width="900" height="530"></iframe>

2.2 预览ofd文件

引入ofd.js依赖,支持ofd文件查看

<div class="ofdContainer" id="ofdContainer" style="width: 900px; height: 530px; overflow-y: scroll;"></div>
$(function() {// ofd文件预览if (suffix && suffix === 'ofd') {var xhr = new XMLHttpRequest();xhr.open('POST', '附件下载地址', true);xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xhr.responseType = 'blob';xhr.send("id=" + 附件id);xhr.onload = function(e) {if (this.status === 200) {var blob = new Blob([this.response], {type: 'application/ofd'});// 处理文件流,比如使用 FileReader 进行读取或者直接下载const file = new File([blob], fileName + '.ofd', { type: blob.type });ofd.parseOfdDocument({ofd: file,success: function (res) {const screenWidth = 800;const ofdRenderRes = ofd.renderOfd(screenWidth, res[0]);let ofdContainerDiv = document.getElementById('ofdContainer');// 清空元素ofdContainerDiv.innerHTML = '';for (const item of ofdRenderRes) {ofdContainerDiv.appendChild(item);}},fail: function (err) {console.error(err);},});}};}
})

2.3 预览图片、txt文档

1)将后端获取的文件流转换为Base64格式,前端展示图片

<img src="data:image/jpeg;base64,${base64Str!}" style="width: 900px; height: 530px; overflow-y: scroll;" />

2)展示txt文档

<pre class="txtContainer" id="txtContainer" style="width: 900px; height: 530px; overflow-y: scroll; text-align: left;"></pre>
fetch('替换为你的后端TXT文件下载地址' + 附件id).then(response => response.text()).then(text => {document.getElementById('txtContainer').textContent = text;}).catch(error => console.error('读取文件出错:', error));

共勉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习Java的日子 Day56 数据库连接池,Druid连接池

Day56 1.数据库连接池 理解&#xff1a;池就是容器&#xff0c;容器中存放了多个连接对象 使用原因&#xff1a; 1.优化创建和销毁连接的时间&#xff08;在项目启动时创建连接池&#xff0c;项目销毁时关闭连接池&#xff09; 2.提高连接对象的复用率 3.有效控制项目中连接的…

Windows下Pytorch入门深度学习环境安装与配置(CPU版本)

Windows下Pytorch入门深度学习环境安装与配置&#xff08;CPU版本&#xff09; 一、安装过程中各个软件的作用&#xff08;一&#xff09;Python&#xff08;二&#xff09;库 / 包 / package / library&#xff08;三&#xff09;PyTorch / Tensorflow&#xff08;四&#xff…

Java之开发 系统设计 分布式 高性能 高可用

1、restful api 基于rest构建的api 规范&#xff1a; post delete put get 增删改查路径 接口命名 过滤信息状态码 2、软件开发流程 3、命名规范 类名&#xff1a;大驼峰方法名&#xff1a;小驼峰成员变量、局部变量&#xff1a;小驼峰测试方法名&#xff1a;蛇形命名 下划…

【Sass】常用全局sass高级函数,可使用原子化CSS减轻代码量,方便快速开发

文章目录 前言一、安装二、样式custom.scssflex.scsscolor.scssmargin-padding.scssorther 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 针对style的预编译器为scss 转载自git前端知识库 原博主是B站up程序员郑清&#xff0c;可以看他的v3教程…

【云原生】Docker搭建知识库文档协作平台Confluence

目录 一、前言 二、企业级知识库文档工具部署形式 2.1 开源工具平台 2.1.1 开源工具优点 2.1.2 开源工具缺点 2.2 私有化部署 2.3 混合部署 三、如何选择合适的知识库平台工具 3.1 明确目标和需求 3.2 选择合适的知识库平台工具 四、Confluence介绍 4.2 confluence特…

平面点云三角化边数与点的关系

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 点云三角化定义 原文 说人话&#xff1a; 一个二维平面点集P三角化结果是一个满足以下条件的三角形集合&#xff1a; 1 所有三角形的并集刚好是P的凸包。 2 所有三角…

python3GUI--new音乐播放器!By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;展示1.启动2.MV推荐3.专辑详情页4.歌手详情页5.搜索结果页6.歌曲播放页7.我喜欢歌曲页8.我喜欢专辑页 三&#xff0e;思路&启发1.布局2.细节3.组件复用4.项目结构5.优化速度1.Nuitka1.显著提高性能&#xff1a;2.减小程序体积&am…

Java集合框架2024最通俗易懂(图片超全)

集合 1.1、定义 集合就是类型统一的数据组合而成的数据结构&#xff0c;该数据结构可以任意的改变长度。 1.3、Set Set数据存储结构&#xff0c;无序&#xff0c;且不可以重复&#xff0c;元素可以为null&#xff0c;但是也只能出现一次&#xff0c;如下图: 1.3.1、HashSe…

WEB渗透Web突破篇-SQL注入(Oracle)

版本 SELECT user FROM dual UNION SELECT * FROM v$version数据库名 SELECT global_name FROM global_name; SELECT name FROM V$DATABASE; SELECT instance_name FROM V$INSTANCE; SELECT SYS.DATABASE_NAME FROM DUAL;列库 SELECT DISTINCT owner FROM all_tables;列表 …

rag输出了幻觉怎么办

首先&#xff0c;幻觉也分类型。 一个是事实性幻觉&#xff0c;就是LLM凭借自身能力回答问题&#xff0c;但是这个回答是编的&#xff0c;也可能有正确答案但是LLM输出错了。总之这是LLM自身原因。 另一个是忠实性幻觉&#xff0c;就是你要求LLM根据你给的材料给出答案&#xf…

Scikit-learn提供了哪些机器学习算法以及如何使用Scikit-learn进行模型训练和评估

Scikit-learn库的使用 一、Scikit-learn提供的机器学习算法 Scikit-learn&#xff08;通常简称为sklearn&#xff09;是一个广泛使用的Python机器学习库&#xff0c;它提供了多种用于数据挖掘和数据分析的算法。Scikit-learn支持的机器学习算法可以大致分为以下几类&#xff…

[240726] Mistral AI 发布新一代旗舰模型 | Node.js 合并 TypeScript 文件执行提案

目录 Mistral AI 发布新一代旗舰模型&#xff1a;Mistral Large 2Node.js 合并 TypeScript 文件执行提案&#xff1a;--experimental-strip-types Mistral AI 发布新一代旗舰模型&#xff1a;Mistral Large 2 Mistral AI 宣布推出新一代旗舰模型 Mistral Large 2&#xff0c;该…

算法-----递归~~搜索~~回溯(宏观认识)

目录 1.什么是递归 1.1二叉树的遍历 1.2快速排序 1.3归并排序 2.为什么会用到递归 3.如何理解递归 4.如何写好一个递归 5.什么是搜索 5.1深度&#xff08;dfs&#xff09;优先遍历&优先搜索 5.2宽度&#xff08;bfs&#xff09;优先遍历&优先搜索 6.回溯 1.什…

Temu测评自养号如何做?三分钟带你入门!

环境系统 现在市场上很多的系统都是现成的或软件包&#xff0c;没有解决风控的能力&#xff0c;如果有需要建议大家自己学习一套技术&#xff0c;把技术掌握在自己手里&#xff0c;这样不会有依赖性 手机端环境:越狱后的ios指定版本手机可以一键新机的系统(参数调试)独享的家…

梧桐数据库:子查询优化技术

在数据库技术中&#xff0c;子查询是一个强大的工具&#xff0c;但不加优化的子查询可能会导致性能问题。优化子查询可以显著提升查询效率。以下是一些常见的子查询优化技术&#xff1a; 1. 使用连接&#xff08;JOIN&#xff09;替代子查询 1.1 基本原理 很多情况下&#x…

【NLP自然语言处理】为什么说BERT是bidirectional

首先&#xff0c;来看一下Transformer架构图&#xff1a; 我们知道&#xff0c;Bert设计时主要采用的是Transformer编码器部分&#xff0c;要论述Bert为啥是双向的&#xff0c;我想从编码器和解码器的注意力机制来阐述。 在看这篇博客前&#xff0c;需要对Transformer有一定的…

[C++] vector入门迭代器失效问题详解

文章目录 vector介绍**vector iterator 的使用** vector迭代器失效问题由扩容或改变数据引起的迭代器失效reserve的实现&#xff08;野指针&#xff09;insert实现&#xff08;迭代器位置意义改变&#xff09;insert修改后失效的迭代器 it迭代器失效 erase后的问题总结&#xf…

nextjs当后端使-读取excel文件

目前nextjs有种php的感觉&#xff0c;现在的需求是读取excel文件&#xff0c;入数据库&#xff0c;拆分出读取excel的代码如下&#xff1a; import { NextRequest } from "next/server"; import { join } from "path"; import { readFile } from "fs…

MyBatis-Plus的基本使用(一)

目录 前言 特性 MyBatis-Plus入门案例 常用注解 小结 前言 这篇文章主要来学习MyBatis-Plus这个非常强大的框架. 在学习MyBatis-Plus之前,需要有MyBatis的学习基础.因为MyBatis -Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#x…

spring —— 全注解实现事务管理器

全注解实现事务管理&#xff0c;就是取消 spring-config.xml 文件&#xff0c;而将配置信息在配置类中实现。 配置类&#xff1a; package com.spring.book;import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org…