Java中实现文件预览的功能(实例代码)

作者:FighterLiu 时间:2023-09-09 16:13:06 

前言

日常开发中常见的文件格式有pdf,word,Excel,PPT,Html,txt,图片等。pdf,Html,txt,图片这种实现在线预览非常简单,有一些前端的插件可以满足要求。word,Excel,PPT如果要实现在线预览,就非常的困难。word,Excel,PPT实现在线预览常用的方式就是先转换成pdf,然后在进行预览。下面我就介绍常用的几种方案

一、kkfileview 文件在线预览

此项目为文件文档在线预览项目解决方案,项目使用流行的 spring boot 搭建,易上手和部署,部署好后可以独立提供预览服务,使用 http 接口访问,不需要和应用集成,具有跨系统跨语言使用的特性。提供 zip/tar.gz 发行包、自定义配置文件、和启动 / 停止脚本等,极大方便部署使用,同时官方发布 Docker 镜像,方便容器环境中部署使用。基本支持主流办公文档的在线预览,如 doc,docx,dwg, ofd, xls,xlsx,ppt,pptx,pdf,txt,zip,rar,7z,mp3,mp4,flv 图片等等。
项目地址:https://gitee.com/kekingcn/file-online-preview
项目官网:https://kkfileview.keking.cn

二、officetohtml纯前端的方式

用纯 javascript 编写的 jQuery 插件,用于将现代 Microsoft Office 文件、pptx、docx、xlsx 和 pdf 转换为 html。
实际上它是一个应用程序,它集成了其他库,如PPTXjs, mammoth.js,SheetJs结合 handsontable 和PDF.js,旨在将 Office 文件和 pdf 文件转换为 HTML。
项目官网:https://officetohtml.js.org/index.html

三、JODConverter

JODConverter是一种Java OpenDocument转换器,能够转换不同格式的文档,它依赖于Apache OpenOffice或 LibreOffice ,它为OpenDocument和Microsoft Office提供了最好的免费导入/导出的过滤器。
JODConverter可以用在这几种地方:
作为一个Java类库,嵌入到你的Java应用程序中。
作为一个命令行工具,可以在你的脚本中调用。
作为一个简单的web应用,上传文档,选择转换的格式并下载转换后的版本。
可以用openoffice,实现原理就是:
通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件流;这样就可以在浏览器上实现预览了。
先去openoffice官网下载进行安装,官网地址:https://www.openoffice.org/download/ 安装完成后启动。

Java中实现文件预览的功能(实例代码)

java中的代码如下:
Maven中添加如下依赖

<dependency>
       <groupId>com.artofsolving</groupId>
       <artifactId>jodconverter</artifactId>
       <version>2.2.1</version>
   </dependency>

将word、excel、ppt转换为pdf流的工具类代码

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 java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* 文件格式转换工具类
*
* @version 1.0
* @since JDK1.8
*/
public class FileConvertUtil {
   /** 默认转换后文件后缀 */
   private static final String DEFAULT_SUFFIX = "pdf";
   /** openoffice_port */
   private static final Integer OPENOFFICE_PORT = 8100;
   /**
    * 方法描述 office文档转换为PDF(处理本地文件)
    *
    * @param sourcePath 源文件路径
    * @param suffix     源文件后缀
    * @return InputStream 转换后文件输入流
    * @author tarzan
    */
   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 InputStream 转换后文件输入流
    * @author tarzan
    */
   public static InputStream convertNetFile(String netFileUrl, String suffix) throws Exception {
       // 创建URL
       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();
           return covertCommonByStream(inputStream, suffix);
       }
       return null;
   }
   /**
    * 方法描述  将文件以流的形式转换
    *
    * @param inputStream 源文件输入流
    * @param suffix      源文件后缀
    * @return InputStream 转换后文件输入流
    * @author tarzan
    */
   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
    *
    * @author tarzan
    */
   public static ByteArrayInputStream outputStreamConvertInputStream(final OutputStream out) throws Exception {
       ByteArrayOutputStream baos=(ByteArrayOutputStream) out;
       return new ByteArrayInputStream(baos.toByteArray());
   }
   public static void main(String[] args) throws IOException {
       //convertNetFile("http://172.16.10.21/files/home/upload/department/base/201912090541573c6abdf2394d4ae3b7049dcee456d4f7.doc", ".pdf");
       //convert("c:/Users/admin/Desktop/2.pdf", "c:/Users/admin/Desktop/3.pdf");
   }
}

