自己整理的Finereport报表制作详细过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己整理的Finereport报表制作详细过程相关的知识,希望对你有一定的参考价值。

参考技术A

  一般来说 一个完整的报表设计流程 大体分为如下几个步骤

   打开设计器

   配置数据源

   新建报表

   配置私有数据源

   报表设计

   预览报表

   发布报表

   第一部分 配置数据源

  步骤一 新建数据库

  打开报表设计器 在设计器最上方的菜单栏当中 选择服务器 在该下拉菜单当中选择公有的数据源管理器 弹出一个数据源管理器对话框

  点击该对话框左上角的增加数据源按钮来添加新的数据源 在这里我们为数据源命名为FRDemo

  用鼠标选中刚刚命名的数据源 右边显示对应的数据源属性编辑面板 共有五项属性 驱动 URL 用户名和密码 以及一个测试数据库连接按钮

  步骤二 设置数据库属性

  首先设置驱动器 在驱动项中选择 sun jdbc odbc JdbcOdbcDriver 然后点击URL文本框旁边的…按钮 系统会根据选择的驱动自动显示对应的URL格式

  将jdbc:odbc:DatabaseName中的DatabaseName换成正在使用的数据库的名字 FRDemo 即jdbc:odbc:FRDemo 由于FRDemo并未设置用户名和密码 因此这两项属性留空

  点击测试连接按钮 系统弹出连接成功的消息框表明数据库连接成功

  如果您的数据库并非Microsoft Access数据库 请根据您原有数据源选择其数据源驱动器 因为URL是根据您的数据源类型来设定的 单击后面的按钮则生成URL的对应模本 如您的数据库是mysql 那么在驱动程序框中选择 gjt mm mysql Driver 对应可以生成URL为 jdbc:mysql://localhost/DatabaseName 将DataBaseName更换成您的数据库名字 下面依次填写您数据库的用户名和密码 如没有则留空 配置完成后选择下面的 测试链接 如链接成功则可以进入下一个步骤

  如非本地数据源请将其中的localhost换成数据库的IP;如在local后有 则将 后的数字改为对应的网络服务器端口即可

   第二部分 报表设计

  报表设计的过程 可以分为如下几个步骤

   新建报表

   定义数据源

   绑定数据列

   汇总

   格式化报表

  步骤一 新建报表

  这一步 就是要选择新建报表的类型 该类型选择共分为三种 分组报表 自由报表 我们的报表设计主要是自由报表类型 因此在下面的报表设计器当中 我们无论选择哪种新建方式 选择的报表类型都可以是自由报表

  新建报表的第一种选择 是点击文件|新建报表 通过二级菜单来选择要新建的报表类型

  第二种途径是在工具栏当中 点击新建报表按钮右侧的下拉箭头 出现报表类型选择的列表 另外 还可以直接点击工具栏当中的新建按钮

  我们设计的主要报表类型是自由报表 因此 选择自由报表类型 打开报表设计界面

  步骤二 定义数据源

  在选定了报表类型之后 我们需要将报表当中用到的数据进行定义 也就是从数据库当中找到我们在该张报表当中需要用到的数据表 关于公有数据源和私有数据源的详细区别 请参见配置数据源章节

  在上一个步骤当中 点击确定选定报表类型 系统会自动弹出一个私有数据源对话框

  点击左上角的添加按钮 新增一个数据源 会弹出一个定义名字的对话框 我们命名为ds (这里ds是datasource的缩写) 点击确定打开私有数据源的编辑页面

  在SQL文本框中 写入SQL语句 select * from sale 点击文本框右侧的预览按钮 即可以看到数据库数据的预览 点击确定打开报表设计界面

  报表设计界面里面 在左侧的数据面板 私有数据源处 可以看到我们刚刚定义的私有数据源ds

  步骤三 绑定数据列

  首先 我们先来设置左侧的分组 将ds 中的字段Region字段拖拽到A 单元格中 保留其默认的设置 即数据纵向扩展 并且进行分组 合并相同内容的值

  将Manager字段拖拽到B 单元格中 同样保留其默认的设置 即数据纵向扩展 并且数据分组 即合并相同内容的值

  然后 我们来设置上方的分组 首先在数据源面板的最下方扩展方向中默认的设置从上到下更改为从左到右

  将ProType拖拽到C 单元格中 其设置为扩展方向是横向的 从左到右 数据是分组 即合并内容相同的值

  将Product字段拖拽到C 单元格中 由于我们在上一步操作已经设置了扩展方向为横向 所以B 单元格我们也保留默认的设置 横向扩展 数据合并内容相同的值

  最后 来添加交叉区域当中的汇总字段 首先在数据源面板当中 将扩展方向由从左到右更改为不扩展 然后下方的汇总当中 选择求和

  将Amount字段拖拽到C 单元格中 也就是对所有的销售量记录进行求和

  步骤四 汇总

  完成了数据列绑定 我们来给报表添加汇总数据

  将A 和A 单元格进行合并 合并后的单元格根据FineReport的单元格命名规则 为A

  在B 当中 写入文字 小计

  在C 当中 写入公式 =sum(C ) 由于我们已经合并了A 和A 单元格 所以这里C 就会跟随A 的分组进行合计

  注 这里合并单元格的作用 是使得C 当中的汇总单元格跟随A 的分组进行组内汇总 如果我们不合并单元格 则C 当中的汇总 就会显示在报表所有数据的下面 成为对所有数据的汇总

  步骤五 格式化报表

  上一步当中 我们已经完成了报表主体的数据的设置 现在我们要给单元格添加边框 表头的斜线 以及文字居中等简单的格式化操作

  边框 首先我们先来选中从A 至C 这一片区域 点击工具栏中的按钮 在系统弹出的边框对话框中 添加内部和外部边框

  斜线 选中A 至B 共四个空白的单元格 点击工具栏中的按钮 合并单元格 右击该单元格 选择单元格元素 在二级菜单中 选择斜线 系统会弹出一个斜线编辑的对话框 在文本编辑框中写入我们在斜线当中要加入的内容 Products|Names 可以通过添加空格来调整文字的位置

  文字居中 用鼠标选中A 至B 整个报表所在的区域 在工具栏当中 点击 也就是文字居中按钮 将报表当中的数据全部居中显示

  最后 预览 即可以得到我们在开始展示的报表效果 该报表在示例当中存储的路径为 /WebReport/WEB INF/reportlets//doc/cross cpt

   第三部分 发布和浏览报表

  在报表设计完成之后 我们将其保存在安装目录下的 /WebReport/WEB INF/reportlets// 目录下 例如我们刚刚设计的报表 其保存的路径和名称为 /WebReport/WEB INF/reportlets//doc/cross cpt 这样就完成了报表在服务器上的部署

