4

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

4

3 回答 3

3

如果我了解您想要做什么,那么是的,这是可能的,但这有点痛苦。我为 Report Builder 2.0 报表的各种快照(在报表管理器中拍摄)执行此操作。

如果您使用报表服务器的内置 Web 服务,则可以以编程方式生成报表。请参阅ReportExecutionService.Render 方法对于一些示例代码(请注意,即使使用 SQL Server 2008,我也使用 ReportExecution2005 Web 服务)。您可以将报表呈现为各种格式,例如 XML、MHTML 或 PDF,然后尝试从中提取数据。您应该将您关心的数据表添加到报表中,通过将其 Visibility 更改为 Hide 来隐藏该表,但将其 DataElementOutput 属性设置为 Output 以便无论何时呈现报表,都会包含该表。给表格一些独特的名称(例如,将“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 标记中(例如,替换my_first_text_field为字段名称其值将需要 CDATA 标记)。

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

对于将 XSLT 转换应用于 XML 的命令行工具,我推荐xalan。这是一个示例用法:

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

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

<?xml version="1.0" encoding="utf-8"?>
<ContainerElementOfMyData ReportID="MyReportName">
<MyNode>
<Key1>Value 1</Key1>
<Key2>Second value of your data</Key2>
</MyNode>
</ContainerElementOfMyData>
于 2010-04-12T20:03:00.293 回答
1

正如 Sarah Vessels 在她的回答中已经提到的那样,您可以推送报表服务器以多种格式呈现数据,也许 EXCEL 是不错的选择,这取决于您的报表设计的复杂性。 我问了类似的问题,经过许多托盘后,我最终在 Mssql 中使用了 #TempTaples,在报告被撕裂之前,它被疯狂了,在我看来,报告服务器是作业处理的最后一个实例,所有数据和存储都应该在后端完成呈现报告

于 2010-04-12T20:18:49.493 回答
0

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

于 2010-04-12T20:04:20.477 回答