`
lz726
  • 浏览: 333511 次
  • 性别: Icon_minigender_2
  • 来自: 福建,福州
社区版块
存档分类
最新评论

在Web应用中动态创建PDF文件

阅读更多

在一个最近的后勤项目中,客户要求我们建一个能让用户能从一个遗留系统查询出货信息的Web站点,有三个主要的需求:
1.出货信息必须以PDF文档的格式返回;
2.PDF文件必须能通过浏览器下载;
3.PDF文件必须能用Adobe Acrobat Reader阅读;
尽管我们的团队有很多J2EE Web应用的开发经验,但在PDF文档处理上却没有多少经验。我们需要找一个能在服务器端Web应用里产生复杂的PDF文档的纯Java类库。最后,我们发现iText(http://www.lowagie.com/iText/)能完全满足我们的需要。

<!---->

 
1.iText类库

iText是一个创建和处理PDF文档的开源纯Java类库。Bruno Lowagie和Paulo Soares领导着这个项目。IText API能让Java开发人员以编程的方式创建PDF文档。iText提供了很多的特性:

支持PDF和FDF文档

各种页面尺寸

横向和竖向布局

页边距

表格

断字

页头

页脚

页码

条形码

字体

颜色

文档加密

JPEG,GIF,PNG和WMF图片

有序和无序列表

阴影

水印

文档模板
iText是一个开源库。在写本文的时候,iText可以在两个许可协议下使用:Mozilla Public License和LGPL。如果想了解详细信息,请参考iText站点。在本文中,你将会看到iText API的应用。我们将阐述如何在服务器端应用中使用iText和servlet动态生成PDF文档。

2.开始(Getting Started)

首先,你需要一个iText Jar文件。访问iText站点并下载最新的版本。在写本文时,最新的版本是使0.99。iText站点提供了API文档和一个全面的指南。
除了iText,我们还要用servlet.如果你不熟悉servlet,你可以通过Jason Hunter的书《Java Servlet Programming》来学习它。你需要一个J2EE应用服务器或可以独立运行的servlet引擎。开源软件Tomcat,Jetty和Jboss是不错的选择。下文假设你使用的是Jakarta Tomcat 4.1。

1.iText API

iText API简单易用。通过使用iText,你能创建自定义的PDF文档。iText库由下边的一些包组成:
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两个包。
我们的例子使用了这些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
关键的类是Document和PdfWriter。在创建PDF文档时,你将经常使用这两个类。Document是PDF文档基于对象的描述。你可以通过调用Document类提供的方法往文档中加入内容。PdfWriter对象通过java.io.OutputStream对象与Document关联在一起。

3.在Web应用中使用iText

在设计阶段,你必须决定如何使用iText。我们使用了下边的技术开发了我们的Web应用。

1.A技术

在服务器文件系统上创建PDF文件。应用使用java.io.FileOutputStream把文件写到服务器文件系统上。用户通过HTTP GET方法下载该文件。

2.B技术

使用java.io.ByteArrayOutputStream在内存中创建PDF文件。应用通过servlet的输出流将该PDF文件字节发送到客户端。
由于应用不需要把文件写到文件系统上,这样能保证在集群服务环境中能正常工作,所以我更倾向于使用B技术。如果你的应用运行在集群环境中且服务器集群不提供会话亲和的功能,A技术可能会导致失败。

3.例子:PDFServlet

我们的例子应用由一个类组成:PDFServlet。这个servlet采用B技术。输出流OutputStream是java.io.ByteArryOutputStream。用ByteArrayOutputStream,PDF文档字节将存储在内存中。当PDFServlet接收到一个HTTP请求时,它将动态地生成一个PDF文档并将该文档发送到客户端。
PDFServlet类扩展了javax.servlet.http.HttpServlet类并导入了两个iText包:com.lowagie.text和com.lowagie.text.pdf。
doGet方法
大多数servlet覆盖了doPost和doGet方法中的一个方法。我们的servlet没有什么不同。PDFServlet类覆盖了doGet方法。该servlet将在接收到HTTP GET请求后生成一个PDF文件。
在核心部分,servlet的doGet方法做了如下的工作:
1.创建一个包含PDF文档字节的ByteArrayOutputStream对象;
2.在reponse对象上设置HTTP响应头内容;
3.得到servlet输出流;
4.把文档字节写到servlet的输出流中;
5.刷新servlet输出流;
generatePDFDocumentBytes方法
generatePDFDocumentBytes方法负责创建PDF文档。在这个方法中三个最重要的对象是Document对象,ByteArrayOutputStream对象和PdfWriter对象。PdfWriter使用ByteArrayOutputStream关联Document。
Document doc = new Document();
ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
PdfWriter docWriter = null;
docWriter = PdfWriter.getInstance(doc, baosPDF);
// ...
用add方法把内容添加到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()));

当你添加完内容后,要关闭Document和PdfWriter对象。
doc.close();
docWriter.close();
当关闭文档后,ByteArrayOutputStream对象返回到调用者。
return baosPDF;
ByteArrayOutputStream包含了PDF文档的所有字节。
HTTP响应头
在这个应用中,我们仅仅关注四个HTTP 响应头:Content-type,Content-disposition,Content-length,和Cache-control。如果你从没有使用过HTTP头,请参考HTTP 1.1规范。
研究在PDFServlet中的doGet方法,你会注意到要在任何数据写到servlet输出流之前设置HTTP响应头内容,这是很重要的,也是细微的一点。
让我们更详细地说明一下每个响应头的含义。
Content-type


在servlet中,HttpServletResponse有一个表明响应所包含内容类型的参数。对PDF文件而言,内容类型是application/pdf。如果servlet没有设置类型,web浏览器很难决定如何处理这个文件。
PDFServlet用下边的代码设置内容类型:
resp.setContentType("application/pdf");
Content-disposition
Content-disposition头提供给浏览器确定HTTP响应内容的信息。当浏览器读到这些头信息后,它能确定:

HTTP响应包含一个文件;

包含在响应中的文件名;

该文件是显示在浏览器主窗口中还是要用外部的应用查看;
RFC 2183中有对Content-disposition头完整的解释。
通过合适地设置Content-disposition的值,servlet能指示浏览器是“内嵌”显示文件还是把它当作附件处理。
例1.内嵌显示一个文件
Content-disposition: inline; filename=foobar.pdf
例2.往response里附加一个文件
Content-disposition: attachment; filename=foobar.pdf
下边的伪码说明了如何设置头信息:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
{
// ...
resp.setHeader(
"Content-disposition",
"inline; filename=foobar.pdf" );
// ...
}
Cache-Control
根据你应用的特性不同,你可以让浏览器缓存或者不缓存你正在生成的PDF文件。服务器端应用可以有很多种HTTP 头来控制内容缓存。下边是一些例子:

Cache-Control: no-cache

Cache-Control: no-store

Cache-Control: must-revalidate

Cache-Control: max-age=30

Pragma: no-cache

Expires: 0
关于Cache-Control头的全面解释见HTTP 1.1规范。
PDFServlet把Cache-Control设置为max-age=30。这个头信息告诉浏览器缓存这个文件的最长时间为30秒。
Content-length
Content-length头必须设置成PDF文件中字节的数值。如果Content-length没有设置正确,浏览器可能不能正确地显示该文件。下边是例子代码:
ByteArrayOutputStream baos = getByteArrayOutputStream();
resp.setContentLength(baos.size());
把PDF文档送到Web浏览器
PDFServlet通过把字节流写到servlet的输出流的方式把PDF文档送到客户端。它通过调用HttpServletResponse对象的getOutputStream方法来获得输出流。getOutputStream方法返回一个javax.servlet.ServletOutputStream类型的对象。
ServletOutputStream sos;
sos = resp.getOutputStream();
baos.writeTo(sos);
sos.flush();
在把所有的数据写到流之后,调用flush()方法把所有的字节发送到客户端。
打包和部署
为了在Tomcat中运行PDFServlet,你需要把应用打包在WAR文件中。iText JAR文件(itext-0.99.jar)必须放在WAR文件的lib目录下边。如果你忘了把iText JAR文件打包进去,servlet会报一个java.lang.NoClassDefFoundError的错误并停止运行。
运行应用
在WAR文件部署之后,你已经准备好了测试servlet了。Jakarta Tomcat在8080端口上监听请求。
在浏览器中请求http://hostname:8080/pdfservlet/createpdf。servlet将会执行并返回浏览器一个PDF文档。

4.iText之外的方案

iText提供了许多产生PDF文档的底层API。然而,它不是对任何应用都有效。
在我的日常工作中,我结合Microsoft Word和Adobe Acrobat使用iText。首先,我们的团队使用Microsoft Word设计了一个出货表单。之后,我们用Acrobat把Word文档转换成PDF文档。然后,我们使用iText的模板的功能,我们把PDF文件装入到我们的应用中。从这里,把数据填入表格和输出最终的PDF文档是相当容易的。
对基于报表的Web应用,像JasperReports这样的工具,它提供了比iText更高层次的抽象。

5.总结

当你的应用需要动态地创建PDF文档的时,iText类库是一个不错的方案。你可以通过增强和扩展本文中的代码来体验iText的能力。很快,由于提供了完善的PDF文档,你将会给你的同事和客户留下深刻的印象。

6.其他资源

http://www.lowagie.com/iText/
www.jpedal.org
www.pdfbox.org
xml.apache.org/fop
HTTP 1.1 protocol specification
RFC 2183
dmoz.org/Computers/Data_Formats/Document/Publishing/PDF
www.planetpdf.com
www.pdfzone.com

分享到:
评论

相关推荐

    C#Web应用程序入门经典_程序设计

    在Web开发领域,C#常与ASP.NET框架结合使用,创建服务器端的Web应用程序。 接下来,Web应用程序是指运行在Web服务器上,通过HTTP协议与客户端(如浏览器)进行交互的应用。C# Web应用程序开发涉及到的知识点包括: ...

    react-reactpdf使用React创建PDF文件

    总的来说,`react-pdf`为React开发者提供了一种强大且灵活的方式来创建PDF文档,使得在Web应用中生成PDF变得更加简单。通过深入理解和熟练运用这个库,你可以在项目中实现各种高级功能,提升用户体验。

    c#+web应用程序入门经典.pdf

    ***是.NET框架的一部分,它允许开发者用C#语言来创建动态网站、Web应用程序和Web服务。 《C# + Web应用程序入门经典》这本书很可能是针对初学者而设计的。这类入门书籍通常会介绍如何安装和配置C#开发环境,如何...

    在MFC应用程序中浏览PDF、Word文档文件

    由于“Microsoft Web浏览器”控件用于浏览PDF和Word文档的目的,且应用程序采用多文档视图结构,因此不适合使用资源视图中拖拽控件的传统方式,而应通过代码实现动态创建。在将控件插入工程后,会自动生成派生于`...

    Java Servlet实现在浏览器中打开pdf文件

    本篇文章将探讨如何使用Java Servlet实现在浏览器中打开PDF文件。首先,我们需要理解Servlet的工作原理和PDF文件的处理方式。 Servlet是Java编程语言中的一个接口,它定义了Web服务器与Java代码之间的交互方式。当...

    SpringBoot在线预览PDF文件

    本项目的核心是实现PDF在线预览功能,它利用了SpringBoot的Web服务特性,结合PDF.js库来实现在浏览器中预览PDF文件。 首先,我们需要理解SpringBoot的Web开发基础。SpringBoot内置了对HTTP请求处理的支持,通过创建...

    基于Django快速开发Web应用

    2. **定义模型**:在应用的models.py文件中定义模型,然后通过`python manage.py makemigrations`和`python manage.py migrate`命令创建数据库表。 3. **创建视图**:在应用的views.py文件中编写视图函数,处理HTTP...

    web应用开发实验报告.pdf

    报告内容中出现的"Internet"一词,指出该Web应用需要在互联网环境下运行,而对浏览器的支持和兼容性也是Web应用开发中必须考虑的因素。 11. 数据库技术 报告内容提到了"MicrosoftAccess",表明实验中使用的数据库...

    SpringBoot采用pdf.js加载pdf文件

    在现代Web应用中,预览PDF文件是一项常见的需求。SpringBoot作为一个轻量级的Java框架,可以帮助我们构建高效、简洁的后端服务。而pdf.js是Mozilla开发的一个用于在浏览器中渲染PDF文件的JavaScript库,它能够使得...

    H5自动展示pdf文件,pdf.js

    在H5中,通过Canvas、SVG等元素,可以创建丰富的动态内容,但原生并不支持PDF的直接展示。这就需要像PDF.js这样的库来填补这个空白。 PDF.js的核心功能在于,它能够将PDF文件解析为一系列可渲染的图像或者文本,...

    ASP NET web 打印PDF

    ASP.NET Web打印PDF技术主要涉及两个关键点:一是如何在Web环境中生成PDF文件,二是如何实现从网页直接打印这些PDF。这项技术对于那些需要在线提供报告、发票或合同等文档的Web应用程序尤其重要。 首先,生成PDF...

    goAhead webServer应用开发文档.pdf

    在GoAhead Web Server 的应用开发中,主要包括三种类型的页面开发方法:静态页面、CGI页面以及嵌入式JavaScript页面。这些方法各有特点,适用于不同的应用场景。 ##### 1. 静态页面 - **定义**:静态页面通常用于...

    4602231《JSP Web应用开发案例教程》(侯玉香)720-9素材与实例.zip

    《JSP Web应用开发案例教程》是侯玉香教授撰写的一本教材,旨在帮助读者深入理解和掌握JSP(JavaServer Pages)技术在Web应用开发中的实际运用。这本教程通过丰富的案例,详细讲解了JSP的基本概念、语法特性以及如何...

    Oracle组件在动态Web数据库的应用.pdf

    在动态Web数据库的构建中,Oracle发挥着核心作用,允许开发者创建交互式的、实时更新的网络应用程序。 在传统的Web服务器中,网页内容是静态的,存储和管理在文件系统中。然而,随着互联网应用的快速发展,这种静态...

    WEB应用与开发与数据库

    1. "Web_应用程序开发——算法分析与应用.pdf":这份文档可能详细介绍了Web应用开发中的算法应用,包括排序、搜索、图论等,这些算法在优化Web性能、解决复杂问题和提高用户体验方面起着关键作用。 2. "CodePub.Com...

    WEB应用数据权限控制.pdf

    10. XML配置:文档中提到了Spring的配置文件"applicationContext-resources.xml",在其中会配置数据源、事务管理器以及相关的业务Bean,这是实现WEB应用数据权限控制的重要配置文件。 通过以上分析,我们可以看出...

    Java.Web应用开发.J2EE和Tomcat第2版.pdf

    从给定的文件标题“Java.Web应用开发.J2EE和Tomcat第2版.pdf”以及描述和标签中,我们可以提炼出一系列与Java Web应用开发、J2EE(Java 2 Platform, Enterprise Edition)和Tomcat相关的关键知识点。下面将详细阐述...

    flex web 显示PDF

    在Flex Web应用中显示PDF文件是一项常见的需求,特别是在开发交互式文档查看或在线阅读平台时。Flex是一种基于ActionScript的开源框架,用于构建富互联网应用程序(RIA),它允许开发者创建高度交互、动态的Web界面...

    quartz 在WEB中应用小结

    在Web应用中,我们可能需要动态添加、修改或删除定时任务。为此,Quartz提供了API接口,例如`Scheduler.scheduleJob()`和`Scheduler.rescheduleJob()`,这些方法可以让我们在运行时调整任务调度。 此外,Quartz还...

    Java+Web动态图表编程(PDF).rar

    本资源“Java+Web动态图表编程(PDF)”提供了一份详细的指南,帮助开发者掌握如何在Java Web应用程序中创建交互式的图表。下面将深入探讨这个主题的主要知识点: 1. **Java基础知识**:Java是一种广泛使用的面向对象...

Global site tag (gtag.js) - Google Analytics