一、环境介绍

  1. java
  2. libreoffice 6.3
  3. springboot整合开发

二、代码实现

  1. pom文件依赖
    在pom文件中添加项目依赖:
<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-core -->
<dependency>
    <groupId>org.jodconverter</groupId>
    <artifactId>jodconverter-core</artifactId>
    <version>4.0.0-RELEASE</version>
</dependency>
  1. 关键代码

注意修改libreoffice安装路径,linux默认在/opt/libreoffice6.3;windows根据自定义安装地址确定

package com.chenlei.worddemo.util;
import org.jodconverter.OfficeDocumentConverter;
import org.jodconverter.office.DefaultOfficeManagerBuilder;
import org.jodconverter.office.OfficeException;
import org.jodconverter.office.OfficeManager;

import java.io.File;
import java.util.regex.Pattern;

public  class Office2PDF {
    //文件转换pdf成功后保存的地址
    private static  String SAVE_PATH = "/home/";
    private Office2PDF(){}
 
    /**
     * 将office格式的文件转为pdf
     * @param sourceFilePath 源文件路径
     * @return
     */
    public static   File openOfficeToPDF(String sourceFilePath){
        return office2pdf(sourceFilePath);
    }

    /**
     * 将office文档转换为pdf文档
     * @param sourceFilePath 原文件路径
     * @return
     */
    public static   File office2pdf(String sourceFilePath){
        OfficeManager officeManager = null;
        try{
            if(StringUtil.isEmpty(sourceFilePath))
            {
                //打印日志...
                return null;
            }
            File sourceFile = new File(sourceFilePath);
            if(!sourceFile.exists())
            {
                //打印日志...
                return null;
            }

            String after_convert_file_path = getAfterConverFilePath(sourceFilePath);
            //启动openOffice
            officeManager = getOfficeManager();
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            return convertFile(sourceFile,after_convert_file_path,sourceFilePath,converter);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("转换异常");
        }finally {
           if(officeManager != null){
               try {
                   officeManager.stop();
               } catch (OfficeException e) {
                   e.printStackTrace();
               }
           }
        }
        return null;
    }

    /**
     * 转换文件
     * @param sourceFile 原文件
     * @param after_convert_file_path 转换后存放位置
     * @param sourceFilePath 原文件路径
     * @param converter 转换器
     * @return
     */
    public static File convertFile(File sourceFile,
                           String after_convert_file_path,String sourceFilePath,OfficeDocumentConverter converter) throws OfficeException {
        File outputFile = new File(after_convert_file_path);
        if(!outputFile.getParentFile().exists()){
            //如果上级目录不存在也就是E:/pdfFile这个文件夹不存在则创建一个
            outputFile.getParentFile().mkdirs();
        }
            converter.convert(sourceFile,outputFile);
        return outputFile;
    }

    public static OfficeManager getOfficeManager(){
        DefaultOfficeManagerBuilder builder = new DefaultOfficeManagerBuilder();
        builder.setOfficeHome(getOfficeHome());
        OfficeManager officeManager = builder.build();
        try {
            officeManager.start();
        } catch (OfficeException e) {
            //打印日志
            System.out.println("start openOffice Fail!");
            e.printStackTrace();
        }
        return officeManager;
    }

    /**
     * 获取转换后文件存放的路径
     * @param sourceFilePath 源文件
     * @return
     */
    public static   String getAfterConverFilePath(String sourceFilePath){
        //截取源文件文件名
        String sourceFileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1);
        return SAVE_PATH + sourceFileName.replaceAll("\\."+FileUtil.getFileSuffix(sourceFileName),".pdf");
    }

    /**
     * 获取libreOffice的安装目录
	 * 支持windows、linux、mac等系统
     * @return
     */
    public static String getOfficeHome(){
        String osName = System.getProperty("os.name");
        if(Pattern.matches("Windows.*",osName))
        {
            return "D:/Program Files/LibreOffice";
        }
        else if(Pattern.matches("Linux.*",osName))
        {
            return "/opt/libreoffice6.3";
        }
        else if (Pattern.matches("Mac.*",osName))
        {
            return "/Application/libreOfficeSoft";
        }
        return null;
    }
}
  1. 代码示例地址
    码云.
    GitHub.

三、部署(docker)

  1. 下载libreoffice包
    官网地址
  2. 下载两个包:

a. 安装包 LibreOffice_6.3.2_Linux_x86-64_rpm.tar.gz
b. 用户界面语言包 LibreOffice_6.3.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz

  1. 下载java环境jdk
    官网地址
  2. 下载一个包:

a. linux系统安装包 jdk-8u221-linux-x64.tar.gz

  1. 编写Dockerfile

