Параметры форматирования xml или CSV для составления отчетов в текстовом формате или Word

#xml #excel #xslt #csv #transformation

#xml #excel #xslt #csv #преобразование

Вопрос:

Мы подписываемся на базу данных, которая позволяет нам экспортировать наши данные в формате csv, Excel или XML. У нас есть несколько отчетов, которые было бы гораздо лучше размещать по странице, а не поперек, и я пытаюсь разработать самый простой способ для наших нетехнических пользователей распечатать отчет, пригодный для собраний. Я подозреваю, что, возможно, я упускаю что-то очевидное!

например, csv, экспортируемый пользователем, будет иметь следующие заголовки:

 title, subtitle, about the project, launch date, key factors to consider, key market
  

При форматировании страницы Excel более длинный текст становится нечитаемым и плохо печатается. В идеале мы хотели бы:

 title
[title here]

subtitle
[subtitle here]

about the project
[paragraph of text here]

launch date
[date here]

key factors to consider
[paragraph or two here]

etc.
  

Все наши пользователи работают на Windows и не являются техническими. Я стремлюсь к одно- или двухэтапному процессу преобразования файлов после их экспорта. Вероятно, мы будем иметь дело с диапазоном от 1 до 100 строк данных для преобразования и примерно 15 полями.

В идеале пользователи могли бы изменять поля, экспортируемые из базы данных, и при этом преобразовывать их в формат tidy report.

Я рассмотрел (т. е. прочитал и кратко попробовал) следующие параметры и был бы признателен за рекомендации по всему, что я пропустил, или какой подход кажется мне лучшим для дальнейшего изучения. Во всех этих случаях они казались слишком сложными для распространения на пользователей и просто чрезмерно сложными для чего-то, что кажется таким простым.

  • Преобразование XML в Word (но, похоже, что кодирование XSLT имеет невероятно крутую кривую обучения)

  • Объединение почты в Word из csv — предоставление пользователям шаблона Word

  • Макросы в Excel для перемещения полей (не уверен, что это сработает для нескольких записей и будет легко печатать?)

  • Создайте инструмент в нашей интрасети для приема файла и предоставления страниц для печати. PHP или JavaScript?

Я искал решения для преобразования XML, XML в Word, Excel в Word, Excel в шаблон, CSV в шаблон и аналогичные.

Я надеюсь, что здесь я упускаю что-то очевидное и просто не смог придумать правильные условия поиска / простое решение. Если это так, я был бы очень признателен, если бы мне указали правильное направление. Спасибо!

Комментарии:

1. Предлагает ли ваша база данных возможность применения таблицы стилей XSLT к экспортируемому XML в рамках процесса экспорта? Или есть какой-либо другой способ автоматизировать это, чтобы это было прозрачно для ваших пользователей?

2. К сожалению, нет. В дополнение к перечисленным мной, он предлагает экспорт в HTML и PDF, но в обоих случаях форматирование похоже на CSV, поэтому печатается плохо. Можно заплатить за дополнительную доработку базы данных, чтобы запросить другой формат вывода, и это может быть путь, которым мы идем, если я не могу заставить простое преобразование работать. Спасибо.

3. Что ж, я боюсь, что это слишком расплывчато, чтобы дать конкретный ответ (и, как следствие, также сильно не по теме для SO). У меня сложилось впечатление, что чем ближе вы подходите к источнику, тем меньше у вас будет движущихся частей. Это означало бы либо (а) заставить базу данных выдать именно то, с чего вам нужно начать; или (б) добавить немедленное преобразование XSLT к выходному XML-файлу — возможно, этого можно достичь с помощью какого-либо промежуточного программного обеспечения для связи с базой данных или сценариев на уровне операционной системы, чтобы инициировать обработку экспортированного файла без вмешательства пользователя.

4. Возможно, вы можете опубликовать простой пример того, какой HTML выводит база данных. Я подозреваю, что это всего лишь простая таблица. Я думаю, было бы не слишком сложно создать XSLT, который «сводит» ячейки в комбинации заголовок / пункт.

Ответ №1:

Возможное вдохновение для вас. Учитывая, что вы говорите, что ваш HTML-вывод распространяется по всей странице, я бы предположил, что, возможно, это просто создание HTML-таблицы. Допустим, ваш простой HTML выглядит следующим образом:

 <html>
    <body>
        <table>
            <tr>
                <th>header1</th>
                <th>header2</th>
                <th>header3</th>
            </tr>
            <tr>
                <td>body text 1</td>
                <td>body text 2</td>
                <td>body text 3</td>
            </tr>
        </table>
    </body>
