手把手教你如何用Spring Boot搭建一个在线

简介: 昨晚搭建环境都花了好一会时间,主要在浪费在了安装 openoffice 这个依赖环境上(Mac 需要手动安装)。然后,又一步一步功能演示,记录,调试项目,并且简单研究了一下核心代码之后才把这篇文章写完。

前言

昨晚搭建环境都花了好一会时间,主要在浪费在了安装 openoffice 这个依赖环境上(Mac 需要手动安装)。然后,又一步一步功能演示,记录,调试项目,并且简单研究了一下核心代码之后才把这篇文章写完。

项目介绍

官方是这样介绍 kkFileView 的:

kkFileView 是使用 spring boot 打造文件文档在线预览项目解决方案,支持 doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3 以及众多类文本如 txt、html、xml、java、properties、sql、js、md、json、conf、ini、vue、php、py、bat、gitignore 等文件在线预览

简单来说 kkFileView 就是常见的文件类型的在线预览解决方案。

总的来说我觉得 kkFileView 是一个非常棒的开源项目,在线文件预览这个需求非常常见。感谢开源!

下面, 我站在一个“上帝”的角度从多个维度来评价一下 kkFileView:

代码质量一般,有很多可以优化的地方比如:
    Controller 层代码嵌套太多逻辑
    没有进行全局异常处理(
    代码中是直接返回错误信息的 json 数据给前端,我并不推荐这样做
    )
    返回值不需要通过ObjectMapper转换为 JSON 格式(ResponseEntity+@RestController 就行了)
    ......
使用的公司比较多,说明项目整体功能还是比较稳定和成熟的!
代码整体逻辑还是比较清晰的,比较容易看懂,给作者们点个赞!

环境搭建
克隆项目

通过以下命令即可将项目克隆到本地:

git clone https://gitee.com/kekingcn/file-online-preview.git

安装 OpenOffice

office 类型的文件的预览依赖了 OpenOffice ,所以我们首先要安装 OpenOffice(Windows 下已内置,Linux 会自动安装,Mac OS 下需要手动安装)。

下面演示一下如何在 Mac 上安装 OpenOffice。

你可以通过以下命令安装最新版的 OpenOffice:

brew cask install openoffice

不过,这种方式下载可能会比较慢,你可以直接去官网下载 dmg 安装包。

官方下载地址:https://www.openoffice.org/download/

OpenOffice下载

很多小伙伴就要问了:OpenOffice 是什么呢?

OpenOffice 是 Apache 旗下的一款开源免费的文字处理软件,支持 Windows、Liunx、OS X 等主流操作系统。

OpenOffice 和 Windows 下 office 办公软件有点类似,不过其实开源免费的。

why openoffice
启动项目

运行FilePreviewApplication的 main 方法,服务启动后,访问http://localhost:8012/ 会看到如下界面,代表服务启动成功。

项目启动成功
使用

我们首先上传了 3 个不同的类型的文件来分别演示一下图片、PDF、Word 文档的预览。

图片的预览

kkFileView 支持 jpg,jpeg,png,gif 等多种格式图片的预览,还包括了翻转,缩放图片等操作。

图片的预览效果如下。

图片的预览效果
Word 文档的预览

kkFileView 支持 doc,docx 文档预览。

另外,根据 Word 大小以及网速问题, Word 预览提供了两种模式:

每页 Word 转为图片预览
整个 Word 文档转成 PDF,再预览 PDF。

两种模式的适用场景如下

图片预览 :Word 文件大(加载 PDF 速度比较慢)的情况。
PDF 预览 :内网访问(加载 PDF 速度比较快)的情况。

图片预览模式预览效果如下:

PDF 预览模式预览效果如下:

PDF 文档的预览

kkFileView 支持 PDF 文档预览。类似 Word 文档预览, PDF 预览提供了两种模式:

每页 Word 转为图片预览
整个 Word 文档转成 PDF,再预览 PDF。

由于和 Word 文档的预览展示效果一致,这里就不放图片了。
文件预览核心代码分析
API 层

