2020-12-26 02:31:34 +08:00
|
|
|
|
package cn.keking.service;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
|
|
|
|
|
|
import com.sun.star.document.UpdateDocMode;
|
2019-11-29 14:40:42 +08:00
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
|
|
|
|
|
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
|
|
|
|
|
import org.artofsolving.jodconverter.office.OfficeManager;
|
2019-04-15 10:23:03 +08:00
|
|
|
|
import org.artofsolving.jodconverter.office.OfficeUtils;
|
2019-11-21 17:00:07 +08:00
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
2021-03-12 21:32:01 +08:00
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
import org.springframework.boot.convert.DurationStyle;
|
2020-12-26 02:31:34 +08:00
|
|
|
|
import org.springframework.core.Ordered;
|
|
|
|
|
|
import org.springframework.core.annotation.Order;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
|
|
|
import javax.annotation.PreDestroy;
|
2019-11-21 17:00:07 +08:00
|
|
|
|
import java.io.ByteArrayOutputStream;
|
2020-05-15 18:09:19 +08:00
|
|
|
|
import java.io.File;
|
2019-11-21 17:00:07 +08:00
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
import java.io.InputStream;
|
2020-05-15 18:09:19 +08:00
|
|
|
|
import java.nio.charset.StandardCharsets;
|
2021-03-12 21:32:01 +08:00
|
|
|
|
import java.util.Arrays;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
|
import java.util.Map;
|
2019-11-21 17:00:07 +08:00
|
|
|
|
import java.util.Properties;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建文件转换器
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author yudian-it
|
|
|
|
|
|
* @date 2017/11/13
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Component
|
2020-12-26 02:31:34 +08:00
|
|
|
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
2020-12-26 19:13:50 +08:00
|
|
|
|
public class OfficePluginManager {
|
2018-01-17 14:10:40 +08:00
|
|
|
|
|
2020-12-26 19:13:50 +08:00
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(OfficePluginManager.class);
|
2019-11-21 17:00:07 +08:00
|
|
|
|
|
2020-05-14 10:11:15 +08:00
|
|
|
|
private OfficeManager officeManager;
|
2018-01-17 14:10:40 +08:00
|
|
|
|
|
2021-03-12 21:32:01 +08:00
|
|
|
|
@Value("${office.plugin.server.ports:2001,2002}")
|
|
|
|
|
|
private String serverPorts;
|
|
|
|
|
|
|
|
|
|
|
|
@Value("${office.plugin.task.timeout:5m}")
|
|
|
|
|
|
private String timeOut;
|
|
|
|
|
|
|
2020-12-26 02:31:34 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 启动Office组件进程
|
|
|
|
|
|
*/
|
2021-07-06 11:12:07 +08:00
|
|
|
|
@PostConstruct
|
|
|
|
|
|
public void startOfficeManager(){
|
2020-12-26 02:31:34 +08:00
|
|
|
|
File officeHome = OfficeUtils.getDefaultOfficeHome();
|
2019-11-21 17:00:07 +08:00
|
|
|
|
if (officeHome == null) {
|
|
|
|
|
|
throw new RuntimeException("找不到office组件,请确认'office.home'配置是否有误");
|
|
|
|
|
|
}
|
2020-05-15 18:09:19 +08:00
|
|
|
|
boolean killOffice = killProcess();
|
2019-11-21 17:00:07 +08:00
|
|
|
|
if (killOffice) {
|
|
|
|
|
|
logger.warn("检测到有正在运行的office进程,已自动结束该进程");
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
|
|
|
|
|
|
configuration.setOfficeHome(officeHome);
|
2021-03-12 21:32:01 +08:00
|
|
|
|
String []portsString = serverPorts.split(",");
|
|
|
|
|
|
|
|
|
|
|
|
int[] ports = Arrays.stream(portsString).mapToInt(Integer::parseInt).toArray();
|
|
|
|
|
|
|
|
|
|
|
|
configuration.setPortNumbers(ports);
|
|
|
|
|
|
long timeout = DurationStyle.detectAndParse(timeOut).toMillis();
|
2019-11-21 17:00:07 +08:00
|
|
|
|
// 设置任务执行超时为5分钟
|
2021-03-12 21:32:01 +08:00
|
|
|
|
configuration.setTaskExecutionTimeout(timeout);
|
2019-11-21 17:00:07 +08:00
|
|
|
|
// 设置任务队列超时为24小时
|
|
|
|
|
|
//configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
|
|
|
|
|
|
officeManager = configuration.buildOfficeManager();
|
|
|
|
|
|
officeManager.start();
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("启动office组件失败,请检查office组件是否可用");
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
}
|
2018-01-17 14:10:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public OfficeDocumentConverter getDocumentConverter() {
|
2020-12-27 14:06:06 +08:00
|
|
|
|
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new OfficePluginExtendFormatRegistry());
|
2018-01-17 14:10:40 +08:00
|
|
|
|
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);
|
2020-05-15 18:09:19 +08:00
|
|
|
|
loadProperties.put("CharacterSet", StandardCharsets.UTF_8.name());
|
2018-01-17 14:10:40 +08:00
|
|
|
|
return loadProperties;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-15 18:09:19 +08:00
|
|
|
|
private boolean killProcess() {
|
2019-11-21 17:00:07 +08:00
|
|
|
|
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();
|
2020-05-15 18:09:19 +08:00
|
|
|
|
byte[] b = new byte[256];
|
2019-11-21 17:00:07 +08:00
|
|
|
|
while (os.read(b) > 0) {
|
|
|
|
|
|
baos.write(b);
|
|
|
|
|
|
}
|
|
|
|
|
|
String s = baos.toString();
|
2020-05-15 18:09:19 +08:00
|
|
|
|
if (s.contains("soffice.bin")) {
|
|
|
|
|
|
Runtime.getRuntime().exec("taskkill /im " + "soffice.bin" + " /f");
|
2019-11-21 17:00:07 +08:00
|
|
|
|
flag = true;
|
|
|
|
|
|
}
|
2019-11-29 14:40:42 +08:00
|
|
|
|
} else {
|
2020-05-15 18:09:19 +08:00
|
|
|
|
Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","ps -ef | grep " + "soffice.bin"});
|
2019-11-21 17:00:07 +08:00
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
|
|
InputStream os = p.getInputStream();
|
2020-05-15 18:09:19 +08:00
|
|
|
|
byte[] b = new byte[256];
|
2019-11-21 17:00:07 +08:00
|
|
|
|
while (os.read(b) > 0) {
|
|
|
|
|
|
baos.write(b);
|
|
|
|
|
|
}
|
|
|
|
|
|
String s = baos.toString();
|
2020-05-15 18:09:19 +08:00
|
|
|
|
if (StringUtils.ordinalIndexOf(s, "soffice.bin", 3) > 0) {
|
|
|
|
|
|
String[] cmd ={"sh","-c","kill -15 `ps -ef|grep " + "soffice.bin" + "|awk 'NR==1{print $2}'`"};
|
2019-11-21 17:00:07 +08:00
|
|
|
|
Runtime.getRuntime().exec(cmd);
|
|
|
|
|
|
flag = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
logger.error("检测office进程异常", e);
|
|
|
|
|
|
}
|
|
|
|
|
|
return flag;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-17 14:10:40 +08:00
|
|
|
|
@PreDestroy
|
|
|
|
|
|
public void destroyOfficeManager(){
|
|
|
|
|
|
if (null != officeManager && officeManager.isRunning()) {
|
2021-07-06 09:10:19 +08:00
|
|
|
|
logger.info("Shutting down office process");
|
2018-01-17 14:10:40 +08:00
|
|
|
|
officeManager.stop();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|