1、 1FineReport 报表二次开发在大多数情况下 FineReport 都可以完全满足用户制作各种报表的需求,但是为了能够满足个别用户的个性化需求,FineReport 提供了丰富二次开发接口,方便用户将 FineReport和自己的项目实现无缝结合,用户在进行二次开发的工程中可以更加深入的体会到FineReport 工具的强大功能。例如:在一些特殊领域,可能需要一些特殊的函数。或者要将某个模板文件通过指定的打印机打印等等。目录2Report 的输入输出 3单元格格式设置 7将模板通过指定打印机打印 10自定义函数 12URL 传递参数 22向报表中添加单元格25读取单元格内容29创建程序
2、网络模版32读取模板报表36Report 的输入输出FineReport 提供了强大的输入输出功能,所有的这些输入输出的类都在com.fr.report.io 包里面。Report 的输入指从报表的模板文件 (XML 格式的)创建 Report 对3象,输出指将 Report 保存为模板文件,FineReport 还支持将 Report 保存为PDF,Excel,Word,SVG,HTML,CSV 等文件格式。 读取模板文件 保存成模板文件 输出成 PDF 文件 输出成 Word 文件 输出成 Excel 文件 输出成文本文件 可执行代码 读取模板文件/ 读取模板 File cptFile =
3、 new File(“D:stuff.cpt“); TemplateImporter templateImporter = new TemplateImporter(); WorkBook workBook = (WorkBook)templateImporter.generate(cptFile); Stuff.cpt 是用报表设计器生成的模板文件。只需要用建立一个 TemplateImporter 对象, 然后调用它的 generateReport()方法来产生一个 Report 对象,同时可以将产生的 Report对象强制转换成 WorkSheet 或者 GroupReport。 保存成
4、模板文件/ CPT / 清空公式计算结果 E:newtemplatestuff.cpt这个是导出后新文档生成的地址 ReportHelper.clearFormulaResult(workBook); outputStream = new FileOutputStream(new File(“E:newtemplatestuff.cpt“); TemplateExporter templateExporter = new TemplateExporter(); templateExporter.export(outputStream,workBook.execute(parameterMap)
5、 ; 通过调用 TemplateExporter 的 exportReport(.)方法, 可以把 Report 对象以 CPT 格式保存到外部磁盘文件当中。 4可执行代码读取报表模板 stuff.cpt,再分别保存为 stuff.cpt,stuff.pdf 和 stuff.xls。package com.fr.demo; import java.io.File; import java.io.FileOutputStream; import com.fr.base.FRContext; import com.fr.base.dav.LocalEnv; import com.fr.report
6、.WorkBook; import com.fr.report.core.ReportHelper; import com.fr.report.io.ExcelExporter; import com.fr.report.io.PDFExporter; import com.fr.report.io.TemplateExporter; import com.fr.report.io.TemplateImporter; import com.fr.report.io.TextExporter; import com.fr.report.io.WordExporter; /* * 演示如何导入导出
7、模板 * author edgar duan * version 6.5 */ public class ReportIO /* * param args */ public static void main(String args) / 报表运行环境路径, WEB-INF 目录所放的位置 String envPath = “C:/FineReport6.5/WebReport/WEB-INF“; / 设置当前报表运行环境, 报表预览时需要一个运行环境 / 没有 WEB-INF 目录时, 路径设置为 null. FRContext.setCurrentEnv(new LocalEnv(null
8、); 5FRContext.setCurrentEnv(new LocalEnv(envPath); try / 读取模板 File cptFile = new File(“D:stuff.cpt“); TemplateImporter templateImporter = new TemplateImporter(); WorkBook workBook = (WorkBook)templateImporter.generate(cptFile); java.util.Map parameterMap = new java.util.HashMap(); FileOutputStream o
9、utputStream; /生成 CPT / 清空公式计算结果 ReportHelper.clearFormulaResult(workBook); outputStream = new FileOutputStream(new File(“E:newtemplatestuff.cpt“); TemplateExporter templateExporter = new TemplateExporter(); templateExporter.export(outputStream, workBook.execute(parameterMap) ;/生成 PDF ReportHelper.cl
10、earFormulaResult(workBook); outputStream = new FileOutputStream(new File(“E:newtemplatestuff.pdf“); PDFExporter pdfExporter = new PDFExporter(); pdfExporter.export(outputStream, workBook.execute(parameterMap) ; / 生成 DOC ReportHelper.clearFormulaResult(workBook); outputStream = new FileOutputStream(n
11、ew File(“E:newtemplatestuff.doc“); WordExporter wordExporter = new WordExporter(); wordExporter.export(outputStream,workBook.execute(parameterMap); / 生成 XLS ReportHelper.clearFormulaResult(workBook); 6outputStream = new FileOutputStream(new File(“E:newtemplatestuff.xls“); ExcelExporter excelExporter
12、 = new ExcelExporter(); excelExporter.export(outputStream,workBook.execute(parameterMap); /生成 TXT ReportHelper.clearFormulaResult(workBook); outputStream = new FileOutputStream(new File(“E:newtemplatestuff.txt“); TextExporter textExporter = new TextExporter(); textExporter.export(outputStream,workBo
13、ok.execute(parameterMap); catch(Exception e) e.printStackTrace(); 单元格格式设置/ 新建一个单元格, 位置为(2, 2), 列宽为 2 / 行高为 2, 值为文本 “FineReport“ CellElement cellElement = new CellElement(2, 2, 2, 2, “FineReport“); / 得到 CellElement 的样式,如果没有新建默认样式 Style style = cellElement.getStyle(); if(style = null) style = Style.ge
14、tInstance(); 7/ 设置字体和前景的颜色 FRFont frFont = FRFont.getInstance(“Dialog“, Font.BOLD, 14); frFont = frFont.applyForeground(new Color(21, 76, 160); style = style.deriveFRFont(frFont); / 设置背景 ColorBackground background = ColorBackground.getInstance(new Color(255,255, 177); style = style.deriveBackground(
15、background); / 设置水平居中 style = style.deriveHorizontalAlignment(Constants.CENTER); / 设置边框 style = style.deriveBorder(Constants.LINE_DASH_DOT, Color.red, Constants.LINE_DASH_DOT, Color.yellow, Constants.LINE_DASH_DOT, Color.BLUE, Constants.LINE_DASH_DOT, Color.CYAN); / 改变单元格的样式 cellElement.setStyle(sty
16、le); 改变单元格的格式,应先取出该单元格(CellElement)的格式(Style)。在默认的情况下Style 是 null,故当取出 Style 后应先判断其值是否为 null,如果这个值为空,则需先新建一个 Style,然后再将该值赋给 CellElement。最后根据 Style 和 FRFont 中的方法进一步地设置该单元格的各种属性。可执行代码如下:package com.fr.demo; import java.awt.Color; 8import java.awt.Font; import com.fr.base.Constants;import com.fr.base.F
17、RFont; import com.fr.base.Style; import com.fr.base.background.ColorBackground;import com.fr.report.CellElement; import com.fr.report.DefaultCellElement; import com.fr.report.WorkBook;import com.fr.report.WorkBookTemplate;import com.fr.report.WorkSheet; import com.fr.web.Reportlet; import com.fr.web
18、.ReportletRequest; /* * ReportletFromTemplateDemo. * author marks * 设置单元格格式 */ public class CellElementStyleDemo implements Reportlet public CellElementStyleDemo() /建立新报表需要传参(ReportletRequest reportletRequest)public WorkBookTemplate createReport(ReportletRequest reportletRequest) /new a WorkSheet Wo
19、rkBook wb = new WorkBook();WorkSheet workSheet = new WorkSheet(); /new a cellElement with String “FineReport“ CellElement cellElement1 = new DefaultCellElement(1, 1, “FineReport“); /add the cellElement to the workSheet workSheet.addCellElement(cellElement1); /set the columnWidth of 1 to 200px,rowHei
20、ght of 1 to 30px workSheet.setColumnWidth(1, 200); workSheet.setRowHeight(1, 30); /set the font of cellElement1 Style style = Style.getInstance(); FRFont frFont = FRFont.getInstance(“Tahoma“, Font.BOLD | Font.ITALIC, 20); frFont = frFont.applyForeground(Color.red); style = style.deriveFRFont(frFont)
21、; / 设置背景 ColorBackground background = ColorBackground.getInstance(new Color(255, 255, 177); 9style = style.deriveBackground(background); / 设置水平居中 style = style.deriveHorizontalAlignment(Constants.CENTER); / 设置边框 style = style.deriveBorder(Constants.LINE_DASH_DOT, Color.red, Constants.LINE_DASH_DOT,
22、Color.yellow, Constants.LINE_DASH_DOT, Color.BLUE, Constants.LINE_DASH_DOT, Color.CYAN); cellElement1.setStyle(style); /set the columnWidth of 4 to 200px,rowHeight of 5 to 50px workSheet.setColumnWidth(4, 200); wb.addReport(workSheet);return wb; 结果如下图所示:将模板通过指定打印机打印用户在使用 FineReport 进行二次开发的过程中有时候需要对不
23、同文件通过不同的打印机打印出来,比如 A 打印机只能打印 A.TXT; B 打印机只能打印 b.txt.。得到当前报表运行环境String envPath = “C:/FineReport6.5/WebReport/WEB-INF“; / 设置当前报表运行环境, 报表预览时需要一个运行环境/ 没有WEB-INF目录时, 路径设置为null. FRContext.setCurrentEnv(new LocalEnv(null);10FRContext.setCurrentEnv(new LocalEnv(envPath); 读取模板文件/ 读取模板 WorkBookTemplate wbTpl
24、= FRContext.getCurrentEnv().readTemplate(“stuff.cpt“); 指定打印机打印PrintUtils.print(wbTpl.execute(null).generateReportPageSet().getTraversingCase(), false, “Smart Print“); 可执行代码package com.fr.demo;import com.fr.base.FRContext;import com.fr.base.dav.LocalEnv;import com.fr.base.print.PrintUtils;import com.
25、fr.report.WorkBookTemplate;/* 演示如何将模板通过指定打印机打印* * author edgar duan* version 6.5*/public class PrintDemo public static void main(String args) / 报表运行环境路径, WEB-INF目录所放的位置String envPath = “C:/FineReport6.5/WebReport/WEB-INF“; / 设置当前报表运行环境, 报表预览时需要一个运行环境/ 没有WEB-INF目录时, 路径设置为null. FRContext.setCurrentEnv
26、(new LocalEnv(null);FRContext.setCurrentEnv(new LocalEnv(envPath); try WorkBookTemplate wbTpl = FRContext.getCurrentEnv().readTemplate(“stuff.cpt“);/null 为模板需要传的参数,false为是否弹出提示窗口,Smart Print 为打印机名称 PrintUtils.print(wbTpl.execute(null).generateReportPageSet().getTraversingCase(), false, “Smart Print“
27、);11 catch(Exception e) e.printStackTrace(); 自定义函数FineReport 已经提供了大量的自带函数,在正常情况下足够满足用户的报表制作需求,但是在一些特殊领域,可能需要一些特殊的函数,在这种情况下,FineReport 提供了自定义函数机制,可以由用户根据业务需要自己来定义一些函数,但这些函数必须满足 FineReport函数定义规则。 FineReport 函数定义规则:Functionname(Para,Para,.),其中 Functionname 为函数名,Para 为参数。 函数原理在 FineReport 中,每一个函数都被定义成一个
28、类,这个类必须要实现 Function 这个接口,在运算的时候首先通过函数名反射取得这个类,然后调用它的 run(Object agrs)方法。下面以 SUM 这个函数为例。 /* Copyright(c) 2001-2008, FineReport Inc, All Rights Reserved.*/package com.fr.report.script.function;import com.fr.report.script.NormalFunction;import com.fr.report.script.core.FArray;import com.fr.report.scrip
29、t.core.FunctionHelper;/* Function.*/public class SUM extends NormalFunction 12/* Run the function on the stack. Pops the arguments from the stack,* then return the result.*/public Object run(Object args) double result = 0;for(int i = 0; i javac -classpath fr-server-6.5.jar AddCellElementsToReport.ja
30、va将编译后的 AddCellElementsToReport.class 放到网络报表根目录下 ,存放地址如下:WEB-INFclassescomfrdemo发布并浏览首先启动报表服务器,既 FineReport 安装目录下面的 Jetty 服务器,Jetty 服务器启动完毕后打开浏览器,在浏览器中输入下列地址:http:/localhost:8079/WebReport/ReportServer?reportlet=com.fr.demo. AddCellElementsToReport结果如下所示:读取单元格内容26TemplateImporter templateImporter =
31、new TemplateImporter(cptFile); Report workSheet = templateImporter.generateReport(); / 根据参数确定这个区域的,为 (0, 0, 4, 3);第一个数字为最左边的列,第二个数字为最上面的行,第三个为列宽,第四个为行高 / 遍历这个区域:数据存在 list 中 List vauleList = new ArrayList(); Iterator cells = workSheet.intersect(0, 0, 4, 3); while(cells.hasNext() CellElement cellEleme
32、nt = (CellElement)cells.next(); vauleList.add(cellElement.getValue(); System.out.println(cellElement.getRow() + “ “ + cellElement.getColumn() + “ “ + cellElement.getValue().toString(); 这里通过 Report 的 intersect(int column, int row, int width, int height)方法获取Report 中部分的单元格,这些单元格放在 Iterator 中,可以像遍历普通的 I
33、terator 对象一样遍历其中的单元格,本例为了演示做了很简单的操作,只是把单元格的行列,值打印出来,可执行代码如下: package com.fr.demo; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.fr.report.CellElement; import com.fr.report.Report; 27import com.fr.report.WorkBook;import com.fr.report.io.
34、TemplateImporter; /* * 演示如何从报表中得到部分单元格 * */ public class IntersectCellIteratorDemo public static void main(String args) File cptFile = new File(“D:stuff.cpt“); try TemplateImporter templateImporter = new TemplateImporter(); WorkBook workbook = templateImporter.generate(cptFile); / 所取得的单元格区域开始位置为(0,0
35、), 宽为4, 高为3 / 参数两个,例如a1,b2 / 根据参数确定这个区域的,为(0, 0, 2, 2);第一个数字为最左边的列,第二个数字为最上面的行,第三个为列宽,第四个为行高 / 遍历这个区域:数据存在list中Report report = workbook.getReport(0);List vauleList = new ArrayList(); Iterator cells = report.intersect(1, 0, 1, 20);while(cells.hasNext() CellElement cellElement = (CellElement)cells.nex
36、t(); vauleList.add(cellElement.getValue(); System.out.println(cellElement.getRow() + “ “ + cellElement.getColumn() + “ “ + cellElement.getValue().toString(); catch(Exception e) e.printStackTrace(); 效果如下图展示:原报表:28程序读出第一列的值:创建程序网络模版由服务器原理章节,我们可以了解到所谓的网络报表就是指实现了 Reportlet 接口的文件,程序网络报表的存在可以用来解决某些特殊应用,而由
37、于程序网络报表需要自己来实现Reportlet 接口,接下来我们给以详细说明。29建议在开始本章节钱稍微了解一下 FineReport 提供的 API 学习,当然需要一定的程序语言基础。FineReport 报表设计器可以设计出绝大多数的报表而不用写一行代码,只有少部分的报表由于有特殊需求需要用写程序的方式来设计,FineReport 提供了丰富的 API 接口可以让用户很轻松的做出需要的报表,下面这个例子就是要新建一个报表,在(1,1)单元格内插入FineReport 这个字符串,对字符串进行格式设置,在其中(4,5)单元格内插入一个FineReport 的 log 标志,用 J2EE 服务
38、器来发布,通过浏览器来浏览,下面以这个简单的例子来详细的介绍如何创建程序网络报表。 新建 JAVA 类文件 编译 JAVA 文件 发布并预览新建 JAVA 类文件创建程序网络报表需要新建一个 JAVA 类,我们把这个类命名成 SimpleReportletDemo,这个类需要实现 com.fr.web.Reportlet 这个接口,并且需要实现 public Report createReport(ReportletRequest reportletRequest)这个方法。 实现 com.fr.web.Reportlet 接口,格式如下:public class SimpleReportle
39、tDemo implements Reportlet public SimpleReportletDemo() public WorkBookTemplate createReport(ReportletRequest reportletRequest) 实现 public Report createReport(ReportletRequest reportletRequest)方法,这个方法需要返回一个 Report 类型的对象,代码格式如下:public Report createReport(ReportletRequest reportletRequest) WorkBook wb=
40、new WorkBook();WorkBook wb=new WorkBook();WorkSheet workSheet=new WorkSheet(); return wb;30下面我们可以给 workSheet 加上一些需要的单元格内容。 我们现在可以给这个 workSheet 的(1,1 )格子内加上一个字符串,如下所示:/new a cellElement with String “FineReport“ CellElement cellElement1 = new DefaultCellElement(1, 1, “FineReport“); /add the cellElemen
41、t to the workSheet workSheet.addCellElement(cellElement1); 然后可以给这个 workSheet 调整列宽和行高,如下所示:/set the columnWidth of 1 to 200px,rowHeight of 1 to 30px workSheet.setColumnWidth(1, 200); workSheet.setRowHeight(1, 30); 给这个单元格设置字体,样式,颜色还有前景色等等。/set the font of cellElement1 Style style = Style.getInstance()
42、; FRFont frFont = FRFont.getInstance(“Tahoma“, Font.BOLD | Font.ITALIC, 20); frFont = frFont.applyForeground(Color.red); style = style.deriveFRFont(frFont); cellElement1.setStyle(style); 完整代码如下所示:package com.fr.demo;import java.awt.Color; import java.awt.Font; import com.fr.base.FRFont; import com.fr.base.Style; import com.fr.report.CellElement; import com.fr.report.DefaultCellElement; import com.fr.report.WorkBook;import com.fr.report.WorkBookTemplate;import com.fr.report.WorkSheet; import com.fr.web.Reportlet;