Java利用libreOffice(jodconverter)将office(ppt,Excel,word,text)文档转换成pdf

本文介绍如何使用Java和LibreOffice库(jodconverter)将各种Office格式(如PPT,Excel,Word,Text)的文档转换为PDF。通过设置配置和调用相关方法,实现稳定的文件转换功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//使用libreOffice比使用OpenOffice转换稳定,libreOffice是OpenOffice的升级版本,但也不能完全盖晗OpenOffice,下面代码注释的部分即为OpenOffice将文档转换成PDF,使用libreOffice/OpenOffice都必须安装对应系统的libreOffice/OpenOffice软件。

package com.frank.demo.file.common.util;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;


import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Component;


import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;
import com.mongodb.gridfs.GridFSDBFile;


@Component
public class FlieToPdfUtilTwo {


    @Autowired
    private GridFsTemplate fileRepository;


    // private static String openOfficePath = "C:\\Program Files
    // (x86)\\OpenOffice 4"; // openoffice软件的安装默认路径
    private static String libreOfficePath = "C:\\Program Files\\LibreOffice 5"; // libreOffice软件的安装默认路径
    // 记录日志信息
    private static Logger logger = LoggerFactory.getLogger(FlieToPdfUtilTwo.class);


    public ByteArrayOutputStream fileToPdf(String fileId) throws Exception {
        GridFSDBFile gridFSDBFile = fileRepository.findOne(new Query(Criteria.where("_id").is(fileId)));
        if (null != gridFSDBFile) {
            String type = this.getFileSufix(gridFSDBFile.getFilename());
            String folder = System.getProperty("java.io.tmpdir");
            String docs[] = {"doc", "docx", "ppt", "pptx", "xls", "xlsx", "txt"};
            String imgs[] = {"jpg", "png", "jpeg", "gif"};
            if (this.isExsitArry(type, imgs)) {
                StringBuffer filePath = new StringBuffer();
                String name = this.generateToken();
                filePath.append(folder);
                filePath.append(name);
                filePath.append("." + type);
                this.readFile(gridFSDBFile, filePath.toString());
                StringBuffer pdfPath = new StringBuffer();
                pdfPath.append(folder);
                pdfPath.append(name);
                pdfPath.append(".pdf");
                this.imgToPDF(filePath.toString(), pdfPath.toString());
                return this.getBytes(pdfPath.toString());
            } else if (this.isExsitArry(type, docs)) {
                StringBuffer filePath = new StringBuffer();
                String name = this.generateToken();
                filePath.append(folder);
                filePath.append(name);
                filePath.append("." + type);
                this.readFile(gridFSDBFile, filePath.toString());
                StringBuffer pdfPath = new StringBuffer();
                pdfPath.append(folder);
                pdfPath.append(name);
                pdfPath.append(".pdf");
                this.libreOfficeToPDF(filePath.toString(), pdfPath.toString());
                return this.getBytes(pdfPath.toString());
            } else {
                InputStream is = gridFSDBFile.getInputStream();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) > -1) {
                    baos.write(buffer, 0, len);
                }
                is.close();
                baos.flush();
                return baos;
            }
        } else {
            throw new Exception("文件不存在!");
        }
    }


    /**
     * 检测元素是否存在数组中 不区分大小写
     *  
     *
     * @param chex
     * @param arry
     * @return 存在 true 不存在 false
     */
    public boolean isExsitArry(String chex, String arry[]) {
        for (String ex : arry) {
            if (chex.equalsIgnoreCase(ex)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 删除单个文件
     *  
     *
     * @param sPath             被删除文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }


    /**
     * 写入当前文件
     */
    public void readFile(GridFSDBFile gridFSDBFile, String filePath) throws Exception {
        InputStream is = gridFSDBFile.getInputStream();
        FileOutputStream os = new FileOutputStream(filePath);
        int index = 0;
        while ((index = is.read()) != -1) {
            os.write(index);
        }
        is.close();
        os.close();
    }


    /**
     * 获取pdf文件输出流
     */
    public ByteArrayOutputStream getBytes(String filePath) {
        File file = new File(filePath);
        ByteArrayOutputStream out = null;
        try {
            FileInputStream in = new FileInputStream(file);
            out = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            while ((in.read(b)) != -1) {
                out.write(b, 0, b.length);
            }
            out.close();
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.deleteFile(filePath.toString());
        return out;
    }


    /**
     * 获取随机名称
     */
    public String generateToken() throws Exception {
        return UUID.randomUUID().toString().replace("-", "");
    }


    /***
     * 判断文件类型
     * 
     * @param fileName
     * @return
     */
    public String getFileSufix(String fileName) {
        int splitIndex = fileName.lastIndexOf(".");
        return fileName.substring(splitIndex + 1);
    }

    /**
     * 利用libreOffice将office doc文档转换成pdf
     */
    private void libreOfficeToPDF(String inputFile, String pdfFile) {
        // 先启动已存在的LibreOffice服务
        OfficeManager officeManager = null;
        officeManager = this.startExsitLibreOffice(officeManager);
        try {
            OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
            File inputFiles = new File(inputFile);
            File outputFile = new File(pdfFile);
            converter.convert(inputFiles, outputFile);
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("libreOfficeToPDF异常:" + e.getMessage());
        }
    }


    private OfficeManager startExsitLibreOffice(OfficeManager officeManager) {
        logger.info("准备启动服务....");
        try {
            logger.info("尝试连接已启动的服务...");
            ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
            externalProcessOfficeManager.setConnectOnStart(true);
            externalProcessOfficeManager.setPortNumber(8200);
            officeManager = externalProcessOfficeManager.buildOfficeManager();
            officeManager.start();
            logger.info("office转换服务启动成功!");
        } catch (Exception ex) {
            logger.info("没有已启动的服务..." + ex.getMessage());
            try {
                logger.info("正在启动office转换服务……");
                DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
                // libreOffice的安装目录
                configuration.setOfficeHome(new File(libreOfficePath));
                // configuration.setOfficeHome(libreOfficePath);
                // 端口号
                configuration.setMaxTasksPerProcess(100);
                configuration.setPortNumber(8200);
                configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
                configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
                officeManager = configuration.buildOfficeManager();
                officeManager.start();
                logger.info("office转换服务启动成功!");
            } catch (Exception e) {
                logger.info("LibreOffice服务启动异常:" + e.getMessage());
            }
        }
        return officeManager;
    }


    private void imgToPDF(String imgFilePath, String pdfFilePath) {
        File file = new File(imgFilePath);
        if (file.exists()) {
            Document document = null;
            FileOutputStream fos = null;
            try {
                // 读取一个图片
                Image image = Image.getInstance(imgFilePath);
                float imageHeight = image.getScaledHeight();
                float imageWidth = image.getScaledWidth();
                int i = 0;
                while (imageHeight > 500 || imageWidth > 500) {
                    image.scalePercent(100 - i);
                    i++;
                    imageHeight = image.getScaledHeight();
                    imageWidth = image.getScaledWidth();
                }
                image.setAlignment(Image.ALIGN_CENTER);
                // 文档页面宽高为图片宽高
                Rectangle rect = new Rectangle(imageWidth, imageHeight);
                document = new Document(rect);
                // 读取文件流,创建可读写的文件
                fos = new FileOutputStream(pdfFilePath);
                PdfWriter.getInstance(document, fos);
                // 设置文档边距
                document.setMargins(0, 0, 0, 0);
                // 打开文档
                document.open();
                // 插入一个图片
                document.add(image);
            } catch (Exception e) {
                e.printStackTrace();
            } 
            document.close();
            try {
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

喜欢朋友可以关注我的个人微信公众号哦,会同步更新相应技术,二维码见下图。

萌萌技术

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追风落叶乔木生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值