doc文件在线预览 vue_跨平台(uniapp)文件在线预览解决方案
一、前言
之前写过一篇文章关于上传目录文件:uni-app系统目录文件上传(非只图片和视频)解决方案,这次来解决文件预览问题。
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。在做业务系统时,不可避免会遇到文件在线预览的需求。这里的文件包括PDF、Word、Excel、PPT、图片等。而在线预览不是下载后再用本地软件或浏览器打开预览,而是直接通过文件流的形式查看。本方案主要解决在线预览问题,以及在uni-app开发过程中遇到一系列问题。
如果有欠缺的地方,或者有更好的方案,还望各位码友多提意见,多多交流,文章最后可以加我。
文件预览,首先会想到pdf预览,前端做pdf预览,首先也会想到pdf.js,那我们就从pdf.js说起。
二、PDF预览
pdf.js开源地址和在线例子GithubOnline Demo
2.1 使用方法一
下载插件包,下载地址
解压,拷贝build和web目录到项目hybrid->html目录下,参考uni-app中web-view用法
新建vue组件file-preview.vue
- viewerUrl:前端本地viewer.html页面地址
- fileUrl:文件流访问地址,参考《三、文件流服务》
<view><web-view :src="allUrl">web-view>view>template><script>import globalConfig from '@/config'export default { data() {return {viewerUrl: '/hybrid/html/web/viewer.html',// viewerUrl: globalConfig.baseUrl + '/pdf/web/viewer.html', allUrl: '' } }, onLoad(options) {let fileUrl = encodeURIComponent( globalConfig.baseUrl + '/api/attachment?name=' + options.name + '&url=' + options.url)this.allUrl = this.viewerUrl + '?file=' + fileUrl } }script>
效果
- h5端 显示正常
- Android端 显示模糊,并且中文显示不全,其中模糊问题是模拟器原因;但是中文显示问题是真,调试出现两个警告。第二个警告pdf.js默认不显示电子签章(数字签名)问题,查了很多资料也没解决,各位码友有遇到过并且解决了吗?
- iOS端 出现跨域问题,并且调试出现无法访问pdf.js国际化文件
解决 基于Android和iOS预览出现的各种问题,最根本原因是viewer.html文件放到前端导致加载资源文件丢失问题。针对这个问题,我就在想能不能直接放在spring后端作为静态资源访问文件呢?于是有了下面的方法。
2.2 使用方法二
在基于spring mvc的后端代码中,将插件包的build和web文件夹放到webapp下面(新建pdf文件夹),spring boot架构的后端项目同理,放到静态资源目录
在xml文件中配置静态文件访问
修改前端组件file-preview.vue中的viewerUrl,其中globalConfig.baseUrl为代理后端地址的baseUrl。如Vue中proxyTable或nginx代理
viewerUrl: globalConfig.baseUrl + '/pdf/web/viewer.html'
- 修改后效果
- iOS端
- Android端 模糊是模拟器原因,在真机上测试通过
三、文件流服务
3.1 方法一:tomcat配置
配置tomcat的config目录下的server.xml,在最后的中间添加如下:
port=8090 文件访问服务端口docBase="/root/" 文件存储目录 服务器上文件会存储到/root/fileData/目录下 文件访问地址为:http://ip地址:8090/fileData/文件名
<Service name="fileData">
<Connector port="8090" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Engine name="fileData" defaultHost="localhost">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="/root/" debug="0" reloadable="false"/> Host> Engine>Service>
3.2 方法二:写代码获取服务器文件进行转换
直接上代码
读取目录文件,转换为二进制流前端组件file-preview.vue中fileUrl为 /api/attachment
核心代码
ios = new FileInputStream(sourceFile);os = response.getOutputStream();int read = 0;byte[] buffer = new byte[1024 * 1024];while ((read = ios.read(buffer)) != -1) { os.write(buffer, 0, read);}os.flush();
完整代码
@RequestMapping(value = "/api/attachment", method = RequestMethod.GET) public void getFileBytes(@RequestParam("name") String name, @RequestParam("url") String url, HttpServletRequest request, HttpServletResponse response) { response.reset(); response.setContentType("application/octet-stream"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + name);
AttachmentVO attachmentVO = new AttachmentVO(); FileInputStream ios = null; OutputStream os = null; try { name = CharsetUtils.toUTF_8(name); url = CharsetUtils.toUTF_8(url);
attachmentVO.setUrl(url); attachmentVO.setName(name); File sourceFile = getDictionaryFile(attachmentVO, request); if (null == sourceFile) {// throw new HttpResponseException(300, "附件不存在!"); return; }
/** * 判断文件类型 */ /* 获得文件名后缀 */ String ext = ""; if (!"".equals(url) && url.contains(".")) { ext = url.substring(url.lastIndexOf(".") + 1, url.length()).toUpperCase(); } /* 根据文件类型不同进行预览 */ /* 预览pdf */ if ("PDF".equals(ext)) { response.setContentType("application/pdf"); }
/** * 将文件写入输出流,显示在界面上,实现预览效果 */ ios = new FileInputStream(sourceFile); os = response.getOutputStream(); int read = 0; byte[] buffer = new byte[1024 * 1024]; while ((read = ios.read(buffer)) != -1) { os.write(buffer, 0, read); } os.flush(); } catch (Exception e) { e.printStackTrace(); try { if (null != ios) { ios.close(); } if (null != os) { os.close(); } } catch (IOException ex) { ex.printStackTrace(); } } }
四、office文件(Word、Excel、PPT)预览
原理:搭建OpenOffice服务,将文件转换为pdf,在使用pdf.js预览
4.1 搭建openOffice服务
下载Apache_OpenOffice
解压
tar xzvfm Apache_OpenOffice_xxx.tar.gzcd zh-CN/RPMSrpm -ivh *rpm
- 运行
# 127.0.0.1只能本机使用该服务/opt/openoffice4/program/soffice "-accept=socket,host=127.0.0.1,port=8100;urp;" -headless -nofirststartwizard &# 0.0.0.0远程ip能使用/opt/openoffice4/program/soffice "-accept=socket,host=0.0.0.0,port=8100;urp;" -headless -nofirststartwizard &
4.2 集成java
- 在pom.xml添加jar包
<dependency> <groupId>org.openofficegroupId> <artifactId>juhartifactId> <version>4.1.2version>dependency><dependency> <groupId>org.openofficegroupId> <artifactId>jurtartifactId> <version>4.1.2version>dependency><dependency> <groupId>org.openofficegroupId> <artifactId>ridlartifactId> <version>4.1.2version>dependency><dependency> <groupId>org.openofficegroupId> <artifactId>unoilartifactId> <version>4.1.2version>dependency><dependency> <groupId>com.artofsolvinggroupId> <artifactId>jodconverterartifactId> <version>2.2.2version>dependency>
注意:jodconverter需要单独下载2.2.2版本,之前的版本都不行,而且maven中央仓库没有2.2.2版本。然后再单独导入。下载地址:https://sourceforge.net/projects/jodconverter/files/
单独导入
mvn install:install-file -Dfile="jodconverter-2.2.2.jar" -DgroupId=com.artofsolving -DartifactId=jodconverter -Dversion=2.2.2 -Dpackaging=jar
- 转换代码
核心代码
connection = new SocketOpenOfficeConnection(openofficeHost, openofficePort);connection.connect();DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection);converter.convert(sourceFile, pdfFile);
完整代码
/* 利用openOffice将office文件转换为pdf格式, 然后预览doc, docx, xls, xlsx, ppt, pptx */if ("DOC".equals(ext) || "DOCX".equals(ext) || "XLS".equals(ext) || "XLSX".equals(ext) || "PPT".equals(ext) || "PPTX".equals(ext)) { /* filePath在数据库中是不带文件后缀的, 由于jodConverter必须要识别后缀,所以将服务器中的文件重命名为带后缀的文件 */ // File docFileWithExt = new File(filePath + "." + ext.toLowerCase()); //带后缀的文件 // docFile.renameTo(docFileWithExt); /* 转换之后的文件名 */ String filePath = sourceFile.getPath(); File pdfFile; if (filePath.contains(".")) { pdfFile = new File(filePath.substring(0, filePath.lastIndexOf(".")) + ".pdf"); } else { pdfFile = new File(filePath + ".pdf"); }
/* 判断即将要转换的文件是否真实存在 */ if (sourceFile.exists()) { /* 判断该文件是否已经被转换过,若已经转换则直接预览 */ if (!pdfFile.exists()) { OpenOfficeConnection connection; /* 打开OpenOffice连接 */ try { connection = new SocketOpenOfficeConnection(openofficeHost, openofficePort); connection.connect(); } catch (java.net.ConnectException e) { log.warn("openOffice未连接,正在重新连接...");
// 启动OpenOffice的服务 String command = openofficeInstallPath + "program/soffice -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard"; Runtime.getRuntime().exec(command);
Thread.sleep(1000);
connection = new SocketOpenOfficeConnection(8100); connection.connect();
log.warn("openOffice重新连接成功!!!"); }
try { // DocumentConverter converter = new OpenOfficeDocumentConverter(connection); DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection); converter.convert(sourceFile, pdfFile); connection.disconnect();
// filePath = pdfFile.getPath(); // 文件转换之后的路径 sourceFile = pdfFile; response.setContentType("application/pdf"); } catch (OpenOfficeException e) { e.printStackTrace(); // 读取转换文件失败 log.info("读取转换文件失败!!!"); return; } finally { // 发生exception时, connection不会自动切断, 程序会一直挂着 try { if (connection != null) { connection.disconnect(); } } catch (Exception e) { e.printStackTrace(); } } } else {// filePath = pdfFile.getPath(); // 文件已经转换过 sourceFile = pdfFile; response.setContentType("application/pdf"); } } else { log.info("需要预览的文档在服务器中不存在!!!"); // 文件不存在,直接返回 return; }}
五、图片预览
5.1 后端文件流
/* 预览图片 */if ("PNG".equals(ext) || "JPEG".equals(ext) || "JPG".equals(ext)) { response.setContentType("image/jpeg");}/* 预览BMP格式的文件 */if ("BMP".equals(ext)) { response.setContentType("image/bmp");}/* 预览GIF格式的文件 */if ("GIF".equals(ext)) { response.setContentType("image/gif");}
5.2 前端预览
采用uni-app的uni.previewImage接口fileUrl:为文件流访问地址
// 预览图片uni.previewImage({ urls: [fileUrl], longPressActions: { itemList: ['发送给朋友', '保存图片', '收藏'], success: function(data) { console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片'); }, fail: function(err) { console.log(err.errMsg); } }})
附:完整文件流代码
@RequestMapping(value = "/api/attachment", method = RequestMethod.GET)public void getFileBytes(@RequestParam("name") String name, @RequestParam("url") String url, HttpServletRequest request, HttpServletResponse response) { response.reset(); // 解决IFrame拒绝的问题,无效// response.setHeader("X-Frame-Options", "SAMEORIGIN"); response.setContentType("application/octet-stream"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + name);
AttachmentVO attachmentVO = new AttachmentVO(); FileInputStream ios = null; OutputStream os = null; try { name = CharsetUtils.toUTF_8(name); url = CharsetUtils.toUTF_8(url);
attachmentVO.setUrl(url); attachmentVO.setName(name); File sourceFile = getDictionaryFile(attachmentVO, request); if (null == sourceFile) {// throw new HttpResponseException(300, "附件不存在!"); return; }
/** * 判断文件类型 */ /* 获得文件名后缀 */ String ext = ""; if (!"".equals(url) && url.contains(".")) { ext = url.substring(url.lastIndexOf(".") + 1, url.length()).toUpperCase(); } /* 根据文件类型不同进行预览 */ /* 预览图片 */ if ("PNG".equals(ext) || "JPEG".equals(ext) || "JPG".equals(ext)) { response.setContentType("image/jpeg"); } /* 预览BMP格式的文件 */ if ("BMP".equals(ext)) { response.setContentType("image/bmp"); } /* 预览GIF格式的文件 */ if ("GIF".equals(ext)) { response.setContentType("image/gif"); } /* 预览pdf */ if ("PDF".equals(ext)) { response.setContentType("application/pdf"); }
/* 利用openOffice将office文件转换为pdf格式, 然后预览doc, docx, xls, xlsx, ppt, pptx */ if ("DOC".equals(ext) || "DOCX".equals(ext) || "XLS".equals(ext) || "XLSX".equals(ext) || "PPT".equals(ext) || "PPTX".equals(ext)) { /* filePath在数据库中是不带文件后缀的, 由于jodConverter必须要识别后缀,所以将服务器中的文件重命名为带后缀的文件 */ // File docFileWithExt = new File(filePath + "." + ext.toLowerCase()); //带后缀的文件 // docFile.renameTo(docFileWithExt); /* 转换之后的文件名 */ String filePath = sourceFile.getPath(); File pdfFile; if (filePath.contains(".")) { pdfFile = new File(filePath.substring(0, filePath.lastIndexOf(".")) + ".pdf"); } else { pdfFile = new File(filePath + ".pdf"); }
/* 判断即将要转换的文件是否真实存在 */ if (sourceFile.exists()) { /* 判断该文件是否已经被转换过,若已经转换则直接预览 */ if (!pdfFile.exists()) { OpenOfficeConnection connection; /* 打开OpenOffice连接 */ try { connection = new SocketOpenOfficeConnection(openofficeHost, openofficePort); connection.connect(); } catch (java.net.ConnectException e) { log.warn("openOffice未连接,正在重新连接...");
// 启动OpenOffice的服务 String command = openofficeInstallPath + "program/soffice -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard"; Runtime.getRuntime().exec(command);
Thread.sleep(1000);
connection = new SocketOpenOfficeConnection(8100); connection.connect();
log.warn("openOffice重新连接成功!!!"); }
try { // DocumentConverter converter = new OpenOfficeDocumentConverter(connection); DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection); converter.convert(sourceFile, pdfFile); connection.disconnect();
// filePath = pdfFile.getPath(); // 文件转换之后的路径 sourceFile = pdfFile; response.setContentType("application/pdf"); } catch (OpenOfficeException e) { e.printStackTrace(); // 读取转换文件失败 log.info("读取转换文件失败!!!"); return; } finally { // 发生exception时, connection不会自动切断, 程序会一直挂着 try { if (connection != null) { connection.disconnect(); } } catch (Exception e) { e.printStackTrace(); } } } else {// filePath = pdfFile.getPath(); // 文件已经转换过 sourceFile = pdfFile; response.setContentType("application/pdf"); } } else { log.info("需要预览的文档在服务器中不存在!!!"); // 文件不存在,直接返回 return; } }
/** * 将文件写入输出流,显示在界面上,实现预览效果 */ ios = new FileInputStream(sourceFile); os = response.getOutputStream(); int read = 0; byte[] buffer = new byte[1024 * 1024]; while ((read = ios.read(buffer)) != -1) { os.write(buffer, 0, read); } os.flush(); } catch (Exception e) { e.printStackTrace(); try { if (null != ios) { ios.close(); } if (null != os) { os.close(); } } catch (IOException ex) { ex.printStackTrace(); } }}
doc文件在线预览 vue_跨平台(uniapp)文件在线预览解决方案相关推荐
- koa中上传文件到阿里云oss实现点击在线预览和下载
比较好的在线预览的方法: 跳转一个新的页面,里面放一个iframe标签,或者object标签 <iframesrc="xxx"></iframe> < ...
- 文件在线预览功能(office文件)
由于项目的功能需要看了一下文件预览的功能实现,主要是看office的word,excel,ppt这些的在线预览. 比较常见的是以下两种: 一.通过iframe直接引用微软提供的方法(最简单) < ...
- php+预览和下载pdf文件,vue实现在线预览pdf文件和下载(pdf.js)
最近做项目遇到在线预览和下载pdf文件,试了多种pdf插件,例如jquery.media.js(ie无法直接浏览) 最后选择了pdf.js插件(兼容ie10及以上.谷歌.安卓,苹果) 强烈推荐改插件, ...
- pdf文件如何在安卓手机端不用下载在线预览
由于H5手机端页面,苹果ios手机端支持在线预览,而安卓手机端不行. 解决方案: 使用pdf.js插件. 官网地址:https://mozilla.github.io/pdf.js/ 第一步:下载整个 ...
- 基于Web的文件管理系统,支持Office、WPS预览/编辑、在线解压缩、文件分享、文件加密、远程存储、远程文件推送、秒传、断点
基于Web的文件管理系统,支持权限管理.历史版本管理.Office预览/编辑.WPS预览/编辑.在线解压缩.文件分享.文件加密.远程存储.远程文件推送.秒传.断点续传.智能搜索.文件备注.本地自动备份 ...
- html 在线预览pdf功能,html中在线预览pdf文件之pdf在线预览插件
html中在线预览pdf文件之pdf在线预览插件 最近遇到一个需求,要在html页面查看pdf生成的pdf文件!javascript 翻来覆去找到两种办法 ,最后采用了jquery.media.js插 ...
- uni-app开发在线预览pdf(h5/app)
本人亲测可用哦! 核心:pdf插件+web-view pdf插件获取地址 https://github.com/DonnaLh/-pdf-/tree/master 注意:这个链接里面的文件都是需要的哦 ...
- 跨平台Office文档预览原生插件,非腾讯X5,支持离线,稳定高可用
引言 2023年4月13日零时起,腾讯浏览服务内核文档能力正式下线,要实现真正离线文档预览,于是有了这边文章. 前面写了多篇关于<跨平台文件在线预览解决方案>,不管使用pdf.js.Lib ...
- java预览openoffice_web使用openoffice实现在线预览office文档
最近搞web项目,使用框架struts+spring+jpa实现,做到项目里面一个在线预览功能,试过无数的方法,最后得到了一个非常使用的方法,这方法也是我看过多篇博客的出来的,仅限参考. 效果图如下: ...
最新文章
- 以后版本网卡命名规则
- webstorm怎么跑项目_快讯!明年厦门中考体育项目定了!初三家长抽的!其他地市抽到啥?...
- 如何在Hibernate中维护表的历史记录
- 为提升效率,阿里取消周报制度?醒醒吧,自动化报表才是出路
- Xml+Xsl:内容与形式的完美分离
- python config方法_Python config.Configuration方法代码示例
- Requirement already satisfied
- 【计算机图形学】OpenGL递归实现光线追踪
- gossiping路由协议仿真
- 小坤二次元炫酷导航HTML源码
- qt5的configure选项说明(2)
- s/μs/ns/ps与Hz/KHz/MHz/GHz换算关系
- 《热浪球爱战》首映 周秀娜现场超低胸打排球
- 实验二实验结论实验总结与体会
- 利用Python爬虫获取招聘网站职位信息
- Markdown插入图片操作
- win10安装程序无法正常启动
- matlab删除行向量里面相同的数据
- pci总线协议学习笔记——PCI总线基本概念
- 开源文件文档在线预览项目解决方案kkFileView本地搭建运行与Docker部署运行