JodConverter 4.1.0 + OpenOffice 4.1.5+Springboot在windows和Linux CentOS 7,解决乱码问题

最近项目需要在线预览功能,所有临阵磨枪,去上网查找了资料,用office转pdf,然后通过pdf.js展示,期间出过大大小小的问题,通过查找资料解决了,试了两种解决方案:

1、第一种是SaveAsPDFandXPS.exe+jacob,但是不是跨平台的,服务器是Linux环境,所有只好换了下面方法;

2、第二种是OpenOffice+JodConverter,这个是跨平台,可以在Linux环境使用;

好了,开始行动吧。

一、引入manven配置


    		org.jodconverter
    		jodconverter-core
    		4.1.0
		
		
    		org.jodconverter
    		jodconverter-local
    		4.1.0
		
		
    		org.jodconverter
    		jodconverter-spring-boot-starter
    		4.1.0
		
		
		    org.libreoffice
		    juh
		    5.4.2
		
		
		    org.libreoffice
		    jurt
		    5.4.2
		
		
		    org.libreoffice
		    ridl
		    5.4.2
		
		
		    org.libreoffice
		    unoil
		    5.4.2
		
		

二、application.properties 配置如下:

jodconverter.enabled=true
jodconverter.portNumbers=8100, 8101, 8102, 8103, 8104, 8105, 8106, 8107, 8108, 8109
jodconverter.maxTasksPerProcess=10

三、java 代码

@Configuration
@ConditionalOnClass({DocumentConverter.class})
@ConditionalOnProperty(
    prefix = "jodconverter",
    name = {"enabled"},
    havingValue = "true",
    matchIfMissing = false
)
@EnableConfigurationProperties({JodConverterProperties.class})
public class JodConverterAutoConfiguration  {

	private JodConverterProperties properties;

    public JodConverterAutoConfiguration(JodConverterProperties properties) {
        this.properties = properties;
    }

	private OfficeManager createOfficeManager() {
        Builder builder = LocalOfficeManager.builder();
        if (!StringUtil.isBlank(this.properties.getPortNumbers())) {
            Set iports = new HashSet();
            String[] var3 = StringUtils.split(this.properties.getPortNumbers(), ", ");
            int var4 = var3.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String portNumber = var3[var5];
                iports.add(NumberUtils.toInt(portNumber, 2002));
            }

            builder.portNumbers(ArrayUtils.toPrimitive((Integer[])iports.toArray(new Integer[iports.size()])));
        }
        String officeHome = LocalOfficeUtils.getDefaultOfficeHome().getPath();
        builder.officeHome(officeHome);
        //builder.officeHome(this.properties.getOfficeHome());
        builder.workingDir(this.properties.getWorkingDir());
        builder.templateProfileDir(this.properties.getTemplateProfileDir());
        builder.killExistingProcess(this.properties.isKillExistingProcess());
        builder.processTimeout(this.properties.getProcessTimeout());
        builder.processRetryInterval(this.properties.getProcessRetryInterval());
        builder.taskExecutionTimeout(this.properties.getTaskExecutionTimeout());
        builder.maxTasksPerProcess(this.properties.getMaxTasksPerProcess());
        builder.taskQueueTimeout(this.properties.getTaskQueueTimeout());
        return builder.build();
    }

    @Bean(
        initMethod = "start",
        destroyMethod = "stop"
    )
    @ConditionalOnMissingBean
    public OfficeManager officeManager() {
        return this.createOfficeManager();
        //return null;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({OfficeManager.class})
    public DocumentConverter jodConverter(OfficeManager officeManager) {
        return LocalConverter.make(officeManager);
        //return null;
    }
}
@ConfigurationProperties("jodconverter")
public class JodConverterProperties {
    private boolean enabled;
    private String officeHome;
    private String portNumbers = "2002";
    private String workingDir;
    private String templateProfileDir;
    private boolean killExistingProcess = true;
    private long processTimeout = 120000L;
    private long processRetryInterval = 250L;
    private long taskExecutionTimeout = 120000L;
    private int maxTasksPerProcess = 200;
    private long taskQueueTimeout = 30000L;

