1. 原理
将 office 文档转换为 pdf ,返回文件流给前端实现预览。
当前的主浏览器都支持直接打开pdf文件,从而实现文件预览。如果是其他格式文件则得下载,因此用openOffice实现文件转pdf格式。

1)openOffice的安装
下载地址:openOffice下载
安装教程可参考:openOffice下载和安装

2)Windows下启动openoffice服务
安装默认目录为

C:\Program Files (x86)\OpenOffice 4\

我们先进入文件目录

cd C:\Program Files (x86)\OpenOffice 4\program>

命令窗口输入以下命令启动:

soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" –nofirststartwizard

输入netstat -anop tcp查看是否启动成功

2.pxm.xml导入依赖

 <!--openoffice--><dependency><groupId>com.artofsolving</groupId><artifactId>jodconverter</artifactId><version>2.2.1</version></dependency><!-- jxls poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.17</version></dependency><!-- https://mvnrepository.com/artifact/net.sf.jxls/jxls-core --><dependency><groupId>net.sf.jxls</groupId><artifactId>jxls-core</artifactId><version>1.0.6</version></dependency>

3.文件格式转换工具类 FileConvertUtil

import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.DocumentFormat;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import com.eccom.common.exception.CustomException;
import com.eccom.common.utils.StringUtils;
import org.apache.commons.io.FilenameUtils;import java.io.*;
import java.net.*;
import java.util.Base64;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;/*** 文件格式转换工具类*/
public class FileConvertUtil {//    @Value("${baseplatform.file.preview-max-size}")private static int previewMaxSize = 100;/*** 默认转换后文件后缀*/private static final String DEFAULT_SUFFIX = "pdf";/*** openoffice_port*/private static final Integer OPENOFFICE_PORT = 8100;/*** 【office文档转换为PDF(处理本地文件) 】** @param sourcePath: 源文件路径* @param suffix:     源文件后缀* @return java.io.InputStream 转换后文件输入流*/public static InputStream convertLocaleFile(String sourcePath, String suffix) throws Exception {File inputFile = new File(sourcePath);InputStream inputStream = new FileInputStream(inputFile);return covertCommonByStream(inputStream, suffix);}/*** 【office文档转换为PDF(处理网络文件)】** @param netFileUrl: 网络文件路径* @param suffix:     文件后缀* @return java.io.InputStream 转换后文件输入流*/public static InputStream convertNetFile(String netFileUrl, String suffix) throws Exception {// 创建URLnetFileUrl = getEncodeUrl(netFileUrl).replaceAll("\\+", "%20");URL url = new URL(netFileUrl);// 试图连接并取得返回状态码URLConnection urlconn = url.openConnection();urlconn.connect();HttpURLConnection httpconn = (HttpURLConnection) urlconn;int httpResult = httpconn.getResponseCode();if (httpResult == HttpURLConnection.HTTP_OK) {InputStream inputStream = urlconn.getInputStream();//根据响应获取文件大小(M)int size = urlconn.getContentLength() / 1024 / 1024;if (size > previewMaxSize) {throw new CustomException("文件太大,请下载查看");}return covertCommonByStream(inputStream, suffix);}return null;}/*** 【将文件以流的形式转换】** @param inputStream: 源文件输入流* @param suffix:      源文件后缀* @return java.io.InputStream 转换后文件输入流*/public static InputStream covertCommonByStream(InputStream inputStream, String suffix) throws Exception {ByteArrayOutputStream out = new ByteArrayOutputStream();OpenOfficeConnection connection = new SocketOpenOfficeConnection(OPENOFFICE_PORT);connection.connect();DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection);DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry();DocumentFormat targetFormat = formatReg.getFormatByFileExtension(DEFAULT_SUFFIX);DocumentFormat sourceFormat = formatReg.getFormatByFileExtension(suffix);converter.convert(inputStream, sourceFormat, out, targetFormat);connection.disconnect();return outputStreamConvertInputStream(out);}/*** 【outputStream转inputStream】** @param out:* @return java.io.ByteArrayInputStream*/public static ByteArrayInputStream outputStreamConvertInputStream(final OutputStream out) {ByteArrayOutputStream baos = (ByteArrayOutputStream) out;return new ByteArrayInputStream(baos.toByteArray());}/*** 【文件压缩】网络文件** @param filePath:* @param zipOut:* @return void*/public static void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {filePath = getEncodeUrl(filePath).replaceAll("\\+", "%20");// 需要压缩的文件File file = new File(filePath);// 获取文件名称,为解决压缩时重复名称问题,对文件名加时间戳处理String fileName = FilenameUtils.getBaseName(URLDecoder.decode(file.getName(), "UTF-8")) + "-"+ String.valueOf(new Date().getTime()) + "."+ FilenameUtils.getExtension(file.getName());InputStream fileInput = getInputStream(filePath);// 缓冲byte[] bufferArea = new byte[1024 * 10];BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10);// 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称zipOut.putNextEntry(new ZipEntry(fileName));int length = 0;// 最常规IO操作,不必紧张while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {zipOut.write(bufferArea, 0, length);}//关闭流fileInput.close();// 需要注意的是缓冲流必须要关闭流,否则输出无效bufferStream.close();// 压缩流不必关闭,使用完后再关}/*** 【获取网络文件的输入流】** @param filePath: 网络文件路径* @return java.io.InputStream*/public static InputStream getInputStream(String filePath) throws IOException {InputStream inputStream = null;// 创建URLURL url = new URL(filePath);// 试图连接并取得返回状态码URLConnection urlconn = url.openConnection();urlconn.connect();HttpURLConnection httpconn = (HttpURLConnection) urlconn;int httpResult = httpconn.getResponseCode();if (httpResult == HttpURLConnection.HTTP_OK) {inputStream = urlconn.getInputStream();}return inputStream;}/*** 判断汉字的方法,只要编码在\u4e00到\u9fa5之间的都是汉字,中文符号,空格,+** @param c:* @return boolean*/public static boolean isChineseChar(char c) {return String.valueOf(c).matches("[\u4e00-\u9fa5\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b\\s\\+]");}/*** 得到中文转码后的 url,只转换 url 中的中文字符** @param url:* @return java.lang.String*/public static String getEncodeUrl(String url) throws UnsupportedEncodingException {String resultURL = StringUtils.EMPTY;for (int i = 0; i < url.length(); i++) {char charAt = url.charAt(i);//只对汉字处理if (isChineseChar(charAt)) {String encode = URLEncoder.encode(charAt + "", "UTF-8");resultURL += encode;} else {resultURL += charAt;}}return resultURL;}public static void main(String[] args) {//        convertNetFile("http://192.168.161.159:8080/profile/upload/2022/03/28/a9b1c5bb-f7a3-478d-afa9-ece99e5b02c6.docx", ".pdf");
//        convert("c:/Users/admin/Desktop/2.pdf", "c:/Users/admin/Desktop/3.pdf");}
}

