RDLC报表之动态生成报表,rdlc报表生成

/// <summary>
/// 获取要素类型表的记录
/// </summary>
/// <param name=”relationCheckClass”></param>
/// <returns></returns>
private List<string>
GetAllRecordFormFeatureTable(RelationCheckClass relationCheckClass)
{
List<string> recordList = new List<string>();
IFeatureClass pfeatureClass =
((IFeatureWorkspace)m_Workspace).OpenFeatureClass(relationCheckClass.TableName);
IFeatureCursor pfeatureCursor = null;
IFeature pfeature = null;
if (pfeatureClass!=null)
{
string fieldName = relationCheckClass.TabelField;
int fieldIndex = pfeatureClass.FindField(Name: fieldName);
int fieldObjectID = pfeatureClass.FindField(Name: “Objectid”);
pfeatureCursor = pfeatureClass.Search(null, true);
pfeature = pfeatureCursor.NextFeature();
if (pfeature==null)
{
return null;
}
string fieldValue = “”;
while (pfeature!=null)
{
fieldValue = pfeature.get_Value(fieldIndex).ToString();
recordList.Add(fieldValue);
pfeature = pfeatureCursor.NextFeature();
}
}
return recordList;
}

RDLC报表之动态生成报表,rdlc报表生成

前段时间,做了RDLC报表,主要是三块功能:

1、从DataGrid提取(包括最新的增删改)的数据,自动生成对应的RDLC报表文件(以流的形式驻存在内存中),用ReportViewer类来展示、打印、排版、预览、分页

1-1、提供一个提取任意控件数据的通用接口,然后拼接成DataTable这种网状的格子。DataGrid里修改、增加、删除等数据变动,立即同步更新到报表

2、给一个简单的RDLC模板,提供表头的字体格式和表内部数据等样式相关的信息,然后再用DataGrid里提取的数据,生成DataTable后其它必需信息,填充到报表里,

自动调整报表格式

3、做了一个TreeView,很简单;根据报表文件名称,切换左侧TreeView的Item,就加载不同的报表,显示数据。用了一点反射的知识

 

 

第一步:根据 Report Definition Language (RDL) 生成对应的类和命名空间。

1、去

下载ReportDefinition2010.xsd。

注意:ReportDefinition和Visual
Studio发布的有个时间差,官网上有ReportDefinition2005版和ReportDefinition2008版。ReportDefinition2005版,VS2008及以后才支持;

ReportDefinition2008版,VS2010及以后支持。2010版,要VS2012以后才支持。我的是VS2010,用ReportDefinition2008版就好。

 

2、找XML Schema Definition Tool
(Xsd.exe),Windows操作系统会自带(微软会自带很多功能强大的exe,要是开源就好了)。For
more detail,please refer to:

官网有详细的命令使用说明

 Below is my CMD in administator mode:

C:Program Files (x86)Microsoft SDKsWindowsv7.0ABinx64>xsd

/c /n:RDLC  

RDLC报表之动态生成报表,rdlc报表生成。/out:C:UsersadminDesktopRDLCReportResearch

C:UsersadminDesktopRDLCReportResearchReportDefinition.xsd

 完了,生成的是这么个样子(ReportDefinition2005的生成出来有8000行左右,ReportDefinition2008的及以后有10000多行,贴一部分,样子参照下面代码)

www.9778.com 1using
System.Xml.Serialization; /// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute(“xsd”,
“2.0.50727.3038”)] [System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute(“code”)]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true,
Namespace=”]
[System.Xml.Serialization.XmlRootAttribute(Namespace=””,
IsNullable=false)] public partial class Report { private object[]
itemsField; private ItemsChoiceType80[] 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(“Classes”,
typeof(ClassesType))]
[System.Xml.Serialization.XmlElementAttribute(“Code”, typeof(string))]
[System.Xml.Serialization.XmlElementAttribute(“CodeModules”,
typeof(CodeModulesType))]
[System.Xml.Serialization.XmlElementAttribute(“ConsumeContainerWhitespace”,
typeof(bool))] ReportDefinition.cs

 

第二步:创建RDLCGenerator类和TablixRDLCGenerator类

1、根据下载的Report Definition
Language(RDL)和一个创建的简单的RDLC文件,知道RDLC文件基本要有哪几部分组成;然后层层嵌套创建就出来了,很简单。

2-1、Tablix是关键数据区,GotReportViewer上面的例子,DynamicMatrix和DynamicTable是根据RDL2005来做的,RDL2008以后,就是一个Tablix:

2-2、Tablix的主要数据区域: TablixHierarchyType
CreateTablixColumnHierarchy()和TablixHierarchyType
CreateTablixRowHierarchy()

2-3、对于HeaderRow和DataRow关键就在下面的不同。

www.9778.com 21 private
LocIDStringWithDataTypeAttribute CreateTablixTextRunValue(bool
isHeaderCell, string name) 2 { 3 LocIDStringWithDataTypeAttribute v =
new LocIDStringWithDataTypeAttribute(); 4 v.Value = isHeaderCell ? name
: “=Fields!” + name + “.Value”; 5 v.DataType =
StringWithDataTypeAttributeDataType.String; 6 return v; 7 } CreateTablixTextRunValue

 2-4、DataSet的名字一定要和ReportDataSource里的名字完全匹配

 

RdlcGenerator的Read和Write方法比较重要。