文件预览调用的接口是 /onlinePreview 。

通过分析 /onlinePreview 接口我们发现, 后端接收到预览请求之后,会从 URL 和请求中筛选出自己需要的信息比如文件后缀、文件名。

之后会调用FilePreview类 的 filePreviewHandle() 方法。filePreviewHandle() 方法是实现文件预览的核心方法。

@RequestMapping(value = "/onlinePreview")
public String onlinePreview(String url, Model model, HttpServletRequest req) {
FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
req.setAttribute("fileKey", req.getParameter("fileKey"));
model.addAttribute("pdfDownloadDisable", ConfigConstants.getPdfDownloadDisable());
model.addAttribute("officePreviewType", req.getParameter("officePreviewType"));
FilePreview filePreview = previewFactory.get(fileAttribute);
logger.info("预览文件url:{},previewType:{}", url, fileAttribute.getType());
return filePreview.filePreviewHandle(url, model, fileAttribute);
}

FilePreview 是文件预览接口,不同的文件类型的预览都实现了 FilePreview 接口,并实现了 filePreviewHandle() 方法。
文件预览接口

public interface FilePreview {
String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);
}

不同的文件类型的预览都实现了 FilePreview 接口,如下图所示。

不同文件类型的预览都会实现 FilePreview 接口,然后重写filePreviewHandle()方法。比如: OfficeFilePreviewImpl 这个主要负责处理 office 文件的预览、PdfFilePreviewImpl 主要负责处理 pdf 文件的预览。
文件预览具体实现分析

下面我们以 office 文件的预览为入口来分析。

首先要明确的是 excel 类型的预览是通过将 excel 文件转换为 HTML 实现的,其他类型 office 文件的预览是通过将文件转换为 PDF 或者是 图片的方式来预览的。

举个例子。我们上传了一份名为 武汉市文化市场管理办法.docx 的 Word 文件并预览的话,jodconverter-web/src/main/file 路径下会生成两个相关文件,这两个文件分别对应了我们提到的 PDF 预览 和 图片预览这两种方式。

武汉市文化市场管理办法.pdf
由 Word 文件所转化得到的一系列图片

我们以一个名为 武汉市文化市场管理办法.docx 的文件来举例说明一下代码中是如何做的。

通过分析代码, 我们定位到了 OfficeFilePreviewImpl 这个主要负责处理 office 文件预览的类。

/**

  • 处理office文件
    */
    @Service
    public class OfficeFilePreviewImpl implements FilePreview {

}

我们来简单分析一下 OfficeFilePreviewImpl 类中实现预览的核心方法是 filePreviewHandle 。

说明:这部分代码的逻辑不够清晰,还可以抽方法优化以让人更容易读懂,感兴趣的小伙伴可以自己动手重构一下,然后去给作者提个 PR。

