Office文檔轉換成PDF文檔

本方案是我在網絡上收集前人智慧,以及辛苦奮鬥探索幾周完成的成果。

本文從一個只會Java零基礎的開發者的角度,全面、瑣碎的進行總結。


具體方案:

方案一、使用OpenOffice.org的系統服務+jodconverter插件 將office文檔轉換爲pdf:

OpenOffice.org 是一套跨平臺的辦公室軟件套件,能在 Windows、Linux、MacOS X (X11)、和 Solaris 等操作系統上執行。它與各個主要的辦公室軟件套件兼容。OpenOffice.org 是自由軟件,任何人都可以免費下載、使用、及推廣它。

OpenOffice org 的 API 以 UNO (UniversalNetwork Object) 寫成,所以本身是電腦語言中立的。現在來說,OpenOffice org主要是以 C++ 撰寫的,但也能以 Java(TM) 來撰寫。

1. 需要用的軟件

    OpenOffice 下載地址http://www.openoffice.org/

    JodConverter 下載地址http://sourceforge.net/projects/jodconverter/files/JODConverter/,也可以直接從附件裏面下載

2.啓動OpenOffice的服務

    利用OpenOffice進行轉碼的時候,都是需要先用cmd啓動一個soffice服務,啓動的命令是:soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;"。

    實際上,在我的項目中,進行轉碼只是偶爾進行,然而當OpenOffice的轉碼服務啓動以後,該進程(進程名稱是soffice.exe)會一直存在,佔用系統資源。可以將執行該服務的命令直接在JAVA代碼裏面調用,然後當轉碼完成的時候,直接幹掉這個進程。

3.將JodConverter相關的jar包添加到項目中

    將JodConverter解壓縮以後,把lib下面的jar包全部添加到項目中,還需要將jodconverter-core-3.0-beta-4.jar包加載到項目中


下面是Java代碼:


package com.warshaw.util;

import java.io.File;
import java.net.ConnectException;
import java.util.Date;

import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;

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;

public class DOC2PDFUtil extends java.lang.Thread {
	private File inputFile;// 需要轉換的文件
	private File outputFile;// 輸出的文件
	
	private static OfficeManager officeManager;
	private static String OFFICE_HOME = "C:\\Program Files (x86)\\OpenOffice 4";//OpenOffice安裝目錄
	private static int port[] = { 8100 };

	public DOC2PDFUtil(File inputFile, File outputFile) {
		this.inputFile = inputFile;
		this.outputFile = outputFile;
	}

	public void docToPdf() {
		Date start = new Date();
		
		OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
		try {
			startService();
			connection.connect();
			DocumentConverter converter = new OpenOfficeDocumentConverter(
					connection);
			converter.convert(inputFile, outputFile);
			stopService();
		} catch (ConnectException cex) {
			cex.printStackTrace();
		} finally {
			// close the connection
			if (connection != null) {
				connection.disconnect();
				connection = null;
			}
		}
	}