www.9778.com 3 /// table

  • matrix = tablix /// Microsoft 用一个tablix来支持Table(表),
    Matrix(矩阵) and List(列表)这三种报表项 ///
    整合了table和matrix的功能 View
    Code
    www.9778.com 4 #region
    Properties // DataGrid 的DataGridColumn的Header private
    List<string> headerNames = new List<string>(); public
    List<string> HeaderNames { get { return headerNames; } } //
    对应DataGrid Binding的Path private List<string> fieldNames = new
    List<string>(); public List<string> FieldNames { get {
    return fieldNames; } } // 对应DataGrid
    Column的ActualWdith(因为实际的窗口宽度会重新计算) private
    List<double> widths = new List<double>(); public
    List<double> Widths { get { return widths; } } //
    如果没有更新过页面设置,用ReportViewer的默认页面设置;否则用最新的页面设置
    public PageSettings PageSettings { get; set; } public string Headline {
    get; set; } public string DataSourceName { get; set; } public string
    DataSetName { get; set; } #endregion #region Methods //
    一层套一层,把xml构造出来 private Report CreateReport() { Report report
    = new Report(); report.Items = new object[] { CreateDataSources(),
    CreateDataSets(), CreateBody(), CalcReportWidth(), CreatePage(), };
    report.ItemsElementName = new ItemsChoiceType80[] {
    ItemsChoiceType80.DataSources, ItemsChoiceType80.DataSets,
    ItemsChoiceType80.Body, ItemsChoiceType80.Width, ItemsChoiceType80.Page,
    }; return report; } private DataSourcesType CreateDataSources() {
    DataSourcesType dataSources = new DataSourcesType();
    dataSources.DataSource = new DataSourceType[] { CreateDataSource() };
    return dataSources; } private DataSourceType CreateDataSource() {
    DataSourceType dataSource = new DataSourceType(); dataSource.Name =
    String.IsNullOrEmpty(DataSetName) ? “TBReport” : DataSetName;
    dataSource.Items = new object[] {
    CreateDataSourceConnectionProperties() }; return dataSource; } private
    ConnectionPropertiesType CreateDataSourceConnectionProperties() {
    ConnectionPropertiesType connectionProperties = new
    ConnectionPropertiesType(); connectionProperties.Items = new object[]
    { “System.Data.DataSet”, “/* Local Connection */”, };
    connectionProperties.ItemsElementName = new ItemsChoiceType[] {
    ItemsChoiceType.DataProvider, ItemsChoiceType.ConnectString, }; return
    connectionProperties; } private DataSetsType CreateDataSets() {
    DataSetsType dataSets = new DataSetsType(); dataSets.DataSet = new
    DataSetType[] { CreateDataSet() }; return dataSets; } //
    Query暂时就不要了 private DataSetType CreateDataSet() { DataSetType
    dataSet = new DataSetType(); // DataSetName写死就好 dataSet.Name =
    “CustomerDataSet”; dataSet.Items = new object[] {
    CreateDataSetFields(), CreateDataSetQuery(), }; return dataSet; }
    private FieldsType CreateDataSetFields() { FieldsType fields = new
    FieldsType(); // DataSet的具体field由DataGrid的Bingding的Path值决定 if
    ((fieldNames != null) && (fieldNames.Count > 0)) { fields.Field = new
    FieldType[fieldNames.Count]; for (int index = 0; index <
    fieldNames.Count; index++) fields.Field[index] =
    CreateDataSetField(fieldNames[index]); } return fields; } private
    FieldType CreateDataSetField(string fieldName) { FieldType field = new
    FieldType(); field.Name = fieldName; field.Items = new object[] {
    fieldName, // CreateDataSetFieldValue(), }; return field; } //
    暂时DataType全部用String private StringWithDataTypeAttribute
    CreateDataSetFieldValue() { StringWithDataTypeAttribute value = new
    StringWithDataTypeAttribute(); value.DataType =
    StringWithDataTypeAttributeDataType.String; return value; } private
    QueryType CreateDataSetQuery() { QueryType query = new QueryType();
    query.Items = new object[] { “TBReport”, “/* Local Query */”, };
    query.ItemsElementName = new ItemsChoiceType1[] {
    ItemsChoiceType1.DataSourceName, ItemsChoiceType1.CommandText, }; return
    query; } private BodyType CreateBody() { BodyType body = new BodyType();
    body.Items = new object[] { “4.8in”, // Height CreateReportItems(), //
    ReportItems CreateBodyStyle(), }; return body; } private ReportItemsType
    CreateReportItems() { ReportItemsType reportItems = new
    ReportItemsType(); // 这是关键数据区域 TablixRdlcGenerator tablixGen =
    new TablixRdlcGenerator(); tablixGen.ResetHeaderNames(HeaderNames);
    tablixGen.ResetFieldNames(FieldNames); List<string>
    tablixColumnWidths;
    DataGridHelper.CalcTablixColumnWidth(CalcReportWidth(), Widths, out
    tablixColumnWidths); tablixGen.ResetWidths(tablixColumnWidths);
    reportItems.Items = new object[] { CreateReportHeadlineTextbox(),
    tablixGen.CreateTablix() }; return reportItems; } // 创建标题 private
    TextboxType CreateReportHeadlineTextbox() { TextboxType headlineTextbox
    = new TextboxType(); headlineTextbox.Name = “headlineTextbox”; string
    left = (PageSettings == null) ? “2cm” :
    ((double)PageSettings.Margins.Left / 100.0).ToString() + “in”; string
    width = (PageSettings == null) ? “17cm” :
    ((double)(PageSettings.PaperSize.Width – PageSettings.Margins.Left –
    PageSettings.Margins.Right) / 100.0).ToString() + “in”;
    headlineTextbox.Items = new object[] { true, true,
    CreateHeadlineTextboxParagraphs(), left, “0.5cm”, “1.0cm”, width,
    CreateHeadlineTextboxStyle() }; headlineTextbox.ItemsElementName = new
    ItemsChoiceType14[] { ItemsChoiceType14.CanGrow,
    ItemsChoiceType14.KeepTogether, ItemsChoiceType14.Paragraphs,
    ItemsChoiceType14.Left, ItemsChoiceType14.Top, ItemsChoiceType14.Height,
    ItemsChoiceType14.Width, ItemsChoiceType14.Style }; return
    headlineTextbox; } private ParagraphsType
    CreateHeadlineTextboxParagraphs() { ParagraphsType headlineParagraphs =
    new ParagraphsType(); headlineParagraphs.Paragraph = new
    ParagraphType[] {CreateHeadlineTextboxParagraph()}; return
    headlineParagraphs; } private ParagraphType
    CreateHeadlineTextboxParagraph() { ParagraphType pt = new
    ParagraphType(); pt.Items = new object[] { CreateHeadlineTextRuns(),
    CreateHeadlineParagraphStyle() }; pt.ItemsElementName = new
    ItemsChoiceType12[] { ItemsChoiceType12.TextRuns,
    ItemsChoiceType12.Style, }; return pt; } private TextRunsType
    CreateHeadlineTextRuns() { TextRunsType trt = new TextRunsType();
    trt.TextRun = new TextRunType[] { CreateHeadlineTextRun() }; return
    trt; } private TextRunType CreateHeadlineTextRun() { TextRunType trt =
    new TextRunType(); trt.Items = new object[] {
    CreateHeadLineTextRunValue(), CreateHeadlineTextRunStyle() };
    trt.ItemsElementName = new ItemsChoiceType11[] {
    ItemsChoiceType11.Value, ItemsChoiceType11.Style }; return trt; }
    private LocIDStringWithDataTypeAttribute CreateHeadLineTextRunValue() {
    LocIDStringWithDataTypeAttribute value = new
    LocIDStringWithDataTypeAttribute(); value.Value = (Headline == null) ?
    “标题” : Headline; value.DataType =
    StringWithDataTypeAttributeDataType.String; return value; } private
    StyleType CreateHeadlineTextRunStyle() { StyleType st = new StyleType();
    st.Items = new object[] { “宋体”, “14pt”, “Bold”, };
    st.ItemsElementName = new ItemsChoiceType4[] {
    ItemsChoiceType4.FontFamily, ItemsChoiceType4.FontSize,
    ItemsChoiceType4.FontWeight }; return st; } private StyleType
    CreateHeadlineParagraphStyle() { StyleType st = new StyleType();
    st.Items = new object[] { “Center” }; st.ItemsElementName = new
    ItemsChoiceType4[] { ItemsChoiceType4.TextAlign }; return st; }
    private StyleType CreateHeadlineTextboxStyle() { StyleType headlineStyle
    = new StyleType(); headlineStyle.Items = new object[] {
    CreateHeadlineTextboxBorder(), “2pt”, “2pt”, “2pt”, “2pt” };
    headlineStyle.ItemsElementName = new ItemsChoiceType4[] {
    ItemsChoiceType4.Border, ItemsChoiceType4.PaddingLeft,
    ItemsChoiceType4.PaddingRight, ItemsChoiceType4.PaddingTop,
    ItemsChoiceType4.PaddingBottom }; return headlineStyle; } private
    BorderType CreateHeadlineTextboxBorder() { BorderType
    headlineTextboxBorder = new BorderType(); headlineTextboxBorder.Items =
    new object[] { “None” }; headlineTextboxBorder.ItemsElementName = new
    ItemsChoiceType2[] { ItemsChoiceType2.Style }; return
    headlineTextboxBorder; } private StyleType CreateBodyStyle() { return
    new StyleType(); } /// <summary> ///
    设置页面基本属性—页眉、页脚、页宽、页高、左边距、右边距等 ///
    </summary> private PageType CreatePage() { PageType page = new
    PageType(); // 根据微软官方文档,PaperSize.Height, PaperSize.Width and
    Margins的Left, Right, Top, Bottom are in hundredths of an inch. string
    pageHeight = (PageSettings == null) ? “29.7cm” :
    ((double)PageSettings.PaperSize.Height / 100.0).ToString() + “in”;
    string pageWidth = (PageSettings == null) ? “21cm” :
    ((double)PageSettings.PaperSize.Width / 100.0).ToString() + “in”; string
    leftMargin = (PageSettings == null) ? “2cm” :
    ((double)PageSettings.Margins.Left / 100.0).ToString() + “in”; string
    rightMargin = (PageSettings == null) ? “2cm” :
    ((double)PageSettings.Margins.Right / 100.0).ToString() + “in”; string
    topMargin = (PageSettings == null) ? “2cm” :
    ((double)PageSettings.Margins.Top / 100.0).ToString() + “in”; string
    bottomMargin = (PageSettings == null) ? “2cm” :
    ((double)PageSettings.Margins.Bottom / 100.0).ToString() + “in”; //
    TODO: // 页眉、页脚(后面再做) page.Items = new object[] {
    //创建Header不能为空 // CreatePageHeader(), pageHeight, pageWidth,
    leftMargin, rightMargin, topMargin, bottomMargin, “0.13cm”, };
    page.ItemsElementName = new ItemsChoiceType77[] { //
    ItemsChoiceType77.PageHeader, ItemsChoiceType77.PageHeight,
    ItemsChoiceType77.PageWidth, ItemsChoiceType77.LeftMargin,
    ItemsChoiceType77.RightMargin, ItemsChoiceType77.TopMargin,
    ItemsChoiceType77.BottomMargin, ItemsChoiceType77.ColumnSpacing };
    return page; } /// <summary> ///
    PageHeader和PageFooter也只是TextRun里Value的数据不一样 ///
    </summary> /// <returns></returns> private
    PageSectionType CreatePageHeader() { return new PageSectionType(); }
    private PageSectionType CreatePageFooter() { return new
    PageSectionType(); } /// <summary> /// 把Report序列化为流 ///
    </summary> /// <param
    name=”stream”>根据Report序列化好的流</param> public void
    Write(Stream stream) { Write(stream, CreateReport()); } public void
    Write(Stream stream, Report report) { new
    XmlSerializer(typeof(Report)).Serialize(stream, report); } public Report
    Read(Stream stream) { return (Report)new
    XmlSerializer(typeof(Report)).Deserialize(stream); } /// <summary>
    /// 把和DataGrid对应的rdlc模板文件反序列化为Report /// </summary>
    /// <param
    name=”rdlcModelFilePath”>和DataGrid对应的rdlc模板文件</param>
    /// <returns>反序列化之后的Report</returns> public Report
    Read(string rdlcModelFilePath) { using (var stream = new
    FileStream(rdlcModelFilePath, FileMode.Open)) { return Read(stream); } }
    public void Write(string rdlcModelFilePath) { using (var stream = new
    FileStream(rdlcModelFilePath, FileMode.OpenOrCreate)) {
    stream.SetLength(0); Write(stream); } } /// <summary> ///
    计算Report的宽度,页宽 – 左边距 – 右边距 /// </summary> ///
    <returns></returns> public string CalcReportWidth() { string
    reportWidth = String.Empty; const double size = 100.0; reportWidth =
    (PageSettings == null) ? “6.5in” :
    ((double)(PageSettings.PaperSize.Width – PageSettings.Margins.Left –
    PageSettings.Margins.Right) / size).ToString() + “in”; return
    reportWidth; } RdlcGenerator.cs
    www.9778.com 5 public
    class TablixRdlcGenerator { #region Properties // DataGrid
    的DataGridColumn的Header private List<string> headerNames = new
    List<string>(); public List<string> HeaderNames { get {
    return headerNames; } } // 对应DataGrid Binding的Path private
    List<string> fieldNames = new List<string>(); public
    List<string> FieldNames { get { return fieldNames; } } public
    string DataSetName { get; set; } // 对应DataGrid Column的ActualWidth
    private List<string> widths = new List<string>(); public
    List<string> Widths { get { return widths; } } #endregion
    #region Methods private void ResetValues(List<string> p,
    List<string> v) { p.Clear(); if (v != null) { p.AddRange(v); } }
    public void ResetHeaderNames(List<string> hns) {
    ResetValues(HeaderNames, hns); } public void
    ResetFieldNames(List<string> fns) { ResetValues(FieldNames, fns);
    } public void ResetWidths(List<string> widths) {
    ResetValues(Widths, widths); } /// <summary> ///
    矩阵和Table对应的Tablix稍微有些不一样,如对于矩阵,TablixBody里的表头和数据项
    ///
    一些值会拆分到TablixColumnHierarchy和TablixRowHierarchy里TablixMember–TablixHeader–CellContents–Textbox
    /// 对于DataGrid我们用最简单的Table就好 /// </summary> ///
    <returns></returns> public TablixType CreateTablix() {
    TablixType tablix = new TablixType(); tablix.Name = “dataGridTablix0”;
    tablix.Items = new object[] { // 创建TablixCorner不能创建个空的 //
    CreateTablixCorner(), CreateTablixBody(), CreateTablixColumnHierarchy(),
    CreateTablixRowHierarchy(), true, true, CreateDataSetName(), // Top,
    Left, Height, Width可具体调整 // Top, Left —>
    Location(距离左上角);Height, Width —> Size //
    (Tablix的大小,这个Width不管用,具体是由各个TablixColumn的Width之和决定)
    “1.8cm”, “2cm”, “2cm”, “17cm”, CreateTablixStyle(), };
    tablix.ItemsElementName = new ItemsChoiceType73[] { //
    ItemsChoiceType73.TablixCorner, ItemsChoiceType73.TablixBody,
    ItemsChoiceType73.TablixColumnHierarchy,
    ItemsChoiceType73.TablixRowHierarchy,
    ItemsChoiceType73.RepeatColumnHeaders,
    ItemsChoiceType73.RepeatRowHeaders, ItemsChoiceType73.DataSetName,
    ItemsChoiceType73.Top, ItemsChoiceType73.Left, ItemsChoiceType73.Height,
    ItemsChoiceType73.Width, ItemsChoiceType73.Style }; return tablix; } ///
    <summary> /// non-essential element, so make it emtpy temprorily
    /// 看样子是表头行,纵向合并的单元格(如纵向两行合并为一行)等相关的 ///
    </summary> /// <returns></returns> private
    TablixCornerType CreateTablixCorner() { return new TablixCornerType(); }
    private TablixBodyType CreateTablixBody() { TablixBodyType tablixBody =
    new TablixBodyType(); tablixBody.Items = new object[] {
    CreateTablixColumns(), CreateTablixRows(), }; return tablixBody; }
    private void EnumHeaderNames(Action<int> act) { for (int i = 0; i
    < HeaderNames.Count; i++) { act(i); } } private TablixColumnsType
    CreateTablixColumns() { TablixColumnsType tablixColumns = new
    TablixColumnsType(); //
    根据DataGridColumns的数量来决定创建几列,并且每列要把具体的宽度传进去
    tablixColumns.Items = new object[headerNames.Count]; EnumHeaderNames(p
    => { tablixColumns.Items[p] = CreateTablixColumn(p); }); return
    tablixColumns; } private TablixColumnType CreateTablixColumn(int index)
    { // Width of
    column,应该根据DataGridColumn.Width来具体设定,暂时给个固定值 return new
    TablixColumnType() { Items = new object[] { Widths[index] } }; } ///
    <summary> /// 对于DataGrid只应有两行,一行是Header,一行是数据 ///
    如果有求 /// </summary> ///
    <returns>TablixRowsType</returns> private TablixRowsType
    CreateTablixRows() { TablixRowsType tablixRows = new TablixRowsType();
    tablixRows.Items = new object[] { CreateTablixRowHeader(),
    CreateTablixRowData(), }; return tablixRows; } private TablixRowType
    CreateTablixRowType(bool isHeader) { TablixRowType trt = new
    TablixRowType(); trt.Items = new object[] { “0.23622in”, // Default
    height CreateTablixCells(isHeader), //
    Header的Cells的内容和Data的Cells的内容应该不同 }; return trt; } ///
    <summary> /// Tablix Header /// </summary> ///
    <returns></returns> private TablixRowType
    CreateTablixRowHeader() { return CreateTablixRowType(true); } private
    TablixRowType CreateTablixRowData() { return CreateTablixRowType(false);
    } private TablixCellsType CreateTablixCells(bool isHeaerCell) {
    TablixCellsType tablixCells = new TablixCellsType(); //
    根据DataGridColumns的数量来决定创建几个Cell,
    Header应传DataGridColumn.Header数据 tablixCells.Items = new
    object[HeaderNames.Count]; EnumHeaderNames(p => {
    tablixCells.Items[p] = CreateTablixCell(isHeaerCell, p); }); return
    tablixCells; } private TablixCellType CreateTablixCell(bool
    isHeaderCell, int index) { TablixCellType tablixCell = new
    TablixCellType(); // 基本的只要”CellContents”就够了 tablixCell.Items =
    new object[] { CreateCellContentes(isHeaderCell, index) }; return
    tablixCell; } private CellContentsType CreateCellContentes(bool
    isheaderCell, int index) { CellContentsType cellContents = new
    CellContentsType(); //
    对于DataGrid转换的rdlc,通常是一个Textbox。具体可以是Chart、Image、Line、Rectangle、Subreport等等
    cellContents.Items = new object[] {
    CreateTablixCellTextbox(isheaderCell, index) };
    cellContents.ItemsElementName = new ItemsChoiceType71[] {
    ItemsChoiceType71.Textbox }; return cellContents; } private TextboxType
    CreateTablixCellTextbox(bool isHeaderCell, int index) { TextboxType
    tablixCellTextbox = new TextboxType(); //
    对于Header的Textbox可以复杂一点,多些字体、背景颜色等字段的定义 //
    Data的简单点//isHeaderCell ? headerNames[index] :
    tablixCellTextbox.Name = isHeaderCell ? “TB” + fieldNames[index] :
    fieldNames[index]; tablixCellTextbox.Items = new object[] { true,
    true, CreateTablixCellTextboxParagraphs(isHeaderCell, isHeaderCell ?
    headerNames[index] : fieldNames[index]),
    CreateTablixCellTextboxStyle(), }; tablixCellTextbox.ItemsElementName =
    new ItemsChoiceType14[] { ItemsChoiceType14.CanGrow,
    ItemsChoiceType14.KeepTogether, ItemsChoiceType14.Paragraphs,
    ItemsChoiceType14.Style, }; return tablixCellTextbox; } private
    ParagraphsType CreateTablixCellTextboxParagraphs(bool isHeaderCell,
    string name) { ParagraphsType pt = new ParagraphsType(); pt.Paragraph =
    new ParagraphType[] { CreateTablixCellTextboxParagraph(isHeaderCell,
    name) }; return pt; } private ParagraphType
    CreateTablixCellTextboxParagraph(bool isHeaderCell, string name) {
    ParagraphType pt = new ParagraphType(); pt.Items = new object[] {
    CreateTablixCellTextboxParagraphTextRuns(isHeaderCell, name),
    CreateTablixCellTextboxParagraphStyle(isHeaderCell), };
    pt.ItemsElementName = new ItemsChoiceType12[] {
    ItemsChoiceType12.TextRuns, ItemsChoiceType12.Style, }; return pt; }
    private TextRunsType CreateTablixCellTextboxParagraphTextRuns(bool
    isHeaderCell, string name) { TextRunsType trt = new TextRunsType();
    trt.TextRun = new TextRunType[] {
    CreateTablixCellTextboxParagraphTextRun(isHeaderCell, name) }; return
    trt; } private TextRunType CreateTablixCellTextboxParagraphTextRun(bool
    isHeaderCell, string name) { TextRunType trt = new TextRunType();
    trt.Items = new object[] { CreateTablixTextRunValue(isHeaderCell,
    name), CreateTablixTextRunStyle(isHeaderCell), }; trt.ItemsElementName =
    new ItemsChoiceType11[] { ItemsChoiceType11.Value,
    ItemsChoiceType11.Style, }; return trt; } //
    数据项和Header的关键不一样就在这个了 private
    LocIDStringWithDataTypeAttribute CreateTablixTextRunValue(bool
    isHeaderCell, string name) { LocIDStringWithDataTypeAttribute v = new
    LocIDStringWithDataTypeAttribute(); v.Value = isHeaderCell ? name :
    “=Fields!” + name + “.Value”; v.DataType =
    StringWithDataTypeAttributeDataType.String; return v; } private
    StyleType CreateTablixTextRunStyle(bool isHeaderCell) { StyleType st =
    new StyleType(); string fontSize = isHeaderCell ? “11pt” : “10pt”;
    string FontWeight = isHeaderCell ? “Bold” : “Default”; st.Items = new
    object[] { “宋体”, fontSize, FontWeight, }; st.ItemsElementName = new
    ItemsChoiceType4[] { ItemsChoiceType4.FontFamily,
    ItemsChoiceType4.FontSize, ItemsChoiceType4.FontWeight, }; return st; }
    //
    暂时设为表头行“居中对齐”,数据行“靠左对齐”;后面可具体定制表头行和数据行的对齐方式
    private StyleType CreateTablixCellTextboxParagraphStyle(bool
    isHeaderCell) { StyleType st = new StyleType(); st.Items = new
    object[] { isHeaderCell ? “Center” : “Left” }; st.ItemsElementName =
    new ItemsChoiceType4[] { ItemsChoiceType4.TextAlign }; return st; } //
    ***************************** //
    Header的Color和Style可以和数据不同,下面是默认的Sytle,可自定义
    //****************************** private
    StyleType CreateTablixCellTextboxStyle() { StyleType st = new
    StyleType(); st.Items = new object[] {
    CreateTablixCellTextboxBorder(), “2pt”, “2pt”, “2pt”, “2pt”, };
    st.ItemsElementName = new ItemsChoiceType4[] {
    ItemsChoiceType4.Border, // ItemsChoiceType4.BackgroundColor,
    默认数据没有BackgroundColor ItemsChoiceType4.PaddingLeft,
    ItemsChoiceType4.PaddingRight, ItemsChoiceType4.PaddingTop,
    ItemsChoiceType4.PaddingBottom, }; return st; } private BorderType
    CreateTablixCellTextboxBorder() { BorderType bt = new BorderType();
    bt.Items = new object[] { “Black”, “Solid”, “1pt” };
    bt.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.Color,
    ItemsChoiceType2.Style, ItemsChoiceType2.Width }; return bt; } ///
    <summary> ///
    按最简单的来,DataGrid对应的应该是有几个column创建几个TablixMember ///
    </summary> private TablixHierarchyType
    CreateTablixColumnHierarchy() { return new TablixHierarchyType() { Items
    = new object[] { CreateTablixColumnMembers() } }; } private
    TablixMembersType CreateTablixColumnMembers() { TablixMembersType tmts =
    new TablixMembersType(); tmts.TablixMember = new
    TablixMemberType[HeaderNames.Count]; EnumHeaderNames(p => {
    tmts.TablixMember[p] = CreateTablixColumnMember(); }); return tmts; }
    // DataGrid的Column对应的TablixMember创建一个空的就行 private
    TablixMemberType CreateTablixColumnMember() { return new
    TablixMemberType(); } //
    DataGrid按最简单的默认的来,即创建2个TablixMember即可 private
    TablixHierarchyType CreateTablixRowHierarchy() { return new
    TablixHierarchyType() { Items = new object[] {
    CreateTablixRowMembers() } }; } private TablixMembersType
    CreateTablixRowMembers() { TablixMembersType tablixMembers = new
    TablixMembersType(); tablixMembers.TablixMember = new
    TablixMemberType[] { CreateTablixRowMember0(),
    CreateTablixRowMember1(), }; return tablixMembers; } private
    TablixMemberType CreateTablixRowMember0() { TablixMemberType tmt = new
    TablixMemberType(); tmt.Items = new object[] {
    CreateTablixRowMemberKeepWithGroup(), true, }; tmt.ItemsElementName =
    new ItemsChoiceType72[] { ItemsChoiceType72.KeepWithGroup,
    ItemsChoiceType72.RepeatOnNewPage, }; return tmt; } private
    TablixMemberTypeKeepWithGroup CreateTablixRowMemberKeepWithGroup() {
    return TablixMemberTypeKeepWithGroup.After; } private TablixMemberType
    CreateTablixRowMember1() { TablixMemberType tmt = new
    TablixMemberType(); tmt.Items = new object[] {
    CreateTablixRowMemberGroup() }; tmt.ItemsElementName = new
    ItemsChoiceType72[] { ItemsChoiceType72.Group }; return tmt; } private
    GroupType CreateTablixRowMemberGroup() { return new GroupType() { Name =
    “详细信息” }; } /// <summary> ///
    ReportDataSource.Name和RDLC文件的DataSetNamey应保持一致 ///
    对于DataGrid构造的报表,可统一固定用”CustormerDataSet”; ///
    DataSetName不需要作为参数传进来 /// </summary> ///
    <returns>DataSet Name</returns> private string
    CreateDataSetName() { return String.IsNullOrEmpty(DataSetName) ?
    “CustomerDataSet” : DataSetName; } private StyleType CreateTablixStyle()
    { StyleType st = new StyleType(); st.Items = new object[] {
    CreateTablixBorder() }; st.ItemsElementName = new ItemsChoiceType4[] {
    ItemsChoiceType4.Border }; return st; } // Tablix的外边框格式 private
    BorderType CreateTablixBorder() { BorderType bt = new BorderType();
    bt.Items = new object[] { “Black”, “Solid”, “2pt” };
    bt.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.Color,
    ItemsChoiceType2.Style, ItemsChoiceType2.Width }; return bt; }
    #endregion } TablixRdlcGenerator.cscs

 

