用记事本打开rdlc报表文件,可以看出文件是xml文件。文件前两行为<?xml version="1.0"?>
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition">,最后面的xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition是文件的命名空间,我们的类ReportDefinition就是从这个命名空间转换过来的,如何转换网上有说明。可以简单的说,rdlc文件就是ReportDefinition类的实例xml序列化后的结果。下面我们通过对比两个文件来分析。
首先看一下rdlc文件的结构
<?xml version="1.0"?>
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition">
<DataSources>
<DataSource Name="DummyDataSource">
<ConnectionProperties>
<ConnectString />
<DataProvider>SQL</DataProvider>
</ConnectionProperties>
</DataSource>
</DataSources>
<Body>
<ReportItems>
<Matrix Name="Matrix1">
<ColumnGroupings>
<ColumnGrouping>
<Height>11pt</Height>
<DynamicColumns>
<Grouping Name="Matrix1_Group1">
<GroupExpressions>
<GroupExpression>=Fields!wastation.Value</GroupExpression>
</GroupExpressions>
</Grouping>
<Subtotal>
<ReportItems>
<Textbox Name="Textbox1">
<Value>总计</Value>
<CanGrow>true</CanGrow>
<Style>
<BackgroundColor>#DAE9F3</BackgroundColor>
<BorderColor>
<Default>#74A4D4</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<FontFamily>Tahoma</FontFamily>
<FontSize>8pt</FontSize>
<TextAlign>Center</TextAlign>
<VerticalAlign>Middle</VerticalAlign>
<BorderWidth>
<Default>0.5pt</Default>
</BorderWidth>
</Style>
</Textbox>
</ReportItems>
</Subtotal>
<ReportItems>
<Textbox Name="Textbox2">
<Value>=Fields!wastation.Value</Value>
<CanGrow>true</CanGrow>
<Style>
<BackgroundColor>#DAE9F3</BackgroundColor>
<BorderColor>
<Default>#74A4D4</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<FontFamily>Tahoma</FontFamily>
<FontSize>8pt</FontSize>
<TextAlign>Center</TextAlign>
<VerticalAlign>Middle</VerticalAlign>
<BorderWidth>
<Default>0.5pt</Default>
</BorderWidth>
</Style>
</Textbox>
</ReportItems>
</DynamicColumns>
</ColumnGrouping>
</ColumnGroupings>
<RowGroupings>
<RowGrouping>
<Width>0.75in</Width>
<DynamicRows>
<Grouping Name="Matrix1_Group2">
<GroupExpressions>
<GroupExpression>=Fields!regdate.Value</GroupExpression>
</GroupExpressions>
</Grouping>
<Subtotal>
<ReportItems>
<Textbox Name="Textbox3">
<Value>总计</Value>
<CanGrow>true</CanGrow>
<Style>
<BackgroundColor>#DAE9F3</BackgroundColor>
<BorderColor>
<Default>#74A4D4</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<FontFamily>Tahoma</FontFamily>
<FontSize>8pt</FontSize>
<TextAlign>Center</TextAlign>
<VerticalAlign>Middle</VerticalAlign>
<BorderWidth>
<Default>0.5pt</Default>
</BorderWidth>
</Style>
</Textbox>
</ReportItems>
</Subtotal>
<ReportItems>
<Textbox Name="Textbox4">
<Value>=Fields!regdate.Value</Value>
<CanGrow>true</CanGrow>
<Style>
<BackgroundColor>#DAE9F3</BackgroundColor>
<BorderColor>
<Default>#74A4D4</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<FontFamily>Tahoma</FontFamily>
<FontSize>8pt</FontSize>
<TextAlign>Center</TextAlign>
<VerticalAlign>Middle</VerticalAlign>
<BorderWidth>
<Default>0.5pt</Default>
</BorderWidth>
</Style>
</Textbox>
</ReportItems>
</DynamicRows>
</RowGrouping>
</RowGroupings>
<MatrixRows>
<MatrixRow>
<Height>11pt</Height>
<MatrixCells>
<MatrixCell>
<ReportItems>
<Textbox Name="Textbox5">
<Value>=Count(Fields!barcode.Value)</Value>
<CanGrow>true</CanGrow>
<Style>
<BorderColor>
<Default>#74A4D4</Default>
</BorderColor>
<BorderStyle>
<Default>Solid</Default>
</BorderStyle>
<FontFamily>Tahoma</FontFamily>
<FontSize>8pt</FontSize>
<VerticalAlign>Middle</VerticalAlign>
<Format>0</Format>
<BorderWidth>
<Default>0.5pt</Default>
</BorderWidth>
</Style>
</Textbox>
</ReportItems>
</MatrixCell>
</MatrixCells>
</MatrixRow>
</MatrixRows>
<MatrixColumns>
<MatrixColumn>
<Width>0.75in</Width>
</MatrixColumn>
</MatrixColumns>
<Corner>
<ReportItems>
<Textbox Name="Textbox6">
<Value>日期/窗口</Value>
<CanGrow>true</CanGrow>
</Textbox>
</ReportItems>
</Corner>
<Left>5pt</Left>
<Top>5pt</Top>
</Matrix>
</ReportItems>
<Height>1in</Height>
</Body>
<DataSets>
<DataSet Name="MyData">
<Query>
<DataSourceName>DummyDataSource</DataSourceName>
<CommandText />
</Query>
<Fields>
<Field Name="barcode">
<DataField>barcode</DataField>
</Field>
<Field Name="regdate">
<DataField>regdate</DataField>
</Field>
<Field Name="category">
<DataField>category</DataField>
</Field>
<Field Name="wastation">
<DataField>wastation</DataField>
</Field>
<Field Name="printer">
<DataField>printer</DataField>
</Field>
<Field Name="catename">
<DataField>catename</DataField>
</Field>
<Field Name="logname">
<DataField>logname</DataField>
</Field>
</Fields>
</DataSet>
</DataSets>
<Width>10in</Width>
</Report
上面是一个包含了一个matrix(矩阵)的报表文件。每一报表文件包含的基本元素有DataSources、DataSets、Body。DataSources、和DataSets是数据源的定义,包括怎样连接数据库、有哪些字段,不过在动态创建报表中我们只需要知道有哪些字段就可以了。最主要的是如何创建body。body下包含多个 ReportItems,每个 ReportItems包含一个报表方式如table、matrix、chart。
下面再看一下ReportDefinition文件,
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition", IsNullable=false)]
public partial class Report {
private object[] itemsField;
private ItemsChoiceType37[] itemsElementNameField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute()]
[System.Xml.Serialization.XmlElementAttribute("Author", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("AutoRefresh", typeof(uint))]
[System.Xml.Serialization.XmlElementAttribute("Body", typeof(BodyType))]
[System.Xml.Serialization.XmlElementAttribute("BottomMargin", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("Classes", typeof(ClassesType))]
[System.Xml.Serialization.XmlElementAttribute("Code", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("CodeModules", typeof(CodeModulesType))]
[System.Xml.Serialization.XmlElementAttribute("CustomProperties", typeof(CustomPropertiesType))]
[System.Xml.Serialization.XmlElementAttribute("DataElementName", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("DataElementStyle", typeof(ReportDataElementStyle))]
[System.Xml.Serialization.XmlElementAttribute("DataSchema", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("DataSets", typeof(DataSetsType))]
[System.Xml.Serialization.XmlElementAttribute("DataSources", typeof(DataSourcesType))]
[System.Xml.Serialization.XmlElementAttribute("DataTransform", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Description", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("EmbeddedImages", typeof(EmbeddedImagesType))]
[System.Xml.Serialization.XmlElementAttribute("InteractiveHeight", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("InteractiveWidth", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("Language", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("LeftMargin", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("PageFooter", typeof(PageHeaderFooterType))]
[System.Xml.Serialization.XmlElementAttribute("PageHeader", typeof(PageHeaderFooterType))]
[System.Xml.Serialization.XmlElementAttribute("PageHeight", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("PageWidth", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("ReportParameters", typeof(ReportParametersType))]
[System.Xml.Serialization.XmlElementAttribute("RightMargin", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("TopMargin", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("Width", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType37[] ItemsElementName {
get {
return this.itemsElementNameField;
}
set {
this.itemsElementNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr {
get {
return this.anyAttrField;
}
set {
this.anyAttrField = value;
}
}
}
上面是report类的定义,可以看到此类是可以序列化的。report包含很多XmlElementAttribute,每个XmlElementAttribute都有自己的类型,有些是基本类型,有些是reportdefinition文件中定义的类型。System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]告诉我们何以选择性的实现这些XmlElementAttribute的一部分。刚才我已经将了redlc报表文件基本的元素包括DataSources、DataSets、Body,那么我们只要实现DataSources、DataSets、Body这三个元素基本上就可以创建一个报表文件了,如下
private Rdl.Report CreateReport(int reportType)
{
Rdl.Report report = new Rdl.Report();
report.Items = new object[]
{
CreateDataSources(),
CreateBody(reportType ),
CreateDataSets(),
m_widthInches + "in",
};
report.ItemsElementName = new Rdl.ItemsChoiceType37[]
{
Rdl.ItemsChoiceType37.DataSources,
Rdl.ItemsChoiceType37.Body,
Rdl.ItemsChoiceType37.DataSets,
Rdl.ItemsChoiceType37.Width,
};
return report;
}
CreateDataSources(), CreateBody(reportType ), CreateDataSets(),在我上传的资源中有。我先介绍一下CreateBody(reportType ),reporttype是报表类型(table、matrix、chart
在前面我讲了每个body里包含很多ReportItems,看一下reportdefinition文件中BodyType 的定义
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")]
public partial class BodyType {
private object[] itemsField;
private ItemsChoiceType30[] itemsElementNameField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute()]
[System.Xml.Serialization.XmlElementAttribute("ColumnSpacing", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("Columns", typeof(uint))]
[System.Xml.Serialization.XmlElementAttribute("Height", typeof(string), DataType="normalizedString")]
[System.Xml.Serialization.XmlElementAttribute("ReportItems", typeof(ReportItemsType))]
[System.Xml.Serialization.XmlElementAttribute("Style", typeof(StyleType))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType30[] ItemsElementName {
get {
return this.itemsElementNameField;
}
set {
this.itemsElementNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr {
get {
return this.anyAttrField;
}
set {
this.anyAttrField = value;
}
}
}
在众多XmlElementAttribute我们可以选择性的实现reportitmes,如下代码
private Rdl.BodyType CreateBody(int reportType)
{
Rdl.BodyType body = new Rdl.BodyType();
body.Items = new object[]
{
CreateReportItems(reportType ),
"1in",
};
body.ItemsElementName = new Rdl.ItemsChoiceType30[]
{
Rdl.ItemsChoiceType30.ReportItems,
Rdl.ItemsChoiceType30.Height,
};
return body;
}
这样我们就将body创建好了,而如何实现CreateReportItems()呢,我们在首先看ReportItems的定义
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")]
public partial class ReportItemsType {
private object[] itemsField;
private System.Xml.XmlAttribute[] anyAttrField;
/// <remarks/>
[System.Xml.Serialization.XmlAnyElementAttribute()]
[System.Xml.Serialization.XmlElementAttribute("Chart", typeof(ChartType))]
[System.Xml.Serialization.XmlElementAttribute("CustomReportItem", typeof(CustomReportItemType))]
[System.Xml.Serialization.XmlElementAttribute("Image", typeof(ImageType))]
[System.Xml.Serialization.XmlElementAttribute("Line", typeof(LineType))]
[System.Xml.Serialization.XmlElementAttribute("List", typeof(ListType))]
[System.Xml.Serialization.XmlElementAttribute("Matrix", typeof(MatrixType))]
[System.Xml.Serialization.XmlElementAttribute("Rectangle", typeof(RectangleType))]
[System.Xml.Serialization.XmlElementAttribute("Subreport", typeof(SubreportType))]
[System.Xml.Serialization.XmlElementAttribute("Table", typeof(TableType))]
[System.Xml.Serialization.XmlElementAttribute("Textbox", typeof(TextboxType))]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAnyAttributeAttribute()]
public System.Xml.XmlAttribute[] AnyAttr {
get {
return this.anyAttrField;
}
set {
this.anyAttrField = value;
}
}
}
reportitems包含了报表的元素如table、matrix、chart、textbox,我们可以实现一个也可以实现多个元素,我们目前只根据实现其中的一种,如table,我们通过CreateTable()来实现,如何实现呢,大家通过上面的介绍应该可以看出一些门道,我们只要按照reportdefinition的定义来实现就可以了。
private Rdl.ReportItemsType CreateReportItems(int reportType)
{
Rdl.ReportItemsType reportItems = new Rdl.ReportItemsType();
switch (reportType)
{
case 1:
MatrixRdlGenerator matrixGen = new MatrixRdlGenerator();
matrixGen.ColumnFields = m_columnFields;
matrixGen.RowFields = m_rowFields;
matrixGen.SummarizedFields = m_summarizedFields;
matrixGen.CornerText = m_cornerText;
matrixGen.CellExpression = m_cellExpression;
matrixGen.CellFormat = m_cellFormat;
matrixGen.ColSubtotal = m_colSubtotal;
matrixGen.RowSubtotal = m_rowSubtotal;
matrixGen.SummarizedTitles = m_summarizedTitles;
matrixGen.Widht = m_ReportWidth;
matrixGen.Height = m_ReportHeight;
reportItems.Items = new object[] { matrixGen.CreateMatrix() };
break;
case 0:
DynamicTable.TableRdlGenerator tablegen = new DynamicTable.TableRdlGenerator();
tablegen.Fields = m_columnFields ;
tablegen.HeaderFields = m_summarizedTitles;
tablegen.FooterFields = m_summarizedFields;
tablegen.Widht = m_ReportWidth;
tablegen.Height = m_ReportHeight;
reportItems.Items = new object[] { tablegen.CreateTable() };
break;
case 2:
DynamicChart.ChartRdlGenerator chartgen = new DynamicChart.ChartRdlGenerator();
chartgen.CategoryAxisTitle = "category";
chartgen.SeriesFields = m_columnFields;
chartgen.ValueAxisTitle ="value";
chartgen.ChartType = Rdl.ChartTypeType.Column;
chartgen.ChartSubType = Rdl.ChartTypeSubtype.Plain;
chartgen.CategoryFields = m_rowFields;
chartgen.DataFields = m_summarizedFields;
chartgen.ChartTitle = m_ReportTitle;
chartgen.CategoryAxisTitle = m_ChartXTitle;
chartgen.ValueAxisTitle = m_ChartYTitle;
chartgen.Width = m_ReportWidth;
chartgen.Height = m_ReportHeight;
chartgen.ChartType =(Rdl.ChartTypeType ) Enum.Parse (typeof (Rdl.ChartTypeType ), m_ChartType,true );
chartgen.ChartSubType = (Rdl.ChartTypeSubtype)Enum.Parse(typeof(Rdl.ChartTypeSubtype), m_ChartSubType, true);
reportItems.Items = new object[] { chartgen.CreateChart() };
break;
default :
break;
}
return reportItems;
}
rdlc的各元素创建完之后就可以生成文件了,代码如下
public void WriteXml(Stream stream, int reportType)
{
XmlSerializer serializer = new XmlSerializer(typeof(Rdl.Report));
serializer.Serialize(stream, CreateReport(reportType));
//将stream输入到文件,如stream.WriteTo(fs);
}
以上介绍了如何创建报表及使用reportdefinition文件。在我的资源中有我做好的各个文件。