    public JodConverterProperties() {
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getOfficeHome() {
        return this.officeHome;
    }

    public void setOfficeHome(String officeHome) {
        this.officeHome = officeHome;
    }

    public String getPortNumbers() {
        return this.portNumbers;
    }

    public void setPortNumbers(String portNumbers) {
        this.portNumbers = portNumbers;
    }

    public String getWorkingDir() {
        return this.workingDir;
    }

    public void setWorkingDir(String workingDir) {
        this.workingDir = workingDir;
    }

    public String getTemplateProfileDir() {
        return this.templateProfileDir;
    }

    public void setTemplateProfileDir(String templateProfileDir) {
        this.templateProfileDir = templateProfileDir;
    }

    public boolean isKillExistingProcess() {
        return this.killExistingProcess;
    }

    public void setKillExistingProcess(boolean killExistingProcess) {
        this.killExistingProcess = killExistingProcess;
    }

    public long getProcessTimeout() {
        return this.processTimeout;
    }

    public void setProcessTimeout(long processTimeout) {
        this.processTimeout = processTimeout;
    }

    public long getProcessRetryInterval() {
        return this.processRetryInterval;
    }

    public void setProcessRetryInterval(long procesRetryInterval) {
        this.processRetryInterval = procesRetryInterval;
    }

    public long getTaskExecutionTimeout() {
        return this.taskExecutionTimeout;
    }

    public void setTaskExecutionTimeout(long taskExecutionTimeout) {
        this.taskExecutionTimeout = taskExecutionTimeout;
    }

    public int getMaxTasksPerProcess() {
        return this.maxTasksPerProcess;
    }

    public void setMaxTasksPerProcess(int maxTasksPerProcess) {
        this.maxTasksPerProcess = maxTasksPerProcess;
    }

    public long getTaskQueueTimeout() {
        return this.taskQueueTimeout;
    }

    public void setTaskQueueTimeout(long taskQueueTimeout) {
        this.taskQueueTimeout = taskQueueTimeout;
    }
}

在这期间出现一个奇怪的问题,本来我是在application配置文件配置了openoffice服务安装路径的,但是我启动的时候老是报错,百度了也没有找到问题,最后在GitHub找到了解决办法https://github.com/sbraconnier/jodconverter,通过jar包本身自带的方法,

LocalOfficeUtils.getDefaultOfficeHome().getPath();获取服务路径,项目可以启动了。

四、在业务层引入DocumentConverter

@Autowired
private DocumentConverter documentConverter;


转换代码
File outFile = new File(outPath);//pdf目标文件
File file = new File(fullFileName);//源文件
in = new FileInputStream(file);
try{
	if("doc".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.DOC).to(outFile).execute();
	}else if("docx".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.DOCX).to(outFile).execute();
    }else if("ppt".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.PPT).to(outFile).execute();
	}else if("pptx".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.PPTX).to(outFile).execute();
	}else if("xls".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.XLS).to(outFile).execute();
	}else if("xlsx".equals(fname.toLowerCase())){
	documentConverter.convert(in).as(DefaultDocumentFormatRegistry.XLSX).to(outFile).execute();
	}else if("txt".equals(fname.toLowerCase())){
		//因为会出现中文乱码问题,所以先通过字符流进行编码转换,再转换成字节流
		bis = new BufferedReader(new InputStreamReader(in,"GBK"));
		StringBuffer buf=new StringBuffer();
		String temp;
		while ((temp = bis.readLine()) != null) {
			buf.append(temp).append(System.getProperty("line.separator"));
		}
		is = new ByteArrayInputStream(buf.toString().getBytes());
	documentConverter.convert(is).as(DefaultDocumentFormatRegistry.TXT).to(outFile).execute();
	}
	return "成功";
}catch (OfficeException e) {
	return "失败";
}

因为我本人是windows环境下开发,但是发布到Linux系统就出了问题,在Linux下安装好openOffice服务后,项目跑不起来,自己配置好的服务路径读取不到,网上都是配置的,但是我的不行,没找到原因,去看源代码,发现在LocalOfficeUtils下没有openoffice4的路径:

JodConverter 4.1.0 + OpenOffice 4.1.5+Springboot在windows和Linux CentOS 7,解决乱码问题_第1张图片

然后我去下载了LocalOfficeUtils.java这个类,在里面添加了一行,发现可以启动服务了

JodConverter 4.1.0 + OpenOffice 4.1.5+Springboot在windows和Linux CentOS 7,解决乱码问题_第2张图片

最后在Linux文件夹/usr/share/fonts下添加字体,解决中文乱码,OK。

最后非常感谢这两位的博客:

https://blog.csdn.net/starboyss/article/details/78498974

https://segmentfault.com/a/1190000011657122

你可能感兴趣的:(JodConverter 4.1.0 + OpenOffice 4.1.5+Springboot在windows和Linux CentOS 7,解决乱码问题)