华为nova开箱评测:使用FineReport报表二次开发详述

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 05:53:18

在大多数情况下FineReport都可以完全满足用户制作各种报表的需求,但是为了能够满足个别用户的个性化需求,FineReport提供了丰富二次开发接口,方便用户将FineReport和自己的项目实现无缝结合,用户在进行二次开发的工程中可以更加深入的体会到FineReport工具的强大功能。

例如:在一些特殊领域,可能需要一些特殊的函数。或者要将某个模板文件通过指定的打印机打印等等。

 

 

 

 

 

 

 

 

 

 

目录

Report的输入输出………………………………………………………… 3

单元格格式设置……………………………………………………………… 7

将模板通过指定打印机打印………………………………………………… 10

自定义函数…………………………………………………………………… 12

URL 传递参数……………………………………………………………… 22

向报表中添加单元格…………………………………………………………25

读取单元格内容………………………………………………………………29

创建程序网络模版……………………………………………………………32

读取模板报表…………………………………………………………………36

 

 

 

 

 

 

 

Report的输入输出

FineReport提供了强大的输入输出功能,所有的这些输入输出的类都在com.fr.report.io包里面。Report的输入指从报表的模板文件(XML格式的)创建Report对象,输出指将Report保存为模板文件,FineReport还支持将Report保存为PDF,Excel,Word,SVG,HTML,CSV等文件格式。

  • 读取模板文件
  • 保存成模板文件
  • 输出成PDF文件
  • 输出成Word文件
  • 输出成Excel文件
  • 输出成文本文件
  • 可执行代码

读取模板文件

  // 读取模板  

            File cptFile = new File("D:\\stuff.cpt");  

            TemplateImporter templateImporter = new TemplateImporter();     WorkBook workBook = (WorkBook)templateImporter.generate(cptFile);     

Stuff.cpt是用报表设计器生成的模板文件。只需要用建立一个TemplateImporter对象, 然后调用它的generateReport()方法来产生一个Report对象,同时可以将产生的Report对象强制转换成WorkSheet或者GroupReport。 

保存成模板文件

// CPT  

            // 清空公式计算结果 

            E:\\newtemplate\\stuff.cpt这个是导出后新文档生成的地址

            ReportHelper.clearFormulaResult(workBook);  

outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.cpt"));  

            TemplateExporter templateExporter = new TemplateExporter();    

    templateExporter.export(outputStream,workBook.execute(parameterMap)) ; 

通过调用TemplateExporter的exportReport(...)方法, 可以把Report对象以CPT格式保存到外部磁盘文件当中。 

可执行代码

读取报表模板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.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;  

 

/** 

 * 演示如何导入导出模板 

 * @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));  

        FRContext.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 outputStream;  

            //生成 CPT  

            // 清空公式计算结果  

ReportHelper.clearFormulaResult(workBook);  

 outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.cpt"));  

            TemplateExporter templateExporter = new TemplateExporter();    

            templateExporter.export(outputStream, workBook.execute(parameterMap)) ;

            //生成 PDF  

            ReportHelper.clearFormulaResult(workBook);  

            outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.pdf"));  

            PDFExporter pdfExporter = new PDFExporter();  

            pdfExporter.export(outputStream, workBook.execute(parameterMap)) ;  

            // 生成DOC  

            ReportHelper.clearFormulaResult(workBook);  

            outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.doc"));  

            WordExporter wordExporter = new WordExporter();  

      wordExporter.export(outputStream,workBook.execute(parameterMap));                 

            // 生成XLS  

            ReportHelper.clearFormulaResult(workBook);  

            outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.xls"));  

            ExcelExporter excelExporter = new ExcelExporter();  

     excelExporter.export(outputStream,workBook.execute(parameterMap));    

            //生成 TXT  

            ReportHelper.clearFormulaResult(workBook);   

            outputStream = new FileOutputStream(new File("E:\\newtemplate\\stuff.txt"));  

            TextExporter textExporter = new TextExporter();               textExporter.export(outputStream,workBook.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.getInstance();   

}     

// 设置字体和前景的颜色   

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(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(style);   

 

改变单元格的格式,应先取出该单元格(CellElement)的格式(Style)。在默认的情况下Style是null,故当取出Style后应先判断其值是否为null,如果这个值为空,则需先新建一个Style,然后再将该值赋给CellElement。最后根据Style和FRFont中的方法进一步地设置该单元格的各种属性。可执行代码如下:

package com.fr.demo;  

import java.awt.Color;     

import java.awt.Font;         

import com.fr.base.Constants;

import com.fr.base.FRFont;     

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.ReportletRequest;     

    

/**   

 * ReportletFromTemplateDemo.   

 * @author marks  

 * 设置单元格格式

 */    