lishixinzhi/Article/program/SQL/201311/16431

关于Web报表FineReport打印的开发应用案例

报表打印是报表使用和开发过程中经常碰到的问题,这里汇总了关于Web报表开发打印功能的一些典型应用案例,以应用最广泛的FineReport为例。

案例一:java直接调用报表打印

当java后台定义定时打印的功能,同时又需要直接调用报表的打印的时候,由于打印机型号和纸张不同,需要指定打印机,从而打印是否成功并设置返回值。那么怎么样可以实现这一过程呢?

实现过程

1、定义报表运行环境

// 定义报表运行环境,才能执行报表  
         String envPath = "D:\\FineReport\\develop\\code\\build\\package\\WebReport\\WEB-INF";  
         FRContext.setCurrentEnv(new LocalEnv(envPath));

2、定义执行模板工作簿

TemplateWorkBook workbook = TemplateWorkBookIO.readTemplateWorkBook(FRContext.getCurrentEnv(), "GettingStarted.cpt");

3、  获取报表参数并设置值

// 参数传值  
             Parameter[] parameters = workbook.getParameters();  
             HashMap<String, String> paraMap = new HashMap<String, String>();
             paraMap.put(parameters[0].getName(), "华北");

4、  java中调用报表打印方法并进行判断

通过公式PrintUtils.printWorkBook(cptPath)进行打印,此时不弹出打印窗口。

若需打印选项对话框,则使用PrintUtils.printWorkBook(cptPath, true),其中参数true为显示打印选项对话框,代码如下所示:

// java中调用报表打印方法  
             boolean a = PrintUtils.printWorkBook("GettingStarted.cpt", paraMap, true);  
             if (a == false) {  
                 System.out.println("失败啦!返回" + a);  
             } else {  
                 System.out.println("成功!返回" + a);  
             }

其中printWorkBook()返回值为boolean型,可通过返回值true(打印成功)和false(打印失败)来判断打印是否成功。

5、  完整代码

上述所示的过程的可以通过完整代码来编辑进行打印,如下所示:

package com.fr.io;    

