本文内容主要目的在于测试Ibreoffice转换docx文档失败的原因是否和系统有关,之前我在CentOS上和MacOS上均转换不成功,但是使用一个开源的项目却可以,而他用的就是Ubuntu和Ibreoffice,抱着找到原因的心态在Ubuntu上进行测试。
实验结论
部分文档转换不成功,跟系统没有关系,猜测跟字体有关。
官网:https://zh-cn.libreoffice.org/download/libreoffice/
参数说明:https://help.libreoffice.org/Common/Starting_the_Software_With_Parameters/zh-CN
查看
sudo apt-cache search libreoffice
安装
# 卸载原来的
sudo apt remove libreoffice-*
# 安装
sudo apt-get install libreoffice
# 安装中文语言包
sudo apt-get install libreoffice-l10n-zh-cn libreoffice-help-zh-cn
查看版本
soffice --version
显示
LibreOffice 6.0.7.3 00m0(Build:3)
查看路径
which soffice
显示
/usr/bin/soffice
创建目录
sudo mkdir /usr/local/office_package
cd /usr/local/office_package
转换
soffice --headless --convert-to pdf /usr/local/office_package/0.docx --outdir /usr/local/office_package/
注意
libreoffice和openoffice原来是一家,所以早期版本的libreoffice命令和openoffice一样,后来版本的libreoffice就变了
创建目录
sudo mkdir /usr/local/office_package
cd /usr/local/office_package
下载
wget https://mirror-hk.koddos.net/tdf/libreoffice/stable/6.4.4/deb/x86_64/LibreOffice_6.4.4_Linux_x86-64_deb.tar.gz
解压
cd /usr/local/office_package/
tar -zxvf LibreOffice_6.4.4_Linux_x86-64_deb.tar.gz
安装
cd /usr/local/office_package/LibreOffice_6.4.4.2_Linux_x86-64_deb/DEBS/
sudo dpkg -i *.deb
下载汉化包
cd /usr/local/office_package/
wget https://download.nus.edu.sg/mirror/tdf/libreoffice/stable/6.4.4/deb/x86_64/LibreOffice_6.4.4_Linux_x86-64_deb_langpack_zh-CN.tar.gz
解压
tar -zxvf LibreOffice_6.4.4_Linux_x86-64_deb_langpack_zh-CN.tar.gz
进入目录安装
cd /usr/local/office_package/LibreOffice_6.4.4.2_Linux_x86-64_deb_langpack_zh-CN/DEBS/
sudo dpkg -i *.deb
查看版本
libreoffice6.4 --version
查看可执行文件位置
which libreoffice6.4
sudo apt remove libreoffice*
sudo apt purge libreoffice*
sudo apt autoremove
在转换中我们会发现转换的pdf和原文档字体是有差异的,是因为系统上没有我们需要的字体,所以我们要安装字体
查看现有字体
fc-list
打开目录
cd /usr/share/
我们会看到fonts
和fontconfig
目录
添加字体
创建目录并进入
mkdir /usr/share/fonts/chinese
cd /usr/share/fonts/chinese
在Windows上找到C://Windows/Fonts
下最后几列中文名称的字体都上传到/usr/share/fonts/chinese
设置目录权限
chmod -R 755 /usr/share/fonts/chinese
接下来需要安装xfonts-utils
来搜索目录中所有的字体信息,并汇总生成fonts.scale
文件,
输入命令:
apt install xfonts-utils
然后执行ttmkfdir命令即可:
mkfontdir
最后一步就是修改字体配置文件了,首先通过编辑器打开配置文件:
vi /etc/fonts/fonts.conf
可以看到一个Font list,即字体列表,在这里需要把我们添加的中文字体位置加进去:
<dir>/usr/share/fonts/chinese</dir>
最后别忘了刷新内存中的字体缓存,这样就不用reboot重启了:
fc-cache -fv
这样所有的步骤就算完成了,最后再次通过fc-list
看一下字体列表:
fc-list
下载doc文档
cd /usr/local/office_package/
wget http://wordupload.xhkjedu.com/resource/0/0.docx
转换参数
--convert-to pdf:writer_pdf_Export 1.doc
--convert-to "html:XHTML Writer File:UTF8" 1.doc
--convert-to "txt:Text (encoded):UTF8" 1.doc
可以简写为
--convert-to pdf 1.doc
--convert-to html 1.doc
--convert-to txt 1.doc
soffice --headless --invisible --convert-to pdf /usr/local/office_package/5.docx --outdir /usr/local/office_package/
或者
soffice --headless --invisible --convert-to pdf:writer_pdf_Export /usr/local/office_package/5.docx --outdir /usr/local/office_package/
或者
soffice -env:UserInstallation=file:///$HOME/.libreoffice-headless/ \
--headless --invisible --convert-to pdf /usr/local/office_package/0.docx --outdir /usr/local/office_package/
我这里直接就成功了
soffice --headless --invisible --convert-to jpg /usr/local/office_package/0.docx --outdir /usr/local/office_package/
或者
soffice -env:UserInstallation=file:///$HOME/.libreoffice-headless/ \
--headless --invisible --convert-to jpg /usr/local/office_package/5.docx --outdir /usr/local/office_package/
soffice -env:UserInstallation=file:///$HOME/.libreoffice-headless/ \
--headless --invisible --convert-to html /usr/local/office_package/5.docx --outdir /usr/local/office_package/
问题描述:
Libreoffice发生转换不成功(比如转换wps文件),再做转换就会直接不做任何操作
当你运行其中一个LibreOffice的时候,再运行另外一个Libreoffice转换时,将不做任何操作。
导致这种问题的原因时有转换进程一直在运行,所以我们也可以杀掉进程
top
或者
top -bc |grep soffice.bin
查看卡死的进程杀死即可
kill -9 进程id
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-spring-boot-starter</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.libreoffice</groupId>
<artifactId>ridl</artifactId>
<version>5.4.2</version>
</dependency>
application.properties
jodconverter:
local:
enabled: true
office-home: /opt/libreoffice6.1
port-numbers: 8100,8101,8102
max-tasks-per-process: 100
调用
@RestController
@RequestMapping("/doc")
public class LibreOfficeController {
@Autowired
private DocumentConverter documentConverter;
@RequestMapping("/toPdf")
public void toPdf() throws OfficeException {
File wfile = new File("/usr/local/office_package/5.docx");
File pfile = new File("/usr/local/office_package/5.pdf");
documentConverter.convert(wfile).to(pfile).execute();
}
}
/**
* 利用libreOffice将office文档转换成pdf
* @param inputFile 目标文件地址
* @param pdfFile 输出文件夹
* @return
*/
public static boolean convertOffice2PDF(String inputFile, String pdfFile){
long start = System.currentTimeMillis();
String command;
boolean flag;
String osName = System.getProperty("os.name");
if (osName.contains("Windows")) {
command = "cmd /c start soffice --headless --invisible --convert-to pdf " + inputFile + " --outdir " + pdfFile;
}else {
command = "soffice --headless --invisible --convert-to pdf " + inputFile + " --outdir " + pdfFile;
}
flag = executeLibreOfficeCommand(command);
long end = System.currentTimeMillis();
logger.debug("用时:{} ms", end - start);
return flag;
}
/**
* 执行command指令
* @param command
* @return
*/
public static boolean executeLibreOfficeCommand(String command) {
logger.info("开始进行转化.......");
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
try {
logger.debug("convertOffice2PDF cmd : {}", command);
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
// 下面两个可以获取输入输出流
// InputStream errorStream = process.getErrorStream();
// InputStream inputStream = process.getInputStream();
} catch (IOException e) {
logger.error(" convertOffice2PDF {} error", command, e);
return false;
}
int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
logger.debug("i----" + i);
} catch (InterruptedException e) {
logger.error("InterruptedException convertOffice2PDF {}", command, e);
return false;
}
if (exitStatus != 0) {
logger.error("convertOffice2PDF cmd exitStatus {}", exitStatus);
} else {
logger.debug("convertOffice2PDF cmd exitStatus {}", exitStatus);
}
process.destroy(); // 销毁子进程
logger.info("转化结束.......");
return true;
}
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>cn.keking</groupId>
<artifactId>jodconverter-core</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
</exclusions>
</dependency>