SpringBoot使用LibreOffice word转换PDF

由于java转pdf Aspose需要收费,documents4j是使用本地的MS Office应用做的文件格式转换,Linux没有对应的MS Office应用。这样造成了我们需要选用别的方式进行word的转换。思路:先用freemarker模板工具,生成docx文档,借助libreOffice将docx转pdf。

1、 生成docx模板和xml模板

docx模板:

xml模板:

用zip方式打开docx文档,拷贝word文件下的document.xml充当数据填充模板

2、freemarker填充数据

 引入依赖

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
        </dependency>

 利用document.xml模板写入数据并生成新的含有效数据的xml文件

    public void createWord(ContractVO contractVO) throws Exception {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLogTemplateExceptions(false);
        cfg.setWrapUncheckedExceptions(true);
        cfg.setDirectoryForTemplateLoading(new File(filePath));
        Template t =  cfg.getTemplate("document.xml");
        // 导出文件
        FileUtils.createFileDir(filePath + CONTRACT);
        String fileName = contractVO.getCode() + "_" + contractVO.getBabyName() + "_" + "合同";
        File outFile = new File(filePath + CONTRACT + fileName + ".xml");
        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8))) {
            // 将填充数据填入模板文件并输出到目标文件
            t.process(convertToMap(contractVO), out);
        } catch (Exception e) {
            throw new CommonException("导出合同失败", e);
        }
    }

利用java的zipFile 和 ZipOutputStream 及zipFile.getInputStream() 来根据docx模板导出 (需要把word/document.xml文件替换成(填充完数据[document.xml文件回填])的xml)完成docx文档生成。

package com.icss.sywn.file.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * 其实docx属于zip的一种,这里只需要操作word/document.xml中的数据,其他的数据不用动
 *
 * @author wenbsu
 */
public class XmlToDocx {

    /**
     * @param documentFile 动态生成数据的docunment.xml文件
     * @param docxTemplate docx的模板
     * @param toFilePath   输出文档路径
     */
    public static void outDocx(File documentFile, String docxTemplate, String toFilePath) {
        try {
            File docxFile = new File(docxTemplate);
            ZipFile zipFile = new ZipFile(docxFile);
            Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
            ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));
            int len = -1;
            byte[] buffer = new byte[1024];
            while (zipEntrys.hasMoreElements()) {
                ZipEntry next = zipEntrys.nextElement();
                InputStream is = zipFile.getInputStream(next);
                // 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
                zipout.putNextEntry(new ZipEntry(next.toString()));
                if ("word/document.xml".equals(next.toString())) {
                    InputStream in = new FileInputStream(documentFile);
                    while ((len = in.read(buffer)) != -1) {
                        zipout.write(buffer, 0, len);
                    }
                    in.close();
                } else {
                    while ((len = is.read(buffer)) != -1) {
                        zipout.write(buffer, 0, len);
                    }
                    is.close();
                }
            }
            zipout.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3、docx 转 PDF

安装LibreOffice,下载地址:https://www.libreoffice.org/download/download/

引入依赖

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

jodconverter:
  local:
    enabled: true
    office-home: C:\\Program Files\\LibreOffice
    port-numbers: 2002  

转换pdf

package com.icss.sywn.file.util;

import lombok.extern.slf4j.Slf4j;
import org.jodconverter.DocumentConverter;
import org.jodconverter.document.DefaultDocumentFormatRegistry;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;

@Slf4j
@Component
public class DocumentConverterUtil {

    @Resource
    private DocumentConverter documentConverter;

