Как я могу получить набор данных для заполнения из файла RDL? - PullRequest
4 голосов
/ 12 апреля 2010

У меня есть файл отчета RDL, и я хотел бы как-то «запустить» отчет и получить набор данных, который будет использоваться для заполнения отчета. То, что я пытаюсь сделать, - это извлечь необработанные данные из данных, которые будут использоваться для заполнения отчета, фактически не показывая отчет пользователю. Возможно ли это?

Ответы [ 3 ]

3 голосов
/ 13 апреля 2010

Если я понимаю, что вы хотите сделать, тогда да, это возможно, но это отчасти боль. Я сделал это для различных снимков (как в диспетчере отчетов) отчетов построителя отчетов 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(@*) &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

Полученный файл 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>
1 голос
/ 13 апреля 2010

Как уже упоминала Сара Вессель в своем ответе, вы можете использовать сервер отчетов для отображения данных, во многих форматах, возможно, EXCEL - неплохой выбор, зависит от сложности вашего отчета. Я задал аналогичный вопрос , и после многих лотков я получил #TempTaples в Mssql, который переделывается до повторной отправки отчета. Мне кажется, что сервер отчетов является последним экземпляром обработки задания, и все данные и хранилище быть сделано в бэкэнд рендеринга отчетов

0 голосов
/ 13 апреля 2010

Это интересная проблема. Когда мне пришлось ее решить (для модульного тестирования файлов rdl), я написал простой синтаксический анализатор xml, который извлекал бы оператор sql из файла rdl и выполнял его. Это довольно просто, но, конечно, усложняется, если в ваших утверждениях много параметров. Однако информация о параметрах также доступна в файле, так что вы должны иметь возможность кодировать общее решение (но вам, конечно же, нужно предоставить значения для параметров).

...