最近一个项目中,涉及到很多报表的开发,以前对水晶报表搞得比较熟,但它的庞大与其它诸多功能限制,特别是发布与部置时面临的困难,实在让人无法忍受(应该很少有人买得起正版吧),决定试一下MS Reporting Services,当然在这里只使用Local Report,对微软的Reporting Services进行了一番了解,蜡人张(http://www.cnblogs.com/waxdoll/category/49402.html)老兄这里有很多很好的学习材料,我也是从蜡人兄那里对自定义报表的研究得出以下部分修正的Demo.
对于微软提供的ReportView控件,大家都知道,不能在其中对报表的边距等进行自定义,其工具条也是根本上无法自定义控制的,每次用户打印时,都必须对页面,边距等进行调整,对用户来说,这可能是一件无法忍受的事情,这或者是为满足Reporting Services报表而这样设计的.
对蜡人张老兄提供的例子做了一些改进,主要修正以下几点:
1,修正无法使用网络打印机进行打印的问题;
2,报表使用钳入式资源加载方式;
3,提取成一用户控件ReportView,更方便于开发人员将其整合到自己的项目中
Demo文件结构:
自定义报表控件ReportView源码分如下:
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Drawing;
5
using System.Data;
6
using System.Text;
7
using System.Windows.Forms;
8
using System.IO;
9
using Microsoft.Reporting.WinForms;
10
namespace LocalReportDemo.Report
11
{
12
public partial class ReportViewer : UserControl
13
{
14
15
private EMFStreamPrintDocument printDoc;
16
17
/// <summary>
18
/// 主报表名称
19
/// </summary>
20
private string m_ReportName = string.Empty;
21
public string ReportName
22
{
23
get
24
{
25
return this.m_ReportName;
26
}
27
set
28
{
29
this.m_ReportName = value;
30
}
31
}
32
33
/// <summary>
34
/// 主报表数据源
35
/// </summary>
36
private object m_MainDataSet = null;
37
public object MainDataSet
38
{
39
get
40
{
41
return this.m_MainDataSet;
42
}
43
set
44
{
45
this.m_MainDataSet = value;
46
47
}
48
}
49
50
/// <summary>
51
/// 主报表数据源名称
52
/// </summary>
53
private string m_MainDataSourceName = string.Empty;
54
public string MainDataSourceName
55
{
56
get
57
{
58
return this.m_MainDataSourceName;
59
}
60
set
61
{
62
this.m_MainDataSourceName = value;
63
}
64
}
65
66
/// <summary>
67
/// 钳入资源中的报表路径
68
/// </summary>
69
private string m_ReportEmbeddedResource;
70
public string MReportEmbeddedResource
71
{
72
get
73
{
74
return m_ReportEmbeddedResource;
75
}
76
set
77
{
78
m_ReportEmbeddedResource = value;
79
}
80
}
81
82
/// <summary>
83
/// 钻取报表数据源
84
/// </summary>
85
private object m_DrillDataSet = null;
86
public object DrillDataSet
87
{
88
get
89
{
90
return this.m_DrillDataSet;
91
}
92
set
93
{
94
this.m_DrillDataSet = value;
95
}
96
}
97
/// <summary>
98
/// 钻取报表数据源名称
99
/// </summary>
100
private string m_DrillDataSourceName = string.Empty;
101
public string DrillDataSourceName
102
{
103
get
104
{
105
return this.m_DrillDataSourceName;
106
}
107
set
108
{
109
this.m_DrillDataSourceName = value;
110
}
111
}
112
113
/// <summary>
114
/// 构造器
115
/// </summary>
116
public ReportViewer()
117
{
118
InitializeComponent();
119
this.Dock = System.Windows.Forms.DockStyle.Fill;
120
}
121
122
/// <summary>
123
/// 加载窗体事件
124
/// </summary>
125
/// <param name="sender"></param>
126
/// <param name="e"></param>
127
private void rpv1_Load(object sender, EventArgs e)
128
{
129
}
130
/// <summary>
131
/// 加载报表
132
/// </summary>
133
public void BindReport()
134
{
135
136
System.Type type = this.MainDataSet.GetType();
137
if (this.m_MainDataSet == null)
138
{
139
MessageBox.Show("报表数据源不存在或为空!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
140
return;
141
}
142
if (type == null)
143
{
144
System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
145
return;
146
}
147
else
148
{
149
System.Reflection.PropertyInfo[] picData = type.GetProperties();
150
bool bolExist = false;
151
foreach (System.Reflection.PropertyInfo piData in picData)
152
{
153
if (piData.Name == "Tables")
154
{
155
bolExist = true;
156
157
if (MainDataSourceName == string.Empty)
158
{
159
MessageBox.Show("报表数据源不存在或为空!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
160
return;
161
}
162
163
this.rpv1.LocalReport.DataSources.Add(
164
new Microsoft.Reporting.WinForms.ReportDataSource(this.MainDataSourceName,
165
(piData.GetValue(this.MainDataSet, null) as System.Data.DataTableCollection)[0])
166
);
167
this.rpv1.LocalReport.ReportEmbeddedResource = this.MReportEmbeddedResource;
168
this.rpv1.RefreshReport();
169
this.lblTotal.Text = @"/" + (this.rpv1.LocalReport.GetTotalPages()+1).ToString();
170
this.tbxPage.Text = "1";
171
break;
172
}
173
}
174
175
if (!bolExist)
176
{
177
System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
178
return;
179
}
180
}
181
}
182
183
工具条事件
368
369
/// <summary>
370
/// 钻取报表事件
371
/// </summary>
372
/// <param name="sender"></param>
373
/// <param name="e"></param>
374
private void rpv1_Drillthrough(object sender, DrillthroughEventArgs e)
375
{
376
if (DrillDataSet == null)
377
{
378
MessageBox.Show("报表数据源不存在或为空!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
379
return;
380
}
381
else
382
{
383
if (this.DrillDataSourceName == string.Empty)
384
{
385
System.Windows.Forms.MessageBox.Show("报表数据源格式不正确!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
386
return;
387
}
388
else
389
{
390
Microsoft.Reporting.WinForms.LocalReport report = e.Report as Microsoft.Reporting.WinForms.LocalReport;
391
report.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource(this.DrillDataSourceName, this.GetTableCollection(this.DrillDataSet)[0]));
392
}
393
}
394
}
395
private System.Data.DataTableCollection GetTableCollection(object ReportSource)
396
{
397
System.Type type = ReportSource.GetType();
398
399
if (type == null)
400
{
401
MessageBox.Show("报表数据源格式不正确!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
402
return null;
403
}
404
else
405
{
406
System.Reflection.PropertyInfo[] picData = type.GetProperties();
407
bool bolExist = false;
408
foreach (System.Reflection.PropertyInfo piData in picData)
409
{
410
if (piData.Name == "Tables")
411
{
412
bolExist = true;
413
return piData.GetValue(ReportSource, null) as System.Data.DataTableCollection;
414
}
415
}
416
417
if (!bolExist)
418
{
419
MessageBox.Show("报表数据源格式不正确!", "提醒对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
420
return null;
421
}
422
}
423
return null;
424
}
425
}
426
}
427

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

报表宿主窗口加载报表与数据源的方法:
1
DataSet ds = new DataSet();
2
ds.ReadXml(Application.StartupPath + @"\DataSource.xml");
3
this.reportViewer1.MainDataSet = ds;//报表主数据源
4
this.reportViewer1.MainDataSourceName = "ReportDemoDataSet_ReportDemoTable";//数据源名称
5
this.reportViewer1.MReportEmbeddedResource = "LocalReportDemo.ReportDemo.rdlc";//钳入资源的报表路径
6
this.reportViewer1.ReportName = "ReportDemo";//报表名称
7
this.reportViewer1.BindReport();//加载挷定报表

2

3

4

5

6

7

数据源名称如下图所示:

其中钳入资源的报表路径中,LocalReportDemo为报表钳入的程序集名称
报表格式配置文件ReportSettings.xml:
1
<?xml version="1.0" standalone="yes"?>
2
<ReportSettings>
3
<ReportDemo>
4
<ReportName>ReportDemo</ReportName>
5
<PrinterName>Microsoft Office Document Image Writer</PrinterName>
6
<PaperName>A4</PaperName>
7
<PageWidth>21.01</PageWidth>
8
<PageHeight>29.69</PageHeight>
9
<MarginTop>0.5</MarginTop>
10
<MarginBottom>0.2</MarginBottom>
11
<MarginLeft>2.3</MarginLeft>
12
<MarginRight>0.2</MarginRight>
13
<Orientation>Z</Orientation>
14
</ReportDemo>
15
</ReportSettings>

2

3

4

5

6

7

8

9

10

11

12

13

14

15

此Demo运行效果:

打印预览:

有任何问题欢迎在此提出,大家共同讨论解决
此Demo完整代码下载:
/Files/mshwu/LocalReportDemo.rar