[转]RDLC报表——动态添加列
本文转自:http://www.cnblogs.com/pszw/archive/2012/07/19/2599937.html
前言
最近接到一个需求:在给定的数据源中,某(些)列,可能需要单独统计,是否单独统计需要根据报表配置来决定。由于项目中一直使用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文件);
/// <summary>
/// 修改RDLC文件
/// </summary>
/// <returns></returns>
private XmlDocument ModifyRdlc()
{
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "FirstRdlc.rdlc"); //添加Field节点
XmlNodeList fileds = xmlDoc.GetElementsByTagName("Fields"); XmlNode filedNode = fileds.Item().FirstChild.CloneNode(true);
filedNode.Attributes["Name"].Value = "GPA";
filedNode.FirstChild.InnerText = "GPA";
fileds.Item().AppendChild(filedNode); //添加TablixColumn XmlNodeList tablixColumns = xmlDoc.GetElementsByTagName("TablixColumns");
XmlNode tablixColumn = tablixColumns.Item().FirstChild;
XmlNode newtablixColumn = tablixColumn.CloneNode(true);
tablixColumns.Item().AppendChild(newtablixColumn); //TablixMember
XmlNodeList tablixMembers = xmlDoc.GetElementsByTagName("TablixColumnHierarchy"); XmlNode tablixMember = tablixMembers.Item().FirstChild.FirstChild;
XmlNode newTablixMember = tablixMember.CloneNode(true);
tablixMembers.Item().FirstChild.AppendChild(newTablixMember); XmlNodeList tablixRows = xmlDoc.GetElementsByTagName("TablixRows"); //TablixRows1
var tablixRowsRowCells1 = tablixRows.Item().FirstChild.ChildNodes[];
XmlNode tablixRowCell1 = tablixRowsRowCells1.FirstChild;
XmlNode newtablixRowCell1 = tablixRowCell1.CloneNode(true);
var textBox1 = newtablixRowCell1.FirstChild.ChildNodes[];
textBox1.Attributes["Name"].Value = "GPA1"; var paragraphs = textBox1.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "Paragraphs").FirstOrDefault();
paragraphs.FirstChild.FirstChild.FirstChild.FirstChild.InnerText = "GPA";
var defaultName1 = textBox1.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "rd:DefaultName").FirstOrDefault().InnerText = "GPA1"; tablixRowsRowCells1.AppendChild(newtablixRowCell1); //TablixRows2
var tablixRowsRowCells2 = tablixRows.Item().ChildNodes[].ChildNodes[];
XmlNode tablixRowCell2 = tablixRowsRowCells2.FirstChild;
XmlNode newtablixRowCell2 = tablixRowCell2.CloneNode(true);
var textBox2 = newtablixRowCell2.FirstChild.ChildNodes[];
textBox2.Attributes["Name"].Value = "GPA"; var paragraphs2 = textBox2.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "Paragraphs").FirstOrDefault();
paragraphs2.FirstChild.FirstChild.FirstChild.FirstChild.InnerText = "=Fields!GPA.Value";
var defaultName2 = textBox2.ChildNodes.Cast<XmlNode>().Where(item => item.Name == "rd:DefaultName").FirstOrDefault().InnerText = "GPA"; tablixRowsRowCells2.AppendChild(newtablixRowCell2); xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "FirstRdlc1.rdlc");
return xmlDoc;
}
(3)将得到的XmlDocument实例,序列化到MemoryStream。
/// <summary>
/// 序列化到内存流
/// </summary>
/// <returns></returns>
private Stream GetRdlcStream(XmlDocument xmlDoc)
{
Stream ms = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(XmlDocument));
serializer.Serialize(ms, xmlDoc); ms.Position = ;
return ms;
}
第三步:加载报表,并显示
(1)添加一个Page页面,并添加ReportView控件和ScriptManager控件,页面代码如下:
(2)加载报表定义,并绑定数据源(使用LoadReportDefinition(Stream stream)方法加载MemoryStream中信息)
/// <summary>
/// 加载报表
/// </summary>
private void LoadReport()
{
//获取数据源
DataTable dataSource = GetDataSource(); //修改xsd文件
ModifyXSD(); //修改rdlc文件
XmlDocument xmlDoc = ModifyRdlc(); //将修改后的rdlc文档序列化到内存流中
Stream stream = GetRdlcStream(xmlDoc); //加载报表定义
rvDemo.LocalReport.LoadReportDefinition(stream);
//rvDemo.LocalReport.ReportPath = "FirstRdlc.rdlc"; //添加数据源,rvDemo是页面上的ReportView控件
rvDemo.LocalReport.DataSources.Add(new ReportDataSource("dsStudent", dt));
rvDemo.LocalReport.Refresh();
} /// <summary>
/// 获取数据源
/// </summary>
/// <returns></returns>
private DataTable GetDataSource()
{
//伪造一个数据源
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[]
{
new DataColumn() { ColumnName = "RecId" },
new DataColumn() { ColumnName = "Name" },
new DataColumn() { ColumnName = "Age" },
new DataColumn() { ColumnName = "Class" },
new DataColumn() { ColumnName = "Scores" },
new DataColumn() { ColumnName = "GPA" }
}); DataRow dr = dt.NewRow();
dr["RecId"] = "";
dr["Name"] = "小明";
dr["Age"] = "";
dr["Class"] = "1年级";
dr["Scores"] = "";
dr["GPA"] = "4.0"; dt.Rows.Add(dr);
return dt;
}
如此,我们便可以动态的添加GPA这列到报表上了,结果如下:
源码地址:HelloRdlc.7z
[转]RDLC报表——动态添加列的更多相关文章
- asp.net gridview动态添加列,并获取其数据;
1,绑定数据前先动态添加列,见方法CreateGridColumn(只在第一次加载动态添加): 2,gvlist_RowDataBound为对应列添加控件: 前台代码: <%@ Page Lan ...
- GridView动态添加列之后,导致PostBack(回发)页面数据丢失问题解决
直入主题,首先声明,这个问题是无法解决的,特此在这说明 一.如何动态添加列,如下: 在页面重写OnInit事件,至于为什么要在这个事件写,根据页面的声明周期和经验可知(不用去别的地方找了,这个我找了之 ...
- DataGridview动态添加列
1.获取数据源(select * from table名称) 2.动态绑定数据源 private void GetTableInfo(DataTable dt) { listBh = new List ...
- Wpf DataGrid动态添加列,行数据(二)
这是第二中方法,可直接绑定,我这里只是做出了一种思路,并不是最完美. 这里注意一下,因为我里面引用了MVVMLight,所以可能代码不是复制过去就能用了的. 样式也是,所以复制过去看不是我贴出来的界面 ...
- [RDLC]报表根据字段列动态加载图片(二)
参照:http://www.cnblogs.com/hcbin/archive/2010/03/26/1696803.html 改动地方value的值可以用报表的字段进行编辑. 效果:
- gridview动态添加列的问题
相信大家也和我一样遇到过这种问题,gridview在生成列的时候当列不确定怎么办?下面分享一下自己的解决方法. 举个列子说明一下. 普通列的添加比较简单. BoundField bf = new Bo ...
- GridView动态添加列并判断绑定数据DataTable的列类型控制展示内容
此篇随笔是2013年根据项目需求开发记录的,不一定符合大众口味,只需了解开发思路,毕竟解决方案多种多样. 下面简单说说需求点吧: (1)通过下拉列表可以选择一个DataSet(数据集),一个DataS ...
- extjs动态添加列
可以根据日期,动态的插入一列 controller层: StdDayWordQuery:function(btn,event){ var form=Ext.getCmp('queryFormSDW') ...
- C# DataGridView 动态添加列和行
https://blog.csdn.net/alisa525/article/details/7350471 dataGridView1.ReadOnly = true ; //禁用编辑功能 ...
随机推荐
- 文本框、评论框原生js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- 基于Arduino的音乐动感节奏灯
1.音乐动感节奏灯是个什么东西? 前段时间听音乐觉得无聊,便想着音乐光听也没意思啊,能不能 “看见” 音乐呢?于是谷歌了一番,发现还真有人做了将音乐可视化的东西,那就是音乐节奏灯.说的简单点就是LED ...
- 解决Scrapy抓取中文网页保存为json文件时中文不显示而是显示unicode的问题
注意:此方法跟之前保存成json文件的写法有少许不同之处,注意区分 情境再现: 使用scrapy抓取中文网页,得到的数据类型是unicode,在控制台输出的话也是显示unicode,如下所示 {'au ...
- collections、random、hashlib、configparser、logging模块
collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict. ...
- namespace的作用及用法
namespace 所谓namespace,是指标识符的可见范围.C++标准库中的所有标识符都被定义在一个名为 std 的namespace 中. 一.<iostream>和<ios ...
- 第2章 Python序列
Python序列类似于C或Basic中的一维.多维数组等,但功能要强大很多,使用也更加灵活.方便,Head First Python一书就戏称列表是“打了激素”的数组. Python中常用的序列结构有 ...
- Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)
题目链接: https://codeforces.com/contest/432/problem/D 题解: 做法一: KMP 显然next树上\(n\)的所有祖先都是答案,出现次数为next树子树大 ...
- 【Codeforces 467C】George and Job
[链接] 我是链接,点我呀:) [题意] 让你从1..n这n个数字中 选出来k个不相交的长度为m的区间 然后这个k个区间的和最大 求出这k个区间的和的最大值 [题解] 设dp[i][j]表示前i个数字 ...
- C++ primer chapter 13
拷贝 赋值 销毁 拷贝构造函数 如果一个构造函数第一个参数是自身的引用,而且任何额外参数都有默认值,则此构造函数是拷贝构造函数拷贝构造函数的第一个类型必须是引用:如果参数不是引用类型,那么调用不会成功 ...
- 关于Spring的xml文档的简单实用配置
Spring的spring.xml文档的配置 最近在写Spring的配置文件时,发现Spring文档的配置其实没必要那么繁琐记忆,网上的很多文章都写得很繁琐,如果所有的东西按照路径去查找,可以很快的帮 ...