iText是一个开放源码的Java类库,可以用来方便地生成PDF文件。大家通过访问
http://sourceforge.net/project/showfiles.php?group_id=15255&release_id=167948下载最新版本的类库,下载完成之后会得到一个.jar包,把这个包加入JDK的classpath即可使用。如果生成的PDF文件中需要出现中文、日文、韩文字符,则还需要通过访问
http://itext.sourceforge.net/downloads/iTextAsian.jar下载iTextAsian.jar包。
关于iText类库的使用,
http://www.lowagie.com/iText/tutorial/index.html有比较详细的教程。该教程从入门开始,比较系统地介绍了在PDF文件中放入文字、图片、表格等的方法和技巧。读完这片教程,大致就可以做一些从简单到复杂的PDF文件了。不过,试图通过教程解决在生成PDF文件过程中遇到的所有困难无疑是一种奢望。所以,阅读iText的api文档显得非常重要。读者在下载类库的同时,也可以下载类库的文档。
如何利用iText在java程序中生成PDF报表
以下是上述教程中一个最简单的例子,这个例子刻画了通过iText生成PDF文件的一般程序框架。读者只需要在document.open();和document.close();两条语句中间加入自己希望放在PDF文件中的内容即可。该例子只在PDF文件中加了“Hello World“一行文字。
CSDN下载地址: http://download.csdn.net/user/chaozi
package com.chaozi;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
com.lowagie.text.Document;
import
com.lowagie.text.DocumentException;
import
com.lowagie.text.Paragraph;
import
com.lowagie.text.pdf.PdfWriter;
public
class
CreatP
{
public
static
void
CreatPgf(){
Document
document
=
new
Document();
try
{
PdfWriter.getInstance(document,
new
FileOutputStream
(
"Chap0101.pdf"
));
document.open();
document.add(
new
Paragraph(
"Hello World"
));
}
catch
(DocumentException
de)
{
System.err.println(de.getMessage());
}
catch
(IOException
ioe)
{
System.err.println(ioe.getMessage());
}
document.close();
}
public
static
void
main(String[]
args){
CreatPgf();
}}
由以上的例子可见,程序的框架十分清楚明了。然而在PDF中指定文字、图画、表格的位置是一件非常麻烦的事情。除了不断地在程序中修改位置、然后运行程序、生成PDF文件、观察元素在PDF中的位置是否合理这样的过程以外,似乎还没有其它更好的方法。
如何通过JSP生成PDF报表
这一部分是在iText的教程中所没有的,网上的相关资料也比较少。我曾在CSDN上看过有人开帖询问实现细节,有人回复了实现的原理:先在服务器上生成PDF文件,然后用户通过点击指向PDF文件的超链接选择下载或打开。这是一个思路,或者说是思路之一。本文实现了这个思路,又给出另外一个思路并通过两种途径实现之。
1) 直接在服务器上生成PDF文件。
<%@ page import ="com.lowagie.text.*,com.lowagie.text.pdf.*, java.io.*"%>
<%
String filename = "F://book//PDFceshi.pdf";
Document document = new Document(PageSize.A4);
try{
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename) );
document.open();
document.add(new Paragraph("Hello World"));
document.close();
}catch(Exception e)
{}%>
上面的程序在服务器上生成了一个静态的PDF文件。显然,每次运行所得的PDF文件的名称应该是独一无二不能有重的。本程序通过随机函数来命名生成的PDF文件。本程序的缺点就是,每次运行都会在服务器上产生一个PDF文件,如果不及时删除,数量会越来越大,这显然是站点维护者所不愿意看到的。
2)将PDF文件通过流的形式输送到客户端的缓存。这样做的好处是不会在服务器上留下任何“遗迹”。
i)直接通过JSP页面生成
<%@
page import="java.io.*,
com.lowagie.text.*,
com.lowagie.text.pdf.*"
%><%
response.setContentType( "application/pdf" );
Document document = new Document();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfWriter.getInstance( document, buffer );
document.open();
document.add(new Paragraph("Hello World"));
document.close();
DataOutput output = new DataOutputStream( response.getOutputStream() );
byte[] bytes = buffer.toByteArray();
response.setContentLength(bytes.length);
for( int i = 0; i < bytes.length; i++ ){output.writeByte( bytes[i] );}%>
注意:不能有空格和回车及任何html的东西。
ii)通过Servlet生成
import
java.io.*;
import
javax.servlet.*;
import
javax.servlet.http.*;
import
com.lowagie.text.*;
import
com.lowagie.text.pdf.*;
public
class
Server_pdf
extends
HttpServlet
{
public
void
doGet(HttpServletRequest
request,
HttpServletResponse
response)
throws
IOException,ServletException
{
Document
document
=
new
Document(PageSize.A4,
36,36,36,36);
ByteArrayOutputStream
ba
=
new
ByteArrayOutputStream();
try
{
PdfWriter
writer
=
PdfWriter.getInstance(document,
ba);
document.open();
document.add(
new
Paragraph(
"Hello World"
));
}
catch
(DocumentException
de)
{
de.printStackTrace();
System.err.println(
"A Document error:"
+de.getMessage());
}
document.close();
response.setContentType(
"application/pdf"
);
response.setContentLength(ba.size());
ServletOutputStream
out
=
response.getOutputStream();
ba.writeTo(out);
out.flush();
}
}
<servlet> <servlet-name>Servlet</servlet-name> <servlet-class>com.chaozi.Server_pdf</servlet-class> </servlet>
<servlet-mapping> <servlet-name>Servlet</servlet-name> <url-pattern>/Servlet</url-pattern>
import
javax.servlet.*;
import
javax.servlet.http.*;
import
java.io.*;
import
com.lowagie.text.*;
import
com.lowagie.text.pdf.*;
public
class
FundsRFServlet
extends
HttpServlet
{
private
static
final
String
CONTENT_TYPE
=
"text/html; charset=GBK"
;
private
String
printDate
=
""
;
private
String
orgName
=
""
;
//Initialize global variables
public
void
init()
throws
ServletException
{
}
//Process the HTTP Get request
public
void
doGet(HttpServletRequest
request,
HttpServletResponse
response)
throws
ServletException,
IOException
{
try
{
String
edate
=
null
;
String
sdate
=
null
;
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream();
//make a pdf reportTable
buildFundsRF(baos,
sdate,
edate);
// write ByteArrayOutputStream to the ServletOutputStream
response.setContentType(
"application/pdf"
);
response.setContentLength(baos.size());
ServletOutputStream
out
=
response.getOutputStream();
baos.writeTo(out);
out.flush();
// this is a workaround for a bug in MSIE
}
catch
(Exception
e2)
{
System.out.println(
"Error in "
+
getClass().getName()
+
"/n"
+
e2);
}
}
//Process the HTTP Put request
public
void
doPut(HttpServletRequest
request,
HttpServletResponse
response)
throws
ServletException,
IOException
{
doGet(request,
response);
}
//Clean up resources
public
void
destroy()
{
}
public
void
buildFundsRF(OutputStream
os,
String
sdate,
String
edate)
{
Document
document
=
new
Document(PageSize.A4.rotate(),
20,
20,
20,
20);
Document.compress
=
false
;
try
{
PdfWriter
writer
=
PdfWriter.getInstance(document,
os);
document.open();
// step 4: we add content to the document
BaseFont
bfChinese
=
BaseFont.createFont(
"STSong-Light"
,
"UniGB-UCS2-H"
,
BaseFont.NOT_EMBEDDED);
Font
headFont
=
new
Font(bfChinese,
12,
Font.NORMAL);
Font
font
=
new
Font(bfChinese,
10,
Font.NORMAL);
PdfPTable
table
=
createFundsTable(sdate,
edate);
PdfPTable
table2
=
createFundsTable_2(sdate,
edate);
Paragraph
p1
=
new
Paragraph(orgName,
headFont);
p1.setAlignment(Element.ALIGN_CENTER);
p1.setLeading(20.0f);
Paragraph
p2
=
new
Paragraph(
"应 收 帐 款"
,
headFont);
p2.setAlignment(Element.ALIGN_CENTER);
p2.setLeading(30.0f);
Paragraph
p3
=
new
Paragraph(
" "
,
headFont);
p3.setAlignment(Element.ALIGN_RIGHT);
p3.setLeading(20.0f);
Paragraph
p4
=
new
Paragraph(
"日期范围:"
+
sdate
+
" 至 "
+
edate
+
" "
+
" "
+
" "
+
" "
+
"列印日期:"
+
printDate,
headFont);
p4.setAlignment(Element.ALIGN_RIGHT);
p4.setLeading(20.0f);
Paragraph
p5
=
new
Paragraph(
" "
,
headFont);
p5.setLeading(20.0f);
document.add(p1);
document.add(p2);
document.add(p3);
document.add(p4);
if
(table
!=
null
)
{
document.add(table);
}
document.add(p5);
if
(table2
!=
null
)
{
document.add(table2);
}
}
catch
(IOException
ex)
{
}
catch
(DocumentException
ex2)
{
ex2.printStackTrace();
}
catch
(Exception
e)
{
e.printStackTrace();
}
document.close();
}
private
PdfPTable
createFundsTable(String
sdate,
String
edate)
{
BaseFont
bfChinese
=
null
;
try
{
bfChinese
=
BaseFont.createFont(
"STSong-Light"
,
"UniGB-UCS2-H"
,
BaseFont.NOT_EMBEDDED);
Font
headFont
=
new
Font(bfChinese,
12,
Font.NORMAL);
Font
font
=
new
Font(bfChinese,
10,
Font.NORMAL);
//create table
PdfPTable
table
=
new
PdfPTable(
new
float
[]
{0.2f,
0.25f,
0.1f,
0.1f,
0.25f});
table.setWidthPercentage(100.0f);
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
table.getDefaultCell().setLeading(1.4f,
1.4f);
table.getDefaultCell().setGrayFill(0.9f);
table.setHeaderRows(1);
table.addCell(
new
Phrase(
"用户名"
,
headFont));
//table.addCell(new Phrase("e络通SN", headFont));
table.addCell(
new
Phrase(
"用户帐号"
,
headFont));
table.addCell(
new
Phrase(
"充值点数"
,
headFont));
table.addCell(
new
Phrase(
"应收金额"
,
headFont));
table.addCell(
new
Phrase(
"备 注"
,
headFont));
table.setSkipFirstHeader(
false
);
table.getDefaultCell().setLeading(1.2f,
1.2f);
table.getDefaultCell().setGrayFill(0.0f);
int
recTotal
=
0;
float
fundsTotal
=
0.00f;
table.getDefaultCell().setGrayFill(0.95f);
PdfPCell
cell
=
new
PdfPCell(
new
Phrase(
"合 计"
,
headFont));
cell.setColspan(2);
cell.setGrayFill(0.95f);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
table.addCell(
new
Phrase(recTotal
+
""
,
headFont));
table.addCell(
new
Phrase(fundsTotal
+
""
,
headFont));
table.addCell(
new
Phrase(
""
,
headFont));
return
table;
}
catch
(IOException
exe)
{
}
catch
(DocumentException
ex)
{
}
return
null
;
}
private
PdfPTable
createFundsTable_2(String
sdate,
String
edate)
{
BaseFont
bfChinese
=
null
;
try
{
bfChinese
=
BaseFont.createFont(
"STSong-Light"
,
"UniGB-UCS2-H"
,
BaseFont.NOT_EMBEDDED);
Font
headFont
=
new
Font(bfChinese,
12,
Font.NORMAL);
Font
font
=
new
Font(bfChinese,
10,
Font.NORMAL);
//create table
PdfPTable
table
=
new
PdfPTable(
new
float
[]
{0.2f,
0.25f,
0.1f,
0.1f,
0.25f});
table.setWidthPercentage(100.0f);
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
table.getDefaultCell().setLeading(1.4f,
1.4f);
table.getDefaultCell().setGrayFill(0.9f);
table.setHeaderRows(1);
table.addCell(
new
Phrase(
"经销商编号"
,
headFont));
table.addCell(
new
Phrase(
"经销商名称"
,
headFont));
table.addCell(
new
Phrase(
"充值点数"
,
headFont));
table.addCell(
new
Phrase(
"应收金额"
,
headFont));
table.addCell(
new
Phrase(
"备 注"
,
headFont));
table.setSkipFirstHeader(
false
);
table.getDefaultCell().setLeading(1.2f,
1.2f);
table.getDefaultCell().setGrayFill(0.0f);
int
recTotal
=
0;
float
fundsTotal
=
0.00f;
table.getDefaultCell().setGrayFill(0.95f);
PdfPCell
cell
=
new
PdfPCell(
new
Phrase(
"合 计"
,
headFont));
cell.setColspan(2);
cell.setGrayFill(0.95f);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
table.addCell(
new
Phrase(recTotal
+
""
,
headFont));
table.addCell(
new
Phrase(fundsTotal
+
""
,
headFont));
table.addCell(
new
Phrase(
""
,
headFont));
return
table;
}
catch
(IOException
ee)
{
}
catch
(DocumentException
exq)
{
}
return
null
;
}
public
static
void
main(String[]
args)
{
FundsRFServlet
v
=
new
FundsRFServlet();
try
{
v.buildFundsRF(
new
FileOutputStream(
"1234.pdf"
),
"2003-06-09"
,
"2003-06-09"
);
}
catch
(FileNotFoundException
ex)
{
}
}
}
CSDN下载地址:http://download.csdn.net/user/chaozi