原文:勿意、勿必、勿固、勿我。
译文:不凭空臆测,不武断绝对,不固执拘泥,不自以为是。
LibreOffice拥有强大的数据导入和导出功能,能直接导入PDF文档、微软Word(.doc文件)、LotusWord,支持主要的OpenXML格式。软件本身并不局限于Debian和Ubuntu平台,现已支持Windows、Mac和其它Linux发行版等多个系统平台。
一、准备工作
1、下载地址:LibreOffice 官网
2、centos系统:作者使用7+版本
3、安装命令:dnf 或更换到 yum命令, 例如:dnf install 变成 yum install
4、LibreOffice文字编码下载:文字编码官网下载地址
进入地址后选择自己需要的版本进入:
选择自己需要的系统进入:https://downloadarchive.documentfoundation.org/libreoffice/old/7.5.9.2/
选择自己需要的位数进入:https://downloadarchive.documentfoundation.org/libreoffice/old/7.5.9.2/rpm/
选择自己需要的文件下载:https://downloadarchive.documentfoundation.org/libreoffice/old/7.5.9.2/rpm/x86_64/
二、安装LibreOffice
下载好的安装包,选择系统匹配的安装包
选择你对应操作系统的包,我这里是Linux的rpm包,建议选择稳定版本
也可查看适配自己系统的历史对应版本下载使用
官网安装指南:官网首页帮助与支持——>安装指南——>选择你自己系统的点击进入
上传至服务器。
centos系统根目录opt文件夹下(根据自己需求上传目录即可,更改目录注意后续命令执行中文件路径)
文字编码下载
- tar -zxvf LibreOffice_7.5.9_Linux_x86-64_rpm_langpack_zh-CN.tar.gz
复制代码
进入文字编码目录
- cd LibreOffice_7.5.9.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/
复制代码
解压文字编码
- tar -zxvf LibreOffice_7.5.9.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz
复制代码
解压LibreOffice
- tar -zxvf LibreOffice_7.5.9.2_Linux_x86-64_rpm.tar.gz
复制代码
进入RPMS目录
- cd LibreOffice_7.5.9.2_Linux_x86-64_rpm/RPMS/
复制代码
安装LibreOffice
进入RPMS目录
- cd LibreOffice_7.5.9.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/
复制代码
安装字体编码
字体编码和LibreOffice安装命令(要在对应文件目录下执行)
验证是否安装成功
成功
卸载LibreOffice
四、报错
- dnf install cairo -y
- dnf install cups-libs -y
- dnf install libSM -y
复制代码
更新依赖
- dnf install -y libreoffice-headless
复制代码
服务器命令行测试生成PDF
- libreoffice7.5 --headless --invisible --convert-to pdf /opt/xxx.docx --outdir /opt
复制代码
转换成功!
解决转换后的PDF中的中文乱码问题
一般在windows下安装我们的LibreOffice成功后,转换中文都是正常的,但在linux上基本上都会出现乱码的问题。 因为linux中缺少一些中文字体导致的。这个时候我们需要把windos中的字体文件夹上传到linux上,同步一下字体信息。
1、打开windows下C:\Windows\fonts目录
2、将fonts目录压缩为zip包,然后上传到服务器上。上传路径为 /usr/share/fonts
3、在linux上解压上传的压缩包,因为是zip包,需要unzip命令。 如果没有要安装
4、输入fc-list 查看系统的字体,如果报错后,需要下载,下载完成后就可以看了
- dnf -y install cups-libs fontconfig
复制代码
5、给给解压后产生的文件夹Fonts权限
- chmod -R 755 /usr/share/fonts/Fonts
复制代码
6、安装ttmkfdir,然后执行对应命令
- ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
复制代码
7、用vi/vim打开/etc/fonts/fonts.conf,添加我们字体文件的位置
- vim /etc/fonts/fonts.conf
复制代码- <dir>/usr/share/fonts/Fonts</dir>
复制代码
8、刷新内存中的字体缓存,输入:
9、fc-list查看一下linux系统中的字体, 有我们刚刚添加进去的
10、再试下转换,发现中文转换成功
Java应用代码
documents4j方式集成LibreOffice
1、引入依赖
- <dependency>
- <groupId>com.documents4j</groupId>
- <artifactId>documents4j-local</artifactId>
- <version>1.0.3</version>
- </dependency>
- <dependency>
- <groupId>com.documents4j</groupId>
- <artifactId>documents4j-transformer-msoffice-word</artifactId>
- <version>1.0.3</version>
- </dependency>
复制代码
2、实现word转pdf的工具类代码,适用于window系统和Linux系统
- import com.documents4j.api.DocumentType;
- import com.documents4j.api.IConverter;
- import com.documents4j.job.LocalConverter;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.ObjectUtils;
- import org.apache.poi.xwpf.usermodel.XWPFDocument;
- import org.jeecg.common.util.DateUtils;
- import javax.servlet.http.HttpServletRequest;
- import java.io.*;
- import java.net.URL;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.nio.file.StandardCopyOption;
- @Slf4j
- public class PdfUtil {
- /**
- * 通过documents4j 实现word转pdf
- */
- public static String documents4jWordToPdf(HttpServletRequest request, String wordPath, String pdfDownloadPath) {
- //获取系统类型
- String os = System.getProperty("os.name").toLowerCase();
- String ym = DateUtils.getDate("yyyyMM");
- String filePath = pdfDownloadPath + "/" + ym;
- File path = new File(filePath);
- // 检查目录是否存在
- if (!path.exists()) {
- // 创建目录
- boolean created = path.mkdirs();
- if (created) {
- log.info("目录已创建");
- } else {
- log.info("目录创建失败");
- }
- } else {
- log.info("目录已经存在或文件不在有效目录中");
- }
- String fileName = wordPath.substring(wordPath.lastIndexOf("/") + 1, wordPath.lastIndexOf("."));
- log.info("fileName:{}", fileName);
- log.info("当前系统:{}", os);
- if (os.contains("win")) {
- String pdfPath = pdfDownloadPath + ym + "/" + fileName + ".pdf";
- File wordFile = null;
- if (ObjectUtils.isNotEmpty(wordPath) && wordPath.indexOf("http") == -1) {
- wordFile = new File(wordPath);
- } else {
- wordFile = getFileByHttpURL(wordPath);
- }
- // Windows操作系统
- winDocuments4jWordToPdf(wordFile, pdfPath);
- return org.jeecg.common.util.http.HttpUtil.getServerUrl(request, 10) + "/pdf/" + ym + "/" + fileName + ".pdf";
- } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
- String pdfPath = pdfDownloadPath + ym + "/";
- String wordWritePath = pdfDownloadPath + ym + "/" + fileName + ".docx";
- try {
- if (ObjectUtils.isNotEmpty(wordPath) && wordPath.indexOf("http") == -1) {
- // 创建源文件和目标文件的路径对象
- Path sourcePath = Paths.get(wordPath);
- Path destinationPath = Paths.get(filePath, sourcePath.getFileName().toString());
- Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
- } else {
- InputStream inputStream = new URL(wordPath).openStream();
- // 创建XWPFDocument对象
- XWPFDocument document = new XWPFDocument(inputStream);
- // 创建输出流,将Word文件写入到本地指定文件夹
- FileOutputStream outputStream = new FileOutputStream(wordWritePath);
- document.write(outputStream);
- outputStream.close();
- log.info("Word文件已成功保存到本地!");
- }
- } catch (IOException e) {
- log.info("发生错误: {}" + e.getMessage());
- }
- File linuxWordPath = new File(wordWritePath);
- // Unix/Linux/Mac操作系统
- linuxDocuments4jWordToPdf(linuxWordPath, pdfPath);
- return org.jeecg.common.util.http.HttpUtil.getServerUrl(request, 10) + "/pdf/" + ym + "/" + fileName + ".pdf";
- } else {
- // 未知操作系统
- throw new RuntimeException("不支持当前操作系统转换文档");
- }
- }
- public static String winDocuments4jWordToPdf(File wordFile, String pdfPath) {
- InputStream docxInputStream = null;
- OutputStream outputStream = null;
- try {
- // 原word地址
- docxInputStream = new FileInputStream(wordFile);
- // 转换后pdf生成地址
- outputStream = new FileOutputStream(pdfPath);
- IConverter converter = LocalConverter.builder().build();
- converter.convert(docxInputStream)
- .as(DocumentType.DOCX)
- .to(outputStream)
- .as(DocumentType.PDF).execute();
- // 关闭
- converter.shutDown();
- // 关闭
- outputStream.close();
- // 关闭
- docxInputStream.close();
- return pdfPath;
- } catch (Exception e) {
- e.printStackTrace();
- log.info("[documents4J] word转pdf失败:" + e.toString());
- } finally {
- try {
- if (outputStream != null) {
- outputStream.close();
- }
- if (docxInputStream != null) {
- docxInputStream.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- log.info("[documents4J] word转pdf失败:" + e.toString());
- }
- }
- return "";
- }
- /**
- * 根据URL地址获取文件
- *
- * @param path URL网络地址
- * @return File
- */
- private static File getFileByHttpURL(String path) {
- String newUrl = path.split("[?]")[0];
- String[] suffix = newUrl.split("/");
- //得到最后一个分隔符后的名字
- String fileName = suffix[suffix.length - 1];
- File file = null;
- InputStream inputStream = null;
- OutputStream outputStream = null;
- try {
- file = File.createTempFile("report", fileName);//创建临时文件
- URL urlFile = new URL(newUrl);
- inputStream = urlFile.openStream();
- outputStream = new FileOutputStream(file);
- int bytesRead = 0;
- byte[] buffer = new byte[8192];
- while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
- outputStream.write(buffer, 0, bytesRead);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != outputStream) {
- outputStream.close();
- }
- if (null != inputStream) {
- inputStream.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return file;
- }
- /**
- * 通过documents4j 实现word转pdf -- linux 环境 需要有 libreoffice 服务
- *
- * @param wordFile 源文件
- */
- public static String linuxDocuments4jWordToPdf(File wordFile, String pdfPath) {
- // 获取文件的绝对路径和目录路径
- String absolutePath = wordFile.getAbsolutePath();
- String parentPath = wordFile.getParent();
- // 构建LibreOffice的命令行工具命令
- String commands = "libreoffice7.5 --headless --invisible --convert-to pdf "
- + absolutePath + " --outdir " + parentPath;
- // 执行转换命令
- try {
- boolean result = executeLinuxCmd(commands);
- if (result) {
- // 转换成功,返回转换后的PDF文件
- String pdfFilePath = parentPath + File.separator + wordFile.getName().replaceAll("\\.(docx?|\\w+)$", "") + ".pdf";
- log.info(pdfFilePath);
- return pdfPath;
- } else {
- return null;
- }
- } catch (Exception e) {
- // 转换失败
- log.error("Word文档转换为PDF失败,原因:执行命令时出现异常。", e);
- return null;
- }
- }
- /**
- * 执行命令行
- *
- * @param cmd 命令行
- * @return
- * @throws IOException
- */
- private static boolean executeLinuxCmd(String cmd) throws IOException {
- // 执行命令行工具命令
- Process process = Runtime.getRuntime().exec(cmd);
- try {
- process.waitFor();
- } catch (InterruptedException e) {
- log.error("执行 Linux 命令异常:", e);
- return false;
- }
- return true;
- }
- }
复制代码
如有错误,评论指出,作者改正
欢迎大家点赞、转发、评论