1. 程式人生 > >JAVA PDF解決方案

JAVA PDF解決方案

概述 Java Servlet 程式設計可以很方便地將 HTML 檔案傳送到客戶端的 Web 瀏覽器。然而許多站點還允許訪問非 HTML 格式的文件,包括 Adobe PDF、Microsoft Word 和 Micorsoft Excel 等。事實上這些非 HTML 格式只要能用 MIME 型別表示,就可以利用 servlet 來發送。本文將以 PDF為例,向你介紹如何使用 servlet 傳送非 HTML 格式檔案及該檔案是如何在伺服器端用Java生成的。

你只要將檔案寫到servlet 的輸出流中,就可以利用 servlet 在瀏覽器中開啟一個檔案。首先從獲得 servlet 的輸出流開始:

ServletOutputStream out = res.getOutputStream();

網際網路上使用 MIME (multipurpos Internet mail extension 多目的網際網路郵件擴充套件協議)來傳送混合格式、多媒體和二進位制資料檔案。如果要在 servlet 的 response 物件中開啟某個文件,就必須設定該文件的 MIME 型別。

向Web客戶端傳送PDF文件
(一)MIME型別
Web 瀏覽器使用 MIME 型別來識別非 HTML 文件,並決定如何顯示該文件內的資料。將外掛 (plug-in) 與 MIME 型別結合使用,則當 Web 瀏覽器下載 MIME 型別指示的文件時,就能夠啟動相應外掛處理此文件。某些 MIME 型別還可以與外部程式結合使用,瀏覽器下載文件後會啟動相應的外部程式。

MIME 型別非常有用。它們允許 Web 瀏覽器處理不同格式的文件,卻不需要事先嵌入相關知識。Java Servlets 可以使用 MIME 型別來向瀏覽器傳送非 HTML 檔案,比如 Adobe PDF 和 Micorsoft Word。使用正確的 MIME 型別能夠保證這些非 HTML 檔案被正確的外掛或外部程式顯示。

PDF 檔案的 MIME 型別是 "application/pdf"。要用servlet 來開啟一個 PDF 文件,需要將 response 物件中 header 的 content 型別設定成 "application/pdf":

// PDF 檔案的 MIME 型別
res.setContentType( "application/pdf" );

(二)Content disposition
HTTP response header中的content-disposition 允許 servlet 指定文件表示的資訊。使用這種header ,你就可以將文件指定成單獨開啟(而不是在瀏覽器中開啟),還可以根據使用者的操作來顯示。如果使用者要儲存文件,你還可以為該文件建議一個檔名。這個建議名稱會出現在 Save As 對話方塊的“檔名”欄中。如果沒有指定,則對話方塊中就會出現 servlet 的名字。在 servlet 中,你需要將 header 設定成下面這樣:

res.setHeader("Content-disposition",
"attachment; filename=" +
"Example.pdf" );
// attachment -因為不希望在瀏覽器中直接開啟它,而是利用Adobe Acrobat。
// 可以通過設定default file name來確定儲存文當時的建議名稱。

(三)封裝非 HTML 文件
完成上述工作後,剩下的就非常簡單了。你需要根據待傳送檔案的名字,建立一個 java.net.URL 物件。交給 URL 構造器的字串必須是指向該檔案的一個有效 URL 地址。在這裡,我要開啟本地的PDF文件:

String fileURL = "http://localhost/aboutadobe/careeropp/pdfs/tables.pdf;

URL 字串也可以類似於 http://www.gr.com/pub/somefile.doc 或 http://www.gr.com/pub/somefile.xls。但必須確保待傳送檔案型別與先前在 HTTP response 物件中設定的 MIME 型別一致。

(四)其他
開始閱讀傳送的文件之前,首先要從 URL 物件中獲得輸入流 InputStream,用 BufferedInputStream 將 InputStream 封裝起來。

BufferedInputStreambis = newBufferedInputStream(url.openStream());

一旦你完成上述操作,就只要簡單地將 InputStream 中的位元組,寫入到 servlet 的輸出流 OutputStream 中:

BufferedOutputStreambos = new BufferedOutputStream(out);

byte[] buff = new byte[2048];
intbytesRead;

// 一個簡單的讀寫迴圈
while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}


在最後的程式碼塊中,關閉這些流 ,如:bos.close();

PDF文件在伺服器端的生成
利用iText040工具包可以很方便的輸出一個十分漂亮的PDF文件。

1.Document的建立
Document document=new Document(p0, p1, p2, p3, p4)

其中,p0為頁面的大小,如 PageSize.A4; p1—p4分別描述上下左右頁邊空白。

2. 構造複寫器
PdfWriter.getInstance(document, new FileOutputStream("tables.pdf"))

執行程式後,將在當前目錄下生成一個名為tables.pdf的檔案。

接著開啟Document:document.open()

3. 根據需要定義一個Table
//一個擁有十列的Table
Table datatable = new Table(10);
//定義Cell與Cell之間的距離為零
datatable.setCellpadding(0);
//定義Cell的間隔
datatable.setCellspacing(3);
//使Table沒有邊框
datatable.setBorder(Rectangle.NO_BORDER);
//定義每一列的寬度
intheaderwidths[] = {10, 30, 15, 15, 5, 5, 5, 5, 5, 5};
datatable.setWidths(headerwidths);
datatable.setWidth(100);

4.字型的定義:
BaseFont bf = BaseFont.createFont(String name, String encoding, boolean embedded)

“name”為字型名,“encoding”為編碼名稱。

5. Cell的定義
Cell cell = new Cell(new Phrase("String string",f));

String為Cell中要顯示的內容。另外有很多方法來控制Cell,其中比較常用的幾個方法如下:

cell.setBorder(int value)

根據經驗,value值對應的邊框形狀見下圖:

圖例 Value 整數值
Rectangle.ALIGN_BOTTOM 6
Rectangle.ALIGN_BASELINE 7
Rectangle.ALIGN_CENTER 1
Rectangle.ALIGN_JUSTIFIED 3
Rectangle.ALIGN_MIDDLE 5
Rectangle.ALIGN_RIGHT 2
Rectangle.ALIGN_TOP 4

cell.setColspan(int value)和 cell.setRowspan(int value)分別定義了cell所佔的列和行。

值得注意的是:一行中各cell所佔列的總和一定要嚴格符合構造table時定義的列數。

cell.setHorizontalAlignment(int value)和cell.setVerticalAlignment(int value)分別確定該cell將處在水平及豎直方向上的位置。

最後,將cell加入到table中去:table.addCell(Cell cell)

6.table加到document中去,並關閉document: