PDF技术(一)-Java实现Office系列文件转PDF文件

最近,公司要求做个文件转pdf的调研报告,于是在网上找了一些实现方法,现在将这些方法做个对比,并记录下来,以后或许有用呢,哈哈。

首先说一下需求,产品要求不能使用第三方软件实现,因为这种实现方式效率不高,所以需要使用“纯Java代码”实现。同时也对跨平台有要求,系统需要运行在linux系统上。综合现阶段发现的方案,决定采用基于Aspose的方式进行实现。

好了,现在先看一下对比的结果:

各实现对比表

于Windows平台进行测试:

测试文件:

Word:大小380k、页数225页。内含图片(排版),文字(不同颜色、字体、不同语言)、表格(含样式)

Excel:大小297k。内含插入图形、长表格。

PPT:大小539k、内含图片、自定义图形、文字(不同颜色、字体、不同语言)、表格(含样式)

 

基于Openoffice

基于libreOffice

基于Office

基于Pio+Itext

基于Aspose

跨平台性

跨平台

跨平台

仅Windows

跨平台

跨平台

是否安装软件

需安装Openoffice

需安装libreOffice

需安装Microsoft Office

是否收费

免费

免费

软件收费

(可破解)

免费

Jar包收费

(可破解)

转换Word

效率

未测

首次开启14s。

平均8s

平均10s

平均10s

平均4.2s

效果

未测

支持不同字体、不同文字、支持表格样式。

插入图形走样

转换后页数相当

(225-227)

大小相当

(380k-360k)

完全一致

转换后大小上升

(380k-1.24M)

字体、表格样式、插入图形失真。(严重失真)

转换后页数下降

(225-105)

大小飙升

(380k-1.74M)

字体样式或无法转换。

转换后页数相当(225-224)

大小上升

(380k-721k)

转换Excel

效率

未测

首次开启10s

平均4.5s

异常(Office2016)

平均5.8s

平均2.6s

效果

未测

支持文本颜色。

不支持插入图形

文本会发生走样

转换后大小相当

(297k-140k)

提示异常

(Office 2016)

样式失真。

excel页面大小过长导致PDF页面被截断,无法显示完整

不支持插入图片转换

转换后大小减小

(297k-196k)

转换PPT

效率

未测

平均5.3s

平均4s

平均15s

平均15.5s

效果

未测

几乎完全一致

能完美支持表格、自定义图形、图片、文字等

大小减小

(539k-255k)

转换成功,无法打开(Office 2016)

样式严重失真。甚至错误。

转换后大小上升

(539K-1.3M)

页数

(225-105)

几乎完全一致

转换后大小减小

(539k-398k)

优点

跨平台

文档转换失真小。

跨平台

转化相对快。对于Office能很好保证少失真,特别是Word文档

跨平台

转换速度快。

支持跨平台。

不需要安装软件。

失真情况较小

缺点

需要安装额外软件

需要安装额外软件、效率较低

不跨平台

需安装Office

Office收费

Office版本不同效果不同(不稳定性)

对JDK有污染

样式失真特别严重、效率极低。

技术复杂

收费(但是可以破解)、即使付费,也不提供源码(官网)

评价

未知

稳定

极差

结论

使用Aspose效果最好。

各种技术实现起来,综合来说Aspose是比较好的方案,唯一的弊端就是收费。

下面介绍各种方案的具体实现,以及其优缺点,效果图。

 

1)基于openoffice(跨平台、需安装openoffice、复杂格式有错位)

原理:

通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件

先安装openoffice软件(Windows或Linux有提供软件)

使用JODConverter的Java的OpenDocument 文件转换器API操作Office系列文件转换为PDF文件

 

优点:

转换效果比较好。是比较主流的做法

缺点:

服务器需要安装openoffice,比较负重

具体实现:

1.下载安装软件

1)Openoffice:Apache下的一个开放免费的文字处理软件

下载地址:http://www.openoffice.org/zh-cn/download/