	// 打開服務器
	public static void startService() {
		DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
		try {
			System.out.println("準備啓動服務....");
			configuration.setOfficeHome(OFFICE_HOME);// 設置OpenOffice.org安裝目錄
			configuration.setPortNumbers(port); // 設置轉換端口,默認爲8100
			configuration.setTaskExecutionTimeout(1000 * 60 * 5L);// 設置任務執行超時爲5分鐘
			configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);// 設置任務隊列超時爲24小時

			officeManager = configuration.buildOfficeManager();
			officeManager.start(); // 啓動服務
			System.out.println("office轉換服務啓動成功!");
		} catch (Exception ce) {
			System.out.println("office轉換服務啓動失敗!詳細信息:" + ce);
		}
	}

	// 關閉服務器
	public static void stopService() {
		System.out.println("關閉office轉換服務....");
		if (officeManager != null) {
			officeManager.stop();
		}
		System.out.println("關閉office轉換成功!");
	}

	/**
	 * 由於服務是線程不安全的,所以……需要啓動線程
	 */
	public void run() {
		this.docToPdf();
	}

	public File getInputFile() {
		return inputFile;
	}

	public void setInputFile(File inputFile) {
		this.inputFile = inputFile;
	}

	public File getOutputFile() {
		return outputFile;
	}

	public void setOutputFile(File outputFile) {
		this.outputFile = outputFile;
	}

	/**
	 * 測試main方法
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		File inputFile = new File("e://xheditor的使用.doc");
		File outputFile = new File("e://xheditor的使用.pdf");
		DOC2PDFUtil dp = new DOC2PDFUtil(inputFile, outputFile);
		dp.start();
	}
}

方案二、使用jacob插件 將office文檔轉換爲pdf:

1、下載jacob的最新版本,並導入到項目的運行環境中中(注意jar包和.dll文件的存放目錄,不然會導致程序運行出錯)

下載地址:http://sourceforge.net/projects/jacob-project/

將jar放到jdk下的jre的ext目錄下:C:\Program Files\Java\jdk1.7.0_21\jre\lib\ext\(這是我的jdk安裝目錄)

將*.dll(有兩個,一個是x_86的,一個是x_64的,根據當前系統選擇。我的系統是win7 64位 旗艦版)放到jdk下的jre的bin目錄下:C:\Program Files\Java\jdk1.7.0_21\jre\bin


下面是Java代碼:

package com.warshaw.util;

import java.io.File;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class Office2PdfUtil {
	
	private String outputpath;//設置輸出路徑
	
	static final int wdFormatPDF = 17;// PDF 格式
	
	private ActiveXComponent app = null;
	private Dispatch doc = null;

	/**
	 * 文件轉換方法
	 * @author warshaw
	 * @dataTime: 2014-10-30 下午4:17:35
	 * @param inpath-指定被轉換文件的完整路徑
	 */
	public void fileConverter(String inpath) {
		// 根據路徑創建文件對象
		File file = new File(inpath);
		System.out.println("文件路徑: " + file.getPath());

		// 獲取文件名(包含擴展名)
		String fileName = file.getName();
		System.out.println("文件名稱: " + file.getName());
		
		// 過濾掉文件名中的擴展名
		int filenamelength = fileName.length();
		System.out.println("文件名長度: " + filenamelength);
		int dotposition = fileName.lastIndexOf(".");
		fileName = fileName.substring(0, dotposition);
		
		// 設置輸出路徑,一定要包含輸出文件名(不含輸出文件的擴展名)
//		String outpath = System.getProperty("java.io.tmpdir");//設置輸出路徑爲系統臨時文件夾路徑
		String outpath = System.getenv("temp");//設置輸出路徑爲系統臨時文件夾路徑
		System.out.println("輸出路徑爲系統臨時文件夾路徑: " + outpath);
		
		outpath = new String(outpath + "\\" + fileName);
		System.out.println(outpath);
		
		try {
			// 啓動Word程序
			app = new ActiveXComponent("Word.Application");
			
			// 接收輸入文件和輸出文件的路徑
			String inFile = inpath;
			setOutputpath(outpath + ".pdf");
			System.out.println("======="+outputpath);
			
			String tpFile = outputpath;
			// 設置word不可見
			app.setProperty("Visible", new Variant(false));
			Dispatch docs = app.getProperty("Documents").toDispatch();
			// 打開輸入的doc文檔
			doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] { inFile, new Variant(false), new Variant(true) }, new int[1]).toDispatch();

			// 另存文件, 其中Variant(n)參數指定另存爲的文件類型
			Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { tpFile, new Variant(wdFormatPDF) }, new int[1]);

			System.out.println("轉換完畢。");
		} catch (Exception e) {
			System.out.println("========Error:文檔轉換失敗:" + e.getMessage());
		} finally {
			Variant f = new Variant(false);
			// 關閉並退出
			Dispatch.call(doc, "Close", f);
			if (app != null) {
				app.invoke("Quit", new Variant[] {});
			}
		}
		ComThread.Release();// 關閉winword.exe進程

	}

	public String getOutputpath() {
		return outputpath;
	}

	public void setOutputpath(String outputpath) {
		this.outputpath = outputpath;
	}
	
	public static void main(String[] args) {
		Office2PdfUtil o2p = new Office2PdfUtil();
		String inpath = new String("e://xheditor的使用.doc");
		
		o2p.fileConverter(inpath);
	}

}

/*
 * 其中第65行中的 invoke()函數中的Variant(n)參數指定另存爲的文件類型(n的取值範圍是0-25),他們分別是:
 * Variant(0):doc
 * Variant(1):dot
 * Variant(2-5),Variant(7):txt
 * Variant(6):rft
 * Variant(8),Variant(10):htm
 * Variant(9):mht
 * Variant(11),Variant(19-22):xml
 * Variant(12):docx
 * Variant(13):docm
 * Variant(14):dotx
 * Variant(15):dotm
 * Variant(16)、Variant(24):docx
 * Variant(17):pdf
 * Variant(18):xps
 * Variant(23):odt
 * Variant(25):與Office2003與2007的轉換程序相關,執行本程序後彈出一個警告框說是需要更高版本的 Microsoft Works
 * Converter由於我計算機上沒有安裝這個轉換器,所以不清楚此參數代表什麼格式
 * 
 */

我的office版本是2010的,如果是2007的版本,還需要安裝一個office的兼容包SaveASPDFandXPS.exe。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章