Office组件启动异步化,提速应用启动速度到5秒内

This commit is contained in:
chenkailing
2020-12-26 02:31:34 +08:00
committed by kl
parent 01218e4a5c
commit 37c37868a3
3 changed files with 25 additions and 16 deletions

View File

@@ -0,0 +1,134 @@
package cn.keking.service;
import com.sun.star.document.UpdateDocMode;
import cn.keking.extend.ControlDocumentFormatRegistry;
import org.apache.commons.lang3.StringUtils;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 创建文件转换器
*
* @author yudian-it
* @date 2017/11/13
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OfficeProcessManager {
private final Logger logger = LoggerFactory.getLogger(OfficeProcessManager.class);
private OfficeManager officeManager;
@PostConstruct
public void initOfficeManager() {
new Thread(this::startOfficeManager).start();
}
/**
* 启动Office组件进程
*/
private void startOfficeManager(){
File officeHome = OfficeUtils.getDefaultOfficeHome();
if (officeHome == null) {
throw new RuntimeException("找不到office组件请确认'office.home'配置是否有误");
}
boolean killOffice = killProcess();
if (killOffice) {
logger.warn("检测到有正在运行的office进程已自动结束该进程");
}
try {
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
configuration.setOfficeHome(officeHome);
configuration.setPortNumber(8100);
// 设置任务执行超时为5分钟
configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
// 设置任务队列超时为24小时
//configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
officeManager = configuration.buildOfficeManager();
officeManager.start();
} catch (Exception e) {
logger.error("启动office组件失败请检查office组件是否可用");
throw e;
}
}
public OfficeDocumentConverter getDocumentConverter() {
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new ControlDocumentFormatRegistry());
converter.setDefaultLoadProperties(getLoadProperties());
return converter;
}
private Map<String,?> getLoadProperties() {
Map<String,Object> loadProperties = new HashMap<>(10);
loadProperties.put("Hidden", true);
loadProperties.put("ReadOnly", true);
loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE);
loadProperties.put("CharacterSet", StandardCharsets.UTF_8.name());
return loadProperties;
}
private boolean killProcess() {
boolean flag = false;
Properties props = System.getProperties();
try {
if (props.getProperty("os.name").toLowerCase().contains("windows")) {
Process p = Runtime.getRuntime().exec("cmd /c tasklist ");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
byte[] b = new byte[256];
while (os.read(b) > 0) {
baos.write(b);
}
String s = baos.toString();
if (s.contains("soffice.bin")) {
Runtime.getRuntime().exec("taskkill /im " + "soffice.bin" + " /f");
flag = true;
}
} else {
Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","ps -ef | grep " + "soffice.bin"});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
byte[] b = new byte[256];
while (os.read(b) > 0) {
baos.write(b);
}
String s = baos.toString();
if (StringUtils.ordinalIndexOf(s, "soffice.bin", 3) > 0) {
String[] cmd ={"sh","-c","kill -15 `ps -ef|grep " + "soffice.bin" + "|awk 'NR==1{print $2}'`"};
Runtime.getRuntime().exec(cmd);
flag = true;
}
}
} catch (IOException e) {
logger.error("检测office进程异常", e);
}
return flag;
}
@PreDestroy
public void destroyOfficeManager(){
if (null != officeManager && officeManager.isRunning()) {
officeManager.stop();
}
}
}

View File

@@ -0,0 +1,64 @@
package cn.keking.service;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.springframework.stereotype.Component;
import java.io.File;
/**
* @author yudian-it
*/
@Component
public class OfficeToPdfService {
private final OfficeProcessManager officeProcessManager;
public OfficeToPdfService(OfficeProcessManager officeProcessManager) {
this.officeProcessManager = officeProcessManager;
}
public void openOfficeToPDF(String inputFilePath, String outputFilePath) {
office2pdf(inputFilePath, outputFilePath);
}
public static void converterFile(File inputFile, String outputFilePath_end,
OfficeDocumentConverter converter) {
File outputFile = new File(outputFilePath_end);
// 假如目标路径不存在,则新建该路径
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
converter.convert(inputFile, outputFile);
}
public void office2pdf(String inputFilePath, String outputFilePath) {
OfficeDocumentConverter converter = officeProcessManager.getDocumentConverter();
if (null != inputFilePath) {
File inputFile = new File(inputFilePath);
// 判断目标文件路径是否为空
if (null == outputFilePath) {
// 转换后的文件路径
String outputFilePath_end = getOutputFilePath(inputFilePath);
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath_end,converter);
}
} else {
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath, converter);
}
}
}
}
public static String getOutputFilePath(String inputFilePath) {
return inputFilePath.replaceAll("."+ getPostfix(inputFilePath), ".pdf");
}
public static String getPostfix(String inputFilePath) {
return inputFilePath.substring(inputFilePath.lastIndexOf(".") + 1);
}
}

View File

@@ -6,7 +6,7 @@ import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileUtils;
import cn.keking.utils.OfficeToPdf;
import cn.keking.service.OfficeToPdfService;
import cn.keking.utils.PdfUtils;
import cn.keking.web.filter.BaseUrlFilter;
import org.springframework.stereotype.Service;
@@ -25,13 +25,13 @@ public class OfficeFilePreviewImpl implements FilePreview {
private final FileUtils fileUtils;
private final PdfUtils pdfUtils;
private final DownloadUtils downloadUtils;
private final OfficeToPdf officeToPdf;
private final OfficeToPdfService officeToPdfService;
public OfficeFilePreviewImpl(FileUtils fileUtils, PdfUtils pdfUtils, DownloadUtils downloadUtils, OfficeToPdf officeToPdf) {
public OfficeFilePreviewImpl(FileUtils fileUtils, PdfUtils pdfUtils, DownloadUtils downloadUtils, OfficeToPdfService officeToPdfService) {
this.fileUtils = fileUtils;
this.pdfUtils = pdfUtils;
this.downloadUtils = downloadUtils;
this.officeToPdf = officeToPdf;
this.officeToPdfService = officeToPdfService;
}
public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
@@ -59,7 +59,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
}
filePath = response.getContent();
if (StringUtils.hasText(outFilePath)) {
officeToPdf.openOfficeToPDF(filePath, outFilePath);
officeToPdfService.openOfficeToPDF(filePath, outFilePath);
if (isHtml) {
// 对转换后的文件进行操作(改变编码方式)
fileUtils.doActionConvertedFile(outFilePath);