2)JODConverter一个Java的OpenDocument 文件转换器,只用到它的jar包

下载地址:https://sourceforge.net/projects/jodconverter/files/JODConverter/

 

2.启动服务:

打开dos窗口,进入openoffice安装盘符,输入以下代码来启动服务:

soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard

 

3.Java实现操作转化:

Pom.xml依赖



    com.artofsolving
    jodconverter-maven-plugin
    2.2.1

转换工具:

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 java.net.ConnectException;
import java.text.SimpleDateFormat;
import java.util.Date; 
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;
/**
 * 利用jodconverter(基于OpenOffice服务)将文件(*.doc、*.docx、*.xls、*.ppt)转化为html格式或者pdf格式,
 * 使用前请检查OpenOffice服务是否已经开启, OpenOffice进程名称:soffice.exe | soffice.bin
 */
public class Doc2HtmlUtil {
    private static Doc2HtmlUtil doc2HtmlUtil;
    /** * 获取Doc2HtmlUtil实例 */
    public static synchronized Doc2HtmlUtil getDoc2HtmlUtilInstance() {
        if (doc2HtmlUtil == null) {
            doc2HtmlUtil = new Doc2HtmlUtil();
        }
        return doc2HtmlUtil;
    }
    /*** 转换文件成pdf */
    public String file2pdf(InputStream fromFileInputStream, String toFilePath,String type) throws IOException {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timesuffix = sdf.format(date);
        String docFileName = null;
        String htmFileName = null;
        if(".doc".equals(type)){
            docFileName = "doc_" + timesuffix + ".doc";
            htmFileName = "doc_" + timesuffix + ".pdf";
        }else if(".docx".equals(type)){
            docFileName = "docx_" + timesuffix + ".docx";
            htmFileName = "docx_" + timesuffix + ".pdf";
        }else if(".xls".equals(type)){
            docFileName = "xls_" + timesuffix + ".xls";
            htmFileName = "xls_" + timesuffix + ".pdf";
        }else if(".ppt".equals(type)){
            docFileName = "ppt_" + timesuffix + ".ppt";
            htmFileName = "ppt_" + timesuffix + ".pdf";
        }else{
            return null;
        } 
        File htmlOutputFile = new File(toFilePath + File.separatorChar + htmFileName);
        File docInputFile = new File(toFilePath + File.separatorChar + docFileName);
        if (htmlOutputFile.exists())
            htmlOutputFile.delete();
        htmlOutputFile.createNewFile();
        if (docInputFile.exists())
            docInputFile.delete();
        docInputFile.createNewFile();
        /*** 由fromFileInputStream构建输入文件  */
        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) {
        } 
        // 连接服务
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
        try {
            connection.connect();
        } catch (ConnectException e) {
            System.err.println("文件转换出错,请检查OpenOffice服务是否启动。");
        }
        // convert 转换
        DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
        converter.convert(docInputFile, htmlOutputFile);
        connection.disconnect();
        // 转换完之后删除word文件
        docInputFile.delete();                                                                
        return htmFileName;
    } 
    public static void main(String[] args) throws IOException {
        Doc2HtmlUtil coc2HtmlUtil = getDoc2HtmlUtilInstance ();
        File file = null;
        FileInputStream fileInputStream = null;
        file = new File("C:/Users/MACHENIKE/Desktop/xxx.doc");
        fileInputStream = new FileInputStream(file);
        coc2HtmlUtil.file2pdf(fileInputStream, "E:/360","doc");
    }
}

简易实现:

public void createPdf(String docFileName) throws IOException{ 
        String path =  this.getSession().getServletContext().getRealPath("/")+"attachment/";
        File inputFile = new File(path+"/doc/"+ docFileName + ".doc");
        File outputFile = new File(path+"/pdf/"+docFileName + ".pdf");
         
        // connect to an OpenOffice.org instance running on port 8100
        OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
        connection.connect();
         
        // convert
        DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
        converter.convert(inputFile, outputFile);
         
        // close the connection
        connection.disconnect();
    }

 

