Java通过documents4j和LibreOffice把word转为pdf

本文介绍了使用Java工具类如Documents4j进行word转pdf的过程,包括不同平台的安装方法、LibreOffice在Linux中的应用以及发现的多线程转换问题。还提到了ApacheOpenOffice作为备选方案。
摘要由CSDN通过智能技术生成

word转pdf的相关第三方jar说明

  • docx4j
    免费开源、稍微复杂点的word,样式完全乱了,且xalan升级为2.7.3后会报错。
  • poi
    免费开源、官方文档少、学习成本大、使用复杂、生成的样式也有问题。
  • aspire.doc
    样式保留很好、使用方便。
    未付费时,第一行会有红色水印且超过500个段落(大概25页)会被截取。
    网上没有破解版。
  • aspose.words
    样式保留很好、使用方便。
    网上有破解版。
  • documents4j
    样式保留很好、使用方便。
    底层直接调用微软的office所以,完美保留样式

Linux系统安装LibreOffice

在线安装

CentOS:使用以下命令安装

sudo yum install libreoffice

Ubuntu:使用以下命令安装

sudo apt-get install libreoffice

执行命令需要root权限:sudo -i、su

离线安装

在linux下离线安装libreoffice

word转pdf验证

查看版本:

libreoffice --version

启动服务:

nohup libreoffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard &

word转pdf验证:

// 安装完后进入/usr/bin 或者 usr/local/bin目录下执行。 outdir输出是一个文件夹
libreoffice --headless --invisible --convert-to pdf /file/word/test.docx --outdir /file/word/test

也可以安装Apache OpenOffice,二者基本差不多,更推荐LibreOffice
LibreOffice vs OpenOffice:哪个免费办公套件更适合你?

Java工具类代码

maven依赖:

<!--word转pdf-->
<dependency>
	<groupId>com.documents4j</groupId>
	<artifactId>documents4j-local</artifactId>
	<version>${documents4j.version}</version>
</dependency>
<dependency>
	<groupId>com.documents4j</groupId>
	<artifactId>documents4j-transformer-msoffice-word</artifactId>
	<version>${documents4j.version}</version>
</dependency>

java代码:

package com.chinamobile.cmss.services.main.util;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Documents4j工具类
 *
 * @author liquanhong
 * @createTime 2023/12/05
 */
@Slf4j
public class Documents4jUtil {

    // windows 生成目录
    private static String winDirUrl = "D:\\temp\\file\\pdf\\";

    /**
     * word转pdf
     *
     * @param file word源文件
     */
    public static void convertWordToPdf(File file) {
        String os = System.getProperty("os.name").toLowerCase();
        log.info("convertWordToPdf 当前操作系统:{}", os);
        if (os.contains("win")) {
            // Windows操作系统
            windowsWordToPdf(file);
        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            // Unix/Linux/Mac操作系统
            linuxWordToPdf(file);
        } else {
            // 未知操作系统
            throw new RuntimeException("不支持当前操作系统转换文档。");
        }
    }

    /**
     * 通过documents4j 实现word转pdf -- Windows 环境 需要有 Microsoft Office 服务
     *
     * @param file 源文件
     */
    public static void windowsWordToPdf(File file) {
        File outputFile = new File(winDirUrl + file.getName().replaceAll("\\.(docx?|\\w+)$", "") + ".pdf");
        try(InputStream  docxInputStream = new FileInputStream(file);
            OutputStream outputStream = new FileOutputStream(outputFile)){
            IConverter converter = LocalConverter.builder().build();
            converter.convert(docxInputStream)
                    .as(DocumentType.DOCX)
                    .to(outputStream)
                    .as(DocumentType.PDF).execute();
        } catch (Exception e) {
            log.error("winWordToPdf windows环境word转换为pdf时出现异常:", e);
        }
    }

    /**
     * 通过libreoffice 实现word转pdf -- linux 环境 需要有 libreoffice 服务
     *
     * @param file 源文件
     */
    public static void linuxWordToPdf(File file) {
        // 获取文件的绝对路径和目标路径
        String absolutePath = file.getAbsolutePath();
        String parentPath = file.getParent();

        // 构建LibreOffice的命令行工具命令
        String command = "libreoffice --headless --invisible --convert-to pdf " + absolutePath + " --outdir " + parentPath;
        // 执行转换命令
        try {
            executeLinuxCmd(command);
        } catch (Exception e) {
            log.error("linuxWordToPdf linux环境word转换为pdf时出现异常:", e);
        }
    }

    /**
     * 执行命令行
     *
     * @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("executeLinuxCmd 执行Linux命令异常:", e);
            Thread.currentThread().interrupt();
            return false;
        }
        return true;
    }
}

LibreOffice不支持多线程文件转换

问题现象: 开两个窗口,执行相同的命令,命令行会卡住无反应。
在这里插入图片描述
Linux安装的版本是5.3.6.1,在windows中下载了最新版本7.6.4问题依然存在,说明和版本没关系。

参考了博客,并没有解决😭 。

后来翻到这篇博客:
使用docker来实现LibreOffice并发转换docx文件为pdf
在这里插入图片描述

结论: LibreOffice不支持多线程文件转换

其他

若命令行不指定,输出目录,LibreOffice默认输出到当前目录。
windows当前目录是,soffice.exe同级目录,如下所示:
在这里插入图片描述
linux当前目录是,输入目录的同级目录

参考链接参考链接参考链接

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在使用LibreOffice中将Word文档转换为PDF时,可能会遇到页数不一致的情况。这可能是由于以下原因导致的: 1. 格式兼容性:LibreOffice和Microsoft Word使用不同的格式和布局方式,这可能会导致在转换过程中某些元素的位置发生改变。例如,字体、行间距、标题等的大小和位置可能会有所不同,从而导致页数的变化。 2. 页面设置:LibreOffice和Microsoft Word的页面设置选项可能不完全相同,例如页面边距、纸张大小和方向等。这些设置的不同可能导致文档在转换为PDF时出现内容溢出或缩小,从而导致页数不一致。 3. 图片和图表:由于LibreOffice和Microsoft Word使用不同的图像引擎和解析方式,图像和图表的布局可能会有差异。这可能导致在转换为PDF后,图像和图表元素的大小和位置发生改变,从而导致页数不一致。 为解决这个问题,您可以尝试以下方法: 1. 重新审查页面设置:检查Word文档和LibreOffice中的页面设置选项,确保它们一致,并且与所需的PDF输出格式相匹配。 2. 更新字体和格式:在转换过程中,尝试使用相同或最接近的字体和格式。这样可以减少在转换后字体和格式发生变化的可能性。 3. 调整布局和图像:在转换前,先调整文档中的布局和图像,以便在LibreOffice中更好地适应。可以尝试重新调整图像和图表的大小和位置,以使其更为紧凑。 请记住,由于LibreOffice和Microsoft Word之间存在差异,无法保证转换后的PDF与原始Word文档完全一致。因此,在进行转换之前,建议您仔细检查PDF文件以确保内容和格式与预期一致。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值