<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    xhchc

    危波帆墻,笑談只在桃花上;與誰(shuí)共尚,風(fēng)吹萬(wàn)里浪; 相依相偎,不做黃泉想;莫惆悵,碧波潮生,一蕭自狂放……

     

    教您怎樣在Web應(yīng)用中動(dòng)態(tài)創(chuàng)建PDF文件

    在一個(gè)最近的后勤項(xiàng)目中,客戶要求我們建一個(gè)能讓用戶能從一個(gè)遺留系統(tǒng)查詢出貨信息的Web站點(diǎn),有三個(gè)主要的需求:

    1.出貨信息必須以PDF文檔的格式返回;

    2.PDF文件必須能通過(guò)瀏覽器下載;

    3.PDF文件必須能用Adobe Acrobat Reader閱讀;

    盡管我們的團(tuán)隊(duì)有很多J2EE Web應(yīng)用的開發(fā)經(jīng)驗(yàn),但在PDF文檔處理上卻沒(méi)有多少經(jīng)驗(yàn)。我們需要找一個(gè)能在服務(wù)器端Web應(yīng)用里產(chǎn)生復(fù)雜的PDF文檔的純Java類庫(kù)。最后,我們發(fā)現(xiàn)iText(http://www.lowagie.com/iText/)能完全滿足我們的需要。

    1.iText類庫(kù)

    iText是一個(gè)創(chuàng)建和處理PDF文檔的開源純Java類庫(kù)。Bruno Lowagie和Paulo Soares領(lǐng)導(dǎo)著這個(gè)項(xiàng)目。IText API能讓Java開發(fā)人員以編程的方式創(chuàng)建PDF文檔。iText提供了很多的特性:

    支持PDF和FDF文檔
    各種頁(yè)面尺寸
    橫向和豎向布局
    頁(yè)邊距
    表格
    斷字
    頁(yè)頭
    頁(yè)腳
    頁(yè)碼
    條形碼
    字體
    顏色
    文檔加密
    JPEG,GIF,PNG和WMF圖片
    有序和無(wú)序列表
    陰影
    水印
    文檔模板

    軟件開發(fā)網(wǎng) www.mscto.com



    iText是一個(gè)開源庫(kù)。在寫本文的時(shí)候,iText可以在兩個(gè)許可協(xié)議下使用:Mozilla Public License和LGPL。如果想了解詳細(xì)信息,請(qǐng)參考iText站點(diǎn)。在本文中,你將會(huì)看到iText API的應(yīng)用。我們將闡述如何在服務(wù)器端應(yīng)用中使用iText和servlet動(dòng)態(tài)生成PDF文檔。

    2、開始(Getting Started)

    首先,你需要一個(gè)iText Jar文件。訪問(wèn)iText站點(diǎn)并下載最新的版本。在寫本文時(shí),最新的版本是使0.99。iText站點(diǎn)提供了API文檔和一個(gè)全面的指南。

    除了iText,我們還要用servlet.如果你不熟悉servlet,你可以通過(guò)Jason Hunter的書《Java Servlet Programming》來(lái)學(xué)習(xí)它。你需要一個(gè)J2EE應(yīng)用服務(wù)器或可以獨(dú)立運(yùn)行的servlet引擎。開源軟件Tomcat,Jetty和Jboss是不錯(cuò)的選擇。下文假設(shè)你使用的是Jakarta Tomcat 4.1。

    1.iText API

    iText API簡(jiǎn)單易用。通過(guò)使用iText,你能創(chuàng)建自定義的PDF文檔。iText庫(kù)由下邊的一些包組成:

    com.lowagie.servlets
    com.lowagie.text
    com.lowagie.text.html
    com.lowagie.text.markup
    com.lowagie.text.pdf
    com.lowagie.text.pdf.codec
    com.lowagie.text.pdf.hyphenation
    com.lowagie.text.pdf.wmf
    com.lowagie.text.rtf
    com.lowagie.text.xml
    com.lowagie.tools  

    為了生成PDF文件,你只需要com.lowagie.text和com.lowagie.text.pdf兩個(gè)包。 軟件開發(fā)網(wǎng) www.mscto.com

    我們的例子使用了這些iText類:

     

    com.lowagie.text.pdf.PdfWriter
    com.lowagie.text.Document
    com.lowagie.text.HeaderFooter
    com.lowagie.text.Paragraph
    com.lowagie.text.Phrase
    com.lowagie.text.Table
    com.lowagie.text.Cell
    

    軟件開發(fā)網(wǎng) www.mscto.com

    關(guān)鍵的類是Document和PdfWriter。在創(chuàng)建PDF文檔時(shí),你將經(jīng)常使用這兩個(gè)類。Document是PDF文檔基于對(duì)象的描述。你可以通過(guò)調(diào)用Document類提供的方法往文檔中加入內(nèi)容。PdfWriter對(duì)象通過(guò)java.io.OutputStream對(duì)象與Document關(guān)聯(lián)在一起。

     

    3、在Web應(yīng)用中使用iText

    在設(shè)計(jì)階段,你必須決定如何使用iText。我們使用了下邊的技術(shù)開發(fā)了我們的Web應(yīng)用。

    1.A技術(shù)

    在服務(wù)器文件系統(tǒng)上創(chuàng)建PDF文件。應(yīng)用使用java.io.FileOutputStream把文件寫到服務(wù)器文件系統(tǒng)上。用戶通過(guò)HTTP GET方法下載該文件。

    2.B技術(shù)

    使用java.io.ByteArrayOutputStream在內(nèi)存中創(chuàng)建PDF文件。應(yīng)用通過(guò)servlet的輸出流將該P(yáng)DF文件字節(jié)發(fā)送到客戶端。

    由于應(yīng)用不需要把文件寫到文件系統(tǒng)上,這樣能保證在集群服務(wù)環(huán)境中能正常工作,所以我更傾向于使用B技術(shù)。如果你的應(yīng)用運(yùn)行在集群環(huán)境中且服務(wù)器集群不提供會(huì)話親和的功能,A技術(shù)可能會(huì)導(dǎo)致失敗。

    3、例子:PDFServlet

    我們的例子應(yīng)用由一個(gè)類組成:PDFServlet。這個(gè)servlet采用B技術(shù)。輸出流OutputStream是java.io.ByteArryOutputStream。用ByteArrayOutputStream,PDF文檔字節(jié)將存儲(chǔ)在內(nèi)存中。

    當(dāng)PDFServlet接收到一個(gè)HTTP請(qǐng)求時(shí),它將動(dòng)態(tài)地生成一個(gè)PDF文檔并將該文檔發(fā)送到客戶端。PDFServlet類擴(kuò)展了javax.servlet.http.HttpServlet類并導(dǎo)入了兩個(gè)iText包:com.lowagie.text和com.lowagie.text.pdf。



    doGet方法

    大多數(shù)servlet覆蓋了doPost和doGet方法中的一個(gè)方法。我們的servlet沒(méi)有什么不同。PDFServlet類覆蓋了doGet方法。該servlet將在接收到HTTP GET請(qǐng)求后生成一個(gè)PDF文件。

    在核心部分,servlet的doGet方法做了如下的工作:

    1.創(chuàng)建一個(gè)包含PDF文檔字節(jié)的ByteArrayOutputStream對(duì)象;

    2.在reponse對(duì)象上設(shè)置HTTP響應(yīng)頭內(nèi)容;

    3.得到servlet輸出流;

    4.把文檔字節(jié)寫到servlet的輸出流中;

    5.刷新servlet輸出流;

    generatePDFDocumentBytes方法

    generatePDFDocumentBytes方法負(fù)責(zé)創(chuàng)建PDF文檔。在這個(gè)方法中三個(gè)最重要的對(duì)象是Document對(duì)象,ByteArrayOutputStream對(duì)象和PdfWriter對(duì)象。PdfWriter使用ByteArrayOutputStream關(guān)聯(lián)Document。

    軟件開發(fā)網(wǎng) www.mscto.com

     

    Document doc = new Document();
    ByteArrayOutputStream
    baosPDF = new ByteArrayOutputStream();
    PdfWriter docWriter = null;
    docWriter
    = PdfWriter.getInstance(doc, baosPDF);
    // ...
    用add方法把內(nèi)容添加到Document中。
    doc.add(new Paragraph(
    "This document was
    created by a class named: "
    this.getClass().getName()));
    doc.add(new Paragraph(
    "This document was created on "
    new java.util.Date())); 軟件開發(fā)網(wǎng) www.mscto.com 

    當(dāng)你添加完內(nèi)容后,要關(guān)閉Document和PdfWriter對(duì)象。

     

    doc.close();
    docWriter.close();  

    當(dāng)關(guān)閉文檔后,ByteArrayOutputStream對(duì)象返回到調(diào)用者。

     

     

    return baosPDF;  

    ByteArrayOutputStream包含了PDF文檔的所有字節(jié)。

    HTTP響應(yīng)頭

    在這個(gè)應(yīng)用中,我們僅僅關(guān)注四個(gè)HTTP 響應(yīng)頭:Content-type,Content-disposition,Content-length,和Cache-control。如果你從沒(méi)有使用過(guò)HTTP頭,請(qǐng)參考HTTP 1.1規(guī)范。

    研究在PDFServlet中的doGet方法,你會(huì)注意到要在任何數(shù)據(jù)寫到servlet輸出流之前設(shè)置HTTP響應(yīng)頭內(nèi)容,這是很重要的,也是細(xì)微的一點(diǎn)。讓我們更詳細(xì)地說(shuō)明一下每個(gè)響應(yīng)頭的含義。

     

    Content-type

     

    在servlet中,HttpServletResponse有一個(gè)表明響應(yīng)所包含內(nèi)容類型的參數(shù)。對(duì)PDF文件而言,內(nèi)容類型是application/pdf。如果servlet沒(méi)有設(shè)置類型,web瀏覽器很難決定如何處理這個(gè)文件。

     

    PDFServlet用下邊的代碼設(shè)置內(nèi)容類型:

     

     

    resp.setContentType("application/pdf");
    

    Content-disposition

     

    Content-disposition頭提供給瀏覽器確定HTTP響應(yīng)內(nèi)容的信息。當(dāng)瀏覽器讀到這些頭信息后,它能確定:

    HTTP響應(yīng)包含一個(gè)文件;

     

    包含在響應(yīng)中的文件名;

     

    該文件是顯示在瀏覽器主窗口中還是要用外部的應(yīng)用查看;

    RFC 2183中有對(duì)Content-disposition頭完整的解釋。

     

    通過(guò)合適地設(shè)置Content-disposition的值,servlet能指示瀏覽器是“內(nèi)嵌”顯示文件還是把它當(dāng)作附件處理。

    軟件開發(fā)網(wǎng) www.mscto.com

     

    例1.內(nèi)嵌顯示一個(gè)文件

     

    Content-disposition: inline;
    filename=foobar.pdf  

    例2.往response里附加一個(gè)文件

    軟件開發(fā)網(wǎng) www.mscto.com

     

    軟件開發(fā)網(wǎng) www.mscto.com

     

    Content-disposition: attachment;
    filename=foobar.pdf  

    下邊的偽碼說(shuō)明了如何設(shè)置頭信息:

     

    軟件開發(fā)網(wǎng) www.mscto.com

     

    public void doGet(HttpServletRequest req,
    HttpServletResponse resp)
    {
    // ...
    resp.setHeader(
    "Content-disposition",
    "inline; filename=foobar.pdf" );
    // ...
    }  

    Cache-Control

    根據(jù)你應(yīng)用的特性不同,你可以讓瀏覽器緩存或者不緩存你正在生成的PDF文件。服務(wù)器端應(yīng)用可以有很多種HTTP 頭來(lái)控制內(nèi)容緩存。下邊是一些例子:











     

    Cache-Control: no-cache
    Cache-Control: no-store
    Cache-Control: must-revalidate
    Cache-Control: max-age=30
    Pragma: no-cache
    

    Expires: 0

     

    關(guān)于Cache-Control頭的全面解釋見HTTP 1.1規(guī)范。

     

    PDFServlet把Cache-Control設(shè)置為max-age=30。這個(gè)頭信息告訴瀏覽器緩存這個(gè)文件的最長(zhǎng)時(shí)間為30秒。

     

    Content-length

     

    Content-length頭必須設(shè)置成PDF文件中字節(jié)的數(shù)值。如果Content-length沒(méi)有設(shè)置正確,瀏覽器可能不能正確地顯示該文件。下邊是例子代碼:

    ByteArrayOutputStream
    baos = getByteArrayOutputStream();
    resp.setContentLength(baos.size());  

    把PDF文檔送到Web瀏覽器

    軟件開發(fā)網(wǎng) www.mscto.com

     

    PDFServlet通過(guò)把字節(jié)流寫到servlet的輸出流的方式把PDF文檔送到客戶端。它通過(guò)調(diào)用HttpServletResponse對(duì)象的getOutputStream方法來(lái)獲得輸出流。getOutputStream方法返回一個(gè)javax.servlet.ServletOutputStream類型的對(duì)象。

     

    ServletOutputStream sos;
    sos = resp.getOutputStream();
    baos.writeTo(sos);
    sos.flush();
    

    在把所有的數(shù)據(jù)寫到流之后,調(diào)用flush()方法把所有的字節(jié)發(fā)送到客戶端。

     

    打包和部署

    為了在Tomcat中運(yùn)行PDFServlet,你需要把應(yīng)用打包在WAR文件中。iText JAR文件(itext-0.99.jar)必須放在WAR文件的lib目錄下邊。如果你忘了把iText JAR文件打包進(jìn)去,servlet會(huì)報(bào)一個(gè)java.lang.NoClassDefFoundError的錯(cuò)誤并停止運(yùn)行。

    運(yùn)行應(yīng)用

    在WAR文件部署之后,你已經(jīng)準(zhǔn)備好了測(cè)試servlet了。Jakarta Tomcat在8080端口上監(jiān)聽請(qǐng)求。

     

    在瀏覽器中請(qǐng)求http://hostname:8080/pdfservlet/createpdf。servlet將會(huì)執(zhí)行并返回瀏覽器一個(gè)PDF文檔。

    4、iText之外的方案

     

    iText提供了許多產(chǎn)生PDF文檔的底層API。然而,它不是對(duì)任何應(yīng)用都有效。在我的日常工作中,我結(jié)合Microsoft Word和Adobe Acrobat使用iText。首先,我們的團(tuán)隊(duì)使用Microsoft Word設(shè)計(jì)了一個(gè)出貨表單。之后,我們用Acrobat把Word文檔轉(zhuǎn)換成PDF文檔。然后,我們使用iText的模板的功能,我們把PDF文件裝入到我們的應(yīng)用中。從這里,把數(shù)據(jù)填入表格和輸出最終的PDF文檔是相當(dāng)容易的。對(duì)基于報(bào)表的Web應(yīng)用,像JasperReports這樣的工具,它提供了比iText更高層次的抽象。

    posted on 2008-08-12 13:58 chu 閱讀(200) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(2)

    隨筆檔案

    我的鏈接

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲砖码砖专无区2023| 亚洲视频在线免费观看| 亚洲国产精品美女久久久久| 野花高清在线电影观看免费视频| 亚洲成a人片在线网站| 精品国产污污免费网站aⅴ | 亚洲人成电影网站国产精品 | 亚洲av无码成人精品区一本二本| 成人av免费电影| 亚洲AV无码成人网站在线观看| 日本黄页网站免费| 免费精品视频在线| 亚洲一区二区三区在线视频| 中文字幕在线成人免费看| 亚洲国产成人一区二区精品区| 免费无码黄网站在线看| 亚洲色欲或者高潮影院| 成年人在线免费观看| 国产精品亚洲专区无码牛牛| 亚洲国产一级在线观看| 国产一精品一av一免费爽爽 | 蜜芽亚洲av无码精品色午夜| 99精品视频在线免费观看| 亚洲国产午夜精品理论片| 日韩免费福利视频| 一个人免费观看视频在线中文| 久久夜色精品国产亚洲AV动态图 | 亚洲精品中文字幕乱码| 四虎成人免费网址在线| 一级成人a做片免费| 亚洲av成人无码久久精品| 色婷婷7777免费视频在线观看 | av电影在线免费看| 亚洲av日韩av激情亚洲| 成人毛片免费观看| 久久av免费天堂小草播放| 亚洲国产精品综合久久网各| 又大又黄又粗又爽的免费视频| 国产午夜精品久久久久免费视| 亚洲人成网站18禁止| 亚洲日韩aⅴ在线视频|