前言
最近接到一个需求:在给定的数据源中,某(些)列,可能需要单独统计,是否单独统计需要根据报表配置来决定。由于项目中一直使用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"?>
 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"?>
 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">
 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>
 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>
 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>
 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节点
 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()
 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
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">
 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
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