先将下载的包导入linux任意文件夹暂存并在目标文件夹创建Dockerfile

  1. Dockerfile文件内容
#基于centos7版本镜像
FROM centos:7
	 
#以下设置中文语言环境与修改时区
ENV LANG=zh_CN.UTF-8 \
	LANGUAGE=zh_CN:zh \
	LC_ALL=zh_CN.UTF-8
RUN yum update -y && \
	yum reinstall -y glibc-common && \
	yum install -y telnet net-tools && \
	yum clean all && \
	rm -rf /tmp/* rm -rf /var/cache/yum/* && \
	localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 && \
	ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
	 
#加入windows字体包
ADD chinese.tar.gz /usr/share/fonts/
	 
#将下载好的包解压到相应文件下
ADD LibreOffice_6.3.2_Linux_x86-64_rpm.tar.gz /home/
ADD LibreOffice_6.3.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz /usr/
	 
#执行安装
RUN cd /home/LibreOffice_6.3.2.2_Linux_x86-64_rpm/RPMS/ \
	&& yum localinstall *.rpm -y \
	&& cd /usr/LibreOffice_6.3.2.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/   \
	&& yum localinstall *.rpm -y \
	 
	#安装依赖
	&& yum install ibus -y \
		  
	#加入中文字体支持并赋权限
	&& cd /usr/share/fonts/ \
	&& chmod -R 755 /usr/share/fonts \
	&& yum install mkfontscale -y \
	&& mkfontscale \
	&& yum install fontconfig -y \
	&& mkfontdir \
	&& fc-cache -fv \
	&& mkdir /usr/local/java/ \
	 
	#清理缓存,减少镜像大小
	&& yum clean all
	 
#加入安装java环境
ADD jdk-8u221-linux-x64.tar.gz /usr/local/java/
RUN ln -s /usr/local/java/jdk1.8.0_221 /usr/local/java/jdk
	 
#配置环境变量
ENV JAVA_HOME /usr/local/java/jdk
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH
CMD ["bash"]

构建libreoffice镜像

docker build -t libreoffice:v1 .

项目打包部署

a. 将项目打包成jar包导入linux任意文件夹
b. 在jar包所在文件夹编写Dockerfile文件,制作运行环境镜像,以刚刚制作的libreoffice:v1为基础镜像

FROM libreoffice:v1
#将jar包添加到容器
WORKDIR app
ADD resume.jar  /app/app.jar
#暴露端口
EXPOSE 8080	 
#运行
CMD java -jar /app/app.jar

构建项目运行环境镜像

docker build -t worddemo:v1 .

四、运行测试

  1. 运行
docker run -d -p 8080:8080 -v /home/:/home/ worddemo:v1

-v /home/:/home/: 表示文件挂载在宿主机/home文件夹下,方便文件测试;
浏览器访问主机8080端口。

五、总结

  1. 踩坑记录
    a. 制作libreoffice镜像时没有完整添加环境依赖
yum install ibus -y \

b. 文件转换出现中文乱码或无法转换中文

进入windows系统下的 C:\Windows\Fonts 目录下,搜索简体列出所有字体包,将所有字体打包上传到linux;加入字体后千万记住授予权限,当执行 mkfontscale 和 mkfontdir 授权的时候报错,一定先进行安装,且 mkfontscale 在 mkfontdir之前执行。

#加入windows字体包
ADD chinese.tar.gz /usr/share/fonts/
#加入中文字体支持并赋权限
&& cd /usr/share/fonts/ \
&& chmod -R 755 /usr/share/fonts \
&& yum install mkfontscale -y \
&& mkfontscale \
&& yum install fontconfig -y \
&& mkfontdir \
&& fc-cache -fv \

c. 镜像不支持中文环境且时区错乱导致中文文件名乱码

原始CentorOs不支持中文环境且默认时区不是国内时区,进行了以下配置安装

#以下设置中文语言环境与修改时区
ENV LANG=zh_CN.UTF-8 \
	LANGUAGE=zh_CN:zh \
	LC_ALL=zh_CN.UTF-8
RUN yum update -y && \
	yum reinstall -y glibc-common && \
	yum install -y telnet net-tools && \
	yum clean all && \
	rm -rf /tmp/* rm -rf /var/cache/yum/* && \
	localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 && \
	ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  1. openoffice介绍
    a. 与libreoffice对比

libreoffice

openoffice

转换较慢,大文件libreoffice转换快

小文件转换速度快

支持命令行和java代码

只支持java代码操作

不支持,同时转换一个文件会出现soffice卡死

支持队列转换

b. 使用openOffice(Linux版)实现word并发多进程word文档转换文档预览