第三步:提取DataGrid的数据

1、主要从DataGrid提取每个Column的Width、BindingPath、Header的Content和每个单元格的数据。数据填充DataTable的Rows,
BindingPath填充DataTable的Columns,

Header的Content用来作为报表Tablix的标题行。BindingPath,对于DataTemplate和DataGridHyperlinkColumn不知道咋个取提取数据.

 

2、dataGrid.ScrollIntoView(dataGrid.Items[rowIndex])这个是关键。DataGrid用了一个虚拟啥子来着的(名字不重要,原理简单,计算机领域大量处理性能的都是用这个办法,

包括所谓的云啊分布式什么的),就是复用界面显示,一个窗口里能装下的几十条RowContainer,每次滚动,人要看到的时候才重新提取新的要显示的数据。

这样提取数万条记录时,界面不会卡,也不会占用很多内存,每次是要显示的时候才取几十条,一点点取。要用,才给,只给需要的那点。

www.9778.com 6 ///
<summary> ///
DataGrid的转换器,从DataGrid里提取出数据源,以及HeaderName、Binding的Path和ActualWidth
/// </summary> /// <param
name=”dataGrid”>包含数据的DatGrid</param> /// <param
name=”dt”>DataGrid数据源转换成的DataTable</param> /// <param
name=”headerNames”>DataGridColumn.Header</param> /// <param
name=”bindingPaths”> DataGridBoundColumn.Binding.Path</param>
public static void DataGridAdapter(this DataGrid dataGrid, DataTable dt,
List<string> headerNames, List<string> bindingPaths,
List<double> widths) { //
取出DataGridColumn的Header,BingdingPath,ActualWidth为构造rdlc文件准备数据
headerNames.Clear(); bindingPaths.Clear(); widths.Clear(); for (int
index = 0; index < dataGrid.Columns.Count; index++) {
headerNames.Add(dataGrid.Columns[index].Header as string);
widths.Add(dataGrid.Columns[index].ActualWidth); //string
tempBindingPath = ((dataGrid.Columns[index] as
DataGridBoundColumn).Binding as Binding).Path.Path; string
tempBindingPath =
GetDataGridColumnBindingPath(dataGrid.Columns[index]);
bindingPaths.Add(tempBindingPath); if
(String.IsNullOrEmpty(tempBindingPath) == false)
dt.Columns.Add(tempBindingPath, typeof(string)); } for (int rowIndex =
0; rowIndex < dataGrid.Items.Count; rowIndex++) { //
要显示后,才能取到数据 DataGridRow rowContainer =
(DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);
//
因为Peformance问题,EnableRowVirtualization被设置为true,只加载要显示的数据
// 重新滚动,然后再重用这些DataGridRow if (rowContainer == null) {
dataGrid.UpdateLayout();
dataGrid.ScrollIntoView(dataGrid.Items[rowIndex]); rowContainer =
(DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex);
} if (rowContainer != null) { DataGridCellsPresenter presenter =
DataGridHelper.GetVisualChild<DataGridCellsPresenter>(rowContainer);
if (presenter != null) { DataRow dr = dt.NewRow(); bool
isLastRowAllEmpty = true; for (int columnIndex = 0; columnIndex <
bindingPaths.Count; columnIndex++) { DataGridCell cell =
(DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
if (cell != null) { if (cell.Content is TextBlock) { //TODO:
DataGridHyperlinkColumn取不到数据 dr[bindingPaths[columnIndex]] =
(cell.Content as TextBlock).Text; if
(!String.IsNullOrEmpty((cell.Content as TextBlock).Text))
isLastRowAllEmpty = false; } else if (cell.Content is CheckBox) { string
value = ((cell.Content as CheckBox).IsChecked == true) ? “是” : “否”;
dr[bindingPaths[columnIndex]] = value; } else if (cell.Content is
ComboBox) { dr[bindingPaths[columnIndex]] = (cell.Content as
ComboBox).Text; if (!String.IsNullOrEmpty((cell.Content as
ComboBox).Text)) isLastRowAllEmpty = false; } } } if
(dataGrid.CanUserAddRows && (rowIndex == dataGrid.Items.Count – 1)) { //
如果CanUserAddRows被设置为true,只有最后一行的数据都不为空(CheckBox不算作内),才把数据添加到DataTable
if (isLastRowAllEmpty) { continue; } } dt.Rows.Add(dr); } } } } 提取DataGrid数据

