1. openoffice下载
2. pom.xml
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.4.2</version>
</dependency>
<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>
3. application.yml
# 上传文件存放路径
file-path: ~/tmp/
# openoffice文档转换配置
jodconverter:
local:
enabled: true
max-tasks-per-process: 10 # 进程重启前的最大进程数
existing-process-action: CONNECT_OR_KILL
# office-home: D:\OpenOffice # OpenOffice本地安装路径
# port-numbers: 9100 # 开启多个进程,每个端口对应一个进程
4. service层
package com.example.common.service.impl;
import cn.afterturn.easypoi.word.WordExportUtil;
import cn.afterturn.easypoi.word.entity.MyXWPFDocument;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.entity.SysFile;
import com.example.common.mapper.SysFileMapper;
import com.example.common.service.SysFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {
@Value("${file-path}")
private String basePath;
@Autowired(required = false)
private DocumentConverter converter;
private String getPath(String fileId, String fileName) {
return String.format("%s%s%s%s", StrUtil.addSuffixIfNot(basePath, File.separator), fileId, StrUtil.DOT, FileUtil.extName(fileName));
}
private String getFilePath(String fileId, String fileName) {
return String.format("%s%s%s", fileId, StrUtil.DOT, FileUtil.extName(fileName));
}
/**
* word转pdf
* @param templates 模版地址 templates/xxx.docx -- 模板需要填充的字段书写格式{{id}}
* @param data 数据
* @return
*/
@Override
public SysFile convertToPdf(String templates, Map<String, Object> data) {
String fileId = IdWorker.getIdStr(); //mybatisplus生成唯一id
try (
//这里面是放会出异常的代码
/*
* getClass(): 获得当前对象所属的Class对象
* getClassLoader(): 获得加载当前类的类加载器对象ClassLoader, 用来加载classpath下的.class文件
* getResourceAsStream(String [相对路径]): 从当前类的当前位置开始查找资源文件, 获得文件的输入流(通过当前的ClassLoader的getResource()方法查找指定文件)
* */
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/" + templates); //name: 资源的类路径,相对与"/"根路径下的位置。
/*
* 新建文档doc
* */
XWPFDocument doc = new MyXWPFDocument(inputStream);
/*
* FileUtil.file(path): return null == path ? null : new File(getAbsolutePath(path));
* */
FileOutputStream fos = new FileOutputStream(FileUtil.file(getPath(fileId, fileId + ".docx"))) //输出流
) {
/*
* 填充文档doc
* */
WordExportUtil.exportWord07(doc, data);
/*
* 把文档doc输出到输出流
* */
doc.write(fos);
File pdfFile = FileUtil.file(getPath(fileId, fileId + ".pdf"));
File docFile = FileUtil.file(getPath(fileId, fileId + ".docx"));
/*
* word转pdf
* */
converter.convert(docFile)
.to(pdfFile)
.as(DefaultDocumentFormatRegistry.PDF)
.execute();
log.info("文档转换,pdf地址:{},world地址:{}", pdfFile, docFile);
/*
* 把路径保存到数据库
* */
SysFile sysFile = new SysFile(fileId + ".pdf", "application/pdf", pdfFile.length());
sysFile.setPath(getFilePath(fileId, pdfFile.getName()));
sysFile.setId(fileId);
super.save(sysFile);
return sysFile;
} catch (Exception e) {
log.error("文件转换失败:", e);
}
return null;
}
}