阿泰的软件实用主义

水晶报表/BOE

博客园 首页 新随笔 联系 订阅 管理
  208 Posts :: 9 Stories :: 3071 Comments :: 43 Trackbacks

置顶随笔 #

有问题请在此贴跟贴回复,我亦会在此贴回复。

请不要到无关的帖子中跟帖

请尽量描述清楚你的问题和需要,我的理解能力不是很强,呵呵。

 

请您遵守以下规则:

 

提问内容中请不要出现 感叹号,跪求等字样。

请尽量不要称呼我为楼主...

请尽量不要冒充女性。

 

谢谢。

 

另外提醒一下,可以用页面左边的“找找看”,或许之前的一些文字能直接解决你的问题。

请不要发送博客园短信,经常注意不到那个位置。

posted @ 2009-07-01 10:23 阿泰 阅读(26) | 评论 (6)编辑

2009年7月1日 #

有问题请在此贴跟贴回复,我亦会在此贴回复。

请不要到无关的帖子中跟帖

请尽量描述清楚你的问题和需要,我的理解能力不是很强,呵呵。

 

请您遵守以下规则:

 

提问内容中请不要出现 感叹号,跪求等字样。

请尽量不要称呼我为楼主...

请尽量不要冒充女性。

 

谢谢。

 

另外提醒一下,可以用页面左边的“找找看”,或许之前的一些文字能直接解决你的问题。

请不要发送博客园短信,经常注意不到那个位置。

posted @ 2009-07-01 10:23 阿泰 阅读(26) | 评论 (6)编辑

2009年6月7日 #

     摘要: 使用水晶报表的人经常会感慨,这么强的报表工具,连个斜线也没有,太不可理解了。 就这么个小效果,折腾坏不少人。 而VS2005里的RDLC工具,是有斜线的,但是当放到WEB应用时,模板上画得好好的,运行起来后,斜线消失了?本文提供了一种可行性解决方案,并提出了RDLC的另一个BUG。  阅读全文
posted @ 2009-06-07 18:36 阿泰 阅读(126) | 评论 (0)编辑

2009年5月31日 #

有问题请在此贴跟贴回复,我亦会在此贴回复。

请不要到无关的帖子中跟帖

请尽量描述清楚你的问题和需要,我的理解能力不是很强,呵呵。

 

请您遵守以下规则:

 

提问内容中请不要出现 感叹号,跪求等字样。

请尽量不要称呼我为楼主...

请尽量不要冒充女性。

 

谢谢。

 

另外提醒一下,可以用页面左边的“找找看”,或许之前的一些文字能直接解决你的问题。

请不要发送博客园短信,经常注意不到那个位置。

posted @ 2009-05-31 23:32 阿泰| 编辑

2009年5月26日 #

本文为解答该贴所做:http://topic.csdn.net/u/20090524/15/911fd15a-32c6-4be9-9aa1-3ee95365e7e3.html 
并没有什么新内容,主要是如何读取本地图片显示在报表中。
如果是CR XI及以上版本,可以用更简便的方法,参考:水晶报表图片动态加载的另一种简单方案
本文的方法是:水晶报表中如何动态加载图片图片文件版本及数据库版本) 中的图片文件版本。
本文适用于VS2003及VS2005自带版本的水晶报表,当然同样适用于CR XI及以上版本,就是烦了点。
本文使用VS2005及自带版本的水晶报表。

在这里,我把命题重新提炼一下:
已经有一个完整的报表,现在报表需要加载一个本地磁盘图片做为logo。报表中的logo随着本地图片的变化自动变化。
一般我们通过插入一个pictureobject来插入磁盘图片,但是插入后,图片就成为报表的一份,达不到变化的目的。

1:首先我们已经有了一个单表的完整水晶报表应用


2:为了能挂接我们的本地图片,在dataset里新建立一个表mylogo。
里面放上两个字段,字段类型为System.Byte[]或System.sByte[]
注意,默认类型里只有System.Byte和System.SByte,要自己输入的。

这个mylogo就是一个中介,我们把本地图片读到这个表里,水晶报表从这个表里读到图片显示。

3:在现有报表里加入一个子报表,数据源就是这个mylogo.

把两个字段拖到子报表上。

4:代码段是这样的

 1  //设置数据源信息
 2         DataSet1 ds1 = new DataSet1();
 3         OleDbDataAdapter da = new OleDbDataAdapter();
 4         String connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath ("~/app_data/test.mdb")+";";
 5         OleDbConnection cn = new OleDbConnection(connstr);
 6 
 7 
 8         //获取记录集,注意,最终获取的记录集需要与xsd的结构一致!      
 9         da = new OleDbDataAdapter("SELECT EmployeeId1 as EmployeeId,EmployeeName1 as EmployeeName From Employee1", cn);
