我有一个RDL报告文件,我想以某种方式“运行”报告并获取用于填充报告的数据集。我想要做的是从用于填充报告的数据中获取原始数据提取,而不实际向用户显示报告。这可能吗?
答案 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(@*) > 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(@*) > 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语句并执行它。这很简单,但如果你的语句有很多参数,当然会变得更复杂。但是,参数信息也可以在文件中使用,因此您应该能够编写通用解决方案(但您当然需要为参数提供值)。