一、环境介绍
- java
- libreoffice 6.3
- 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 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;
}
}
三、部署(docker)
- 下载libreoffice包
官网地址 - 下载两个包:
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
- 下载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 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 .
四、运行测试
- 运行
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
- openoffice介绍
a. 与libreoffice对比
libreoffice | openoffice |
转换较慢,大文件libreoffice转换快 | 小文件转换速度快 |
支持命令行和java代码 | 只支持java代码操作 |
不支持,同时转换一个文件会出现soffice卡死 | 支持队列转换 |
b. 使用openOffice(Linux版)实现word并发多进程word文档转换文档预览