public class CellElementStyleDemo implements Reportlet {     

    public CellElementStyleDemo() {     

    }     

     //建立新报表需要传参(ReportletRequest reportletRequest)

    public WorkBookTemplate createReport(ReportletRequest reportletRequest) {     

        //new a WorkSheet   

    WorkBook 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,rowHeight 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);

     // 设置背景  

        ColorBackground background = ColorBackground.getInstance(new Color(255, 255, 177));  

        style = style.deriveBackground(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);  

          

        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进行二次开发的过程中有时候需要对不同文件通过不同的打印机打印出来,比如A打印机只能打印A.TXT; B打印机只能打印b.txt.。

得到当前报表运行环境

  String envPath = "C:/FineReport6.5/WebReport/WEB-INF";  

        // 设置当前报表运行环境, 报表预览时需要一个运行环境

        // 没有WEB-INF目录时, 路径设置为null. FRContext.setCurrentEnv(new LocalEnv(null));

      FRContext.setCurrentEnv(new LocalEnv(envPath));  

读取模板文件

  // 读取模板  

WorkBookTemplate wbTpl = 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.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(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");

          

        } catch(Exception e) {  

            e.printStackTrace();  

        }  

 

    }

}

自定义函数


FineReport已经提供了大量的自带函数,在正常情况下足够满足用户的报表制作需求,但是在一些特殊领域,可能需要一些特殊的函数,在这种情况下,FineReport提供了自定义函数机制,可以由用户根据业务需要自己来定义一些函数,但这些函数必须满足FineReport函数定义规则。

FineReport函数定义规则:Functionname(Para,Para,...),其中Functionname为函数名,Para为参数。

函数原理

在FineReport中,每一个函数都被定义成一个类,这个类必须要实现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.script.core.FunctionHelper;

/**

 * Function.

 */

public class SUM extends NormalFunction {

    /**

     * 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 < args.length; i++) {

            //p:需要先判断是否为null.

            if(args[i] == null) {

               continue;

            }

            result += parseObject(args[i]);

        }

        return FunctionHelper.parsePrimitiveDouble(result);

    }

    /*

     * 把Object转成double类型的值

     */

    private double parseObject(Object obj) {

    if (obj instanceof Number) {

          return ((Number)obj).doubleValue();

        } else if (obj instanceof Boolean) {

            return ((Boolean)obj).booleanValue() ? 1 : 0;

        } else if (obj instanceof FArray) {

          FArray array = (FArray)obj;

          double sum = 0;

          for(int i = 0, len = array.length(); i < len; i++) {

                sum += parseObject(array.elementAt(i));

          }

          return sum;

        } else if(obj != null) {

          try {

                return Double.parseDouble(obj.toString());

          } catch(NumberFormatException exp) {

                return 0;

          }

        }

   

    return 0;

    }

      public String getCN(){

      return "SUM(number1,number2,…): 求一个指定单元格区域中所有数字之和。\n"

      +"Number1,number2,…:1到30个参数或指定单元格区域中所有数字。\n"

      +"备注:\n"

      +"    函数将直接键入参数中的数值、逻辑值及文本表达式计算在内。\n"

      +"    若参数是数组或引用,则只有数组或单元格引用中的数值进行计算。\n"

      +"示例:\n"

      +"SUM(70,80)等于150。\n"

      +"SUM(\"70\",80,TRUE)等于151,逻辑值“TRUE”作为1来计算;“FALSE”作为0计算;文本“70”作为70来计算。";

}

public String getEN(){

      return "SUM(number1,number2,…): Adds all the numbers in a range of cells.\n"

      +"Number1, number2, ...    are 1 to 30 arguments for which you want the total value or sum.\n"

      +"\n"

      +"Remarks:\n"

      +"1. Numbers, logical values, and text representations of numbers that you type directly into the list of arguments are counted. See the first and second examples following. \n"

      +"2. If an argument is an array or reference, only numbers in that array or reference are counted. Empty cells, logical values, text, or error values in the array or reference are ignored. See the third example following. \n"

      +"\n"

      +"Example:\n"

      +"   SUM(70,80)=150.\n"

      +"   SUM(\"70\",80,TRUE)=151, TRUE is calculated as 1, FALSE for 0, String \"70\" fo 70.";

}

}SUM类用来运算SUM函数,它继承了AbstractFunction这个类,而AbstractFunction实现了Function这个接口,在函数元算的时候首先根据函数名取得运算这个函数的类,比如SUM(2,4,true)这个函数首先根据函数名SUM取得SUM这个类,然后调用SUM类的run(Object[] agrs)方法,agrs中存放的是SUM函数的参数,在运算的时候可以从args中取得参数进行运算。

