??xml version="1.0" encoding="utf-8" standalone="yes"?>
现在JFreeReport加入CPentahoQ所以JFreeReport的最新版本只到jfreereport-0.8.7-9.jarQ之后就以Pentaho Report Designer命名了?br />
二、JFreeReportlg的结?br />
JFreeReportlg的核心对象就是JFreeReport对象Q我其视两部分Q一部分是报表格式定义,另一部分是数据存储?br />
JFreeReportlg的数据用的是java.swing.table.TableModelc,我们对它都非常熟悉了Q用JTable做表格时都会用到Q所以在此不再篏q?br />
我主要讲讲JFreeReport的报表格式定义以及输出方法?br />
JFreeReport报表分Z下几个部分:
报头QReportHeaderQ?br />
报尾QReportFooterQ?br />
头QPageHeaderQ?br />
尾QPageFooterQ?br />
分组_GroupHeaderQ?br />
分组(GroupFooterQ和数据域?br />
l 表头QReportHeaderQ——内ҎC在整个报表的开_可以包括报表名称{内宏V?br />
l 表尾QReportFooterQ——内ҎC在整个报表的末?br />
l 首QPageHeaderQ——内ҎC在每一늚首部Q第一则昄在ReportHeader下面Q可以包括报表日期、填表h{内宏V?br />
l 尾QPageFooterQ——内ҎC在每一늚末尾Q可以包括页L信息?br />
l 分组_GroupHeaderQ——如果将数据分组Q则GroupHeadar内容会显C在每一l分l的头部?br />
l 分组(GroupFooterQ——如果将数据分组Q则GroupHeadar内容会显C在每一l分l的头部?br />
l 数据域——报表数据,一般位于每늚中间部分?br />
三、报表格式定?br />
知道了JFreeReportlg的报表结构,下面该介l如何定义了。有两种ҎQ一U是使用java代码实现Q另一U是使用xml定义?br />
1、代码方式实现报表格式定?br />
使用代码方式实现步骤很简单,是分别构造报_ReportHeaderQ、报(ReportFooterQ、页_PageHeaderQ、页(PageFooterQ?br />
分组_GroupHeaderQ和分组(GroupFooterQ对象,然后使用setҎ加入JFreeReport对象可以了?br />
上面q几个对象我们一般只会用到其addElement(Element element)ҎQ即一个元素(ElementQ加入到指定部分。在q里Q元素的意义
是昄在报表中的内容,包括文本、表根{图形、图片等{。Element是一个抽象类Q他有几个子c,但我们不必直接用这些子c,
而是通过org.jfree.report.elementfactory包中的工厂类来构建。:
l LabelElementFactory——标{օ素工厂类Q定义报表中昄的固定文本内宏V?br />
l TextElementFactory——文本元素工厂类Q根据定义的域名Q显C其域名下的内容。比如:tableModel中的“~号”字段下的内容?br />
l StaticShapeElementFactory——图形元素类Q可以绘制直Uѝ矩形等囑Ş?br />
其他的元素我没用q,大家可以查看JFreeReport的API文档。他们的用法L下面的例子?br />
public static final int ROW_HEIGHT = 20; //报告Q行高度
public static final int HEADER_HEIGHT = 40; //报告Q报头高?br />
JFreeReport report = new JFreeReport(); //构造JFreeReport对象
report.setName("Report Name");
PageDefinition pd = report.getPageDefinition(); //取得报告面定义
float pageWidth = pd.getWidth(); //取得打印材质的页?br />
//定义头
PageHeader header = new PageHeader();
LabelElementFactory title = new LabelElementFactory(); //标题元素
title.setText("l计报表"); //讄文本内容
title.setColor(Color.BLACK); //讄颜色
title.setAbsolutePosition(new Point2D.Float(0, HEADER_HEIGHT)); //讄昄位置
title.setMinimumSize(new FloatDimension(pageWidth, 36)); //讄寸
title.setHorizontalAlignment(ElementAlignment.LEFT);
title.setVerticalAlignment(ElementAlignment.MIDDLE);
title.setDynamicHeight(true); //讄是否动态调整高度(如果为trueQ当文本内容出昄范围旉度自动加长)
header.addElement(title.createElement());
report.setPageHeader(header);
String[] columnNames = getColumnNames(); //取得报表数据域的所有列?br />
if (columnNames != null && columnNames.length > 0) ...{
report.getItemBand().addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), 0)); //l制表格的横U?br />
//定义报表?br />
ReportHeader reportHeader = new ReportHeader();
for (int i = 0; i < columnNames.length; i++) ...{
//字段名元?br />
LabelElementFactory col = new LabelElementFactory();
col.setName(columnNames[i]);
col.setColor(Color.BLACK);
col.setHorizontalAlignment(ElementAlignment.CENTER);
col.setVerticalAlignment(ElementAlignment.MIDDLE);
col.setDynamicHeight(true);
col.setAbsolutePosition(new Point2D.Float((pageWidth
/ (columnNames.length))
* i, 0));
col.setMinimumSize(new FloatDimension(pageWidth
/ (columnNames.length), ROW_HEIGHT)); //讄最尺?br />
col.setBold(true); //讄是否_体昄
col.setText(columnNames[i]);
reportHeader.addElement(col.createElement());
reportHeader.addElement(StaticShapeElementFactory.createVerticalLine(null, Color.BLACK, new BasicStroke(1), col.getAbsolutePosition().getX())); //元素左侧竖线
reportHeader.addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), 0)); //元素上方横线
reportHeader.addElement(StaticShapeElementFactory.createVerticalLine(null, Color.BLACK, new BasicStroke(1), pageWidth)); //元素右侧竖线
report.setReportHeader(reportHeader);
//字段内容元素
TextFieldElementFactory data = new TextFieldElementFactory();
data.setName(columnNames[i]);
data.setColor(Color.BLACK);
data.setAbsolutePosition(new Point2D.Float((pageWidth
/ (columnNames.length))
* i, 0));
data.setMinimumSize(new FloatDimension(pageWidth
/ (columnNames.length), ROW_HEIGHT));
data.setHorizontalAlignment(ElementAlignment.CENTER);
data.setVerticalAlignment(ElementAlignment.MIDDLE);
data.setDynamicHeight(true);
data.setWrapText(new Boolean(true));
data.setNullString("-"); //如果字段内容为空Q显C的文本
data.setFieldname(columnNames[i]);
report.getItemBand().addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), 0));
report.getItemBand().addElement(data.createElement());
report.getItemBand().addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), -100));
report.getItemBand().addElement(StaticShapeElementFactory.createVerticalLine(null, Color.BLACK, new BasicStroke(1), data.getAbsolutePosition().getX()));
report.getItemBand().addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), 0));
}// end for(int i=0;i<columnNames.length;i++)
//最后的竖线
report.getItemBand().addElement(StaticShapeElementFactory.createVerticalLine(null, Color.BLACK, new BasicStroke(1), pageWidth));
PageFooter footer = new PageFooter();
//讄号
PageOfPagesFunction pageFunction = new PageOfPagesFunction("PAGE_NUMBER"); //构造一个页号函数对?br />
pageFunction.setFormat("{0} / {1}?); //讄号昄格式Q此处显C的格式?#8220;1/5?#8221;Q?br />
report.addExpression(pageFunction);
TextFieldElementFactory pageCount = new TextFieldElementFactory();
pageCount.setFieldname("PAGE_NUMBER");
pageCount.setColor(Color.black);
pageCount.setAbsolutePosition(new Point2D.Float(0, 0));
pageCount.setMinimumSize(new FloatDimension(pageWidth, 0));
pageCount.setHorizontalAlignment(ElementAlignment.RIGHT);
pageCount.setVerticalAlignment(ElementAlignment.MIDDLE);
pageCount.setDynamicHeight(true);
footer.addElement(pageCount.createElement());
report.setPageFooter(footer);
ReportFooter reportFooter = new ReportFooter();
reportFooter.addElement(StaticShapeElementFactory.createHorizontalLine(null, Color.BLACK, new BasicStroke(1), 0));
report.setReportFooter(reportFooter);
2、XML方式实现报表格式定义
对于单的报表Q我们可以用代码来实现Q但对于复杂的报表,代码可能无能ؓ力了
Q虽然也可以实现Q但对于M码的人来说可能将是场NQ,那么我们可以通过定义XML来实现报表格式的定义?br />
q种Ҏ非常方便而且清晰?br />
JFreeReport定义了两UXML实现Ҏ。这里我只介l一U,因ؓ另一U我没有用过。我直接通过例子来解释如何实玎ͼ
<?xml version="1.0" encoding="GB2312"?>
<report name="My Report" pageformat="A4" leftmargin="40" rightmargin="40">
<configuration>
<property name="com.jrefinery.report.preview.PreferredWidth">1024</property>
<property name="com.jrefinery.report.preview.PreferredHeight">768</property>
</configuration>
<!-- 报头 -->
<reportfooter height="20" fontname="宋体" fontsize="12">
</reportfooter>
<!-- 首 -->
<pageheader fontname="宋体" fontsize="12">
<!-- 文本域,用于昄表数据中某列的内?nbsp; -->
<!-- x,y: 为坐标点Q以首区域的左上角?0, 0)点) -->
<!-- width, height: 为文本域的宽度和高度Q如果ؓ数值则表示为绝对尺寸,如果为百分数Q则自动以百分比方式调整寸大小 -->
<!-- alignment: 排列方式 -->
<!-- fieldname: 域名Q即数据域的列名 -->
<!-- nullstring: 当数据域内容为空时显C的字符串内?-->
<!-- alignment: 水^排列方式centerQleft或right -->
<!-- vertical-alignment: 竖直排列方式top、middle或bottom -->
<!-- dynamic: 是否动态调整单元格高度Q如果ؓtrueQ当文本内容不以在当前寸中显C时自动增加单元格高度 -->
<string-field x="0" y="0" width="100%" height="30" alignment="center" fontname="黑体" fontsize="15" fieldname="report.title" nullstring=""></string-field>
<!-- 标签域,用于在报表中昄固定文本内容 -->
<label x="0" y="20" width="100%" height="20" alignment="center" fontname="黑体" fontsize="15">报表</label>
<label x="5%" y="80" width="100%" height="20" alignment="left">l计旉Q?lt;/label>
<string-field x="90" y="80" width="30%" height="18" alignment="left" fieldname="report.time" nullstring=""/>
<label x="70%" y="80" width="100%" height="20">l计日期Q?lt;/label>
<!-- 旉域,用于昄旉 -->
<!-- report.date: 下面<function>中定义的函数Q显C当前时?-->
<!-- format: 日期格式 -->
<date-field fieldname="report.date" format="yyyy/M/d" x="0%" y="80" width="95%" height="20" alignment="right"></date-field>
</pageheader>
<!-- 尾 -->
<pagefooter height="20" fontname="宋体" fontsize="12">
<string-field fieldname="pageXofY" x="0" y="4" width="100%" height="18" alignment="right"/>
</pagefooter>
<!-- 分组 -->
<groups>
<group name="group1">
<!-- 分组?-->
<groupheader fontname="宋体" fontsize="10.5">
<label x="0%" y="5" width="20%" height="40" alignment="center" vertical-alignment="middle"> l?nbsp; ?</label>
<rectangle x="0%" y="0" width="20%" height="50" color="#000000" draw="true" fill="false"/>
<label x="20%" y="5" width="40%" height="20" alignment="center" vertical-alignment="middle">?q??lt;/label>
<!-- 囑ŞQ矩?-->
<!-- color: 颜色 -->
<!-- fill: 是否填充 -->
<rectangle x="20%" y="0" width="40%" height="25" color="#000000" draw="true" fill="false"/>
<label x="20%" y="30" width="20%" height="20" alignment="center" vertical-alignment="middle">??lt;/label>
<rectangle x="20%" y="25" width="20%" height="25" color="#000000" draw="true" fill="false"/>
<label x="40%" y="30" width="20%" height="20" alignment="center" vertical-alignment="middle">占比(%)</label>
<rectangle x="40%" y="25" width="20%" height="25" color="#000000" draw="true" fill="false"/>
<label x="60%" y="5" width="40%" height="20" alignment="center" vertical-alignment="middle">?q??lt;/label>
<rectangle x="60%" y="0" width="40%" height="25" color="#000000" draw="true" fill="false"/>
<label x="60%" y="30" width="20%" height="20" alignment="center" vertical-alignment="middle">??lt;/label>
<rectangle x="60%" y="25" width="20%" height="25" color="#000000" draw="true" fill="false"/>
<label x="80%" y="30" width="20%" height="20" alignment="center" vertical-alignment="middle">占比(%)</label>
<rectangle x="80%" y="25" width="20%" height="25" color="#000000" draw="true" fill="false"/>
</groupheader>
<!-- 可以q有分组?lt;groupfooter> -->
</group>
</groups>
<!-- 数据?nbsp; -->
<items fontname="宋体" fontsize="12">
<!-- 囑ŞQ直U?-->
<line x1="0" y1="0" x2="0" y2="100%"/>
<string-field fieldname="q度体检l论" x="0%" y="5" width="20%" height="20" alignment="center" vertical-alignment="middle" nullstring="" dynamic="true"/>
<line x1="20%" y1="0" x2="20%" y2="100%"/><!-- l论 -->
<string-field fieldname="上年? x="20%" y="5" width="20%" height="20" alignment="center" vertical-alignment="middle" nullstring="" dynamic="true"/>
<line x1="40%" y1="0" x2="40%" y2="100%"/><!-- 上年度h?-->
<string-field fieldname="上年?%)" x="40%" y="5" width="20%" height="20" alignment="center" vertical-alignment="middle" nullstring="" dynamic="true"/>
<line x1="60%" y1="0" x2="60%" y2="100%"/><!-- 上年度占?-->
<string-field fieldname="本年? x="60%" y="5" width="20%" height="20" alignment="center" vertical-alignment="middle" nullstring="" dynamic="true"/>
<line x1="80%" y1="0" x2="80%" y2="100%"/><!-- 本年度h?-->
<string-field fieldname="本年?%)" x="80%" y="5" width="20%" height="20" alignment="center" vertical-alignment="middle" nullstring="" dynamic="true"/>
<line x1="100%" y1="0" x2="100%" y2="100%"/><!-- 本年度占?-->
<line x1="0" y1="100%" x2="100%" y2="100%"/>
</items>
<!-- 函数定义 -->
<functions>
<!-- 昄当前旉的函数用?nbsp; -->
<property-ref name="report.date"/>
<!-- 昄当前늠的函数用?-->
<function name="PageNumber" class="org.jfree.report.function.PageFunction" deplevel="1"/>
<!-- 昄总页数的函数用法 -->
<function name="PageTotal" class="org.jfree.report.function.PageTotalFunction" deplevel="1"/>
<!-- 表达式,ơ表辑ּ定义一个显C页码格式的用法 -->
<expression name="pageXofY" class="org.jfree.report.function.TextFormatExpression">
<properties>
<property name="pattern">{0}/{1}?lt;/property>
<property name="field[0]">PageNumber</property>
<property name="field[1]">PageTotal</property>
</properties>
</expression>
</functions>
</report>
另一U方法我没有用过Q以后了解了再补充?br />
四、输?br />
定义完JFreeReport对象Q就可以q行输出了。下面介l几U输出方法?br />
1、通过预览H口对象输出
该方式只能在Application环境中用。通过预览H口Q用户可以自行选择打印、排版或生成各种格式的文Ӟq也是我们在Application中常用的方式。代码示例如下:
PreviewDialog preview = null; //预览H口对象
try ...{
// 生成的报表攑ֈ预览H口?br />
preview = new PreviewDialog(report);
} catch (ReportProcessingException e) ...{
e.printStackTrace();
}
if (preview != null) ...{
preview.pack();
preview.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// 讄报表起始点及长宽
preview.setLocation(new Point(0, 0));
Dimension screen = getToolkit().getScreenSize();
int width = (int) (screen.getWidth() - 2 * preview.getLocation().x);
int height = (int) (screen.getHeight());
preview.setSize(new Dimension(width, height));
// 昄报表预览H口
preview.setVisible(true);
preview.requestFocus();
// preview.addWindowListener(new CloseHandler());
}
2、输出HTML文本?br />
q种Ҏ可以报表输ZؓHTML语言形成的文本,q种方式适用于在览器中昄报表内容。示例代码如下:
ByteArrayOutputStream bo = null;
StreamHtmlFilesystem filesystem = null;
try ...{
// 生成Html
bo = new ByteArrayOutputStream();
final HtmlProcessor processor = new HtmlProcessor(report);
processor.setGenerateBodyFragment(true);
processor.setEncoding ("UTF-8");
filesystem = new StreamHtmlFilesystem(bo);
processor.setFilesystem(filesystem);
processor.processReport();
String htmlCode = new String(bo.toByteArray(), "UTF-8");
bo.close();
bo = null;
filesystem.close();
filesystem = null;
} catch(FileNotFoundException e) ...{
e.printStackTrace();
} catch(SecurityException e) ...{
e.printStackTrace();
} catch (ReportProcessingException e) ...{
e.printStackTrace();
} catch (IOException e) ...{
e.printStackTrace();
}
3、输出PDF文g
PDF的输出方式跟HTML的差不多Q但有一点,JFreeReport本n无法输出中文字符Q如果想要输Z文,我没有找到更好的ҎQ所以更改了JFreeReport包中org.jfree.report.modules.output.support.itext.BaseFontSupportcȝ源码Q将
final BaseFont f = BaseFont.createFont(BaseFont.HELVETICA, stringEncoding, embedded,
false, null, null)中的BaseFont.HELVETICA改ؓ“STSong-Light”,另外需要到www.lowagie.com/iText|站下蝲iText.jar包以支持STSong-Light字体~码Q这P可以输Z文了。示例代码如下所C:
q里注意Q必dtarget的字体编码设?#8220;UniGB-UCS2-H”而且使用Java1.5q行~译
PDFOutputTarget target = null;
try ...{
//生成pdf
FileOutputStream fos = new FileOutputStream("PDF.pdf");
target = new PDFOutputTarget(fos);
target.configure(report.getReportConfiguration());
target.setFontEncoding("UniGB-UCS2-H");
target.open();
final PageableReportProcessor proc = new PageableReportProcessor(report);
proc.setOutputTarget(target);
proc.processReport();
target.close();
target = null;
} catch(FileNotFoundException e) ...{
e.printStackTrace();
} catch(SecurityException e) ...{
e.printStackTrace();
} catch (OutputTargetException e) ...{
e.printStackTrace();
} catch (ReportProcessingException e) ...{
e.printStackTrace();
}
以上是我对JFreeReportlg的ȝQ写的不好希望对大家有所
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2056738