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:\Windows\Fonts目錄中的字體到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:\Windows\Fonts 下的字體到 /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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM