1821349743@qq.com
2023-02-20 6bc78be53ddf8a6474ea71477fbc9e92149d7938
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package com.product.file.util;
 
import com.alibaba.druid.util.StringUtils;
import com.product.core.config.Global;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.file.config.FileCode;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager;
 
import java.io.File;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
 
/**
 * Copyright © 6c
 * @Date: 2021-03-01 13:59
 * @Author: 6c
 * @Description:
 */
public class PdfConcurrenceUtil {
 
    private static BlockingQueue<OfficeManager> officeManagerQueue = new LinkedBlockingQueue<>();
 
    // 安装地址
    private static String openOfficeHome;
    // 端口号信息,逗号分割
    private static String portInfo;
    // 单个任务执行超时时间,单位:毫秒
    private static long taskTimeout;
    // 单个任务排队超时时间,单位:毫秒
    private static long queueTimeout;
 
    static {
        SpringMVCContextHolder.getSystemLogger().info("初始化->");
        init();
    }
 
    private PdfConcurrenceUtil() {}
 
    /**
     * 初始化转换服务
     */
    public static void init() {
        SpringMVCContextHolder.getSystemLogger().info("初始化转换服务->");
        openOfficeHome = Global.getSystemConfig("open.office.home","");
        portInfo = Global.getSystemConfig("open.office.port.info","");
        taskTimeout = StringUtils.isEmpty(Global.getSystemConfig("open.office.task.timeout","")) ? 1000 * 60 *5 : Long.parseLong(Global.getSystemConfig("open.office.task.timeout",""));
        queueTimeout = StringUtils.isEmpty(Global.getSystemConfig("open.office.queue.timeout","")) ? 1000 * 60 *5 : Long.parseLong(Global.getSystemConfig("open.office.queue.timeout",""));
 
        String[] portArr = portInfo.split(",");
        for (String port : portArr) {
            if (StringUtils.isEmpty(port)) {
                continue;
            }
            try {
                OfficeManager officeManager = start(Integer.parseInt(port));
                if (officeManager != null) {
                    officeManagerQueue.put(officeManager);
                } else {
                    SpringMVCContextHolder.getSystemLogger().error(String.format("端口%s启动失败", port));
                }
            } catch (InterruptedException e) {
                SpringMVCContextHolder.getSystemLogger().error(String.format("%s,port:%s", FileCode.INIT_TRANSFER_SERVER_FAIL.getText(), port) +  e.getMessage());
            }
        }
        SpringMVCContextHolder.getSystemLogger().info("当前转换队列中端口数:" + officeManagerQueue.size());
    }
 
    /**
     * 开启新的openoffice的进程
     * @param port
     * @return
     */
    private static OfficeManager start(int port) {
        try {
            SpringMVCContextHolder.getSystemLogger().info("curPort: " + port);
            OfficeManager officeManager = reconnect(port);
            if (officeManager == null) {
                DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
                configuration.setOfficeHome(openOfficeHome);
                configuration.setPortNumbers(port);
                configuration.setTaskExecutionTimeout(taskTimeout);
                configuration.setTaskQueueTimeout(queueTimeout);
                SpringMVCContextHolder.getSystemLogger().info( "1.启动"+port);
                officeManager = configuration.buildOfficeManager();
                SpringMVCContextHolder.getSystemLogger().info("2.启动"+port);
                officeManager.start(); // 启动服务
                SpringMVCContextHolder.getSystemLogger().info( "3.启动成功"+ port);
            }
            return officeManager;
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(String.format("%s:%s", FileCode.INIT_TRANSFER_SERVER_FAIL.getText(), port) + e.getMessage());
        }
        return null;
    }
 
    /**
     * 尝试连接openoffice的已存在的服务器
     * @param port
     * @return
     */
    private static OfficeManager reconnect(int port) {
        try {
            ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
            externalProcessOfficeManager.setConnectOnStart(true);
            externalProcessOfficeManager.setPortNumber(port);
            OfficeManager officeManager = externalProcessOfficeManager.buildOfficeManager();
            officeManager.start();
            return officeManager;
        } catch (OfficeException e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().info(String.format("%s,port:%s", FileCode.NO_EXISTS_TRANSFER_PORT.getText(), port));
            return null;
        }
    }
 
    /**
     * 销毁进程
     */
    private static void destory() {
        for (OfficeManager officeManager : officeManagerQueue) {
            stop(officeManager);
        }
    }
 
    /**
     * 使用完需要关闭该进程
     * @param officeManager
     */
    private static void stop(OfficeManager officeManager) {
        SpringMVCContextHolder.getSystemLogger().info("关闭OpenOffice服务");
        try {
            if (officeManager != null)
                officeManager.stop();
        } catch (Exception e) {
            SpringMVCContextHolder.getSystemLogger().error("关闭OpenOffice服务出错" + e);
        }
    }
 
    /**
     * 转换pdf
     * @param input
     * @param output
     * @return
     */
    public static File convertToPdf(String input, String output) {
        File inputFile = null;
        File outFile = null;
        OfficeManager officeManager = null;
        try {
            SpringMVCContextHolder.getSystemLogger().info("从队列中提取转换端口...");
            officeManager = officeManagerQueue.take();
            inputFile = new File(input);
            outFile = new File(output);
            SpringMVCContextHolder.getSystemLogger().info("开始转换文档:" + input + "=>" + output);
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            converter.convert(inputFile, outFile); // 转换文档
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error("转换文档出错" + e);
            outFile = null;
        } finally {
            SpringMVCContextHolder.getSystemLogger().info("结束转换文档");
            if (officeManager != null) {
                try {
                    officeManagerQueue.put(officeManager);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return outFile;
    }
}