    public String convert(File in, File out) {

        try {
            long startTime = System.currentTimeMillis();
            documentConverter.convert(in).as(DefaultDocumentFormatRegistry.HTML)
                    .to(out).as(DefaultDocumentFormatRegistry.PDF).execute();
            long conversionTime = System.currentTimeMillis() - startTime;
            log.info(String.format("successful conversion: %s to %s in %dms", in.getName(), "pdf", conversionTime));

        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }

        return "SUCCESS";
    }
}

完成window环境下生成docx 转 pdf操作,如果是linux环境需要在linux系统安装LibreOffice

操作如下:

1、下载rpm包并解压https://mirrors.cloud.tencent.com/libreoffice/libreoffice/stable/

2、安装

yum install /root/LibreOffice_7.3.1.3_Linux_x86-64_rpm/RPMS/*.rpm

yum install /root/LibreOffice_7.3.1.3_Linux_x86-64_rpm_langpack_zh-CN/RPMS/*.rpm

 3、安装libcairo.so.2依赖库

yum install ibus

4、启动服务

安装路径:/opt/libreoffice7.3
快捷方式:/usr/bin/libreoffice7.3

/usr/bin/libreoffice7.3 --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard

5、安装字体

在CentOS7服务器上,利用LibreOffice将word等格式转换为PDF,发现不支持汉字。需要安装字体库。

yum -y install fontconfig

安装完成后,/usr/share目录就可以看到fonts和fontconfig两个目录。

yum -y install ttmkfdir

检查已有字体库

fc-list

复制字体

mkdir /usr/share/fonts/chinese

把docx中用到的字体copy到chinese文件夹里边

修改权限

chmod -R 644 /usr/share/fonts/chinese

汇总生成fonts.scale文件

ttmkfdir /usr/share/fonts/chinese

修改字体配置文件

vim /etc/fonts/fonts.conf

修改的内容如下

<fontconfig>
  ....
  <dir>....
  <dir>/usr/share/fonts/chinese</dir>
  ....
</fontconfig>

更新字体缓存

fc-cache -fv

如果转码出现乱码方格情况,需要把window下docx用到的字体都拷到/opt/libreoffice7.3/share/fonts/truetype目录下,重启服务就可以。

<think>好的,我需要回答用户关于如何使用JavaLibreOfficeDOCX转换PDF的问题。用户已经提供了几个相关的引用内容,我需要整合这些信息,给出一个清晰的示例代码和步骤。 首先,根据引用[4],LibreOffice需要安装在服务器上,并且可能需要安装字体以避免乱码。然后,用户提到了使用SpringBoot框架,但用户可能只需要一个基础的Java示例,所以应该保持代码简单,不依赖太多框架。 引用[3]提到documents4j库,它支持LibreOffice。但引用[4]中的代码示例可能更直接,使用LibreOffice的API。不过引用[2]和[4]都提到了直接通过Java调用LibreOffice的方法。可能需要检查这些引用中的具体实现方式。 根据引用[4],用户封装了一个工具类,可能使用了JNI或者UNO连接。LibreOffice通常通过UNO(Universal Network Objects)桥接来调用,这需要本地LibreOffice的安装和正确的环境配置。 现在,我需要确保示例代码的正确性。可能需要使用LibreOffice的SDK或者一些封装好的Java库。引用[4]提到不需要手动启动LibreOffice,由框架控制,但用户需要一个简单的代码示例,可能需要使用jodconverter这样的库,它封装了UNO的调用。 不过根据用户提供的引用,引用[4]中的代码可能更直接。查看引用[4],他们可能使用了类似以下的步骤: 1. 添加Maven依赖,比如jodconverter。 2. 编写工具类,初始化LibreOffice连接。 3. 调用转换方法。 但用户给出的引用[4]中的具体代码并未显示,所以可能需要参考常见的做法。例如,使用jodconverter库的示例代码: ```java import org.jodconverter.LocalConverter; import org.jodconverter.office.LocalOfficeManager; import org.jodconverter.office.OfficeManager; public class DocxToPdf { public static void main(String[] args) { OfficeManager officeManager = LocalOfficeManager.builder() .install() .build(); try { officeManager.start(); LocalConverter.builder() .build() .convert(new File("input.docx")) .to(new File("output.pdf")) .execute(); } catch (Exception e) { e.printStackTrace(); } finally { officeManager.stop(); } } } ``` 不过需要确认是否在引用中有提到相关依赖。引用[4]提到了POM依赖,可能包括jodconverter-spring-boot-starter或其他相关库。但用户可能需要基础的依赖,如: ```xml <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-local</artifactId> <version>4.4.4</version> </dependency> ``` 此外,还要确保LibreOffice已正确安装,并且在代码中指定路径,或者在环境变量中。如果用户的环境没有设置,可能需要配置officeHome: ```java OfficeManager officeManager = LocalOfficeManager.builder() .officeHome("/usr/lib/libreoffice") .install() .build(); ``` 总结步骤: 1. 安装LibreOffice2. 添加相关依赖到项目。 3. 编写代码启动OfficeManager,执行转换。 4. 处理异常,确保正确关闭OfficeManager。 需要确保代码示例正确,并且引用相关引用中的内容。例如,引用[4]提到“不需要手动启动LibreOffice软件,一切由框架掌握”,这可能指的是jodconverter自动管理LibreOffice进程。 最后,生成相关问题,可能涉及性能优化、异常处理或其他转换方法。</think>### Java 使用 LibreOfficeDOCX 转换PDF 示例代码 以下是基于 **LibreOffice** 和 `jodconverter` 库实现 DOCX PDF 的步骤和代码示例: --- #### **1. 环境准备** - **安装 LibreOffice** 在服务器或本地安装 LibreOffice(Linux 示例)[^4]: ```bash sudo apt-get install libreoffice ``` - **字体配置(可选)** 如需处理中文字体,需安装中文字体包(如 `fonts-noto-cjk`)[^4]。 --- #### **2. 添加 Maven 依赖** 使用 `jodconverter` 库简化 LibreOffice 的调用[^4]: ```xml <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-local</artifactId> <version>4.4.4</version> </dependency> ``` --- #### **3. 核心代码实现** ```java import org.jodconverter.LocalConverter; import org.jodconverter.office.LocalOfficeManager; import org.jodconverter.office.OfficeManager; import java.io.File; public class DocxToPdfConverter { public static void main(String[] args) { // 1. 初始化 LibreOffice 进程管理器 OfficeManager officeManager = LocalOfficeManager.builder() .officeHome("/usr/lib/libreoffice") // 指定 LibreOffice 安装路径 .portNumbers(2002) // 指定端口 .build(); try { // 2. 启动 LibreOffice 服务 officeManager.start(); // 3. 执行 DOCX PDF LocalConverter.builder() .build() .convert(new File("input.docx")) .to(new File("output.pdf")) .execute(); System.out.println("转换成功!"); } catch (Exception e) { e.printStackTrace(); } finally { // 4. 关闭服务 try { officeManager.stop(); } catch (Exception e) { e.printStackTrace(); } } } } ``` --- #### **4. 关键说明** - **路径配置** `officeHome` 需根据实际安装路径调整(Windows 示例:`C:\\Program Files\\LibreOffice`)。 - **多线程优化** 可通过 `portNumbers` 指定多个端口实现并发处理。 - **异常处理** 确保 `officeManager.stop()` 在 `finally` 中调用,避免进程残留。 --- #### **5. 其他方法** - **使用 documents4j** 若需兼容 Microsoft Office,可结合 `documents4j` 和 LibreOffice 实现跨平台转换[^3]。 - **SpringBoot 集成** 参考引用[4]中的工具类封装,结合 `@PostConstruct` 管理 LibreOffice 生命周期。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值