10         da.Fill(ds1, "Employee");
11 
12         //把本地图片先写入到数据集
13 
14         //将图片读到stream,并转换为byte[]
15         //图片1
16         FileStream fs1 = new FileStream(@"c:\1.bmp", FileMode.Open, FileAccess.Read);
17         BinaryReader br1 = new BinaryReader(fs1);        
18         byte[] bt1 = br1.ReadBytes((int)fs1.Length);
19         //图片2
20         FileStream fs2 = new FileStream(@"c:\a2.jpg", FileMode.Open, FileAccess.Read);
21         BinaryReader br2 = new BinaryReader(fs2);
22         byte[] bt2 = br2.ReadBytes((int)fs2.Length);
23         
24         fs1.Close();
25         fs2.Close();
26         //写入到ds1中(仅1行)
27         ds1.myLogo.AddmyLogoRow(bt1, bt2);
28        
29 
30         //以上为数据部分,与报表无关
31         //-----------------------------------------------------------
32         //以下为报表部分
33 
34         //使用报表对象加载报表
35         
36         string reportPath = Server.MapPath("~/app_data/crystalreport1.rpt");
37         myReport.Load(reportPath);
38         //绑定数据集,注意,一个报表用一个数据集。
39         myReport.SetDataSource(ds1);
40         CrystalReportViewer1.ReportSource = myReport;

 

5:效果是这样的

  

posted @ 2009-05-26 20:00 阿泰| 编辑

2009年5月20日 #

在前文《动态水晶报表:任意表,任意列,以及动态格线》中,
有一个地方还没有完全实现。就是根据内容自动调整表头的列,跟内容表格相对应。

我们也注意到了,在前文中,后面的列之所以不显示,不是因为它们没有了,它们是存在的,只是内容是空(''),注意是空,不是空格。
依此延伸开来,表头也可以用此原理来实现。

本文接上文,稍加改动
把原来的表头删除,放上6个参数字段,p1,p2...p6,都设置边框。设置好与字段的对齐。

然后,改进一下窗体的代码即可。

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Text;
 6 using System.Windows.Forms;
 7 using CrystalDecisions.Shared;
 8 using CrystalDecisions.CrystalReports.Engine;
 9 using CrystalDecisions.Windows.Forms;
10 using System.Data.OleDb;
11 namespace DyCrystalReportDemo
12 {
13     public partial class Form1 : Form
14     {
15         public Form1()
16         {
17             InitializeComponent();
18         }
19 
20         private void button1_Click(object sender, EventArgs e)
21         {
22             String tblName = comboBox1.Text ;
23              String connstr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Threading.Thread.GetDomain().BaseDirectory+ "bbtcrall.mdb" + ";";
24             
25             if (tblName == "")
26             {
27                 MessageBox.Show("请选择表名");
28                 comboBox1.Focus();
29                 return;
30             }
31 
32             //打开数据库连接
33             
34             DataTable dt1 = new DataTable();
35             DataTable dtx = new DataTable();
36             OleDbDataAdapter da = new OleDbDataAdapter();
37             OleDbConnection cn = new OleDbConnection(connstr);
38             
39             //打开选择的表(注意进行错误保护)
40 
41             //如果要实现任意列,只要更改此处的SQL为具体的字段即可
42             da = new OleDbDataAdapter("SELECT * From " + tblName, cn);
43             da.Fill(dt1);
44 
45             //根据dtl获得实际列数
46             int cols = dt1.Columns.Count;
47             
48 
49             //处理ds1
50             clsDyCrystalReportCore xCore = new clsDyCrystalReportCore();
51             dtx = xCore.dtx(dt1);
52             
53             ReportDocument myReport = new ReportDocument();
54             string reportPath = System.Threading.Thread.GetDomain().BaseDirectory + "crystalreport1.rpt";
55             myReport.Load(reportPath);
56 
57             //绑定数据集,注意,一个报表用一个数据集。
58 
59             myReport.SetDataSource(dtx);
60                 
61             //设置参数,即表头
62             for (int i = 1; i <= 6; i++
63             {
64                 if (i <= cols)
65                     myReport.SetParameterValue("p" + i.ToString(), "列名" + i.ToString());
66                 else
67                     //注意,这个不能省,一定要给没用到的参数一个空值
68                     myReport.SetParameterValue("p" + i.ToString(), "");          
69             }
70             crystalReportViewer1.ReportSource = myReport;
71             //crystalReportViewer1.RefreshReport();
72         }
73 
74         private void Form1_Load(object sender, EventArgs e)
75         {          
76             comboBox1.Items.Add ("Test1_1");
77             comboBox1.Items.Add ("Test1_2");        
78         }
79 
80         private void crystalReportViewer1_Load(object sender, EventArgs e)
81         {
82 
83         }
84     }
85 }
86 

 

不好意思,偷懒了,没对齐。

稍加说明:

1: //根据dtl获得实际列数
      int cols = dt1.Columns.Count;

2: //设置参数,即表头
            for (int i = 1; i <= 6; i++)
            {
                if (i <= cols)
                    myReport.SetParameterValue("p" + i.ToString(), "列名" + i.ToString());
                else
                    //注意,这个不能省,一定要给没用到的参数一个空值
                    myReport.SetParameterValue("p" + i.ToString(), "");         
            }

3://crystalReportViewer1.RefreshReport();

这个要注意,这里注释掉了,因为每次刷新的时候,参数窗口会重新弹出来。
所以要使用参数功能的话,尽量把toolbar上的刷新按钮禁止掉。防止出问题。

 

posted @ 2009-05-20 00:33 阿泰 阅读(245) | 评论 (2)编辑