@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
    // 1.获取预览类型(image/pdf/html),用户请求中传了officePreviewType参数就取参数的,没传取系统默认(image)
    String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
    // 2.获取 URL 地址
    String baseUrl = BaseUrlFilter.getBaseUrl();// http://localhost:8012/
    // 3.获取图片相关信息
    String suffix=fileAttribute.getSuffix();//文件后缀如docx
    String fileName=fileAttribute.getName();//文件名如:武汉市文化市场管理办法.docx
    // 4. 判断是否为 html 格式预览也就是判断文件否为 excel
    boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
    // 5. 将文件的后缀名更换为 .pdf 或者 .html(excel文件的情况)
    String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
    // 6. 转换后的文件输出的文件夹如 file-online-preview/jodconverter-web/src/main/file/武汉市文化市场管理办法.pdf)
    String outFilePath = FILE_DIR + pdfName;
    // 7 .判断之前是否已转换过,如果转换过,直接返回,否则执行转换
    // 文件第一次被预览的时候会首先对文件进行缓存处理
    if (!fileUtils.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
        String filePath;
        // 下载文件
        ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
        if (0 != response.getCode()) {
            model.addAttribute("fileType", suffix);
            model.addAttribute("msg", response.getMsg());
            return "fileNotSupported";
        }
        filePath = response.getContent();
        if (StringUtils.hasText(outFilePath)) {
            officeToPdf.openOfficeToPDF(filePath, outFilePath);
            if (isHtml) {
                // 对转换后的文件进行操作(改变编码方式)
                fileUtils.doActionConvertedFile(outFilePath);
            }
            if (ConfigConstants.isCacheEnabled()) {
                // 加入缓存
                fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
            }
        }
    }
    // 8.根据预览类型officePreviewType,选择不同的预览方式
    // 比如,如果预览类型officePreviewType为pdf则进行pdf方式预览
    if (!isHtml && baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
        return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, pdfUtils, OFFICE_PREVIEW_TYPE_IMAGE);
    }
    model.addAttribute("pdfUrl", pdfName);
    return isHtml ? "html" : "pdf";
}
相关文章
|
4月前
|
IDE Java 开发工具
快速上手指南:如何用Spring Boot开启你的Java开发之旅?
【8月更文挑战第22天】Spring Boot由Pivotal团队开发,简化了Spring应用的创建过程。本文详述了从零开始搭建Spring Boot项目的步骤:首先确保安装了新版JDK、Maven/Gradle及IDE如IntelliJ IDEA或Eclipse;接着访问Spring Initializr网站(start.spring.io),选择所需依赖(如Web模块)并生成项目;最后,使用IDE打开生成的项目,添加`@SpringBootApplication`注解及main方法来启动应用。通过这些步骤,即便是新手也能快速上手,专注于业务逻辑的实现。
47 1
|
7月前
|
XML 安全 Java
轻松上手:Spring环境搭建的实用指南
轻松上手:Spring环境搭建的实用指南
69 1
轻松上手:Spring环境搭建的实用指南
|
前端开发 Java 数据库
手把手教你使用Spring Boot从零开始制作用户注册登录功能
手把手教你使用Spring Boot从零开始制作用户注册登录功能
5283 1
手把手教你使用Spring Boot从零开始制作用户注册登录功能
|
Java Maven 开发者
从零开始的Spring Boot自动配置学习和starter制作教程
从零开始的Spring Boot自动配置学习和starter制作教程
160 0
从零开始的Spring Boot自动配置学习和starter制作教程
|
Java Maven Spring
快速搭建一个spring入门案例及整合日志(上)
快速搭建一个spring入门案例及整合日志
|
存储 监控 Java
快速搭建一个spring入门案例及整合日志(下)
快速搭建一个spring入门案例及整合日志(下)
|
算法 Java 数据库
【Spring】简单的登录案例和配套知识
1. 演示一下 Spring 管理类的模式 2. 用户登录案例 2.1 准备的对象和其功能 2.1.1 User 2.1.2 UserController 2.1.3 UserService 2.1.4 UserDao 2.1.5 AppConfig 2.1.6 DemoApplication 2.2 各对象之间的依赖关系 2.3 IOC 带来的一个好处 3. Spring 中的日志打印 3.1 Spring 官方提供的方式 3.2 lombok 提供的方法 3.2 日志打印级别 3.3 修改当前日志级别
108 0
|
XML 开发框架 Java
《Spring核心技术》开篇:我要带你一步步调试Spring6.0源码啦!
沉淀,成长,突破,帮助他人,成就自我。
368 0
《Spring核心技术》开篇:我要带你一步步调试Spring6.0源码啦!
|
Java 测试技术 开发工具
小白都能听懂的spring boot自动化配置原理
spring boot最核心的特性就是他的自动化配置特性,极大的减少了构建一个spring web工程的工作量。那么你知道spring boot自动化配置的原理吗?
185 0
小白都能听懂的spring boot自动化配置原理
|
Java 开发工具 git
Spring 源码阅读环境的搭建
本文记录了 Spring 源码环境的搭建方式,以及踩过的那些坑!当前版本:5.3.2-SNAPSHOT。
380 0
下一篇
DataWorks