www.9778.com, 

第四步:填充数据

关键在设置ReportViewer类的LocalReport.ReportPath
和LocalReport.DataSources这两项。

www.9778.com 7 ///
<summary> /// 报表数据源发生变化时,及时更新显示报表控件的数据源
/// </summary> /// <param
name=”reportDataModel”>报表数据模型基类</param> public void
ResetReportData(ReportDataModel reportDataModel) { if (reportDataModel
!= null) { reportViewer.Reset();
reportViewer.LocalReport.DataSources.Clear(); reportViewer.Clear(); if
(!reportDataModel.IsDataGrid) reportViewer.LocalReport.ReportPath =
reportDataModel.RDLCReportPath; else { //
如果是DataGrid转换成的,直接从内存流里加载数据 if
(reportDataModel.MsDataGrid != null) {
reportViewer.LocalReport.LoadReportDefinition(reportDataModel.MsDataGrid);
// 用完就释放掉,流所占用的所有资源 //
reportDataModel.MsDataGrid.Dispose(); } }
reportViewer.LocalReport.DataSources.Add(reportDataModel.ReportDataSource);
reportViewer.RefreshReport(); } } ResetReportData

 

第五步:提供一个ReportHelper类

具体拼接数据以及计算高度等,还有用另一套办法实现第二个功能。

