Если я понимаю, что вы хотите сделать, тогда да, это возможно, но это отчасти боль. Я сделал это для различных снимков (как в диспетчере отчетов) отчетов построителя отчетов 2.0.
Вы можете программно генерировать отчет, если используете встроенные веб-службы сервера отчетов. См. ReportExecutionService.Render Method для примера кода (обратите внимание, что я использую веб-сервис ReportExecution2005 даже с SQL Server 2008). Вы можете отобразить отчет в различных форматах, таких как XML, MHTML или PDF, а затем попытаться извлечь данные из этого. Вы должны добавить таблицу данных, которые вам нужны, в отчет, скрыть таблицу, изменив ее видимость на Скрыть, но установите для свойства DataElementOutput значение Выход, чтобы при каждом отображении отчета таблица включалась. Дайте таблице какое-то отличительное имя (например, замените «Tablix1» на «FlatData»). Затем вы можете отобразить отчет в формате XML и использовать XSLT для извлечения только строк в этой таблице. Вот некоторый XSLT, который я использовал ранее для извлечения данных из обработанного отчета Report Builder 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
Полученный файл transmed.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>