Java使用OpenOffice将office文件转换为PDF

问题:

目前遇到需求:将上传的文件生成一个缩略图,让用户能够直观的看到文件第一页,如Word、PPT、Excel、视频文件等。

  • 如果是视频文件可以使用ffmpeg进行截取视频开头的图片作为缩略图;
  • 如果是Word、PPT、Excel文件需要将文件转化为PDF再生成缩略图。

文件转PDF介绍:

  • yeokm1/docs-to-pdf-converter 不再维护,纯Java,开源
  • opensagres/xdocreport 纯Java,开放源代码
  • OpenOffice 需要安装OpenOffice结合Java使用,本文基于此介绍。

本文针对第三点进行说明。


使用OpenOffice进行文件的转化

1.准备工作:

  • OpenOffice官网下载

  • JODConverter官网下载

    或者为方便下载,我已将上面两个上传了百度云 百度云下载(提取码:ndiq)

2.介绍:

  • OpenOffice: OpenOffice是一套跨平台的办公室软件套件,功能非常强大,适用windows、linux、mac等各大平台,简单来说Office能做到的OpenOffice也基本都能做到。

  • JODConverter: 是一个Java的OpenDocument文件转换器,可以进行许多文件格式的转换。它依赖于OpenOffice.org或者LibreOffice提供的服务来进行转换,它能将Microsoft Office文档(Word,Excel,PowerPoint)转换为PDF格式。你可以将JODConverter内嵌在Java应用程序里,也可以单独作为命令行由脚本调用,更可以应用为网页程序或者Web Service以供网络应用。

3.启动OpenOffice服务

安装OpenOffice后:

//进入目录
cd C:\Program Files (x86)\OpenOffice 4\program
//启动OpenOffice服务
soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
//查看是否启动成功
netstat -ano|findstr "8100"

4.代码

  • 4.1 解压下载的JODConverter并把lib目录下jar包导入到项目。
  • 4.2 转化代码如下:
    需要注意的是代码里的C:\Program Files (x86)\OpenOffice 4\program要根据自己的安装位置配置
