Ø ** 在 ** ** .NET ** ** 中利用 ** ** FORMULA ** ** ** ** ONE ** ** 实现动态报表技术 ** ** ( ** ** 一 ** ** ) **
相信对大家 Formula One ( 简称 F1) 不会太陌生,它是一个优秀第三方报表制作控件,本人以前一直使用它与 PB 结合制作动态报表。现在有一 .NET 项目,有大量报表要实现,那么利用原先的 FORMULA ONE 制作的报表技术能否在 .NET 中继续延用呢 ? 经过几天的摸索终于把原来利用 Formula One 的动态报表解决方案完全的移植到 .NET 中。
.NET ** 调用 ** ** COM ** ** 组件基本原理 ** ** **
在微软 .NET 通用语言运行时 (CLR) 中运行的代码称为托管代码,不在 CLR 中动行的代码被称为非托管代码。可以说所有的 COM 组件都是非托管代码。而托管代码组件不只依赖 CLR ,它们还要求与之交互的组件也要依赖于 CLR 。微软的解决方案是 RCW( 运行时可调用封装器 )---- 用于从托管代码调用非托管代码的特殊类型的代理。下图显示了如果利用 RCWs 调用非托管组件。此图包括一个名为 NetUI.exe 的 .NET 程序,两个名为 BackEnd.dll 和 Service.dll 的 COM 组件,以及链接它们的必要技术。
利用 TLBIMP 转换元数据
并不是 .NET 首先使用元数据描述公有接口。 COM 类型库也有描述 COM 组件公用接口的元数据。其实 RCW 的功能主要是将 COM 类型的元数据转换为 .NET 的元数据。 .NET FrameWork 软件开发工具包中有一工具 tlbimp( 类型库导入器 ) 用来进行此转换。 TlbImp 从 COM 类型库中读取元数据并创建与 CLR 匹配部件以调用 COM 组件。
也可以利用 VS.NET 工具以便直接引用 COM 组件 ( 其实仍然是利用 RCW), 下面例程使用此方法。
** 报表模板管理模块实例分析 **
下面以一个具体的报表模板管理模块为实例,说明怎么在 .NET 中利用 Formula One 技术。
说明:每一张定义的报表有一张对应的模板,模板可在外部利用 Excel 定义。模板管理是对报表对应的模板增、删、改进行管理的模块。
** 一、准备工作 ** ** **
1. 确认安装了 VS.NET2002 或 VS.NET2003
2. 安装或注册了 F1
3. 安装了 SQLSERVER 并建 Report_List_Data 表,表结构如下:
CREATE REPORT_LIST_DATA
(
NUM INT NOT NULL , -- 主键
RPT_ID INT NOT NULL , -- 报表表号 ID
RPT_NAME VARCHAR(60) NOT NULL , -- 报表名
RPT_DATA IMAGE NULL , -- 报表内容
USER_NAME VARCHAR(40) NULL , -- 制表人
RPT_DATE DATETIME NULL , -- 报表日期
CONSTRAINT T_RPT_LIB_PK PRIMARY KEY (NUM)
);
二、 界面设计 ** **
1. 选择工具箱 à Window 窗体控件 à 添加 / 移除项 … à COM 组件 , 选择 Tidestone Formula One 6.0 WorkBook
2. 新建一窗体,把新增加进入工具箱的 F1 控件,和一些相关的控件加入窗体,界面设计如下图所示:
三、 系统设计及编码 ** **
1. 一打开模块,模块窗体组合框中检索出所有的数据库中的模板。
在 TemplateManger 类构造函数中加入 comboTemplateFillValue() 函数,用来向组合框中填充数据
// 向组合框中加入已经保存的模板名
private void comboTemplateFillValue()
{
string strQuery = "Select rpt_id,rpt_name from report_list_data";
SqlDataReader aReader = db.Query(strQuery);
while (aReader.Read())
{
comboTemplate.Items.Add(aReader[1].ToString()+"["+aReader[0].ToString()+"]");
}
aReader.Close();
}
注:其中 db.Query() 为自定义的数据库操作基类中一查询方法。
2. F1 控件能完全兼容 Excel 格式文档,我们可以把模板利用大家都熟悉的 Excel 来定义模板,然后读入 F1 控件。在“读入模板”按键可加入如下脚本 .
private void btnRead_Click( object sender, System.EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string tplName = openFileDialog1.FileName.ToString();
tplName = tplName.Remove(0,tplName.LastIndexOf("\")+1);
tplName = tplName.Substring(0,tplName.Length - 4); // 去掉扩展名
//MessageBox.Show(FileName);
comboTemplate.Text = " 模板 "+tplName+"["+GetPKID("report_list_data","rpt_id").ToString()+"]";
// 读 EXCEL Files
axF1Book1.ReadEx(openFileDialog1.FileName.ToString());
axF1Book1.ShowEditBar = true ;
ShowVScrollBar();
btnDel.Enabled = false ;
}
}
注: 1. 读入的模板名命名方式为“模板” + “模板名称” + “ [ 模板 ID] ”形式
2. 主要语句为 axF1Book1.ReadEx(openFileDialog1.FileName.ToString()); 功能是读取模板文件进入 F1 控件。
3. 脚本中 GetPKID() 函数的作用是取得模板唯一 ID 值, ShowVScrollBar(); 主要是保存 F1 控件滑动条一直存在
3. 读入的模块可以在控件中直接修改,也可以调用 F1 的服务端程序进行修改 , 调用服务端程序很简单 .
private void btnServer_Click( object sender, System.EventArgs e)
{
axF1Book1.AllowDesigner = true ;
axF1Book1.LaunchDesigner();
}