1、根据DataGrid每列的宽度,按百分比,重新设置每列的宽度。

www.9778.com 8 1 ///
<summary> 2 /// 根据DataGrid的Column的Actual
Width来设置报表里对应Tablix的TablixColumn的宽度 3 /// </summary> 4
/// <param name=”reportWidth”>报表的总宽度</param> 5 ///
<param name=”widths”>DataGrid的Column的Actual Width</param>
6 /// <param
name=”tablixColumnWidths”>重新按百分比计算的TablixColumn的宽度列表</param>
7 public static void CalcTablixColumnWidth(string reportWidth,
List<double> widths, out List<string> tablixColumnWidths) 8
{ 9 double totalWidth = 0.0; 10 double originalTotalWidth = 0.0; 11
List<double> rateColumnWidth = new List<double>(); 12 string
unit = reportWidth.Substring(reportWidth.Length – 2, 2); 13 14 //
取到报表宽度字符串除去单位in或者cm的数值 15
Double.TryParse(reportWidth.Substring(0, reportWidth.Length – 2), out
totalWidth); 16 17 18 for (int index = 0; index < widths.Count;
index++) 19 originalTotalWidth += widths[index]; 20 21 22 for (int
index = 0; index < widths.Count; index++) 23
rateColumnWidth.Add(widths[index] / originalTotalWidth); 24 25
tablixColumnWidths = new List<string>(); 26
tablixColumnWidths.Clear(); 27 for (int index = 0; index <
widths.Count; index++) 28
tablixColumnWidths.Add((rateColumnWidth[index] *
totalWidth).ToString() + unit); 29 } CalcTablixColumnWidth