serve层在线预览方法代码

/**
    * @Description:系统文件在线预览接口
    */
   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.convertNetFile(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();
   }

四、Aspose

Aspose.Words是一款先进的类库,通过它可以直接在各个应用程序中执行各种文档处理任务。Aspose.Words支持DOC,OOXML,RTF,HTML,OpenDocument, PDF, XPS, EPUB和其他格式。使用Aspose.Words,可以生成,更改,转换,渲染和打印文档而不使用Microsoft Word。
实现原理也是通过Aspose把文件转换成pdf然后在预览,实现步骤如下:
添加jar包,下载地址:https://download.csdn.net/download/xinghui_liu/85931977
配置License.xml,去掉水印

<?xml version="1.0" encoding="UTF-8" ?>
<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>

添加如下工具类,程序中调用doc2pdf即可实现文件转pdf

package com.weemambo.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
public class Word2PdfAsposeUtil {
   public static boolean getLicense() {
       boolean result = false;
       InputStream is = null;
       try {
           Resource resource = new ClassPathResource("license.xml");
           is = resource.getInputStream();
           //InputStream is = Word2PdfAsposeUtil.class.getClassLoader().getResourceAsStream("license.xml"); // license.xml应放在..\WebRoot\WEB-INF\classes路径下
           License aposeLic = new License();
           aposeLic.setLicense(is);
           result = true;
       } catch (Exception e) {
           e.printStackTrace();
       }finally {
           if (is != null) {
               try {
                   is.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
       return result;
   }
   public static boolean doc2pdf(String inPath, String outPath) {
       if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
           return false;
       }
       FileOutputStream os = null;
       try {
           long old = System.currentTimeMillis();
           File file = new File(outPath); // 新建一个空白pdf文档
           os = new FileOutputStream(file);
           Document doc = new Document(inPath); // Address是将要被转化的word文档
           doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
           // EPUB, XPS, SWF 相互转换
           long now = System.currentTimeMillis();
           System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时
       } catch (Exception e) {
           e.printStackTrace();
           return false;
       }finally {
           if (os != null) {
               try {
                   os.flush();
                   os.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
       return true;
   }
}

如上代码在window下不会出现乱码,在Linux系统中会出现乱码,原因为Linux系统中缺少相应的字体。解决方案如下:
获取window字体C:\Windows\Fonts目录下字体复制到 Linux /usr/share/fonts/win,具体步骤如下:
1.把字体上传到ninux服务器。这里上传到 /home 目录。
2.把刚刚上传的字体解压:unzip Fonts.zip -d Fonts
3.创建字体目录:mkdir /usr/share/fonts/win
4.把解压后的字体复制到创建的字体目录中:cp /home/Fonts/Fonts/* /usr/share/fonts/win
5.安装字体:

cd /usr/share/fonts
sudo mkfontscale
sudo mkfontdir
sudo fc-cache -fv

6.执行命令让字体生效

source /etc/profile

7.如果安装失败,可以考虑修改字体权限

chmod 755 *.ttf

8.重启服务器就可以正常转换了

总结

上面介绍了四种文件预览的方法,每种方法的优缺点如下:
方法一:kkfileview支持文件格式多,而且不用开发。不过需要单独部署一个文件预览的服务,而且服务器也需要安装openoffice。
方法二:officetohtml纯前端的方式可以不用安装任何插件及服务,但是目前只支持文件地址的方式预览,如果是文件流的话无法使用
方法三:JODConverter 依赖于openoffice,需要在服务器单独安装openoffice。
方法四:Aspose使用的是破解版的,如果商用使用需要考虑版权问题。

综上所述,如果不能在服务器安装相应的软件,而且程序中的附件是以地址的方式访问的话使用officetohtml。如果服务器可以安装插件,优先kkfileview,Aspose,JODConverter 。

三,四都是将文件转换成pdf,前端可以使用pdfjs,官网地址为:http://mozilla.github.io/pdf.js/getting_started/#download
下载完成后放入到项目中,如下:

Java中实现文件预览的功能(实例代码)

在项目中新建一个viewPdf.jsp页面:

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<title>文件预览</title>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/resources/layui/css/layui.css" rel="external nofollow" >
<script type="text/javascript" src="<%=request.getContextPath()%>/resources/layui/layui.js?v=1.1"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.8.3.js"></script>
   <script type="text/javascript">
       $(function() {
           $("#pdf").attr("height", $(document).height());
           var fileId='${fileId}';
           var url = "${pageContext.request.contextPath}/pdfjs/web/viewer.html?file=${pageContext.request.contextPath}/xxxx.do?fileId="+fileId;
           $("#pdf").attr("src", url);
       })
   </script>
</head>
<body>
<div class="main">
   <iframe id="pdf" width="100%"></iframe>
</div>
</body>
</html>

file后面可以直接写一个文件地址,如果是文件流的方式写一个后端的请求并传递相应的参差。文件流要注意的地方是下面这个要设置为inline
response.setHeader(&ldquo;Content-disposition&rdquo;, &ldquo;inline; filename=&rdquo; + fileName);

参考资料:

https://blog.csdn.net/weixin_40986713/article/details/109527294

https://blog.csdn.net/qq_20143059/article/details/106427297

https://blog.csdn.net/wybaby168/article/details/122842866

来源:https://blog.csdn.net/xinghui_liu/article/details/125641300

标签:java,文件预览
0
投稿

猜你喜欢

  • SpringMVC用JsonSerialize日期转换方法

    2021-12-06 10:59:59
  • C#特性-对象集合初始化器介绍

    2023-05-27 18:26:29
  • Java使用动态规划算法思想解决背包问题

    2022-12-02 03:53:49
  • Eclipse下基于Java的OpenCV开发环境配置教程

    2022-01-30 21:02:54
  • Java 按行读取文件按行写入文件并以空格分割字符串的方法

    2023-08-31 12:32:21
  • 一篇文章教你如何用多种迭代写法实现二叉树遍历

    2023-12-23 04:03:29
  • JAVA基础-GUI

    2023-10-24 22:26:07
  • Java多线程常见案例分析线程池与单例模式及阻塞队列

    2022-06-01 06:42:42
  • 详解MyBatis-Puls中saveBatch批量添加慢的问题

    2021-10-14 02:36:27
  • java中Hashmap的get方法使用

    2023-10-29 13:10:05
  • Android源码中final关键字的用法及final,finally,finalize的区别

    2023-10-11 09:03:43
  • java判断list不为空的实现,和限制条数不要在一起写

    2022-01-24 13:14:38
  • Java I/O中I/O流的典型使用方式详解

    2023-07-08 21:07:51
  • Android开发之判断有无虚拟按键(导航栏)的实例

    2023-01-29 07:48:45
  • SparkSQl简介及运行原理

    2023-09-17 05:18:19
  • Activiti开发环境的搭建过程详解

    2021-08-16 07:13:05
  • java实现一个简单TCPSocket聊天室功能分享

    2022-06-11 20:04:36
  • Android开发自定义双向SeekBar拖动条控件

    2022-06-02 03:55:25
  • Android项目类似淘宝 电商 搜索功能,监听软键盘搜索事件,延迟自动搜索,以及时间排序的搜索历史记录的实现

    2022-01-20 22:21:12
  • Android自定义View制作仪表盘界面

    2021-10-05 06:45:01
  • asp之家 软件编程 m.aspxhome.com