如果我明白你想做什么,那么是的,这是可能的,但这是一种痛苦。我对报表生成器2.0报表的各种快照(如在报表管理器中拍摄的)执行了此操作。
如果使用报表服务器的内置web服务,则可以通过编程方式生成报表。见
ReportExecutionService.Render Method
对于一些示例代码(请注意,我甚至在使用SQL Server 2008时也使用ReportExecution2005 web服务)。您可以将报表呈现为多种格式,如XML、MHTML或PDF,然后尝试从中提取数据。您应该向报表中添加所关心的数据表,通过将其可见性更改为hide来隐藏该表,但将其DataElementOutput属性设置为Output,以便在呈现报表时包含该表。为表指定一些独特的名称(例如,将“Tablix1”替换为“FlatData”)。然后,可以将报表呈现为XML格式,并使用XSLT只提取该表中的行。以下是我以前使用过的一些XSLT,用于从呈现的报表生成器2.0报表中提取数据:
<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标记中(例如,替换
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>