2、把内存中的流读出来,生成对应的RDLC文件,我那里没调用。所以设置LocalReport.ReportPath换成reportViewer.LocalReport.LoadReportDefinition(reportDataModel.MsDataGrid);

www.9778.com 9 1 ///
<summary> 2 /// 把内存的流生成为rdlc文件 3 /// </summary> 4
/// <param name=”rdlc”>按rdlc格式构造成功的内存流</param> 5
public static void DumpRdlc(MemoryStream rdlc) 6 { 7 string tempRdlcPath
= AppDomain.CurrentDomain.BaseDirectory +
@”../../../CommonReport/Templates/GeneratedDataGrid.rdlc”; 8 if
(File.Exists(tempRdlcPath)) 9 File.Delete(tempRdlcPath); 10 11 using
(FileStream fs = new FileStream(tempRdlcPath, FileMode.Create)) 12 { 13
rdlc.WriteTo(fs); 14 } 15 } DumpRdlc

3、部分调用的代码——给一个简单的RDLC模板,以提供表头的字体格式和表内部数据等样式相关的信息,然后再用DataGrid里提取的数据,填充到报表里

www.9778.com 10 1 ///
<summary> 2 ///
将DataGrid的数据抽取出来,转换成rdlc报表,以实现对提供DataGrid的打印、预览、分页和页面布局等功能的支持
3 ///
但需要提供一个rdlc报表的模板,必须包括页眉页脚,至少一列数据和标题,以便拿到数据的表头的
4 ///
style和数据项的style,这一列数据项必须是第一项(且第一项的表头和数据都完整提供了style)
5 /// </summary> 6 /// <param
name=”dataGrid”>提供数据的DataGrid</param> 7 /// <param
name=”reportViewer”>要加载DataGrid数据的ReportViewer</param> 8
/// <param
name=”rdlcModelFileName”>rdlc模板的完整路径</param> 9 ///
<param name=”headline”>报表标题</param> 10 public static
void Print(this DataGrid dataGrid, CommonReport.Views.ReportViewer
reportViewer, string rdlcModelFileName, string headline) 11 { 12 if
(!File.Exists(rdlcModelFileName)) return; 13 14 //
从DataGrid对应的rdlc模板里读出报表数据来 15 Report report = null; 16
string dataSourceName = DatasetName; 17
dataGrid.UnderRdlcGenProc(reportViewer, headline, gen => 18 { 19
report = gen.Read(rdlcModelFileName); 20 21 //
ReportDataSource的Name应该用取DataSet的Name 22 #region 取DataSourceName
23 24 DataGridHelper.ResetRdlcHeadline(report, headline); 25 for (int
index = 0; index < report.Items.Length; index++) 26 { 27 if
(report.Items[index] is DataSetsType) 28 { 29 DataSetsType dataSets =
report.Items[index] as DataSetsType; 30 dataSourceName =
dataSets.DataSet[0].Name; 31 break; 32 } 33 } 34 35 #endregion 36 },
(gen, ms, dt) => 37 { 38 //
根据从DataGrid里提取的数据重新构造rdlc文件 39 RdlcReportAdapter(report,
gen.HeaderNames, gen.FieldNames, gen.Widths); 40 gen.Write(ms, report);
41 return new
Microsoft.Reporting.WinForms.ReportDataSource(dataSourceName) { Value =
dt }; 42 }); 43 } Print

4、打印的关于页面的一些默认设置(看情况)

www.9778.com 111 //
设置默认打印布局模式为“显示物理页” 2
reportViewer.SetDisplayMode(DisplayMode.PrintLayout); 3
reportViewer.ZoomMode = ZoomMode.Percent; 4 reportViewer.ZoomPercent =
100; 打印设置

5、TreeView反射那块——功能三

www.9778.com 12 1 ///
<summary> 2 ///
TreeView上选择的项发生变化时,根据所选TreeViewItem的Header信息和Tag里所存储的信息,利用反射构造对应报表的数据类实例
3 /// 加载报表模板,调用委托将数据传到报表的显示控件上 4 ///
</summary> 5 /// <param name=”sender”></param> 6 ///
<param name=”e”></param> 7 private void
RdlcTree_SelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e) 8 { 9 if ((sender !=
null) && (sender is TreeView)) 10 { 11 if ((sender as
TreeView).SelectedItem is TreeViewItem) 12 { 13 TreeViewItem tempItem =
(sender as TreeView).SelectedItem as TreeViewItem; 14 if (tempItem.Tag
is TreeViewItemDataType) 15 { 16 TreeViewItemDataType
tempTreeViewDataType = tempItem.Tag as TreeViewItemDataType; 17 //
报表类型 18 if (tempTreeViewDataType.UserControlType ==
TreeViewItemDataType.ControlType.Report) 19 { 20 string
reportDataModelInstanceName = tempItem.Header + “Model”; 21 Type type =
typeof(ReportDataModel); 22 Assembly assembly = type.Assembly; 23 try 24
{ 25 ReportDataModel reportDataModelInstance =
(ReportDataModel)assembly.CreateInstance(type.Namespace + “.” +
reportDataModelInstanceName); 26 if (reportDataModelInstance != null) 27
{ 28 reportDataModelInstance.RDLCReportPath = (tempItem.Tag as
TreeViewItemDataType).FullPath; 29
reportDataModelInstance.InitDataSource(); 30 if (Viewer != null) 31
Viewer.ResetReportData(reportDataModelInstance); 32 } 33 } 34 catch
(Exception ex) 35 { 36 MessageBox.Show(ex.Message); 37 } 38 } 39 40 //
DataGrid 类型 41 else if (tempTreeViewDataType.UserControlType ==
TreeViewItemDataType.ControlType.DataGrid) 42 { 43 Type type =
this.GetType(); 44 Assembly assembly = type.Assembly; 45 try 46 { 47
UserControl dataGridUserControlInstance =
(UserControl)assembly.CreateInstance(type.Namespace + “.DataGrid.” +
tempItem.Header); 48 } 49 catch (Exception ex) 50 { 51
MessageBox.Show(ex.Message); 52 } 53 } 54 } 55 } 56 } 57 } RdlcTree_SelectedItemChanged