package com.xiaohaitang.somedemo.utils;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class FileConversionUtil {

    //启动OpenOffice服务
    static {
        List<String> command = new ArrayList<>();
        //OpenOffice的安装目录下的soffice路径C:\Program Files (x86)\OpenOffice 4\program\soffice.exe
        command.add("C:\\Program Files (x86)\\OpenOffice 4\\program\\soffice.exe");
        command.add("-headless");
        command.add("-accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard");
        command.add("-nofirststartwizard");
        command.forEach(v -> System.out.print(v + " "));
        System.out.println();
        ProcessBuilder builder = new ProcessBuilder();
        //正常信息和错误信息合并输出
        builder.redirectErrorStream(true);
        builder.command(command);
        //开始执行命令
        try {
            Process process = builder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * office文件转换成pdf或html文件
     *
     *
     * @param file         要转换文件的路径,要包含名称和后缀(如:D:\GoogleDownload\中国地理复习笔记归纳总结(特细).doc)
     * @param saveFilePath 转换完后文件的保存路径(如:F:/test)
     * @param finalType    最终要转换为的文件的后缀传pdfh或html (如:pdf)
     *
     * @return             返回最后转换后的文件名
     * @throws             IOException
     */
    public static String conversionPdfOrHtml(String file, String saveFilePath, String finalType) throws IOException {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String type = file.substring(file.lastIndexOf(".") + 1);
        return conversionPdfOrHtml(inputStream, saveFilePath, type, finalType);
    }


    /**
     * office文件转换成pdf或html文件
     *
     *
     * @param fromFileInputStream 要转换文件的文件流
     * @param saveFilePath        转换完后文件的保存路径(如:F:/test)
     * @param fileType            原始文件的后缀(如:doc)
     * @param finalType           最终要转换为的文件的后缀 (如:pdf)
     *
     * @return                    返回最后转换后的文件名
     * @throws                    IOException
     */
    public static String conversionPdfOrHtml(InputStream fromFileInputStream, String saveFilePath, String fileType, String finalType) throws IOException {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timesuffix = sdf.format(date);
        String docFileName = null;
        String resultFileName = null;
        finalType = "." + finalType;
        //识别文件类型
        if ("doc".equals(fileType)) {
            docFileName = "doc_" + timesuffix + ".doc";
            resultFileName = "doc_" + timesuffix + finalType;
        } else if ("docx".equals(fileType)) {
            docFileName = "docx_" + timesuffix + ".docx";
            resultFileName = "docx_" + timesuffix + finalType;
        } else if ("xlsx".equals(fileType)) {
            docFileName = "xlsx_" + timesuffix + ".xlsx";
            resultFileName = "xlsx_" + timesuffix + finalType;
        } else if ("xls".equals(fileType)) {
            docFileName = "xls_" + timesuffix + ".xls";
            resultFileName = "xls_" + timesuffix + finalType;
        } else if ("ppt".equals(fileType)) {
            docFileName = "ppt_" + timesuffix + ".ppt";
            resultFileName = "ppt_" + timesuffix + finalType;
        } else if ("pptx".equals(fileType)) {
            docFileName = "pptx_" + timesuffix + ".pptx";
            resultFileName = "pptx_" + timesuffix + finalType;
        } else {
            return "转换错误,文件后缀不是doc、docx、xls、ppt、pptx";
        }
        //如果saveFilePath路径下有同名的原始文件和转化后的文件则删除。然后在saveFilePath下创建空的原始文件和转化后的文件
        File resultOutputFile = new File(saveFilePath + File.separatorChar + resultFileName);
        File docInputFile = new File(saveFilePath + File.separatorChar + docFileName);
        if (resultOutputFile.exists()) {
            resultOutputFile.delete();
        }
        if (docInputFile.exists()) {
            docInputFile.delete();
        }
        resultOutputFile.createNewFile();
        docInputFile.createNewFile();
        //将待转文件拷贝一份写入到saveFilePath下创建的空原始文件里
        try {
            OutputStream os = new FileOutputStream(docInputFile);
            int bytesRead = 0;
            byte[] buffer = new byte[1024 * 8];
            while ((bytesRead = fromFileInputStream.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fromFileInputStream.close();
        } catch (IOException e) {
        }

        //连接OpenOffice服务。需提前开启OpenOffice服务,否则会报错。参考https://www.cnblogs.com/of-course/p/10064874.html
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
        try {
            connection.connect();
        } catch (Exception e) {
            System.out.println("连接OpenOffice服务失败,请检查是否启动OpenOffice服务");
        }
        // 转化,saveFilePath下的拷贝的原始文件转化为pdf
        System.out.println("转换中......");
        DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
        converter.convert(docInputFile, resultOutputFile);
        connection.disconnect();
        //转换完之后删除拷贝的原始文件
        docInputFile.delete();
        return resultFileName;
    }
}

  • 测试转pdf
        String file = "D:\\GoogleDownload\\中国地理复习笔记归纳总结(特细).doc";
        String fileSavePath = "F:/test";
        try {
            String name = FileConversionUtil.conversionPdfOrHtml(file, fileSavePath, "pdf");
            System.out.println(name);
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 结果:
    Java使用OpenOffice将office文件转换为PDF_第1张图片
  • 测试转html
         String file = "D:\\GoogleDownload\\中国地理复习笔记归纳总结(特细).doc";
        String fileSavePath = "F:/test";
        try {
            String name = FileConversionUtil.conversionPdfOrHtml(file, fileSavePath, "html");
            System.out.println(name);
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 结果:
    Java使用OpenOffice将office文件转换为PDF_第2张图片

其他说明:

如果你是想在网页中预览 word、excel、ppt 等类型的文件,其实最推荐的是使用 kkFileView 来预览,安装使用可以参考我这篇文章 kkFileView安装及使用——文件预览解决方案

另外不推荐使用 openoffice把 word 转 html ,因为 word 里有许多格式和文字效果转换后html不能很好展示。
如果非要用 openoffice ,可以把 word 转换为 pdf ,然后就可以使用 PDF.js 等开源前端组件来预览 pdf 啦。


参考文章:
Java实现在线预览–openOffice实现
Springboot 使用 OpenOffice 实现附件在线预览功能

你可能感兴趣的:(java,java,文件转pdf,openoffice,word转pdf)