使用Openoffice实现并发多进程word文档转换预览

2 篇文章 0 订阅
2 篇文章 0 订阅

一、环境介绍

  1. java
  2. openoffice 4.1.6
  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>
    
  2. 关键代码

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

    package com.chenlei.worddemo.util;
    
    import java.io.*;
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    import java.util.regex.Pattern;
     
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
     
    import org.jodconverter.OfficeDocumentConverter;
    import org.jodconverter.office.DefaultOfficeManagerBuilder;
    import org.jodconverter.office.OfficeException;
    import org.jodconverter.office.OfficeManager;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
     
    /**
     * 利用jodconverter(基于OpenOffice服务)将文件(*.doc、*.docx、*.xls、*.ppt)转化为html格式或者pdf格式,
     * 使用前请检查OpenOffice服务是否已经开启, OpenOffice进程名称:soffice.exe | soffice.bin
     *
     * @author lcx
     */
    @Component
    public class Doc2HtmlUtil {
        @Value("${BASE_PATH}")
        private String BASE_PATH;
     
        @Value("${OPENOFFICE_PORT_STR}")
        private String portsStr;
     
        private static OfficeManager OfficeManager = null;
     
        private static Lock lock = new ReentrantLock();
     
        public BlockingQueue<OfficeManager> queue = new LinkedBlockingQueue<>();//这里用线程安全的queue管理运行的端口号
     
     /**
     * 获取openOffice的安装目录
     *
     * @return
     */
     public String getOfficeHome() {
            String osName = System.getProperty("os.name");
            if (Pattern.matches("Windows.*", osName)) {
                return "D:\\Program Files\\OpenOffice";
            } else if (Pattern.matches("Linux.*", osName)) {
                return "/opt/OpenOffice";
            } else if (Pattern.matches("Mac.*", osName)) {
                return "/Application/openOfficeSoft";
            }
            return null;
        }
     
        @PostConstruct
     public void initOpenOfficeService() {
            String[] ports = portsStr.split(",");
            DefaultOfficeManagerBuilder builder = new DefaultOfficeManagerBuilder();
            builder.setOfficeHome(getOfficeHome());
            for (String port : ports) {
                builder.setPortNumbers(Integer.parseInt(port));
                OfficeManager = builder.build();
                try {
                    OfficeManager.start();
                    System.out.println("##############officeManager start !");
                } catch (OfficeException e) {
                    //打印日志
     System.out.println("start openOffice Fail!");
                    e.printStackTrace();
                }
                try {
                    //都放入阻塞队列中
     queue.put(OfficeManager);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
     
        @PreDestroy
     public void destroyOpenOfficeService() {
            for (OfficeManager manager : queue) {
                try {
                    System.out.println("close all officeManager");
                    manager.stop();
                } catch (OfficeException e) {
                    System.out.println("officeManager stop fail!" + e.getMessage());
                    e.printStackTrace();
                }
            }
        }
     
        public String fileHandler(String fileName) throws ExecutionException, InterruptedException {
            String result = null;
            String fileSuffix = FileUtil.getFileSuffix(fileName);
            System.out.println(fileSuffix);
            if ("pdf".equals(fileSuffix)) {
                System.out.println("file is pdf type");
                result = BASE_PATH + fileName;
            }
            synchronized(this) {
                if (!new File(BASE_PATH + fileName.replaceAll("." + FileUtil.getFileSuffix(fileName), ".pdf")).exists()) {
                    System.out.println("file start conveted");
                    office2pdf(BASE_PATH + fileName, fileName);
                }
                result = BASE_PATH + fileName.replaceAll("." + FileUtil.getFileSuffix(fileName), ".pdf");
            }
            return result;
        }
     
        public void convertFile(File sourceFile,
                                String after_convert_file_path, OfficeManager officeManager) throws OfficeException {
            File outputFile = new File(after_convert_file_path);
            if (!outputFile.getParentFile().exists()) {
                //如果上级目录不存在也就是E:/pdfFile这个文件夹不存在则创建一个
     outputFile.getParentFile().mkdirs();
            }
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            if (new File(after_convert_file_path).exists()) {
                System.out.println("文件有了");
                return;
            }
            converter.convert(sourceFile, outputFile);
            try {
                queue.put(officeManager);
                System.out.println("blockingQueue puted OfficeManagerQueue size :" + queue.size());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
     
        public void office2pdf(String sourceFilePath,String fileName) {
            OfficeManager officeManager = null;
            File sourceFile = new File(sourceFilePath);
            try {
                if (StringUtil.isEmpty(sourceFilePath)) {
                    //打印日志...
     return;
                }
     
                if (!sourceFile.exists()) {
                    //打印日志...
     return;
                }
                officeManager = queue.take();
                System.out.println("blockingQueue taked , OfficeManagerQueue size :" + queue.size());
                convertFile(sourceFile, BASE_PATH + fileName.replaceAll("." + FileUtil.getFileSuffix(fileName), ".pdf"), officeManager);
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    queue.put(officeManager);
                    System.out.println("blockingQueue put , OfficeManagerQueue size :" + queue.size());
                } catch (InterruptedException e1) {
                    // lock.unlock();
     e1.printStackTrace();
                    return;
                }
                System.out.println("转换异常");
            }
        }
    }
    	
    

三、部署(docker)

  1. 下载openoffice包
    官网地址

  2. 下载两个包:

    a. 安装包 Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_zh-CN.tar.gz
    b. 用户界面语言包 Apache_OpenOffice_4.1.6_Linux_x86-64_langpack-rpm_zh-CN.tar.gz

  3. 下载java环境jdk
    官网地址

  4. 下载一个包:

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

  5. 编写Dockerfile

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

    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 Apache_OpenOffice_4.1.6_Linux_x86-64_install-rpm_zh-CN.tar.gz /home/
    ADD Apache_OpenOffice_4.1.6_Linux_x86-64_langpack-rpm_zh-CN.tar.gz /usr/
     
    #执行安装
    RUN cd /home/zh-CN/RPMS/ \
          && yum localinstall *.rpm -y \
          && cd /usr/zh-CN/RPMS/   \
          && yum localinstall *.rpm -y \
     
          #安装windows组件环境支持
          && yum install libXext.x86_64 -y \
          && cp -a /lib64/libXext.so.6 /opt/openoffice4/program/ \
          && yum groupinstall "X Window System" -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 openoffice:v1 .
    

    项目打包部署

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

    FROM openoffice: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
    

六、使用libreOffice(Linux版)实现word文档预览
https://blog.csdn.net/qq_44470091/article/details/1025175560

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中使用OpenOfficeWord转换PDF可以通过以下步骤实现: 1. 首先,确保已经安装了OpenOffice软件,并且OpenOffice服务已经启动。 2. 在Spring Boot项目的pom.xml文件中添加对OpenOffice JODConverter的依赖: ```xml <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-spring-boot-starter</artifactId> <version>4.2.2</version> </dependency> ``` 3. 创建一个Controller类,用于接收Word文件并将其转换PDF。可以使用`JodConverter`类来实现转换功能。以下是一个简单的示例: ```java import org.jodconverter.DocumentConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController public class ConvertController { @Autowired private DocumentConverter documentConverter; @PostMapping("/convert") public String convertToPdf(@RequestParam("file") MultipartFile file) { try { // 将上传的Word文件转换PDF File inputFile = File.createTempFile("input", ".docx"); file.transferTo(inputFile); File outputFile = File.createTempFile("output", ".pdf"); documentConverter.convert(inputFile).to(outputFile).execute(); // 返回转换后的PDF文件路径 return outputFile.getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); return "转换失败"; } } } ``` 4. 运行Spring Boot应用程序,并使用POST请求将Word文件上传到`/convert`接口。接口将返回转换后的PDF文件路径。 这样,你就可以使用Spring Boot和OpenOfficeWord文件转换PDF了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值