效果:(略)

 

 

2)基于libreoffice(跨平台、需安装libreoffice)

原理:

通过第三方工具libreoffice,将word、excel、ppt、txt等文件转换为pdf文件

先安装libreoffice软件(Windows或Linux有提供软件)

使用JODConverter的Java的OpenDocument 文件转换器API操作Office系列文件转换为PDF文件

优点:

转换效果比较好。是比较主流的做法

缺点:

服务器需要安装libreoffice,比较负重。启动服务时效率不是很高

具体实现:

1.下载安装软件

1)Openoffice:Apache下的一个开放免费的文字处理软件

下载地址:http://www.openoffice.org/zh-cn/download/

2)JODConverter一个Java的OpenDocument 文件转换器,只用到它的jar包

下载地址:https://sourceforge.net/projects/jodconverter/files/JODConverter/

2.Java实现

依赖:

        
            com.itextpdf
            itextpdf
            5.5.0
        
        
            com.itextpdf
            itext-pdfa
            5.5.0
        
        
            com.itextpdf
            itext-asian
            5.2.0
        
        
            com.itextpdf.tool
            xmlworker
            5.5.0
        


        
            org.jodconverter
            jodconverter-local
            4.1.0
        

        
            org.xhtmlrenderer
            flying-saucer-pdf
            9.0.7
        

转换

public class LibreOfficeAndJodconverter {
    private static OfficeManager officeManager = null;
    private static final String dirPath = "F:/pdf/";
    private static final String LibreOfficeDirPath = "D:/LibreOffice6.1.1.2/LibreOffice";
    public static void init() {
        try {
            System.out.println("尝试连接已启动的服务...");
            ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
            externalProcessOfficeManager.setConnectOnStart(true);
            externalProcessOfficeManager.setPortNumber(8100);
            officeManager = externalProcessOfficeManager.buildOfficeManager();
            officeManager.start();
            System.out.println("转换服务启动成功!");
        } catch (Exception e) {
            //命令方式:soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
            System.out.println("启动新服务!");
            String libreOfficePath = LibreOfficeDirPath;
            // 此类在jodconverter-core中3版本中存在,在2.2.2版本中不存在
            DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
            // libreOffice的安装目录
            configuration.setOfficeHome(new File(libreOfficePath));
            // 设置端口号
            configuration.setPortNumber(8100);
            // 设置任务执行超时为5分钟
            configuration.setTaskExecutionTimeout(1000 * 60 * 5L);
            // 设置任务队列超时为24小时
            configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);

            // 开启转换服务
            officeManager = configuration.buildOfficeManager();
            officeManager.start();
            System.out.println("服务启动成功!");
        }
    }
    public static void desory() {
        if (officeManager != null) {
            officeManager.stop();
        }
    }
    /** * 合并多个PDF,注意,源pdf中不能含有目的pdf,否则将合并失败*/
    public static boolean mergePdfFiles(String[] files, String newfile) {
        boolean retValue = false;
        Document document = null;
        try {
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));
            document.open();
            for (int i = 0; i < files.length; i++) {
                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
            }
            retValue = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            document.close();
        }
        return retValue;
    }
    /**
     * 开启服务时耗时,需要安装
     * 并不是看到什么,就转化为什么样的。有偏移
     *
     * @param args
     */
    public static void main(String[] args) {
        init();
        task();
        desory();
    }
    public static void task() {
        String outputname = "output.pdf";
        doDocToFdpLibre("test.docx", outputname);
        doDocToFdpLibre("ppt.pptx", outputname);
        doDocToFdpLibre("放弃.xlsx", outputname);
        doDocToFdpLibre("1.txt", outputname);
        doDocToFdpLibre("不老梦.jpg", outputname);
    }
    public static String doDocToFdpLibre(String inputFileName, String outputFileName) {
        File inputFile = new File("F:/pdf/" + inputFileName);
        System.out.println("libreOffice开始转换..............................");
        Long startTime = System.currentTimeMillis();
        OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);

        File outputFile = new File(dirPath + outputFileName);
        if (outputFile.exists()) {
            String uuid1 = UUID.randomUUID().toString();
            File temp1 = new File(dirPath + uuid1 + ".pdf");
            outputFile.renameTo(temp1);

            String uuid = UUID.randomUUID().toString();
            File temp2 = new File(dirPath + uuid + ".pdf");
            converter.convert(inputFile, temp2);

            String[] files = {dirPath + uuid1 + ".pdf", dirPath + uuid + ".pdf"};
            String savepath = dirPath + outputFileName;

            if (mergePdfFiles(files, savepath)) {
                temp1.delete();
                temp2.delete();
            }
        } else {
            converter.convert(inputFile, outputFile);
        }
        // 转换结束
        System.out.println("转换结束。。。。。");
        //转换时间
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("libreOffice转换所用时间为:" + time);
        return outputFile.getPath();
    }
}