自定义函数步骤

下面以一个自定义函数的例子来说明如何使用自定义函数,我们定义一个函数FunctionDemo,它的功能是填报数据校验的时候,某个单元格的值希望与数据库中的某个值进行比较。

实现FunctionDemo.java

编译FunctionDemo.java

    注册函数FunctionDemo

使用函数FunctionDemo

实现FunctionDemo.java

代码如下:

package com.fr.demo;

 

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import java.util.logging.Level;

import com.fr.base.FRContext;

import com.fr.base.dav.LocalEnv;

import com.fr.base.file.DatasourceManager;

import com.fr.data.impl.DatabaseConnection;

import com.fr.report.script.NormalFunction;

 

public class FunctionDemo extends NormalFunction {

 

    /**

     * 此方法用于定义数据库连接 C:/FineReport6.5/WebReport/WEB-INF 是当前报表运行环境

     * FRDemo 是当前的数据库连接名

     *

     */

    public static Connection getConn() {

       LocalEnv env = new LocalEnv("C:/FineReport6.5/WebReport/WEB-INF");

       FRContext.setCurrentEnv(env);

       try {

           DatasourceManager datasourceManager = FRContext

                  .getDatasourceManager();

           FRContext.getLogger().log(Level.WARNING, datasourceManager + "");

           com.fr.data.impl.Connection dcon = datasourceManager

                  .getConnection("FRDemo");

           if (dcon instanceof DatabaseConnection) {

              return ((DatabaseConnection) dcon).createConnection();

           }

       } catch (Exception e) {

           FRContext.getLogger().log(Level.WARNING, e.getMessage(), e);

       }

       return null;

    }

    public String getManageName() {

       String resText = "";

       String selSQL = "SELECT province FROM demo1 where number = 1";

       Connection con = getConn();

       try {

           Statement stmt = con.createStatement();

           ResultSet rs = stmt.executeQuery(selSQL);

           while (rs.next()) {

              resText = rs.getString(1);

              break;

           }

           rs.close();

           con.close();

       } catch (Exception exp) {

           try {

              con.close();

           } catch (Exception exp2) {

           }     

       }

       return resText;

    }

    public Object run(Object[] arg0) {

       FRContext.getLogger().log(Level.WARNING, "run");

       return this.getManageName();

    }

    public String getCN() {

       // TODO Auto-generated method stub

       return "dsfhkds";

    }

    public String getEN() {

       // TODO Auto-generated method stub

       return null;

    }

}

注:demo1 表的内容如图:


编译FunctionDemo.java

将编译后的FunctionDemo.class放到FineReport的安装目录WEB-INF下面的classes目录下,因为STRINGCAT.java属于包com.fr.demo,所以FunctionDemo.class需要放到classes\com\fr\demo目录下,全目录如下: %FineReport_HOME%\WebReport\WEB-INF\classes\com\fr\demo

·              注册FunctionDemo函数

需要在FineReport中注册这个函数才可以使用这个函数,首先打开服务器|函数管理器打开FineReport函数管理器,如下图所示:

点击 按钮,系统自动添加一个函数名,你可以双击默认的函数名,清除以后自定义你所需要的函数名,如下所示:

 

在上图的描述输入框中,我们可以写入对该函数的函数明细。

在这里我们定义成FunctionDemo。然后再在右侧选择实现FunctionDemo函数的类FunctionDemo.class,如下图所示:

·              使用Funcation函数

打开一张报表,在这里通过定义报表参数来使用FunctionDemo函数。选择  报表---报表填报属性---数据校验---
 

这里定义的是将D3单元格的内容和函数返回值相比较,如果不一致则返回“ 请输入正确的地址”

对报表进行填报预览:


因为函数FunctionDemo返回值为北京,所以对第二行省份列报错。

至此校验完成。

URL传递参数的例子