</html>
  

Тогда довольно простым преобразованием было бы следующее:

     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="html">
        <html>
            <xsl:apply-templates/>    
        </html>
    </xsl:template>
        <xsl:template match="body">
            <body>
                <xsl:apply-templates/>    
            </body>
        </xsl:template>
        <xsl:template match="table">
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match="tr[not(child::th)]">
            <xsl:apply-templates/>
        </xsl:template>
        <xsl:template match="tr"/>
        <xsl:template match="td">
            <!--Store and retrieve table headers into h1 elements -->
            <xsl:variable name="pos" select="count(preceding-sibling::td)   1"/>
            <xsl:variable name="headers" select="ancestor::table//th"/>
            <h1>
                <xsl:value-of select="$headers[$pos]"/>
            </h1>
            <p>
                <xsl:value-of select="."/>
            </p>
        </xsl:template>
        <xsl:template match="text()"/>
    </xsl:stylesheet>
  

Для получения этого:

 <html>
   <body>    
     <h1>header1</h1>
     <p>body text 1</p>             
     <h1>header2</h1>
     <p>body text 2</p>            
     <h1>header3</h1>
     <p>body text 3</p>
  </body>
</html>
  

Другим вариантом было бы прямо из CSV в HTML (или XSL FO). Я немного изменил отличный конвертер CSV в XML здесь:

http://andrewjwelch.com/code/xslt/csv/csv-to-xml_v2.html

Использование XSL 2.0 и CSV, подобного этому:

«заголовок 1», «заголовок 2», «заголовок 3»

«основной текст 1», «основной текст 2», «основной текст 3»

«2 основных текста 1», «2 основных текста 2», «2 основных текста 3»

Вы получаете это:

  <html>
 <body>
  <div>
     <h1>header1</h1>
     <p>body text 1</p>
     <h1>header2</h1>
     <p>body text 2</p>
     <h1>header3</h1>
     <p>body text 3</p>
  </div>
  <div>
     <h1>header1</h1>
     <p>2 body text 1</p>
     <h1>header2</h1>
     <p>2 body text 2</p>
     <h1>header3</h1>
     <p>2 body text 3</p>
  </div>
  </body>
  </html>
  

Простая модификация находится здесь:

     <xsl:template match="/" name="main">
        <xsl:choose>
            <xsl:when test="unparsed-text-available($pathToCSV)">
                <xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
                <xsl:variable name="lines" select="tokenize($csv, 'amp;#xa;')" as="xs:string "/>
                <xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string "/>
                <html>
                    <body>
                    <xsl:for-each select="$lines[position() > 1]">
                        <div>
                            <xsl:variable name="lineItems" select="fn:getTokens(.)" as="xs:string "/>

                            <xsl:for-each select="$elemNames">
                                <xsl:variable name="pos" select="position()"/>
                                <h1>
                                    <xsl:value-of select="."/>
                                </h1>
                                <p>
                                    <xsl:value-of select="$lineItems[$pos]"/>
                                </p>
                            </xsl:for-each>
                        </div>
                    </xsl:for-each>
                    </body>
                </html>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>Cannot locate : </xsl:text><xsl:value-of select="$pathToCSV"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
  

Комментарии:

1. Нам сказали, что база данных может выводить XML, поэтому совершенно непонятно, почему вы предпочли бы выбрать менее оптимальные форматы в качестве входных данных для XSLT. Кроме того, я полагаю, что проблема здесь заключается в том, как применить преобразование XSL, а не в том, каким должно быть фактическое преобразование.

2. Я пропустил, что база данных экспортировала XML. И, перечитывая это, я думаю, я пропустил всю суть вопроса. Без знания того, что такое DB и какие интерфейсы существуют и как пользователи хотели бы взаимодействовать, невозможно ответить на вопрос.

3. Следуя указаниям @KevinBrown, я продолжил изучение XSL. Это показалось довольно сложным для Word, когда я первоначально исследовал, но, похоже, можно использовать простой HTML-стиль и открыть документ в Word fine. Я создал простую таблицу стилей XSL, и мы тестируем пользователей, экспортирующих xml из базы данных, открывающих xml в Word 2010, а затем переходящих к документу XSL на общем диске для преобразования документа (Word запрашивает это при открытии файла XML). Это не очень терпимо к ошибкам пользователя, но я думаю, что для них это может быть достаточно просто.

4. Отлично. Вероятно, вы могли бы добавить пункт меню в Word с простым кодом VBA, который выполняет оба этих действия. Предлагает пользователю выбрать XML, а затем применяет преобразование.