一、环境介绍
- java
- openoffice 4.1.6
- springboot整合开发
二、代码实现
-
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>
-
关键代码
注意修改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)
-
下载openoffice包
官网地址 -
下载两个包:
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 -
下载java环境jdk
官网地址 -
下载一个包:
a. linux系统安装包 jdk-8u221-linux-x64.tar.gz
-
编写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 .
四、运行测试
- 运行
docker run -d -p 8080:8080 -v /home/:/home/ worddemo:v1
-v /home/:/home/: 表示文件挂载在宿主机/home文件夹下,方便文件测试;
浏览器访问主机8080端口。
五、总结
-
踩坑记录
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