4.controller 代码

 @ApiOperation(value = "系统文件在线预览接口")@GetMapping("/onlinePreview")public void onlinePreview(@RequestParam("url") String url, HttpServletResponse response) throws Exception {attachmentsService.onlinePreview(url, response);}

5.service 代码

  public void onlinePreview(String url, HttpServletResponse response) throws Exception             {//获取文件类型String[] str = SmartStringUtil.split(url, "\\.");if (str.length == 0) {throw new Exception("文件格式不正确");}String suffix = str[str.length - 1];if (!suffix.equals("txt") && !suffix.equals("doc") && !suffix.equals("docx") && !suffix.equals("xls")&& !suffix.equals("xlsx") && !suffix.equals("ppt") && !suffix.equals("pptx")) {throw new Exception("文件格式不支持预览");}//处理本地文件InputStream in = FileConvertUtil.convertLocaleFile(url, suffix);OutputStream outputStream = response.getOutputStream();//创建存放文件内容的数组byte[] buff = new byte[1024];//所读取的内容使用n来接收int n;//当没有读取完时,继续读取,循环while ((n = in.read(buff)) != -1) {//将字节数组的数据全部写入到输出流中outputStream.write(buff, 0, n);}//强制将缓存区的数据进行输出outputStream.flush();//关流outputStream.close();in.close();}

常见异常
1.java.lang.IllegalArgumentException: inputFormat is null at com.artofsolving.jodconverter.openoffice.converter.AbstractOpenOfficeDocumentConverter.ensureNotNull(AbstractOpenOfficeDocumentConverter.java:113)
这是因为转换07版本及高版本(.docx/.xlsx/.pptx)时,这三种格式不在所支持的文件格式中。
解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常
解决办法:
方案一:
重写
BasicDocumentFormatRegistry (一定得在com.artofsolving.jodconverter包下)

package com.artofsolving.jodconverter;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** 【重写 BasicDocumentFormatRegistry 文档格式】** @author y* @date 2022-04-01*/
public class BasicDocumentFormatRegistry implements DocumentFormatRegistry {private List/* <DocumentFormat> */ documentFormats = new ArrayList();public void addDocumentFormat(DocumentFormat documentFormat) {documentFormats.add(documentFormat);}protected List/* <DocumentFormat> */ getDocumentFormats() {return documentFormats;}/*** @param extension the file extension* @return the DocumentFormat for this extension, or null if the extension* is not mapped*/@Overridepublic DocumentFormat getFormatByFileExtension(String extension) {if (extension == null) {return null;}//将文件名后缀统一转化if (extension.indexOf("doc") >= 0) {extension = "doc";}if (extension.indexOf("ppt") >= 0) {extension = "ppt";}if (extension.indexOf("xls") >= 0) {extension = "xls";}String lowerExtension = extension.toLowerCase();for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {DocumentFormat format = (DocumentFormat) it.next();if (format.getFileExtension().equals(lowerExtension)) {return format;}}return null;}@Overridepublic DocumentFormat getFormatByMimeType(String mimeType) {for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {DocumentFormat format = (DocumentFormat) it.next();if (format.getMimeType().equals(mimeType)) {return format;}}return null;}
}

方案二:

目前maven公网仓库中,没有jodconverter-2.2.2.jar,只有jodconverter-2.2.1.jar.而支持新版office和html转换格式的支持,需要2.2.2版本,这个需要自己去下载,并维护到maven私服上。步骤如下:
(1)下载

https://sourceforge.net/projects/jodconverter/?source=typ_redirect 去这个地址下载即可。

(2)上传maven私服

通过步骤1下载下来的是一个.zip的包,解压后在jodconverter-2.2.2\lib目录下可以看到,如下图:

我们可以看到jodconverter-2.2.2.jar包,把这个jar包上传maven私服即可。而这个包里面含有对新版office(.docx .xlsx .pptx)的支持,HTML的支持等。对于juh-3.0.1.jar、ridl-3.0.1.jar、unoil-3.0.1.jar这三个包在maven公网仓库中是可以查到的,所以直接在pom.xml中添加即可。

乱码问题
网上有很多攻略,大致讲的是向JDK的编码和linux系统中的编码添加可支持的字体即可。

OpenOfficeDocumentConverter和StreamOpenOfficeDocumentConverter的区别

(1)最终生成文件权限问题

当Apache OpenOffice服务和java程序部署在同一台服务上时,可以使用OpenOfficeDocumentConverter,但是同时需要注意,使用该类转换的PDF文件用户权限为Apache OpenOffice的启动用户权限。例如,java服务使用较低的权限用户worker启动,而Apache OpenOffice使用root用户启动,那么生成的PDF文件也为root,那么java程序如果对后续生成的PDF文件进行读写等操作时,由于java服务为worker权限,会造成读取不到文件流的问题。而使用StreamOpenOfficeDocumentConverter,是由OpenOffice生成完PDF后,把PDF的流传给java服务,由java服务生成的PDF文件,所以不会产生用户权限的问题

(2)性能问题

OpenOfficeDocumentConverter直接由OpenOffice生成PDF文件,而StreamOpenOfficeDocumentConverter是由OpenOffice把PDF流回传给java服务,有java服务生成。所以OpenOfficeDocumentConverter在性能上更快。但是OpenOfficeDocumentConverter的问题是,不能实现java服务和OpenOffice的高可用性(因为两个服务部署在同一台物理机上)

(3)实现java服务与OpenOffice服务的高可用部署

java服务与OpenOffice服务在同一台物理机时,可以使用OpenOfficeDocumentConverter,因为他转换的更快。如果两个服务不在同一台物理机上,可以使用StreamOpenOfficeDocumentConverter类。

java用openOffice实现在线预览相关推荐

  1. Java使用OpenOffice实现在线预览

    公司业务:在线预览office文件,调研了一下,目前市场上免费的,比较合适的,也就是OpenOffice了,事已至此,干活... 思路: 1.利用 OpenOffice 以及 jodconverter ...

  2. Java 实现word pdf在线预览

    Java 实现word pdf在线预览 最近项目有这个需求,查找了一些资料,在这整理一下. 首先,pdf的文件,浏览器本身支持预览,不需要做什么处理. controller: 简单说下思路:就是利用i ...

  3. 使用openOffice实现在线预览

    一 .OpenOffice的在线预览## 我的具体逻辑: ①我是文件上传到阿里云服务器上 ②然后我需要把上传的文件下载下来,下载到另外一台服务器上,然后获取下载文件的地址,进行转码,转成html或者p ...

  4. java预览openoffice_web使用openoffice实现在线预览office文档

    最近搞web项目,使用框架struts+spring+jpa实现,做到项目里面一个在线预览功能,试过无数的方法,最后得到了一个非常使用的方法,这方法也是我看过多篇博客的出来的,仅限参考. 效果图如下: ...

  5. web使用openoffice实现在线预览office文档

    最近搞web项目,使用框架struts+spring+jpa实现,做到项目里面一个在线预览功能,试过无数的方法,最后得到了一个非常使用的方法,这方法也是我看过多篇博客的出来的,仅限参考. 效果图如下: ...

  6. Java实现文档在线预览

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 主要思路 使用openoffice方式实现word预览 安装open ...

  7. Java 实现文档在线预览功能

    一.说明 因系统需要,要在系统中做一个文档预览的功能,网上有挺多第三方的工具,但是都是收费的,有 什么永中啊,OFFICE 365 XDOC啊,这些大概一搜都能搜到,价格也不是很贵. 但是,能不付费就 ...

  8. 快速实现word、excel、ppt、txt等办公文件在线预览功能(Java版)

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/weixin_40986713/ article/details/109527294 java实现办公文件在线预览功能是一个大家 ...

  9. Java 实现word、excel、ppt、txt等办公文件在线预览功能!

    大家好,我是宝哥! 如何用 Java 实现word.excel.ppt.txt等办公文件在线预览功能?本文告诉你答案! java 实现办公文件在线预览功能是一个大家在工作中也许会遇到的需求,网上些公司 ...

最新文章

  1. 揭秘鸿蒙系统中的 JS 开发框架
  2. Java枚举类使用和总结
  3. How to enable javascript in windows server 2008 R2 enterprise
  4. sql注入-union select
  5. Servlet获取Web应用程序的初始化参数
  6. 75 jsp基础语法汇总
  7. 【数据挖掘】数据挖掘和数据分析基础
  8. arp协议的主要功能是_计算机网络之ARP协议
  9. python一个星期可以入门吗_Python一星期入门第6篇: 模块和包
  10. JSK-5 矩阵翻转【入门】
  11. Unix网络-select
  12. sybase相关的知识
  13. 女程序员做了个梦,神评论。。。
  14. Python,PyCharm2017安装教程,包含注册码
  15. 史上最全人工智能英文原版PDF教材1.03G资源包Artificial Intelligence
  16. 寻路系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 案例二——网页倒计时(秒杀)
  18. 前端工程师的摸鱼日常(2)
  19. 原来棒棒糖还有这功能~
  20. 小米、360、萤石等智能摄像头如何选购?需要注意哪些功能信息

热门文章

  1. Flutter对话框
  2. html实现自动手动广告轮播,HTML+CSS+jQuery实现轮播广告图
  3. 获取网站流量的方法有哪些?
  4. 微信小程序中全局变量userInfo在其它页面不可用(wx.getUserInfo为异步获取信息)
  5. 运筹说 第25期 | 对偶理论经典例题讲解
  6. DAC8822QBDBTR
  7. 时尚创意孟菲斯风格PPT模板
  8. 查找CAD图纸中的坐标
  9. 智还市场竞争激烈,信用卡红利还能维持多久?
  10. [教程]Ubuntu20.04安装Node.js