如何从RDL文件中获取数据集?

时间:2010-04-12 19:08:12

标签: c# .net reporting business-intelligence rdl

我有一个RDL报告文件,我想以某种方式“运行”报告并获取用于填充报告的数据集。我想要做的是从用于填充报告的数据中获取原始数据提取,而不实际向用户显示报告。这可能吗?

3 个答案:

答案 0 :(得分:3)

如果我明白你想做什么,那么是的,这是可能的,但这有点痛苦。我为Report Builder 2.0报告的各种快照(在Report Manager中采用)做了这个。

如果您使用报表服务器的内置Web服务,则可以以编程方式生成报表。有关示例代码,请参阅ReportExecutionService.Render Method(请注意,即使使用SQL Server 2008,我也使用ReportExecution2005 Web服务)。您可以将报表呈现为各种格式,如XML,MHTML或PDF,然后尝试从中提取数据。您应该将您关注的数据表添加到报表中,通过将其“可见性”更改为“隐藏”来隐藏表,但将其DataElementOutput属性设置为“输出”,以便在呈现报表时,将包含该表。给表格一些独特的名称(例如,将'Tablix1'替换为'FlatData')。然后,您可以将报表呈现为XML格式,并使用XSLT仅提取该表中的行。以下是我之前用于从呈现的Report Builder 2.0报告中提取数据的一些XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="utf-8"/>
  <xsl:variable name="reportID" select="*[local-name()='Report']/@Name"/>

  <!-- Uppercase and lowercase alphabets for case-insensitive string comparisons -->
  <xsl:variable name="up" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:variable name="lo" select="'abcdefghijklmnopqrstuvwxyz'"/>

  <xsl:template match="/">
    <xsl:element name="ContainerElementOfMyData">
      <xsl:attribute name="ReportID">
        <xsl:value-of select="$reportID"/>
      </xsl:attribute>

      <xsl:for-each select="*[local-name()='Report']/*[local-name()='FlatData']">
        <!-- If the FlatData node has attributes on its tag, insert all of those
             attributes in a single node -->
        <xsl:if test="count(@*) &gt; 0">
          <MyNode>
            <xsl:for-each select="@*">
              <xsl:variable name="parentAttrName" select="name(.)"/>
              <xsl:element name="{$parentAttrName}">
                <xsl:value-of select="."/>
              </xsl:element>
            </xsl:for-each>
          </MyNode>
        </xsl:if>

        <!-- Go through each tag in FlatData that starts with 'Details' -->
        <xsl:for-each select="//*[substring(local-name(), 1, 7)='Details']">
          <xsl:if test="count(@*) &gt; 0">
            <MyNode>
              <!-- For each attribute of the Details tag: -->
              <xsl:for-each select="@*">
                <xsl:variable name="attrName" select="name(.)"/>
                <xsl:variable name="lowerAttrName" select="translate($attrName,$up,$lo)"/>
                <xsl:variable name="attrValue" select="."/>

                <!-- Write the attribute name as its own tag -->
                <xsl:element name="{$attrName}">
                  <xsl:choose>
                    <xsl:when test="$attrValue = ''">
                      <!-- Do nothing because no value to output and we don't want empty CDATA tags -->
                    </xsl:when>

                    <!-- When field might have HTML tags, we want to wrap it in CDATA tags: -->
                    <xsl:when test="$lowerAttrName = 'my_first_text_field' or $lowerAttrName = 'my_other_text_field'">
                      <xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
                      <xsl:value-of select="$attrValue"/>
                      <xsl:text disable-output-escaping="yes">]]</xsl:text>
                      <xsl:text disable-output-escaping="yes">></xsl:text>
                    </xsl:when>

                    <!-- When field will not have HTML tags, just output its value as normal -->
                    <xsl:otherwise>
                      <xsl:value-of select="$attrValue"/>
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:element>
              </xsl:for-each>
            </MyNode>
          </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:element><!--End of ContainerElementOfMyData-->
  </xsl:template>
</xsl:stylesheet>

请注意,此XSLT取决于您将报表中隐藏的数据表命名为“FlatData”。如果您知道报告中的某些数据将包含HTML标记或其他不是有效XML的数据(如果放在两个XML标记之间),请更改上面的XSLT以将该数据包装在CDATA标记中(例如,替换{{1}使用字段名称,其值将需要CDATA标记)。

将此XSLT应用于呈现的XML版本的报告将生成更多XML,这次只包含您关注的报告中的数据。仅使用报告的呈现XML版本的问题在于它包含所有图表,外观信息等,而不仅仅是您的数据。尝试以XML格式呈现您的一个报告并查看源代码;它有各种你可能不想要的疯狂。

对于将XSLT转换应用于XML的命令行工具,我建议xalan。以下是一个示例用法:

my_first_text_field

生成的transformed.xml将具有如下格式:

PS C:\Program Files\xalan-j_2_7_0> java org.apache.xalan.xslt.Process -IN rdl_rendered_to_xml.xml -XSL xsl_shown_above.xsl -OUT transformed.xml

答案 1 :(得分:1)

正如Sarah Vessels在她的回答中已经提到的那样你可以推送报表服务器来呈现数据, 在许多格式中,也许EXCEL是不错的选择取决于您的报告设计的复杂性。 I asked similar qestion在许多托盘之后我最终在Mssql中使用了#TempTaples,在报告出现之前已经报错了,看起来我认为报表服务器是作业处理的最后一个实例,所有数据和存储应该在后端完成渲染报告

答案 2 :(得分:0)

这是一个有趣的问题。当我必须解决它(对于rdl文件的单元测试)时,我编写了一个简单的xml解析器,它将从rdl文件中提取sql语句并执行它。这很简单,但如果你的语句有很多参数,当然会变得更复杂。但是,参数信息也可以在文件中使用,因此您应该能够编写通用解决方案(但您当然需要为参数提供值)。