不能的ReportViewer aspx.net显示数据表 [英] Can't Display DataTable in ReportViewer aspx.net

查看:354
本文介绍了不能的ReportViewer aspx.net显示数据表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ReportViewer控件显示一个DataTable对象的内容难度。有没有错误,只是被显示在页面上的空白报表查看器。我看过各种类似的问题psented解决方案$ P $找到<一href=\"http://stackoverflow.com/questions/11725634/datatable-as-datasource-in-reportviewer?rq=1\">here, <一href=\"http://stackoverflow.com/questions/22017968/how-to-bind-dynamically-datasource-to-reportviewer-on-windows-forms-c-sharp\">here和<一个href=\"http://stackoverflow.com/questions/23751478/how-to-show-dynamically-generated-datatable-in-reportviewer-in-asp-net\">here - 这最后一个是作为最后评论说:让我们继续聊天的讨论,没有答案提供特别令人沮丧,它本质上是我的确切问题

I am having difficulty displaying the contents of a DataTable object in a ReportViewer control. There are no errors, just a blank report viewer being shown on the page. I have looked at the solutions presented in various similar questions found here, here and here - that last one is particularly frustrating as the last comment says "let's continue this discussion in chat" with no answer provided and it is essentially my exact issue.

页code:

    <div class="panel-body">
         <rsweb:ReportViewer ID="ReportViewer1" runat="server" Width="100%">
              <LocalReport ReportPath="reports\Report1.rdlc">
              </LocalReport>
         </rsweb:ReportViewer>
   </div>

codebehind:

Codebehind:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string repstr = Request.Form["repId"];
            int repId = -1;
            int.TryParse(repstr, out repId);
            CustomReport rpt = new CustomReport(repId);
            data = rpt.ReportResult.Copy();//The report result property is a DataTable object that can have varying # of columns
            data.TableName = "CustomReport";
            ReportViewer1.ProcessingMode = ProcessingMode.Local;
            ReportDataSource source = new ReportDataSource("CustomReport", data);
            ReportViewer1.LocalReport.DataSources.Clear();
            ReportViewer1.LocalReport.DataSources.Add(source);
            ReportViewer1.DataBind();
            ReportViewer1.LocalReport.Refresh();
            ReportViewer1.Visible = true;
        }
    }

我已经验证了数据表被填充数据,并通过调试我验证过的ReportViewer数据属性显示有数据以及 - 它只是没有显示....

I have verified that the DataTable is being populated with data and through debugging I've verified that the ReportViewer data properties appear to have the data as well - it's just not being displayed....

任何帮助将大大AP preciated!

Any help would be greatly appreciated!

推荐答案

所以,经过大量的从我真棒发展的同事研究和谷歌搜索和帮助我碰到,基本上涉及必须重建.rdlc的XML结构的解决方案来文件以支持动态列。有几个注意事项,以这种方法。
1.您必须手动配置XML引用的数据源,提供了数据表的报表设计器不支持此您的对象方法指向。以下列出一些我的XML的变化。
2.你有一个表添加到报表定义,只有一列,一行。也许有人可以做到这一点更好。

So after a lot of research and googling and help from my awesome development colleagues I came across a solution that essentially involves having to reconstruct the xml structure of the .rdlc file in order to support dynamic columns. There are a couple of caveats to this approach. 1. You have to manually configure the xml referencing the datasource to point at your object method that provides the datatable as the report designer does not support this. I've included my xml changes below. 2. You have to add a table to the report definition with only one column and one row. Maybe somebody can do this better.

因此​​该溶液中。首先RDLC XML数据源配置:

So the solution. First the rdlc xml datasource config:

<DataSet Name="DataSet1">
  <Query>
    <DataSourceName>DataLayer</DataSourceName>
    <!--//Put the table name of your datatable object here-->
    <CommandText>CustomReportsDs</CommandText>
  </Query>
  <!--//This is a single empty field for mapping to the table control-->
  <Fields>
    <Field Name="ReportTitle">
      <DataField>ReportTitle</DataField>
      <rd:TypeName>System.String</rd:TypeName>
    </Field>
  </Fields>
  <rd:DataSetInfo>
    <!--//This must be configured to point to the method that supplies the datatable
        //In my instance the DataSetName is the namespace of the object, 
        //TableName is the object that provides the method and
        //ObjectDataSourceSelectMethod is the method that provides the datatable-->        
    <rd:DataSetName>DataLayer</rd:DataSetName>
    <rd:TableName>CustomReport</rd:TableName>
    <rd:ObjectDataSourceSelectMethod>ReportResult</rd:ObjectDataSourceSelectMethod>
    <rd:ObjectDataSourceType>DataLayer.CustomReport, DataLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</rd:ObjectDataSourceType>
  </rd:DataSetInfo>
</DataSet>

接下来,您必须配置报表查看器从内存流收到报告定义:

Next you have to configure the report viewer to recieve the report definition from a memory stream:

            //load the data
            int repId = -1;
            int.TryParse(Request.Form["repId"], out repId);
            CustomReport rpt = new CustomReport(repId);
            DataTable data = rpt.ReportResult.Copy();//The report result property is a DataTable object that can have varying # of columns
            data.TableName = "CustomReportDs";
            //setup the report viewer
            ReportViewer1.ProcessingMode = ProcessingMode.Local;
            ReportViewer1.LocalReport.ReportPath = string.Empty;
            //prepare to load the report definition xml file
            string ReportPath = Server.MapPath(@"\reports\Report1.rdlc");
            //my datatable comes with "friendly" column headings - these don't work well as the xml requires cls compliant
            //columnheadings so here we rename the columns in the data table but preserve the friendly names for use later
            Dictionary<string, string> columns = new Dictionary<string, string>();
            int counter = 0;
            foreach(DataColumn col in data.Columns)
            {
                columns.Add("column"+counter.ToString(), col.ColumnName);
                col.ColumnName = "column" + counter.ToString();
                counter++;
            }
            //format the report definition xml
            byte[] reportDefinitionBytes = Encoding.UTF8.GetBytes(ConfigurXMLReport(ReportPath, "CustomReportDs", columns).OuterXml);
            //load the formatted report into the reportviewer
            MemoryStream stream = new MemoryStream(reportDefinitionBytes);
            ReportViewer1.LocalReport.LoadReportDefinition(stream);
            //bind and display the data as normal
            ReportDataSource source = new ReportDataSource("DataSet1", data);
            ReportViewer1.LocalReport.DataSources.Clear();
            ReportViewer1.LocalReport.DataSources.Add(source);
            ReportViewer1.DataBind();
            ReportViewer1.LocalReport.Refresh();

最后,我有这样的方法,这是被别人说我我对这个问题

Finally I have this method, which is a modified version of several methods written by others that I found during my research on the problem

public static XmlDocument ConfigurXMLReport(string path, Dictionary<string, string> Columns)
    {
        XmlDocument objXmlDocument = new XmlDocument();
        objXmlDocument.Load(path);
        XmlNamespaceManager mgr = new XmlNamespaceManager(objXmlDocument.NameTable);
        string uri = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
        mgr.AddNamespace("df", uri);

        //locate and create nodes for cloning and modification
        XmlNode tablixCols = objXmlDocument.SelectSingleNode("/df:Report/df:Body/df:ReportItems/df:Tablix/df:TablixBody/df:TablixColumns", mgr);

        XmlNode dataField = objXmlDocument.SelectSingleNode("/df:Report/df:DataSets/df:DataSet/df:Fields/df:Field", mgr);

        XmlNode tablixMember = objXmlDocument.SelectSingleNode("/df:Report/df:Body/df:ReportItems/df:Tablix/df:TablixColumnHierarchy/df:TablixMembers/df:TablixMember", mgr);

        XmlNode rowHeaders = objXmlDocument.SelectSingleNode("/df:Report/df:Body/df:ReportItems/df:Tablix/df:TablixBody/df:TablixRows/df:TablixRow", mgr);
        XmlNode rowValues = rowHeaders.NextSibling.SelectSingleNode("./df:TablixCells", mgr);
        rowHeaders = rowHeaders.SelectSingleNode("./df:TablixCells", mgr);

        XmlNode sampleCol = tablixCols.SelectSingleNode("./df:TablixColumn", mgr);
        XmlNode sampleHeader = rowHeaders.SelectSingleNode("./df:TablixCell", mgr);
        XmlNode sampleValue = rowValues.SelectSingleNode("./df:TablixCell", mgr);
        //Iterate through the column definitions and add nodes to the xml to support the columns
        foreach (KeyValuePair<string,string> column in Columns)
        {
            //clone the sample nodes into new nodes
            XmlNode newDataField = dataField.CloneNode(true);
            newDataField.SelectSingleNode("./df:DataField", mgr).InnerText = column.Key;
            newDataField.Attributes["Name"].Value = column.Key;
            dataField.ParentNode.AppendChild(newDataField);

            XmlNode newCol = sampleCol.CloneNode(true);
            XmlNode newHeader = sampleHeader.CloneNode(true);
            XmlNode newValue = sampleValue.CloneNode(true);

            //update the new nodes with the column data
            newHeader.SelectSingleNode("./df:CellContents/df:Textbox", mgr).Attributes["Name"].Value = "Header" + column.Key;
            newValue.SelectSingleNode("./df:CellContents/df:Textbox", mgr).Attributes["Name"].Value = "Value" + column.Key;

            //because I use friendly column names - modify the report output to use the friendly name as the display value
            newHeader.SelectSingleNode("./df:CellContents/df:Textbox/df:Paragraphs/df:Paragraph/df:TextRuns/df:TextRun/df:Value", mgr).InnerText = column.Value;
            newValue.SelectSingleNode("./df:CellContents/df:Textbox/df:Paragraphs/df:Paragraph/df:TextRuns/df:TextRun/df:Value", mgr).InnerText = string.Format("=Fields!{0}.Value", column.Key);

            //add the new nodes to the document
            tablixCols.AppendChild(newCol);
            rowHeaders.AppendChild(newHeader);
            rowValues.AppendChild(newValue);

            tablixMember.ParentNode.AppendChild(tablixMember.CloneNode(true));
        }

        //remove the nodes used for cloning
        objXmlDocument.SelectSingleNode("/df:Report/df:DataSets/df:DataSet/df:Fields", mgr).RemoveChild(dataField);
        objXmlDocument.SelectSingleNode("/df:Report/df:Body/df:ReportItems/df:Tablix/df:TablixColumnHierarchy/df:TablixMembers", mgr).RemoveChild(tablixMember);
        tablixCols.RemoveChild(sampleCol);
        rowHeaders.RemoveChild(sampleHeader);
        rowValues.RemoveChild(sampleValue);
        //return the completed report definition
        return objXmlDocument;
    }

非常感谢<一个href=\"http://dobrzanski.net/2009/02/06/how-to-dynamically-add-new-columns-to-report-created-with-reporting-services/\"相对=nofollow>获取我这个文章指出了正确的方向。

Many thanks to this article for getting me pointed in the right direction.

这篇关于不能的ReportViewer aspx.net显示数据表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