import java.io.File;    
import java.util.HashMap; 
import com.fr.base.FRContext;      
import com.fr.base.Parameter;    
import com.fr.dav.LocalEnv;
import com.fr.main.TemplateWorkBook; 
import com.fr.print.PrintUtils;  
   
  
public class JavaPrint {    
     public static void main(String[] args) {    
         // 定义报表运行环境,才能执行报表    
         String envPath = "D:\\FineReport\\develop\\code\\build\\package\\WebReport\\WEB-INF";    
         FRContext.setCurrentEnv(new LocalEnv(envPath));    
         try {    
             TemplateWorkBook workbook = TemplateWorkBookIO.readTemplateWorkBook(FRContext.getCurrentEnv(), "GettingStarted.cpt");    
             // 参数传值    
             Parameter[] parameters = workbook.getParameters();    
             HashMap<String, String> paraMap = new HashMap<String, String>();  
             paraMap.put(parameters[0].getName(), "华北");  
               
             // java中调用报表打印方法    
             boolean a = PrintUtils.printWorkBook("GettingStarted.cpt", paraMap, true);    
             if (a == false) {    
                 System.out.println("失败啦!返回" + a);    
             } else {    
                 System.out.println("成功!返回" + a);    
             }    
         } catch (Exception e) {    
             e.printStackTrace();    
         }    
     }    
 }

编辑该程序,弹出打印机设置窗口,选择打印机就可以进行打印了,并在后台返回结构:成功!返回true。

案例二:打印模板与预览模板不同

问题反馈

在打印的过程中,有的用户可能会遇到如下情况:用户系统中使用iframe嵌入报表,客户端浏览器看到的是报表样式1,打印的时候不是看到的效果,而是样式2.例如用户系统显示报表的iframe大小固定,无法完全显示A4纸张大小的模板,因此在显示报表的时候进行了分页处理。如果直接将这个显示结构打印到A4纸上,每页纸上只显示固定条数据,下面全是空白的,这样既不美观又浪费纸张。

点击打印的时候,通过js调用FR的打印方法,使用打印模板进行打印,如下:

<html>
<head>
<script type="text/javascript" src="/WebReport/ReportServer?op=emb&resource=finereport.js"></script>
<link rel="stylesheet" type="text/css" href="/WebReport/ReportServer?op=emb&resource=finereport.css"/>
<script type="text/javascript">
	function doFRPrint(){  //点击打印时触发
		var reportURL="/WebReport/ReportServer?reportlet=report_print.cpt"; //打印模板路径,与BS查看的效果不同
        FR.doURLFlashPrint(reportURL);   //调用FR打印方法
	}
</script>
</head>
<body>
<div id="toolbar">
	<button type="button" onclick=doFRPrint()>打印</button>
</div>
<iframe id="reportFrame" src="/WebReport/ReportServer?reportlet=report.cpt&__showtoolbar__=false" width=100% height=80%></iframe>
</body>
</html>

案例三:将当前页数据入库数据入库

模板多张页面,如一些了的账簿模板,每次纸打印部分页面,每次打印后希望触发事件,在数据库中对于位置记录本页面对应的账簿已经打印过了。每张页面在固定位置有本张账簿的编号,对于到数据库中有一个记录是否已经打印的记录字段。

技术分享

 技术分享

以已部署过FineReport的WebReport工程到tomcat服务器为例,其详细过程如下:

1、  对模板添加打印后事件

打开设计器,打开其tomcat报表共组目录,在菜单中点击报表>报表WEB属性>分页预览设置,在右边栏中,如点击添加Flash打印后事件。

在其JavaScript中,输入js代码,目的是调用其WedReport工程下写的一个jsp的执行入库操作。

2.、获取所在页单元格的值

如编号ID在J3单元格,即第三行、第十列,则js方法如下:

var a =$("#r-2-0","div.reportPane").children().eq(9)[0].innerHTML;

3、通过Ajax把值传到jsp页面

完整代码如下:

var a =$("#r-2-0","div.reportPane").children().eq(9)[0].innerHTML;

$.ajax({

url : ‘http://localhost:8080/WebReport/print1.jsp?ID=‘+a

})

4、定义jsp获取编号修改数据库表

   定义页面print1.jsp,首先获取编号ID的值,连接数据库通过update语句把表中toprint字段进行修改,代码如下:

package com.fr.io;

