(LibreOffice) 使用 documents4j 实现 Word 转 PDF 转换

documents4j使用

1. 业务背景

在许多应用场景中,将 Microsoft Word 文档(.doc 或 .docx)转换为 PDF 格式是一个常见需求。PDF 格式方便共享和查看,并且保证了文档的格式和内容一致性。为了满足这一需求,documents4j 提供了一个高效的解决方案,支持跨平台操作,包括 Windows 和 Linux 系统。

2. documents4j 简介

documents4j 是一个基于 Java 的文档转换库,支持使用 Microsoft Office API 或 LibreOffice/OpenOffice 编辑器进行文档格式转换。它能够在不同操作系统上执行文档转换任务,是一个灵活且强大的工具。

在 Windows 系统中,documents4j 通常依赖于 Microsoft Office API,而在 Linux 系统中,则需要依赖于预先安装的 LibreOffice 或 OpenOffice 进行转换。(自行查找 还没写文档)

3. Maven 依赖配置

要在项目中使用 documents4j,需要在 pom.xml 文件中添加以下依赖:

		<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>

4. 核心代码实现

4.1获取操作系统类型

以下代码演示了如何根据操作系统类型选择不同的文档转换方式:

public static void convertWordToPdf(String srcPath, String destPath) throws IOException, InterruptedException {
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT);

        if (osName.contains("win")) {
            // 如果是Windows系统,使用documents4j进行转换
            convertUsingDocuments4j(srcPath, destPath);
        } else if (osName.contains("nix") || osName.contains("nux") || osName.contains("mac")) {
            // 如果是Linux或Mac系统,使用LibreOffice进行转换
            convertUsingLibreOffice(srcPath, destPath);
        } else {
            throw new UnsupportedOperationException("Unsupported operating system: " + osName);
        }
    }

4.2 Windows 环境 word to pdf

在 Windows 环境下,可以使用 documents4j 将 Word 文档转换为 PDF 格式,代码如下:

public static void convertUsingDocuments4j(String srcPath, String destPath) throws IOException {
        IConverter converter = null;
        try (InputStream docxInputStream = new FileInputStream(new File(srcPath));
             OutputStream outputStream = new FileOutputStream(new File(destPath))) {

            // 创建LocalConverter实例
            converter = LocalConverter.builder().build();

            // 动态获取源文件的DocumentType
            DocumentType sourceType = getDocumentTypeFromExtension(srcPath);

            Future<Boolean> conversion = converter.convert(docxInputStream)
                    .as(sourceType)  // 使用动态确定的DocumentType
                    .to(outputStream)
                    .as(DocumentType.PDF)
                    .schedule();

            conversion.get(10, TimeUnit.SECONDS); // 等待转换完成或超时10秒

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (converter != null) {
                converter.shutDown(); // 确保正确关闭转换器
            }
        }
    }

其中,getDocumentTypeFromExtension 方法用于根据文件扩展名确定文档类型:

private static DocumentType getDocumentTypeFromExtension(String filePath) {
        // 获取文件的扩展名并转换为小写
        String extension = FilenameUtils.getExtension(filePath).toLowerCase(Locale.ROOT);
        switch (extension) {
            case "doc":
                return DocumentType.DOC;
            case "docx":
                return DocumentType.DOCX;
            case "rtf":
                return DocumentType.RTF;
            case "xls":
                return DocumentType.XLS;
            case "xlsx":
                return DocumentType.XLSX;
            case "ods":
                return DocumentType.ODS;
            case "csv":
                return DocumentType.CSV;
            case "xml":
                return DocumentType.XML;
            case "mhtml":
                return DocumentType.MHTML;
            case "txt":
                return DocumentType.TEXT;
            case "pdf":
                return DocumentType.PDF;
            case "pdfa":
                return DocumentType.PDFA;
            default:
                throw new IllegalArgumentException("Unsupported file type: " + extension);
        }
    }

4.3 Linux 环境 word to pdf

在 Linux 环境中,使用 LibreOffice 进行文档转换。以下是转换的代码示例:

public static void convertUsingLibreOffice(String srcPath, String destPath) throws IOException, InterruptedException {
        // 使用libreoffice7.4命令(无需完整路径)
        String[] command = {
                "libreoffice7.4", // 使用配置后的命令
                "--headless",
                "--invisible",
                "--convert-to", "pdf",
                srcPath,
                "--outdir", new File(destPath).getParent()
        };

        ProcessBuilder processBuilder = new ProcessBuilder(command);

        // 重定向错误流到标准输出流
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();

        // 读取并打印命令的输出
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }

        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new IOException("Conversion failed with exit code " + exitCode);
        }
    }

5. 常见问题及解决方案

问题1: Windows中书签未被正确识别

问题原因:

  • 文档处理差异: documents4j和LibreOffice对Word文档处理可能不同,可能无法准确处理书签。
  • 书签处理问题: documents4j可能不完全支持书签。

解决方案:

  • 检查文档格式: 确保书签格式标准,尝试将文档保存为.docx格式。
  • 使用其他库: 尝试Apache POI或Aspose.Words处理书签。

问题2:转换时间较长,可能需要调整超时时间

问题原因:

  • 文档复杂度: 文档较大或复杂,导致转换时间长。
  • 系统性能: 受限于系统的CPU和内存资源。

解决方案:

  • 检查文档格式:将Future.get()中的超时时间从10秒增加到30秒或更长(也可以根据file.size()动态调整)。
  • 使用其他库: 精简文档内容,删除不必要的元素,压缩图片。

问题3:Linux中书签正常识别但字体有差异

问题原因:

  • 字体缺失: Linux系统中缺少字体库,导致字体显示不一致。
  • 字体渲染差异: LibreOffice和其他工具在字体渲染方面可能有差异。

解决方案:

KKFileView 是一个基于 LibreOffice 的文档在线预览工具。它利用 LibreOffice 的转换能力来将多种文档格式(如 Word、Excel、PowerPoint 等)转换为 PDF 或 HTML 格式,以便在浏览器中进行预览。
KKFileView 字体和 LibreOffice 的关系:
字体渲染: KKFileView 使用 LibreOffice 进行文档转换和渲染,这意味着文档中的字体显示取决于 LibreOffice 的字体库和渲染能力。
字体依赖: 如果 Linux 系统中缺少某些字体,LibreOffice 在渲染文档时会使用替代字体,这可能导致文档外观与原始文件有所不同。因此,KKFileView 作为基于 LibreOffice 的工具,同样会受到这种字体依赖的影响。
关键点:
安装字体: 为了确保 KKFileView 渲染的文档与原始文件一致,需要在系统中安装相应的字体库,这同样适用于 LibreOffice。
文档一致性: 通过安装正确的字体库,可以在使用 LibreOffice 或 KKFileView 时保持文档的字体和排版的一致性。
总之,KKFileView 和 LibreOffice 之间的关系在于 KKFileView 依赖 LibreOffice 的文档转换功能,而 LibreOffice 的字体库直接影响文档的渲染效果。

6. 效果图

源文件:
word
Windows 环境下转换的 PDF(无书签):书签还没识别到....有空再改一版吧
Linux 环境下转换的 PDF:在这里插入图片描述

总结

documents4j 是一个高效的 Java 文档转换工具,适用于多种操作系统。通过结合不同平台的转换工具,如 Microsoft Office 和 LibreOffice,documents4j 能够在 Windows 和 Linux 系统中实现一致的文档转换效果。在实际应用中,根据操作系统环境选择合适的转换工具,并结合特定的优化措施,如安装字体库或调整超时时间,以确保转换效果和性能的最佳平衡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值