人不疯难成功

http://tianyameishi.taobao.com 这是我家的淘宝店欢迎光临,知识分享的同时,一起品味新疆特产,哈哈,打个广告

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近折腾采用第三方报表控件(DevExpress),开始采用的是 文件(.repx)读取的方式进行报表设计器的加载。实现方式如下:

不设置文件复制到输出目录,是无法加载到该报表模块文件的。

 1  //获取datatable数据
2 CreateDataTable();
3 DataSet ds = new DataSet();
4 ds.Tables.Add(dt);
5 //加载数据,用户自定义报表格式
6 DevExpress.XtraReports.UI.XtraReport report = new DevExpress.XtraReports.UI.XtraReport();
7 report.LoadLayout(Application.StartupPath + @"\ReportFile\ReporTemplate.repx");
8 report.DataSource = ds;
9 report.ShowDesignerDialog();
10 report.Dispose();

       做到这里表面上看,基本功能很简单的就实现了,但是我们应该考虑一个问题就是,用户在设置后,我们怎样保存,其实这个也比较简单,采用

1 report.SaveLayout(Application.StartupPath + @"\ReportFile\ReporTemplate1.repx");

      保存过程中,注意文件名不能重复,因为本身的模版正在使用中,无法覆盖的。

      基本功能就说到这里。说说这里面的问题吧, 用户保存模块文件过多,使用起来不方便,无疑造成用户或者服务器端文件不断增大承载比较重,直到一天崩溃为止。下面说说,通过模版二进制流的方式来完成该功能无疑是最佳选择。

      设计思路:

      1、数据库中设计一个表,来存储采用二进制byte生成的文件。最好是两个一个是初始化模版,一个是用户设计后的模版。

 1  try
2 {
3 string filepath = Application.StartupPath.ToString();
4 FileStream file = new FileStream(filepath + @"\ReportFile\ReporTemplate.repx", FileMode.Open, FileAccess.ReadWrite);
5 byte[] a = new byte[file.Length];
6 file.Read(a, 0, (int)file.Length);
7 //这里是我将二进制转换成文本显示的
8 txtContent.Text = Convert.ToBase64String(a);
9 }
10 catch (Exception)
11 {
12 throw;
13 }

            这样你就可以获取初始化的模版文件的二进制模版数据,保存到初始化的数据字段中,以后就不用这个了。

       2、读取报表二进制数据,加载到模版报表中。如下:

 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8 using DevExpress.XtraEditors;
9 using System.IO;
10 using System.Linq;
11 using DevExpress.XtraReports.UI;
12 using DevExpress.XtraReports.UserDesigner;
13 using System.Drawing.Design;
14 using System.ComponentModel.Design;
15 using DevExpress.XtraReports;

 

 1 XtraReport r;
2 private void btnRead_Click(object sender, EventArgs e)
3 {
4 r = new XtraReport();
5 //二进制流读取转换
6 byte[] ff=Convert.FromBase64String(txtContent.Text.Trim());
7 System.IO.MemoryStream ms = new MemoryStream(ff);
8 r.LoadLayout(ms);
9
10 XRDesignFormEx designForm = new XRDesignFormEx();
11
12 //隐藏按钮 这段
13 //designForm.DesignPanel.SetCommandVisibility(new ReportCommand[]{
14 // ReportCommand.NewReport,
15 // ReportCommand.SaveFileAs,
16 // ReportCommand.NewReportWizard,
17 // ReportCommand.OpenFile
18 //},new DevExpress.XtraReports.UserDesigner.c CommandVisibility.None);
19
20
21
22 //更改状态
23 designForm.ReportStateChanged += new ReportStateEventHandler(designForm_ReportStateChanged);
24 designForm.FormClosing += new FormClosingEventHandler(designForm_FormClosing);
25 // 加载报表.
26 designForm.OpenReport(r);
27 // 打开设计器
28 designForm.ShowDialog();
29 designForm.Dispose();
30 }
31
32 void designForm_FormClosing(object sender, FormClosingEventArgs e)
33 {
34 //在此处处理关闭设计器时的操作,主要用来自定义保存数据
35
36 System.IO.MemoryStream ms = new MemoryStream();
37 r.SaveLayout(ms);
38 byte[] fff = ms.ToArray();
39 txtContent.Text = Convert.ToBase64String(fff);
40 }
41
42 void designForm_ReportStateChanged(object sender, ReportStateEventArgs e)
43 {
44 //只要报表发生改变就立即将状态设置为保存
45 //避免系统默认保存对话框的出现
46 if (e.ReportState == ReportState.Changed)
47 {
48 ((XRDesignFormEx)sender).DesignPanel.ReportState = ReportState.Saved;
49 }
50 }

          实现以上代码需要引用 DevExpress.XtraReports.v11.1.Design、DevExpress.XtraReports.v11.1.Extensions、DevExpress.XtraReports.v11.1 就可以了。

         通过以上代码就可以实现了。多说一句,以下代码中,通过System.IO.MemoryStream 内存流的方式获取报表设计界面更改后的二进制数据模版的状态只。
 

1   r = new XtraReport();
2 //二进制流读取转换
3 byte[] ff=Convert.FromBase64String(txtContent.Text.Trim());
4 System.IO.MemoryStream ms = new MemoryStream(ff);
5 r.LoadLayout(ms);

         通过以上的折腾基本上草稿已经出来了,具体数据库怎样搞就非常easy了。就不多说了

         我这段代码中,还存在一个小问题,也正在研究中,我代码中注释的一段,怎样禁用设计器中的按钮。如果有博友知道的,麻烦一起分享一下。

posted on 2011-12-03 13:33  萧從军  阅读(1603)  评论(0编辑  收藏  举报