import java.io.File;  
import java.io.FileInputStream;  
import java.io.InputStream;  
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.PreparedStatement;  
import com.fr.base.FRContext;  
import com.fr.base.Env;  
public class SaveReportToDatabase {  
    public static void main(String[] args) {  
        SaveReport();  
    }  
    private static void SaveReport() {  
        try {  
            // 连接数据库  
            String driver = "oracle.jdbc.driver.OracleDriver";  
            String url = "jdbc:oracle:thin:@192.168.100.169:1521:orcl10g";  
            String user = "temp";  
            String pass = "temp123";  
            Class.forName(driver);  
            Connection conn = DriverManager.getConnection(url, user, pass);  
            PreparedStatement presmt = conn  
                    .prepareStatement("insert into report values(?,?)");  
            // 读进需要保存入库的模板文件  
            Env oldEnv = FRContext.getCurrentEnv();  
            String envPath = oldEnv.getPath();  
            File cptfile = new File(envPath  
                    + "\\reportlets\\gettingstarted.cpt");  
            int lens = (int) cptfile.length();  
            InputStream ins = new FileInputStream(cptfile);  
            // 将模板保存入库  
            presmt.setString(1, "gettingstarted.cpt"); // 第一个字段存放模板相对路径  
            presmt.setBinaryStream(2, ins, lens); // 第二个字段存放模板文件的二进制流  
            presmt.execute();  
            conn.commit();  
            presmt.close();  
            conn.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

案例四:将打印信息提交入库

打印时,有时想清楚的知道,哪些报表在什么时间被打印的信息,并将其记录到数据库的一张记录表中,以方便查看相关信息。一般地,点击打印后就会直接触发打印事件,即点击打印就是执行打印的状态。以整个工程,在浏览器中对其中的报表预览时,点击FLASH打印后将其打印信息记录到库表中为例。

1、  新建信息表

新建一张记录信息表,如:在access数据库中新建一张表,命名为表1。其中输入两个字段:date和tableName,类型分别为日期和文本类型。

2、  添加打印后事件

点击服务器>服务器配置,选择分页预览设置选项,进入分页预览设置窗口。在右边栏中,点击添加FLASH打印后事件,如下图所示:

技术分享

选择提交入库及选择其信息记录表,且点击智能添加字段后,如上在date中输入公式:=today()获取当前日期,在tablename中输入公式:=reportName获取当前打印的报表。

案例五:动态打印

在进行报表查看时,有时会发现一两条重要或者错误信息,需要将其进行打印出来备份一下,这时就需要动态实现打印效果,勾选需打印的信息,将其打印出来。

1、  父模板

  • 数据准备

新建模板,新建数据查询:sql为SELECT * FROM 雇员。

  • 报表主体设计

在A3单元格中使用复选框控件,用来勾选需要打印的信息,如下图:

技术分享

  • 获取复选框的值

为复选框添加初始化事件,将勾选项的信息放到数组中保存,代码如下:

if(!FR.checkBoxes){
FR.checkBoxes=new Array();
}
var len=FR.checkBoxes.length;
FR.checkBoxes[len]=this;
  • 工具栏添加自定义打印按钮

点击模板>模板web属性>填报页面设置,选择为该模板单独设置,添加一个自定义打印按钮至工具栏中,并把自定义打印按钮清空

技术分享

 

自定义JavaScript,代码如下:

var joinData=function(){
var datas=[];
 for(var i=0;i<FR.checkBoxes.length;i++){
var checkBox=FR.checkBoxes[i];
if(checkBox.getValue()===true){
var colRow=FR.cellStr2ColumnRow(checkBox.options.location);
colRow.col++;
var location=FR.columnRow2CellStr(colRow);
var value=_g().getCellValue(location,null);
datas[datas.length]=value;
}
}
return datas.join(",");

}
var data=joinData();
var url="http://localhost:8075/WebReport/ReportServer?reportlet=doc/Advanced/PrintReport/SelectPrint_son.cpt"+"&ids="+data;
window.onbeforeunload=null;
FR.doURLPDFPrint(url);

并保存

1、  子模板

  • 数据准备

新建模板,新建数据查询ds1,sql为SELECT * FROM 雇员 where 雇员id in (${ids}),该参数是为了接收父模板传递过来的雇员id。

  • 报表主体设计

技术分享保存

3、  预览和打印

打开父模板,点击填报预览,选中需要打印的数据,点击工具栏上的打印按钮,即可将选中信息打印出来了,如下图:

技术分享

以上是关于自己整理的Finereport报表制作详细过程的主要内容,如果未能解决你的问题,请参考以下文章

FineReport报表和水晶报表的比较

FineReport学习——各种报表的制作

FineReport中如何制作树数据集来实现组织树报表

FineReport中如何制作树数据集来实现组织树报表

关于Web报表FineReport打印的开发应用案例

FineReport----报表模板入门教程