• SpringBoot + LibreOffice + Hutool 实现附件预览简单示例


    1. 简介

      在日常开发中,经常会遇到需要预览附件的需求,如果附件类型为图片、文本、PDF或者网页文件,则直接可以在浏览器预览;如果附件类型为Word、Excel、PPT等文件,则需要通过工具转换为PDF后在浏览器预览。
      本博客使用LibreOffice和Hutool实现文件预览简单示例。
      LibreOffice官网:https://zh-cn.libreoffice.org/

    2. 安装Libreoffice

    • Windows安装
    • Linux安装
      • yum安装
      yum -y install libreoffice
      # 安装后的目录为:/usr/lib64/libreoffice
      
      • 乱码问题
      # 上传Windows的C:WindowsFonts目录中的字体到Linux的/usr/share/fonts/windows目录
      # 执行授权
      chmod 644 /usr/share/fonts/windows/* && fc-cache -fv
      
    • 官网安装手册
        https://zh-cn.libreoffice.org/get-help/install-howto/

    3. 示例代码

    • 创建工程
    • 修改pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>com.c3stones</groupId>
    	<artifactId>spring-boot-libreoffice-demo</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>spring-boot-libreoffice-demo</name>
    	<description>Spring Boot Libreoffice Demo</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.3.4.RELEASE</version>
    		<relativePath />
    	</parent>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.jodconverter</groupId>
    			<artifactId>jodconverter-spring-boot-starter</artifactId>
    			<version>4.4.2</version>
    		</dependency>
    		<dependency>
    			<groupId>org.jodconverter</groupId>
    			<artifactId>jodconverter-local</artifactId>
    			<version>4.4.2</version>
    		</dependency>
    		<dependency>
    			<groupId>org.jodconverter</groupId>
    			<artifactId>jodconverter-core</artifactId>
    			<version>4.4.2</version>
    		</dependency>
    		<dependency>
    			<groupId>org.libreoffice</groupId>
    			<artifactId>ridl</artifactId>
    			<version>7.2.0</version>
    		</dependency>
    		<dependency>
    			<groupId>cn.hutool</groupId>
    			<artifactId>hutool-all</artifactId>
    			<version>5.7.13</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-thymeleaf</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    
    • 创建配置文件application.yml
    server:
      port: 8080
    
    spring:
      thymeleaf:
        prefix: classpath:/view/
        suffix: .html
        encoding: UTF-8
        servlet:
          content-type: text/html
        cache: false
      servlet:
        multipart:
          max-file-size: 50MB
          max-request-size: 50MB
    
    # 附件预览
    jodconverter:
      local:
        enabled: true
    #   # 设置LibreOffice目录
        officeHome: D:LibreOffice
    #   # CentOS 下安装 LibreOffice:
    #   # 1、安装:yum -y install libreoffice
    #   # 2、配置:officeHome: /usr/lib64/libreoffice
    #   # Linux 中文字体乱码解决:
    #   # 1、上传 C:WindowsFonts 下的字体到 /usr/share/fonts/windows 目录
    #   # 2、执行命令: chmod 644 /usr/share/fonts/windows/* && fc-cache -fv
    #   # 监听端口,开启多个LibreOffice进程,每个端口对应一个进程
    #   portNumbers: 8100,8101,8102
        portNumbers: 2002
    #   # LibreOffice进程重启前的最大进程数
        maxTasksPerProcess: 10
    #   # 任务在转换队列中的最大生存时间,默认30s
        taskQueueTimeout: 30
    
    • 创建Controller
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.tomcat.util.http.fileupload.IOUtils;
    import org.jodconverter.core.DocumentConverter;
    import org.jodconverter.core.office.OfficeException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    import cn.hutool.core.io.IORuntimeException;
    import cn.hutool.core.io.IoUtil;
    import cn.hutool.core.util.StrUtil;
    
    /**
     * 附件预览Controller
     * 
     * @author CL
     *
     */
    @Controller
    @RequestMapping(value = "/file")
    public class FilePreviewController {
    
    	private static final Logger log = LoggerFactory.getLogger(FilePreviewController.class);
    
    	@Autowired
    	private DocumentConverter documentConverter;
    
    	/**
    	 * 跳转到附件预览和下载页面
    	 * 
    	 * @return
    	 */
    	@RequestMapping(value = "")
    	public String index() {
    		return "fileIndex";
    	}
    
    	/**
    	 * 附件预览
    	 * 
    	 * @param file     附件
    	 * @param response
    	 */
    	@RequestMapping(value = "/preview")
    	@ResponseBody
    	public void preview(MultipartFile file, HttpServletResponse response) {
    		if (file == null) {
    			return;
    		}
    		InputStream inputStream = null;
    		OutputStream outputStream = null;
    		try {
    			inputStream = file.getInputStream();
    			outputStream = response.getOutputStream();
    			String fileName = file.getOriginalFilename();
    			if (StrUtil.endWithAnyIgnoreCase(fileName, ".doc", ".docx", ".xls", ".xlsx", ".csv", ".ppt", ".pptx")) {
    				// 转为PDF
    				documentConverter.convert(inputStream).to(outputStream)
    						.as(documentConverter.getFormatRegistry().getFormatByExtension("pdf")).execute();
    			} else if (StrUtil.endWithAnyIgnoreCase(fileName, ".pdf", ".txt", ".xml", ".md", ".json", ".html", ".htm",
    					".gif", ".jpg", ".jpeg", ".png", ".ico", ".bmp")) {
    				IoUtil.copy(inputStream, outputStream);
    			} else {
    				outputStream.write("暂不支持预览此类型附件".getBytes());
    			}
    		} catch (IORuntimeException e) {
    			log.error("附件预览IO运行异常:{}", e.getMessage());
    		} catch (IOException e) {
    			log.error("附件预览IO异常:{}", e.getMessage());
    		} catch (OfficeException e) {
    			log.error("附件预览Office异常:{}", e.getMessage());
    		} finally {
    			IOUtils.closeQuietly(inputStream);
    		}
    		IoUtil.writeUtf8(outputStream, true);
    	}
    
    }
    
    • 创建附件预览示例页面
        在resources下新建目录view,在view目录下新建页面:fileIndex.html
    <html>
    <head>
    	<title>附件预览和下载</title>
    </head>
    <body>
    	<h5>支持附件类型为:.doc, .docx, .xls, .xlsx, .csv, .ppt, .pptx, .pdf, .txt, .xml, .md, .json, .gif, .jpg, .jpeg, .png, .ico, .bmp</h5>
    	<form id="fileForm" action="" method="post" enctype="multipart/form-data">
    		<i style="color: red">*</i> 上传附件:<input id="file" name="file" type="file" /><br/>
    	</form>
    	<button onclick="preview()">预览</button>
    </body>
    </html>
    <script>
    // 预览方法
    function preview() {
    	// 检查是否为空和大小限制
    	var file = document.getElementById('file').files[0];
    	if (!file) {
    		alert("附件不能为空");
    		return;
    	}
    	var fileSize = file.size;
    	if (fileSize > 50 * 1024 * 1024) {
    		alert("最大支持附件大小为 50MB");
    		return;
    	}
    	
    	// 提交表单
    	var fileForm = document.getElementById('fileForm');
    	fileForm.action = "[[@{/}]]file/preview";  
    	fileForm.submit();
    }
    </script>
    
    • 创建启动类
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 启动类
     * 
     * @author CL
     *
     */
    @SpringBootApplication
    public class Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    }
    

    4. 测试

    • 启动项目
    • 浏览器访问:http://127.0.0.1:8080/file
    • 测试预览图片
    • 测试预览文本
    • 测试预览Word文件
    • 测试预览PPT文件
    • 测试预览PDF

    5. 项目地址

      spring-boot-libreoffice-demo

  • 相关阅读:
    python selenium
    selenium 遇到chrome 弹出是否保存密码框
    selenium实现在新窗口打开链接
    linux 查看日志
    Selenium+Python :WebDriver设计模式( Page Object )
    Python Logging模块的简单使用
    【工作感悟】——员工因公司而加入,却因中层管理而离开
    【工作感悟】——如何协调人与事?
    J2EE的十三个技术——EJB之消息驱动JMS
    J2EE的十三个技术——EJB之实体Bean
  • 原文地址:https://www.cnblogs.com/cao-lei/p/15406724.html
Copyright © 2020-2023  润新知