效果:

Word文档

除去刚开启,平均8s

libreOffice转换所用时间为:14044ms

libreOffice转换所用时间为:7147ms

libreOffice转换所用时间为:6886ms

libreOffice转换所用时间为:7176ms

libreOffice转换所用时间为:7001ms

libreOffice转换所用时间为:8397ms

libreOffice转换所用时间为:8141ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第1张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第2张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第3张图片

 

Excel

PDF技术(一)-Java实现Office系列文件转PDF文件_第4张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第5张图片

libreOffice转换所用时间为:10584ms

libreOffice转换所用时间为:4534ms

libreOffice转换所用时间为:4453ms

libreOffice转换所用时间为:4369ms

ppt转换

libreOffice转换所用时间为:59257ms

libreOffice转换所用时间为:52320ms

libreOffice转换所用时间为:52571ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第6张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第7张图片

 

3)基于Microsofe Office(仅Windows、需安装Microsoft Office)

原理:

类似于Microsoft Office的“另存为”操作。用Jacob实现对Office系列文件的转换(用jacob(Java COM Bridge)操作office的方式

需要在Windows下安装Microsoft Office,使用jacob操作Office文件,

并把jacob-x.xx-x64.dll放到java/bin(与java.exe相同)目录下

 

优点:

能很好的转换,失真小(完美保持原doc格式)

缺点:

1需要安装Microsoft Office。

2需要把jacob-x.xx-x64.dll放到java/bin(与java.exe相同)目录下,对JDK目录有污染。

3不支持跨平台

4. Microsoft Office版本不同可能影响转换是否成功

具体实现

1.下载jacob包并加入到环境中:

Pom:

        
        
            com.hynnet
            jacob
            1.18
        

2.将jacob包的dll导入到jdk/jre/bin下

(不放会报错:java.lang.NoClassDefFoundError: Could not initialize class com.jacob.com.Dispatch)

PDF技术(一)-Java实现Office系列文件转PDF文件_第8张图片

或指定路径:System.getProperty("java.library.path");

3.转换方法:

public class Jacob {
	/** 转PDF格式值 */
	static final int WORD_FORMAT_PDF = 17;
	static final int EXCEL_FORMAT_PDF = 0;
	static final int PPT_FORMAT_PDF = 32;
	/*** @Description:根据文件类型转换为pdf */
	public static void convert2PDF(String inputFile, String pdfFile) {
		String suffix = getFileSufix(inputFile);
		if (suffix.equals("doc") || suffix.equals("docx") || suffix.equals("txt")) {
	        word2PDF(inputFile, pdfFile);
	    } else if (suffix.equals("xls") || suffix.equals("xlsx")) {
	    	excel2PDF(inputFile, pdfFile);
	    } else if (suffix.equals("ppt") || suffix.equals("pptx")) {
	        ppt2PDF(inputFile, pdfFile);
	    } else {
	        System.out.println("文件格式不支持转换!");
	    }
	}
	/** * @Description:word转pdf  */
	private static void word2PDF(String inputFile, String pdfFile) {    
        System.out.println("启动Word...");      
        long start = System.currentTimeMillis();      
        ActiveXComponent app = null;  
        Dispatch doc = null;  
        try {      
        	// 创建一个word对象
            app = new ActiveXComponent("Word.Application");      
            // 不可见打开word (但默认是不可见的)
            app.setProperty("Visible", new Variant(false));  
            // 获取文挡属性
            // 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document 
Dispatch docs = app.getProperty("Documents").toDispatch(); 
            doc = Dispatch.call(docs, "Open", inputFile).toDispatch();  
            System.out.println("打开文档..." + inputFile);  
            System.out.println("转换文档到PDF..." + pdfFile);      
            File tofile = new File(pdfFile);      
            if(tofile.exists()) {      
                tofile.delete();      
            }      
            // word保存为pdf格式宏,值为17
            Dispatch.call(doc, "SaveAs", pdfFile, WORD_FORMAT_PDF);      
            long end = System.currentTimeMillis();      
            System.out.println("转换完成..用时:" + (end - start) + "ms.");  
        } catch (Exception e) {      
            System.out.println("========Error:文档转换失败:" + e.getMessage());      
        } finally {  
            Dispatch.call(doc, "Close", false);  
            System.out.println("关闭文档");  
            if (app != null)      
                app.invoke("Quit", new Variant[] {});      
            }  
          //如果没有这句话,winword.exe进程将不会关闭  
           ComThread.Release();
    }
	/** * @Description:excel转pdf  */
	private static void excel2PDF(String inputFile, String pdfFile) {    
        System.out.println("启动Excel...");      
        long start = System.currentTimeMillis();      
        ActiveXComponent app = null;  
        Dispatch excel = null;  
        try {      
        	// 创建一个excel对象
            app = new ActiveXComponent("Excel.Application");      
            // 不可见打开excel
            app.setProperty("Visible", new Variant(false));  
            // 获取文挡属性
            Dispatch excels = app.getProperty("Workbooks").toDispatch();    
            // 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document
            excel = Dispatch.call(excels, "Open", inputFile).toDispatch();  
            System.out.println("打开文档..." + inputFile);  
            System.out.println("转换文档到PDF..." + pdfFile);      
            File tofile = new File(pdfFile);      
            if(tofile.exists()) {      
                tofile.delete();      
            }      
            // Excel不能调用SaveAs方法
            Dispatch.call(excel, "ExportAsFixedFormat", EXCEL_FORMAT_PDF, pdfFile);
            long end = System.currentTimeMillis();      
            System.out.println("转换完成..用时:" + (end - start) + "ms.");  
        } catch (Exception e) {      
            System.out.println("========Error:文档转换失败:" + e.getMessage());      
        } finally {  
            Dispatch.call(excel, "Close", false);  
            System.out.println("关闭文档");  
            if (app != null)      
                app.invoke("Quit", new Variant[] {});      
            }  
          //如果没有这句话,winword.exe进程将不会关闭  
           ComThread.Release();
    }
	/*** @Description:ppt转pdf  */
	private static void ppt2PDF(String inputFile, String pdfFile) {    
        System.out.println("启动PPT...");      
        long start = System.currentTimeMillis();      
        ActiveXComponent app = null;  
        Dispatch ppt = null;  
        try {      
        	// 创建一个ppt对象
            app = new ActiveXComponent("PowerPoint.Application");      
            // 不可见打开(PPT转换不运行隐藏,所以这里要注释掉)
            // app.setProperty("Visible", new Variant(false));  
            // 获取文挡属性
            Dispatch ppts = app.getProperty("Presentations").toDispatch();    
            // 调用Documents对象中Open方法打开文档,并返回打开的文档对象Document
            ppt = Dispatch.call(ppts, "Open", inputFile, true, true, false).toDispatch();  
            System.out.println("打开文档..." + inputFile);  
            System.out.println("转换文档到PDF..." + pdfFile);      
            File tofile = new File(pdfFile);      
            if(tofile.exists()) {      
                tofile.delete();      
            }      
            Dispatch.call(ppt, "SaveAs", pdfFile, PPT_FORMAT_PDF); 
            long end = System.currentTimeMillis();      
            System.out.println("转换完成..用时:" + (end - start) + "ms.");  
        } catch (Exception e) {      
            System.out.println("========Error:文档转换失败:" + e.getMessage());      
        } finally {  
            Dispatch.call(ppt, "Close");  
            System.out.println("关闭文档");  
            if (app != null)      
                app.invoke("Quit", new Variant[] {});      
            }  
          //如果没有这句话,winword.exe进程将不会关闭  
           ComThread.Release();
    }
	/*** @Description:获取文件后缀*/
	private static String getFileSufix(String fileName) {
	    int splitIndex = fileName.lastIndexOf(".");
	    return fileName.substring(splitIndex + 1);
	}
}

效果:

word文档

成功:用时10821ms

成功:用时9865ms

成功:用时9867ms

成功:用时10481ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第9张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第10张图片

 

excel:

PDF技术(一)-Java实现Office系列文件转PDF文件_第11张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第12张图片

ppt

成功:用时5265ms

成功:用时3885ms

成功:用时3788ms

成功:用时3817ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第13张图片

 

原因探究

报错的原因主要是:office版本问题。开发的时候使用的office2013,PPT不能转pdf。在服务器上安装的office2007,出现了PPT可以转成PDF,excel不能转pdf。卸载了office2007安装office2010后出现了excel能转PDF,PPT不能转PDF。office的版本问题中,world文档不管什么版本都可以成功的转pdf。最后解决的办法:安装2007的excel,2010的PPT,world就能成功的转pdf。注意:office2007不能转pdf,需要安装一个插件。

 

4)POI+IText方式(跨平台、效果差、效率低)