6、通过VisualTreeHelper找到指定类型的子或者父的方法,可在WPF里通用

www.9778.com 13 ///
<summary> /// 找出子Visual的特定类型的Parent /// </summary>
/// <typeparam name=”T”>指定类型</typeparam> /// <param
name=”child”>继承自Visual的基本控件类型的子Visual</param> ///
<returns></returns> public static T
GetParent<T>(Visual child) where T : Visual { T parent =
default(T); Visual visual = VisualTreeHelper.GetParent(child) as Visual;
parent = visual as T; if (parent == null) return
GetParent<T>(visual); else return parent; } /// <summary>
/// 遍历取父控件的子Viusal,取到指定类型的子Viusal /// </summary>
/// <typeparam
name=”T”>T是Visual或其子类(基本上WPF的控件都是Visual的子类),指定子类型</typeparam>
/// <param name=”parent”>父控件</param> ///
<returns>子Viusal</returns> public static T
GetVisualChild<T>(Visual parent) where T : Visual { T child =
default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++) { Visual visual =
(Visual)VisualTreeHelper.GetChild(parent, i); child = visual as T; if
(child == null) child = GetVisualChild<T>(visual); else break; }
return child; } VisualTreeHelper

7、提供一个数据深拷贝的通用方法(C#类以及除基类型之外,好多都是传引用,这个是地址,值拷贝不好搞,这个方法直接拷贝流,但是必须类的每个字段都支持序列化)

www.9778.com 14 1 ///
<summary> 2 ///
对引用类型的数据——“所有字段都加了Serializable特性,以支持序列化” 3 ///
利用序列化和反序列化实现深度拷贝,即拷贝了堆上的数据,搞了个堆的副本 4
/// 而不是浅拷贝那样,只是拷贝了一个指向数据堆的内存地址 5 ///
非常实用的小函数,支持所有引用类型数据 6 /// </summary> 7 ///
<param name=”original”>要拷贝的引用类型数据源</param> 8 ///
<returns>源数据的副本</returns> 9 public static object
DeepColne(Object original) 10 { 11 // 构造一个临时的内存流 12 using
(MemoryStream ms = new MemoryStream()) 13 { 14 //
调用BinaryFormatter来完成复杂的序列化和反序列化工作 15 BinaryFormatter
formatter = new BinaryFormatter(); 16 17 //
StreamingContext—描述给定的序列化流的源和目标,并提供一个由调用方定义的附加上下文
18 formatter.Context = new
StreamingContext(StreamingContextStates.Clone); 19 20 //
把对象图序列化到内存流,original的每个字段必须标记为可序列化,否则会出错
21 formatter.Serialize(ms, original); 22 23 //
反序列化之前需要设置流的当前位置为最开始的位置 24 ms.Position = 0; 25 26
// 把内存流反序列化为对象图,再以基类的形式返回给调用者 27 return
formatter.Deserialize(ms); 28 } 29 } DeepColne

 

六、运行效果

1、含有DataGrid或者其它控件的界面

www.9778.com 15

2、点击打印后,报表生成

www.9778.com 16

附:

1、ReportItems!具体RDLC报表上控件的名称.Value这个取到报表设计器里任意项的数据,然后就可在表达式里进行各种逻辑运算。例如:

= ReportItems!forestryMaintenance.Value + ReportItems!pension.Value +
ReportItems!SumPolicy.Value

  • ReportItems!livingExpenses.Value + ReportItems!resettlement.Value

2、合并单元格,纵向和横向的

这个要分组,具体请搜索网上资源

3、控制每页都显示

对于标题,设置KeepWith属性和Tablix一起出现就好;还有一个办法,是设置其它的属性,暂时忘了,网上有

4、XML很重要,据目前所知,微软的工程文件、WPF、打印、报表、XPS、Office2007以后版本等,XML都是基石。(未完,待续)

5、页面纸张尺寸(PageSetting里的一些关于大小的值,单位都是1/100
inch;页面设置布局排版打印有点麻烦,稍不注意就多出去一点,字体、页眉、页脚、边框、页边距等),如下图:

www.9778.com 17

 6、border style

www.9778.com 18

 

末了,必须感谢和致敬蜡人张前辈:

2.微软GotReportViewer官方的案例:

前段时间,做了RDLC报表,主要是三块功能:
1、从DataGrid提取(包括最新的增删改)的数据,自动生…

/// <summary>
/// 获取Table类型表的记录
/// </summary>
/// <param name=”relationCheckClass”></param>
/// <returns></returns>
private List<string> GetAllRecordFormTTable(RelationCheckClass
relationCheckClass)
{
List<string> recordList = new List<string>();
ITable table =
((IFeatureWorkspace)m_Workspace).OpenTable(relationCheckClass.TableName);
if (table!=null)
{
string fieldName = relationCheckClass.TabelField;
int fieldIndex = table.FindField(Name: fieldName);
string fieldValue = “”;
for (int i = 0; i < table.RowCount(null); i++)
{
fieldValue = table.GetRow(i).get_Value(fieldIndex).ToString();
recordList.Add(fieldValue);
}
}
return recordList;
}