这个例子是要从URL中接收传递的参数,对报表模板进行参数值的修改。

  • 步骤一:在设计器中新建一个自由报表的模板,在报表|报表参数中新建两个参数,命名为province ,country,如下图所示:

·   

  • 步骤二:新建实现了Reportlet的类URLParameterDemo
    在createReport(ReportletRequest req)这个方法中需要从req中得到参数的值,并且用它来设置刚才建的模板中的参数值,首先要先得到模板的所有参数,然后取得这个参数,根据参数名在URL中取得参数的值,再用取得的值来设置模板中的参数,代码如下所示:

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.WorkBookTemplate;

import com.fr.report.io.TemplateExporter;

import com.fr.report.parameter.Parameter;

 

/** 

 * 模板传参 

 * @author edgar duan

 * @version 6.5 

 */ 

public class URLParameterDemo {  

 

    /** 

     * @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));  

        FRContext.setCurrentEnv(new LocalEnv(envPath));  

          

        try {  

            WorkBookTemplate wbTpl = FRContext.getCurrentEnv().readTemplate("URLParameterDemo.cpt");

              

            java.util.Map parameterMap = new java.util.HashMap();  

           

            Parameter[] ps = wbTpl.getParameters();

            for (int i = 0; i < ps.length; i++) {

//向报表中传入两个参数,province是参数名称   北京是参数值

               parameterMap.put("province ", "北京");

               parameterMap.put("country", "china");

            }

           

            FileOutputStream outputStream;      

            //得到参数后重新生成报表

            outputStream = new FileOutputStream(new File("E:\\newtemplate\\URLParameterDemo.cpt"));  

            TemplateExporter templateExporter = new TemplateExporter();    

            templateExporter.export(outputStream, wbTpl.execute(parameterMap)) ;

        

        } catch(Exception e) {  

            e.printStackTrace();  

        }  

    }  

 

}  

 效果对比如下:

未传参之前:


添加条件后输出模板为:

 

向报表中添加单元格

报表是由单元格元素组成,单元格元素CellElement构成了FineReport内核最基本的单元,CellElement的最基本的属性有五个:col,row,colSpan,rowSpan,value,这些属性构成了CellElement的基本性质。(col,row)表示了CellElement在Report中的位置,而colSpan和rowSpan分别表示了CellElement在列方向和行方向上占据了几个格子,默认的是1,默认一个格子的长和宽分别是72px和19px,当单元格元素所占的行宽(colSpan)和列高(rowSpan)大于一个格子的长宽,那么这个单元格元素是merged的。

FineReport能够设计极度复杂的报表都是由这些单元格根据不同的形式组织起来的,下面的代码演示了如何创建CellElement并且将他们添加到Report中:

// 新建一个CellElement, 列为 1, 行为 1, 列宽为 1,   

// 行高为 1, 值为文本:"FineReport"   

CellElement cellElement1 = new CellElement(1,1,"FineReport");   

workSheet.addCellElement(cellElement1);     

// 新建一个CellElement, 列为 2, 行为 2, 列宽为 2,   

// 行高为 1, 值为当前日期   

CellElement cellElement2 = new CellElement(2, 10, 2, 1, new Date());   

workSheet.addCellElement(cellElement2);     

// 新建一个CellElement, 列为 4, 行为 5, 列宽为 3,   

// 行高为 4, 值为公式 = 23 * 34   

CellElement cellElement3 = new CellElement(4, 5, 3, 4, new Formula("23 * 34"));   

workSheet.addCellElement(cellElement3);   

 

根据所给的列、行、列宽、行高及元素值创建出不同的CellElement对象,再利用report接口中的addCellElement方法将新建的CellElement添加到报表中。可执行代码如下:

package com.fr.demo;

  

import java.awt.Color;     

import java.awt.Font;         

import java.util.Date;

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.report.cellElement.Formula;

import com.fr.web.Reportlet;     

import com.fr.web.ReportletRequest;     

    

/**   

 * ReportletFromTemplateDemo.   

 *  

 * 增加单元格

 */    

public class AddCellElementsToReport implements Reportlet {     

    

    public AddCellElementsToReport() {     

    }     

     //建立新报表需要传参(ReportletRequest reportletRequest)