原理:

用 poi 将word转换成 html

用IText 将html转换成pdf(要求html中所有标签都必须要闭合,所以这里用jsoup对html进行转换)

优点:

不需要安装软件、跨平台

缺点:

  1. 失真问题比较大。(格式兼容差)
  2. 涉及到中文编码问题。
  3. 效率比较低

具体实现

    public static String officeToHtml(String sourcePath,String targetPath){
        String ext = FileUtils.getFileExt(sourcePath).toLowerCase();
        String result = null;
        switch (ext){
            case Consts.OFFICE.DOC:
            case Consts.OFFICE.DOCX:
                result = POIWordToHtml.wordToHtml(sourcePath, wordImagePath, targetPath);
                break; 
            case Consts.OFFICE.XLS:
            case Consts.OFFICE.XLSX:
                result = POIExcelToHtml.excelToHtml(sourcePath,targetPath, true);
                break; 
            case Consts.OFFICE.PPT:
            case Consts.OFFICE.PPTX:
                POIPptToHtml.pptToHtml(sourcePath,targetPath);
                break;
            default:
        }
        return result;
}
具体工具类暂略
 

具体工具类暂略

PDF技术(一)-Java实现Office系列文件转PDF文件_第14张图片

注意事项:

注意:IText 根据html生成文件的是否会验证html文件是否标准,例如通过poi转换的出来的html文件的一些标签会缺少标签闭合 ,

