文章目录

一、基础对比
1.版本对比

03版本office

07版本及高版本office

.doc

.docx

.xls

.xlsx

.ppt

.pptx

2.异常现象

搭建好 SpringBoot + OpenOffice + jodconverter2.2.1 后,转换07版本及高版本(.docx/.xlsx/.pptx)时,转换 docx、xlsx、pptx 时报了以下错误:

SocketOpenOfficeConnection : connected
java.lang.IllegalArgumentException: inputFormat is null at com.artofsolving.jodconverter.openoffice.converter.AbstractOpenOfficeDocumentConverter.ensureNotNull(AbstractOpenOfficeDocumentConverter.java:113)

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_java

二、分析定位
2.1. 找异常输出处

找到输出异常的代码处

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_抽象类_02


在AbstractOpenOfficeDocumentConverter 抽象类中的79行代码的convert方法处输出的异常

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_在线预览_03

2.2. 找异常源头

为什么会输出这个异常信息?

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_后缀名_04


从上图中可以看出由于​​inputFormat参数为null​​​,导致​​inputFormat is null​​ 校验异常,进一步分析,既然是由于参数为null触发的这个异常,那这个参数到底从获取的呢?对吧

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_后缀名_05


从上图中可以看出,这个类的第95行获取的对吧,那就好办了,进入源码,一探究竟。

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_在线预览_06


从图中可以看到​​BasicDocumentFormatRegistry​​​抽象类的​​getFormatByFileExtension​​方法,功能就是提供文件扩展名

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_后缀名_07


解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_后缀名_08


从上图可以看出,支持文件格式有21种,但是,咱们传入的文件类型xlsx、docx、pptx这3种格式,均不在这21种格式之内,因此,导致返回的​​sourceFormat​​​参数是​​null​

2.3. api源头

小伙伴们现在跟着我考虑以下二个问题哈?

问题1:
是由于以前默认提供了21种文件格式,不包括07版本及高版本的文件格式,但是,支持转换xlsx、docx、pptx文件格式的文件?

问题2:只支持默认的21种文件格式的文件转换呢?

下面小伙伴们跟着我一起来探究一下真相到底如何?
咱们先假设:预期结果问题1

那咱们又该如何解决呢?找源头

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_抽象类_09


从图中可以看出下面获取文件后缀名和​​DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry();​​有关系,是最开始的地方,对吧!进入源码一探究竟

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_抽象类_10


从山图中可以看出​​DefaultDocumentFormatRegistry​​​定义了默认支持的后缀名对吧。不仅如此,还​​extends BasicDocumentFormatRegistry​​​,进入​​BasicDocumentFormatRegistry​

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_抽象类_11


发现又回到了刚才获取文件后缀名的地方,对吧!

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_抽象类_12


这个校验是由于传入的文件类型,不在默认21种文件格式之内,才会被触发对吧?

咱们需要想个办法,让他跳过这个校验,既然默认提供的21种格式,又不能新增文件格式,能不能让咱们传入的格式在默认提供的21种格式之内呢?可以的

当传入的参数为xlsx、docx、pptx文件格式时,返回的对应的文件格式为xls、doc、ppt格式后缀名,就可实现了对吧!

三、实现流程
3.1. 思路

既然DefaultDocumentFormatRegistry继承BasicDocumentFormatRegistry类,那咱们就重写BasicDocumentFormatRegistry类,在判断后缀名之前对传入的文件后缀名做处理​​“返回的对应的文件格式为xls、doc、ppt格式后缀名”​

3.2. 新建包重写类

新建​​com.artofsolving.jodconverter​​​重写​​BasicDocumentFormatRegistry​​类

解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常_后缀名_13

3.3. 完整类
package com.artofsolving.jodconverter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* @description: 重写 BasicDocumentFormatRegistry 文档格式
* @Author: gblfy
* @Data: 2021-10-27
**/
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
*/
@Override
public 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;
}

@Override
public 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;
}
}