    public WorkBookTemplate createReport(ReportletRequest reportletRequest) {     

        //new a WorkSheet   

           WorkBook wb = new WorkBook();

        WorkSheet workSheet = new WorkSheet();     

     

        //new a cellElement with String "FineReport"     

        CellElement cellElement1 = new DefaultCellElement(1, 1, "FineReport");     

        

        // 新建一个CellElement, 列为 2, 行为 1, 列宽为 2,  

        // 行高为 1, 值为当前日期  

        CellElement cellElement2 = new DefaultCellElement(2, 1, 2, 1, new Date());  

        workSheet.addCellElement(cellElement2);  

          

        // 新建一个CellElement, 列为 , 行为 1, 列宽为 3,  

        // 行高为 4, 值为公式 = 23 * 34  

        CellElement cellElement3 = new DefaultCellElement(4, 1, 3, 4, new Formula("23 * 34"));  

       

        //add the cellElement to the workSheet     

        workSheet.addCellElement(cellElement1);  

        workSheet.addCellElement(cellElement2);  

        workSheet.addCellElement(cellElement3);  

        //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();     

    

        FRFont frFont = FRFont.getInstance("Tahoma", Font.BOLD | Font.ITALIC, 20);     

        frFont = frFont.applyForeground(Color.red);     

        style = style.deriveFRFont(frFont);     

        cellElement1.setStyle(style);  

        cellElement2.setStyle(style);  

        cellElement3.setStyle(style);  

    

        //set the columnWidth of 4 to 200px,rowHeight of 5 to 50px     

        workSheet.setColumnWidth(4, 200);     

    

        wb.addReport(workSheet);

        return wb;     

    }     

}

编译JAVA文件

下面命令用于编译JAVA文件:

注意在编译时将fr-server-6.5.jar放置在当前目录

C:\>javac -classpath fr-server-6.5.jar AddCellElementsToReport.java

将编译后的AddCellElementsToReport.class放到网络报表根目录下,存放地址如下:

WEB-INF\classes\com\fr\demo

发布并浏览

首先启动报表服务器,既FineReport安装目录下面的Jetty服务器,Jetty服务器启动完毕后打开浏览器,在浏览器中输入下列地址:

http://localhost:8079/WebReport/ReportServer?reportlet=com.fr.demo. AddCellElementsToReport

结果如下所示:

 

读取单元格内容

TemplateImporter templateImporter = 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 cellElement = (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中,可以像遍历普通的Iterator对象一样遍历其中的单元格,本例为了演示做了很简单的操作,只是把单元格的行列,值打印出来,可执行代码如下:

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;  

import com.fr.report.WorkBook;

import com.fr.report.io.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), 宽为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.next();  

                vauleList.add(cellElement.getValue());  

                System.out.println(cellElement.getRow() + " " + cellElement.getColumn() + " "   

                        + cellElement.getValue().toString());  

            }  

              

        } catch(Exception e) {  

            e.printStackTrace();  

        }  

    }

    }

效果如下图展示:

原报表:


程序读出第一列的值:


创建程序网络模版

由服务器原理章节,我们可以了解到所谓的网络报表就是指实现了Reportlet接口的文件,程序网络报表的存在可以用来解决某些特殊应用,而由于程序网络报表需要自己来实现Reportlet接口,接下来我们给以详细说明。

建议在开始本章节钱稍微了解一下FineReport提供的API学习,当然需要一定的程序语言基础。

FineReport报表设计器可以设计出绝大多数的报表而不用写一行代码,只有少部分的报表由于有特殊需求需要用写程序的方式来设计,FineReport提供了丰富的API接口可以让用户很轻松的做出需要的报表,下面这个例子就是要新建一个报表,在(1,1)单元格内插入FineReport这个字符串,对字符串进行格式设置,在其中(4,5)单元格内插入一个FineReport的log标志,用J2EE服务器来发布,通过浏览器来浏览,下面以这个简单的例子来详细的介绍如何创建程序网络报表。

  新建JAVA类文件

  编译JAVA文件

  发布并预览

新建JAVA类文件

创建程序网络报表需要新建一个JAVA类,我们把这个类命名成SimpleReportletDemo,这个类需要实现com.fr.web.Reportlet这个接口,并且需要实现public Report createReport(ReportletRequest reportletRequest)这个方法。

  实现com.fr.web.Reportlet接口,格式如下:

public class SimpleReportletDemo implements Reportlet {      

       public SimpleReportletDemo() {     

}    

