前言
最近接到一个需求:在给定的数据源中,某(些)列,可能需要单独统计,是否单独统计需要根据报表配置来决定。由于项目中一直使用RDLC来生成报表,临时为了一个需求换一种技术也不是很现实,所以自己捉摸了下。
认识RDLC
RDLC的主要有三个部分:
(1)*.rdlc文件,本质是一个XML文件,这里定义了报表样式;
(2)*.xsd文件,也是一个XML文件,这里定义了数据源格式;
(3)*.aspx文件,呈现报表的web页面。
注:RDLC是什么,可参考蜡人张的博客:http://www.cnblogs.com/waxdoll/archive/2006/02/25/337713.html
如何实现动态
(1)LocalReport对象提供了方法LoadReportDefinition(Stream stream)和属性ReportPath保证了我们不仅可以从流中读取文件,也可以指定本地文件路径加载rdlc文件;
(2).rdlc,.xsd都是xml文件,可使用XmlDocument进行读写操作。
实例
下面实现一个学生成绩统计报表为例,介绍如何实现动态列。
第一步 准备工作
新建空web项目->添加xsd文件,创建一个table(文件名Students.xsd)->添加rdlc文件,与xsd的table关联,并绑定相关字段(文件名FirstRdlc.rdlc)。
Students.xsd设计器视图:
对应的xml文件:
View Source<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Students" targetNamespace="http://tempuri.org/Students.xsd" xmlns:mstns="http://tempuri.org/Students.xsd" xmlns="http://tempuri.org/Students.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections />
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="Students" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:EnableTableAdapterManager="true" msprop:Generator_DataSetName="Students" msprop:Generator_UserDSName="Students">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="dtStudent" msprop:Generator_TableClassName="dtStudentDataTable" msprop:Generator_TableVarName="tabledtStudent" msprop:Generator_TablePropName="dtStudent" msprop:Generator_RowDeletingName="dtStudentRowDeleting" msprop:Generator_UserTableName="dtStudent" msprop:Generator_RowChangingName="dtStudentRowChanging" msprop:Generator_RowEvHandlerName="dtStudentRowChangeEventHandler" msprop:Generator_RowDeletedName="dtStudentRowDeleted" msprop:Generator_RowEvArgName="dtStudentRowChangeEvent" msprop:Generator_RowChangedName="dtStudentRowChanged" msprop:Generator_RowClassName="dtStudentRow">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" msprop:Generator_ColumnVarNameInTable="columnName" msprop:Generator_ColumnPropNameInRow="Name" msprop:Generator_ColumnPropNameInTable="NameColumn" msprop:Generator_UserColumnName="Name" type="xs:string" minOccurs="0" />
<xs:element name="Age" msprop:Generator_ColumnVarNameInTable="columnAge" msprop:Generator_ColumnPropNameInRow="Age" msprop:Generator_ColumnPropNameInTable="AgeColumn" msprop:Generator_UserColumnName="Age" type="xs:string" minOccurs="0" />
<xs:element name="Scores" msprop:Generator_ColumnVarNameInTable="columnScores" msprop:Generator_ColumnPropNameInRow="Scores" msprop:Generator_ColumnPropNameInTable="ScoresColumn" msprop:Generator_UserColumnName="Scores" type="xs:string" minOccurs="0" />
<xs:element name="RecId" msprop:Generator_ColumnVarNameInTable="columnRecId" msprop:Generator_ColumnPropNameInRow="RecId" msprop:Generator_ColumnPropNameInTable="RecIdColumn" msprop:Generator_UserColumnName="RecId" type="xs:string" />
<xs:element name="Class" msprop:Generator_ColumnVarNameInTable="columnClass" msprop:Generator_ColumnPropNameInRow="Class" msprop:Generator_ColumnPropNameInTable="ClassColumn" msprop:Generator_UserColumnName="Class" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="dtStudentKey1" msdata:PrimaryKey="true">
<xs:selector xpath=".//mstns:dtStudent" />
<xs:field xpath="mstns:RecId" />
</xs:unique>
</xs:element>
</xs:schema>
观察这段xml,会注意这段代码:
<xs:element name="Class" msprop:Generator_ColumnVarNameInTable="columnClass" msprop:Generator_ColumnPropNameInRow="Class" msprop:Generator_ColumnPropNameInTable="ClassColumn" msprop:Generator_UserColumnName="Class" type="xs:string" minOccurs="0" />
这句代码定义了报表数据源的“Class”这列。可想而知,我们如果动态添加一列,这里势必应该要修改。
FirstRdlc.rdlc文件设计器视图:
对应的xml文件如下:
View Source<?xml version="1.0" encoding="utf-8"?>
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition">
<DataSources>
<DataSource Name="Students">
<ConnectionProperties>
<DataProvider>System.Data.DataSet</DataProvider>
<ConnectString>/* Local Connection */</ConnectString>
</ConnectionProperties>
<rd:DataSourceID>9a61684e-8669-405d-b9ef-dc43279c6ff0</rd:DataSourceID>
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="dsStudent">
<Fields>
<Field Name="Name">
<DataField>Name</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="Age">
<DataField>Age</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="Scores">
<DataField>Scores</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="RecId">
<DataField>RecId</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="Class">
<DataField>Class</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
</Fields>
<Query>
<DataSourceName>Students</DataSourceName>
<CommandText>/* Local Query */</CommandText>
</Query>
<rd:DataSetInfo>
<rd:DataSetName>Students</rd:DataSetName>
<rd:SchemaPath>E:\Demo\HelloRDLC\HelloRDLC\Students.xsd</rd:SchemaPath>
<rd:TableName>dtStudent</rd:TableName>
<rd:TableAdapterFillMethod />
<rd:TableAdapterGetDataMethod />
<rd:TableAdapterName />
</rd:DataSetInfo>
</DataSet>
</DataSets>
<Body>
<ReportItems>
<Tablix Name="Tablix5">
<TablixBody>
<TablixColumns>
<TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
<TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
<TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
<TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
<TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
</TablixColumns>
<TablixRows>
<TablixRow>
<Height>0.23622in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox25">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>序号</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox25</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox27">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>姓名</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox27</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox29">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>年龄</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox29</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox32">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>班级</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox32</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox34">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>得分</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox34</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
<TablixRow>
<Height>0.23622in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="RecId">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!RecId.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>RecId</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Name">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Name.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Name</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Age">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Age.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Age</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Class">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Class.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Class</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Scores">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Scores.Value</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Scores</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
</TablixRows>
</TablixBody>
<TablixColumnHierarchy>
<TablixMembers>
<TablixMember />
<TablixMember />
<TablixMember />
<TablixMember />
<TablixMember />
</TablixMembers>
</TablixColumnHierarchy>
<TablixRowHierarchy>
<TablixMembers>
<TablixMember>
<KeepWithGroup>After</KeepWithGroup>
</TablixMember>
<TablixMember>
<Group Name="详细信息" />
</TablixMember>
</TablixMembers>
</TablixRowHierarchy>
<DataSetName>dsStudent</DataSetName>
<Top>0.52035cm</Top>
<Left>0.47625cm</Left>
<Height>1.2cm</Height>
<Width>12.49997cm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
</Style>
</Tablix>
</ReportItems>
<Height>2.96875in</Height>
<Style />
</Body>
<Width>6.5in</Width>
<Page>
<PageHeader>
<Height>1.34938cm</Height>
<PrintOnFirstPage>true</PrintOnFirstPage>
<PrintOnLastPage>true</PrintOnLastPage>
<ReportItems>
<Textbox Name="txtHeader">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>学生成绩统计报表</Value>
<Style />
</TextRun>
</TextRuns>
<Style>
<TextAlign>Center</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>0.65299cm</Top>
<Height>0.6cm</Height>
<Width>16.51cm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<VerticalAlign>Middle</VerticalAlign>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Style>
<Border>
<Style>None</Style>
</Border>
</Style>
</PageHeader>
<PageFooter>
<Height>1.7507cm</Height>
<PrintOnFirstPage>true</PrintOnFirstPage>
<PrintOnLastPage>true</PrintOnLastPage>
<ReportItems>
<Textbox Name="txtFooter">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Copy Right 2001-2012 infosky R&D</Value>
<Style />
</TextRun>
</TextRuns>
<Style>
<TextAlign>Right</TextAlign>
</Style>
</Paragraph>
</Paragraphs>
<Top>1.04069cm</Top>
<Height>0.71cm</Height>
<Width>16.51cm</Width>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</ReportItems>
<Style>
<Border>
<Style>None</Style>
</Border>
</Style>
</PageFooter>
<PageHeight>29.7cm</PageHeight>
<PageWidth>21cm</PageWidth>
<LeftMargin>2cm</LeftMargin>
<RightMargin>2cm</RightMargin>
<TopMargin>2cm</TopMargin>
<BottomMargin>2cm</BottomMargin>
<ColumnSpacing>0.13cm</ColumnSpacing>
<Style />
</Page>
<rd:ReportID>7d9ab7b5-369c-4d46-86a6-b8723598c7cd</rd:ReportID>
<rd:ReportUnitType>Cm</rd:ReportUnitType>
</Report>
仔细观察这段xml文件,不难看出有几部分代码是值得关注的:
(1)路径Report/DataSets/DataSet/Fields下得Field节点,这里定义的是同数据源相关的列;
View Source <Field Name="Name">
<DataField>Name</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
(2)路径Report/DataSets/DataSet/rd:DataSetInfo节点,这里定义了rdlc关联的xsd文件的路径;
View Source <rd:DataSetInfo>
<rd:DataSetName>Students</rd:DataSetName>
<rd:SchemaPath>E:\Demo\HelloRDLC\HelloRDLC\Students.xsd</rd:SchemaPath>
<rd:TableName>dtStudent</rd:TableName>
<rd:TableAdapterFillMethod />
<rd:TableAdapterGetDataMethod />
<rd:TableAdapterName />
</rd:DataSetInfo>
(3)路径Report/Body/ReportItems/Tablix/TablixBody/TablixColumns下的TablixColumn节点,这里应该定义了RDLC报表的列数
View Source <TablixColumn>
<Width>0.98425in</Width>
</TablixColumn>
(4)路径Report/Body/ReportItems/Tablix/TablixBody/TablixRows下的TablixRow。从名称可知是报表行相关内容,其中每个TablixRow,又定义了单元格信息(在TablixCells下的TablixCell节点)。这里默认情况下有两行,第一行定义了报表列头显示内容,如:姓名,性别等,第二行定义了报表数据的绑定项。如:姓名绑定到xsd的Name字段。这里便有:<Value>=Fields!Name.Value</Value>
View Source<TablixCell>
<CellContents>
<Textbox Name="Textbox27">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>姓名</Value>
<Style />
</TextRun>
</TextRuns>
<Style />
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox27</rd:DefaultName>
<Style>
<Border>
<Color>LightGrey</Color>
<Style>Solid</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
所以,这以上几处在我们修改xml时,势必可能需要修改。其实,这里还有一处需要修改,路径:Report/Body/ReportItems/Tablix/TablixColumnHierarchy/TablixMembers下的TablixMember,该节点个数一定要和报表列数相同。否则编译便会报错。
第二步:操作XML,动态添加列(GPA列)
(1)操作XML文件使用XmlDocument类,需要添加节点时,可以使用XmlNode.CloneNode(bool)方法。
View Source //添加Field节点
XmlNodeList fileds = xmlDoc.GetElementsByTagName("Fields");
XmlNode filedNode = fileds.Item(0).FirstChild.CloneNode(true);
filedNode.Attributes["Name"].Value = "GPA";
filedNode.FirstChild.InnerText = "GPA";
fileds.Item(0).AppendChild(filedNode);
(2)操作xsd文件,将需要添加的列,加入到xsd中,并保存指定路径(保存文件命名为Student1.xsd);
View Source private void ModifyXSD()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "Students.xsd");
XmlNodeList nodeList = xmlDoc.GetElementsByTagName("xs:sequence");
XmlNode node = nodeList.Item(0).FirstChild.CloneNode(true);
node.Attributes["name"].Value = "GPA";
node.Attributes["msprop:Generator_ColumnVarNameInTable"].Value = "columnGPA";
node.Attributes["msprop:Generator_ColumnPropNameInRow"].Value = "GPA";
node.Attributes["msprop:Generator_ColumnPropNameInTable"].Value = "GPAColumn";
node.Attributes["msprop:Generator_UserColumnName"].Value = "GPA";
nodeList.Item(0).AppendChild(node);
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "Students1.xsd");
}
(2)修改rdlc文件,包括,待添加列、xsd文件路径等,中(或保存为rdlc文件);
View Code
1 /// <summary>
2 /// 修改RDLC文件
3 /// </summary>
4 /// <returns></returns>
5 private XmlDocument ModifyRdlc()
6 {
7 XmlDocument xmlDoc = new XmlDocument();
8
9 xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "FirstRdlc.rdlc");
10
11 //添加Field节点
12 XmlNodeList fileds = xmlDoc.GetElementsByTagName("Fields");
13
14 XmlNode filedNode = fileds.Item(0).FirstChild.CloneNode(true);
15 filedNode.Attributes["Name"].Value = "GPA";
16 filedNode.FirstChild.InnerText = "GPA";
17 fileds.Item(0).AppendChild(filedNode);
18
19 //添加TablixColumn
20
21 XmlNodeList tablixColumns = xmlDoc.GetElementsByTagName("TablixColumns");
22 XmlNode tablixColumn = tablixColumns.Item(0).FirstChild;
23 XmlNode newtablixColumn = tablixColumn.CloneNode(true);
24 tablixColumns.Item(0).AppendChild(newtablixColumn);
25
26 //TablixMember
27 XmlNodeList tablixMembers = xmlDoc.GetElementsByTagName("TablixColumnHierarchy");
28
29 XmlNode tablixMember = tablixMembers.Item(0).FirstChild.FirstChild;
30 XmlNode newTablixMember = tablixMember.CloneNode(true);
31 tablixMembers.Item(0).FirstChild.AppendChild(newTablixMember);
32
33 XmlNodeList tablixRows = xmlDoc.GetElementsByTagName("TablixRows");
34
35 //TablixRows1
36 var tablixRowsRowCells1 = tablixRows.Item(0).FirstChild.ChildNodes[1];
37 XmlNode tablixRowCell1 = tablixRowsRowCells1.FirstChild;
38 XmlNode newtablixRowCell1 = tablixRowCell1.CloneNode(true);
39 var textBox1 = newtablixRowCell1.FirstChild.ChildNodes[0];
40 textBox1.Attributes["Name"].Value = "GPA1";
41
42 var paragraphs = textBox1.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "Paragraphs").FirstOrDefault();
43 paragraphs.FirstChild.FirstChild.FirstChild.FirstChild.InnerText = "GPA";
44 var defaultName1 = textBox1.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "rd:DefaultName").FirstOrDefault().InnerText = "GPA1";
45
46 tablixRowsRowCells1.AppendChild(newtablixRowCell1);
47
48 //TablixRows2
49 var tablixRowsRowCells2 = tablixRows.Item(0).ChildNodes[1].ChildNodes[1];
50 XmlNode tablixRowCell2 = tablixRowsRowCells2.FirstChild;
51 XmlNode newtablixRowCell2 = tablixRowCell2.CloneNode(true);
52 var textBox2 = newtablixRowCell2.FirstChild.ChildNodes[0];
53 textBox2.Attributes["Name"].Value = "GPA";
54
55 var paragraphs2 = textBox2.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "Paragraphs").FirstOrDefault();
56 paragraphs2.FirstChild.FirstChild.FirstChild.FirstChild.InnerText = "=Fields!GPA.Value";
57 var defaultName2 = textBox2.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "rd:DefaultName").FirstOrDefault().InnerText = "GPA";
58
59 tablixRowsRowCells2.AppendChild(newtablixRowCell2);
60
61 xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "FirstRdlc1.rdlc");
62 return xmlDoc;
63 }
(3)将得到的XmlDocument实例,序列化到MemoryStream。
1 /// <summary>
2 /// 序列化到内存流
3 /// </summary>
4 /// <returns></returns>
5 private Stream GetRdlcStream(XmlDocument xmlDoc)
6 {
7 Stream ms = new MemoryStream();
8 XmlSerializer serializer = new XmlSerializer(typeof(XmlDocument));
9 serializer.Serialize(ms, xmlDoc);
10
11 ms.Position = 0;
12 return ms;
13 }
第三步:加载报表,并显示
(1)添加一个Page页面,并添加ReportView控件和ScriptManager控件,页面代码如下:
View Source<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<rsweb:ReportViewer ID="rvDemo" runat="server" Width="100%">
</rsweb:ReportViewer>
<asp:ScriptManager ID="smDemo" runat="server">
</asp:ScriptManager>
</div>
</form>
</body>
</html>
(2)加载报表定义,并绑定数据源(使用LoadReportDefinition(Stream stream)方法加载MemoryStream中信息)
View Code
1 /// <summary>
2 /// 加载报表
3 /// </summary>
4 private void LoadReport()
5 {
6 //获取数据源
7 DataTable dataSource = GetDataSource();
8
9 //修改xsd文件
10 ModifyXSD();
11
12 //修改rdlc文件
13 XmlDocument xmlDoc = ModifyRdlc();
14
15 //将修改后的rdlc文档序列化到内存流中
16 Stream stream = GetRdlcStream(xmlDoc);
17
18 //加载报表定义
19 rvDemo.LocalReport.LoadReportDefinition(stream);
20 //rvDemo.LocalReport.ReportPath = "FirstRdlc.rdlc";
21
22 //添加数据源,rvDemo是页面上的ReportView控件
23 rvDemo.LocalReport.DataSources.Add(new ReportDataSource("dsStudent", dt));
24 rvDemo.LocalReport.Refresh();
25 }
26
27 /// <summary>
28 /// 获取数据源
29 /// </summary>
30 /// <returns></returns>
31 private DataTable GetDataSource()
32 {
33 //伪造一个数据源
34 DataTable dt = new DataTable();
35 dt.Columns.AddRange(new DataColumn[]
36 {
37 new DataColumn() { ColumnName = "RecId" },
38 new DataColumn() { ColumnName = "Name" },
39 new DataColumn() { ColumnName = "Age" },
40 new DataColumn() { ColumnName = "Class" },
41 new DataColumn() { ColumnName = "Scores" },
42 new DataColumn() { ColumnName = "GPA" }
43 });
44
45 DataRow dr = dt.NewRow();
46 dr["RecId"] = "1";
47 dr["Name"] = "小明";
48 dr["Age"] = "26";
49 dr["Class"] = "1年级";
50 dr["Scores"] = "90";
51 dr["GPA"] = "4.0";
52
53 dt.Rows.Add(dr);
54 return dt;
55 }
如此,我们便可以动态的添加GPA这列到报表上了,结果如下:
源码地址:HelloRdlc.7z