documents4j 将word转pdf文件,本地(Windows)测试没问题,部署到服务器(centos)报错

问题

报错如下:

代码

首先要保证你的Java代码没问题,可以参考下面代码

maven依赖

pom 复制代码
<!--documents4j-->
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-local</artifactId>
    <version>1.0.3</version>
</dependency>
<!-- documents4j-->
<dependency>
    <groupId>com.documents4j</groupId>
    <artifactId>documents4j-transformer-msoffice-word</artifactId>
    <version>1.0.3</version>
</dependency>

DocxToPdfUtil工具类

java 复制代码
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DocxToPdfUtil {

    /**
     * 通过documents4j 实现word转pdf
     *
     * @param sourcePath 源文件地址 如 /root/example.doc
     */
    public static File documents4jWordToPdf(String sourcePath) {
        return documents4jWordToPdf(new File(sourcePath));
    }

    /**
     * 通过documents4j 实现word转pdf
     *
     * @param file 源文件
     */
    public static File documents4jWordToPdf(File file) {
        String os = System.getProperty("os.name").toLowerCase();

        log.info("当前系统:{}", os);
        if (os.contains("win")) {
            // Windows操作系统
            return winDocuments4jWordToPdf(file);
        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            // Unix/Linux/Mac操作系统
            return linuxDocuments4jWordToPdf(file);
        } else {
            // 未知操作系统
            throw new RuntimeException("不支持当前操作系统转换文档");
        }
    }

    /**
     * 通过documents4j 实现word转pdf -- Windows 环境 需要有 Microsoft Office 服务
     *
     * @param file 源文件
     */
    public static File winDocuments4jWordToPdf(File file) {
        String parentPath = file.getParent();
        File outputFile = new File(parentPath + File.separator + file.getName().replaceAll("\\.(docx?|\\w+)$", "") + ".pdf");
        try {
            // 这种方式在Linux服务器不可用,所以除非你是window服务器
            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();
            docxInputStream.close();
            outputStream.close();
            return outputFile;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

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

        // 构建LibreOffice的命令行工具命令
        String commands = "libreoffice --convert-to pdf "
                + absolutePath + " --outdir " + parentPath;
        // 执行转换命令
        try {
            boolean result = executeLinuxCmd(commands);
            if (result) {
                // 转换成功,返回转换后的PDF文件
                String pdfFilePath = parentPath + File.separator + file.getName().replaceAll("\\.(docx?|\\w+)$", "") + ".pdf";
                log.info(pdfFilePath);
                log.info(pdfFilePath);
                return new File(pdfFilePath);
            } 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;
    }
}

测试

java 复制代码
@SpringBootApplication
public class PdfdemoApplication {

    public static void main(String[] args) {
        //Linux服务器
         String inputFile = "/usr/local/a.docx";

        //本地
//        String inputFile = "C:\\zhushanglin\\test\\a.docx";
        
        DocxToPdfUtil.documents4jWordToPdf(inputFile);
        System.out.println("Done! Pdf ");
        SpringApplication.run(PdfdemoApplication.class, args);
    }
}

发现本地win没问题,到服务器Linux就有问题,原因是 documents4j 利用 Microsft Office 的 APIs 来进行文档转换,因此需要在Linux上安装 OpenOffice/LibreOffice 编辑器

Ubuntu:

shell 复制代码
sudo apt-get install libreoffice

CentOS:

shell 复制代码
sudo yum install libreoffice

把这装上后,再测试,发现可以完美转换。

下课!

相关推荐
阿巴~阿巴~35 分钟前
告别命令行:Navicat可视化操作数据库(附安装使用教程)
服务器·数据库·mysql·navicat·可视化操作数据库
TG:@yunlaoda360 云老大1 小时前
华为云国际站代理商跨境容灾是如何实现的?
服务器·数据库·华为云
云川之下1 小时前
【网络】华为交换机S3700与S5700详解
服务器·网络·华为
咕噜签名-铁蛋1 小时前
云服务器故障服务保障体系构建与实践
服务器
·云扬·1 小时前
Linux系统下MySQL服务器关键配置优化指南
linux·服务器·mysql
同聘云2 小时前
阿里云云服务器云备份满了可以删除吗?不小心把备份删除了怎么办
服务器·阿里云·云计算
阿华hhh2 小时前
Linux系统编程(网络udp)
linux·服务器·c语言·网络·网络协议·udp
TG:@yunlaoda360 云老大3 小时前
华为云国际站代理商TaurusDB的读写分离可以应用于哪些场景?
服务器·网络·数据库·华为云
TG:@yunlaoda360 云老大3 小时前
如何在华为云国际站代理商控制台进行SFS Turbo的基础状态核查?
大数据·服务器·华为云·php
Wang's Blog3 小时前
Kafka: 生产环境配置优化与服务器最佳实践指南
服务器·kafka