如果用这种html进行转换是没有办法通过itext 的校验的。会出现以下异常 

错误: “The element type "meta" must be terminated by the matching end-tag "".”
org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException: The element type "meta" must be terminated by the matching end-tag "".  。

html不规范可采用第三方 jar 包  Jsoup,  直接调用parse方法让html标准

 

相关博客:

java 实现word 转PDF (采用第三方技术 IText、Poi、Jsoup)

 

效果(很差):

Word:

耗时大概平均10s左右

耗时:10832ms

耗时:8788ms

耗时:9035ms

耗时:8827ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第15张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第16张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第17张图片

Ppt:

平均大概15s左右

耗时:15932ms

耗时:14835ms

耗时:14884ms

耗时:14889ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第18张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第19张图片

Excel:

平均5.8s

耗时:6263ms

耗时:5858ms

耗时:5698ms

耗时:5546ms

PDF技术(一)-Java实现Office系列文件转PDF文件_第20张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第21张图片

 

5)Aspose实现(跨平台、付费)

优点:

比较完美,低失真。

缺点:

不跨平台、不免费

具体实现:

下载相应jar包。(若不是付费版,将出现水印,限制页数等情况)

Word:

    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = new FileInputStream(new File("E:\\IDEA2017\\something2pdf-demo\\src\\main\\resources\\license.xml")); //  license.xml应放在..\WebRoot\WEB-INF\classes路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void doc2pdf(String Address) {
        if (!getLicense()) {          // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            long old = System.currentTimeMillis();
            File file = new File("F:\\pdf/pdf1.pdf");  //新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(Address);                    //Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");  //转化用时
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Excel

    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Excel2Pdf.class.getClassLoader().getResourceAsStream("xlsxlicense.xml"); //  license.xml应放在..\WebRoot\WEB-INF\classes路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void excel2pdf(String Address) {
        if (!getLicense()) {          // 验证License 若不验证则转化出的pdf文档会有水印产生
            return;
        }
        try {
            long old = System.currentTimeMillis();
            File file = new File("F:\\pdf/pdf2.pdf");// 输出路径
            Workbook wb = new Workbook(Address);// 原始excel路径
            FileOutputStream fileOS = new FileOutputStream(file);
            wb.save(fileOS, SaveFormat.PDF);
            fileOS.close();
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒\n\n" + "文件保存在:" + file.getPath()); //转化过程耗时
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Ppt

    public static boolean getLicense() {
        boolean result = false;
        try {
            license = Ppt2Pdf.class.getClassLoader().getResourceAsStream("pptlicense.xml");// license路径
            License aposeLic = new License();
            aposeLic.setLicense(license);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    public static void ppt2pdf(String Address) {
        // 验证License
        if (!getLicense()) {
            return;
        }
        try {
            long old = System.currentTimeMillis();
            File file = new File("F:\\pdf/pdf3.pdf");// 输出pdf路径
            Presentation pres = new Presentation(Address);//输入pdf路径
            FileOutputStream fileOS = new FileOutputStream(file);
            pres.save(fileOS, SaveFormat.Pdf);
            fileOS.close();
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒\n\n" + "文件保存在:" + file.getPath()); //转化过程耗时
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Linux下编译运行:

javac -cp /usr/local/temp/aspose-words-15.8.0-jdk16.jar Doc2Pdf.java

java -cp /usr/local/temp/aspose-words-15.8.0-jdk16.jar:/usr/local/temp Doc2Pdf

 

效果:

转换文档:

PDF技术(一)-Java实现Office系列文件转PDF文件_第22张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第23张图片

平均4.2s。

共耗时:4.213秒

共耗时:4.2秒

共耗时:4.361秒

共耗时:3.959秒

共耗时:4.235秒

 

转换ppt:

PDF技术(一)-Java实现Office系列文件转PDF文件_第24张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第25张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第26张图片

平均15.5s

共耗时:15.979秒

共耗时:15.212秒

共耗时:14.663秒

转换excel:

平均2.6s

PDF技术(一)-Java实现Office系列文件转PDF文件_第27张图片

PDF技术(一)-Java实现Office系列文件转PDF文件_第28张图片

共耗时:2.67秒

共耗时:2.524秒

共耗时:2.741秒

共耗时:2.7秒

 

暂时就发现这些实现Office转PDF的方法,以后还有其他方法的话,欢迎大家评论共讨,同时本博客也会继续更新下去。

 

你可能感兴趣的:(PDF技术)