     public WorkBookTemplate createReport(ReportletRequest reportletRequest) {

  实现public Report createReport(ReportletRequest reportletRequest)方法,

这个方法需要返回一个Report类型的对象,代码格式如下:

public Report createReport(ReportletRequest reportletRequest){ 

WorkBook wb=new WorkBook();

WorkBook wb=new WorkBook();

WorkSheet workSheet=new WorkSheet(); 

return wb;

}

下面我们可以给workSheet加上一些需要的单元格内容。

♦ 我们现在可以给这个workSheet的(1,1)格子内加上一个字符串,如下所示:

//new a cellElement with String "FineReport"     

        CellElement cellElement1 = new DefaultCellElement(1, 1, "FineReport");     

        //add the cellElement 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();     

    

        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;     

import com.fr.web.ReportletRequest;     

    

/**   

 * SimpleReportletDemo.   

 * 

 */    

public class SimpleReportletDemo implements Reportlet {     

    

    public SimpleReportletDemo() {     

    }     

     //建立新报表需要传参(ReportletRequest reportletRequest)

 public WorkBookTemplate createReport(ReportletRequest reportletRequest) {     

        //new a WorkSheet   

    WorkBook 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,rowHeight 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);     

        cellElement1.setStyle(style);     

        //set the columnWidth of 4 to 200px,rowHeight of 5 to 50px     

        workSheet.setColumnWidth(4, 200);      

        wb.addReport(workSheet);

        return wb;     

    }     

}

编译JAVA文件

下面命令用于编译JAVA文件:

注意在编译时将fr-server-6.5.jar放置在当前目录

C:\>javac -classpath fr-server-6.5.jar SimpleReportletDemo.java

将编译后的SimpleReportletDemo.class放到网络报表根目录下,存放地址如下:

WEB-INF\classes\com\fr\demo

发布并浏览

首先启动报表服务器,既FineReport安装目录下面的Jetty服务器,Jetty服务器启动完毕后打开浏览器,在浏览器中输入下列地址:

http://localhost:8079/WebReport/ReportServer?reportlet=com.fr.demo.SimpleReportletDemo

结果如下所示:

读取模板报表

用设计器设计好报表,导出内置数据模板到硬盘上,是以.cpt结尾的模板文件,cpt文件既可以用设计器打开,也可以用来创建Report对象,本例就是讲解如何从一个cpt的模板文件创建Report,设计一张为自由报表,保存在D盘,为cross.cpt。下面的代码用于从模板创建Report对象

// 读取模板并创建WorkBook(这里的模板为导出的内置数据模板)   

// cross.cpt是一个模板文件.   

File cptFile = new File("D:\\stuff.cpt");   

TemplateImporter templateImporter = new TemplateImporter(cptFile);   

WorkBook workBook = (WorkBook)templateImporter.generateReport();   

注意:模板文件路径字符串不要使用“\”,这是转义字符,应该使用“\\”代替。可执行代码如下所示:

package com.fr.demo;

       import java.io.File;  

import com.fr.base.BaseUtils;

       import com.fr.base.FRContext;  

       import com.fr.base.dav.LocalEnv;  

       import com.fr.report.WorkBook;  

       import com.fr.report.io.TemplateImporter;  

import com.fr.view.PreviewFrame;  

       /** 

        * 这个例子用来说明怎样从模板读取报表Report(模板为 *.cpt 格式) 

        * @author Edgar Duan 

        * @version 6.5 

        * 

        */ 

       public class ReadTemplateReportDemo {  

           /** 

            * @param args 

            */ 

           public static void main(String[] args) {  

               // 报表运行环境路径, WEB-INF目录所放的位置  

               String envPath = "C:/FineReport6.5/WebReport/WEB-INF"; 

               BaseUtils.readIcon("/com/fr/cell/images/tabscroll/first.png");

               // 设置当前报表运行环境, 报表预览时需要一个运行环境  

               // 没有WEB-INF目录时, 路径设置为null. FRContext.setCurrentEnv(new LocalEnv(null));  

               FRContext.setCurrentEnv(new LocalEnv(envPath));  

                 

               try {  

                   // 读取模板并创建WorkBook(这里的模板为导出的内置数据模板)                      

                   File cptFile = new File("D:\\stuff.cpt");  

                   TemplateImporter templateImporter = new TemplateImporter();    

                   WorkBook workBook =(WorkBook) templateImporter.generate(cptFile);  

                   PreviewFrame previewFrame = new PreviewFrame();    

                   previewFrame.print(workBook);  

                   previewFrame.setVisible(true);  

               } catch (Exception e) {  

                   e.printStackTrace();  

               }  

           }  

       }  

实现效果如下图: