Pull to refresh

Выводим отчеты в формате DocX

Не так давно, в нашей программе потребовалось сделать отчет, который представлял из себя некий договор на n-листах в формате doc. Программа пишется на .NET, отчеты делаем на StimulSoft Reports.Net. Сложность была еще и в том, что пользователям программы необходимо было дать возможность править шаблон отчета. В Stimulsoft Reports.NET есть дизайнер шаблона, но, согласитесь, он не очень подходит для рядового пользователя программы.
После нескольких попыток корректно переложить шаблон отчета, было принято решение оставить этот шаблон в word-формате. Как у нас это получилось читайте ниже.

P.S. Чтобы было понятней и наглядней, я создал маленький тестовый проект, который вы можете скачать в конце этого топика.


Составление XSD-схемы

В нашем примере будем работать со следующей схемой:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="BulletinOfClosedVoting"
targetNamespace="http://test.ru/test.xsd"
elementFormDefault="qualified"
xmlns="http://test.ru/test.xsd"
xmlns:mstns="http://test.ru/test.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="TestDocxReport">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="xs:string" />
<xs:element name="PatrName" type="xs:string" />
<xs:element name="Age" type="xs:int" />
<xs:element name="BirthDate" type="xs:date" />
<xs:element name="Books">
<xs:complexType>
<xs:sequence>
<xs:element name="Book" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Author" type="xs:string" minOccurs="0" />
<xs:element name="ToDate" type="xs:date" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>


Создание DocX шаблона

Открываем новый документ Microsoft Word (от 2007 и выше, нужна возможность сохранять документ в формате docx). Печатаем некий документ, который мы хотим увидеть на выходе (можно с тестовыми данными).
У меня получился вот такой документ:
image

Теперь необходимо привязать созданную ранее схему к нашему документу. Для этого необходимо во вкладке «Разработчик» зайти в «Схемы» и добавить нашу созданную схему. В окне выбора псевдонима для схемы напишите название схемы, к примеру test. После чего справа должна открыться вкладка с выбором элементов из схемы.
image
Если у вас не видна вкладка «Разработчик» инструкция по ее отображению:

Осталось раскидать наши элементы по документу. У меня получилось следующее:
image

Немного комментариев по расположению элементов. Как вы видите на рисунке, есть 2 типа блоков:
— сиреневые не закрашенные (сложные элементы)
— сиреневые закрашенные (элементы-поля). В этих элементах как раз и будет выводиться текст из xml данных. Иногда Word будет выставлять вам эти поля сиреневыми не закрашенными. Чтобы преобразовать их, необходимо перед элементам поставить любой символ и затем стереть его.

Сохраняем наш файл в формате word document 2007 (с расширением docx).

Запускаем отчет с xml данными

Теперь запускаем Visual Studio, будем вызывать наш отчет с отправкой в него xml данных. Подсоединяем в проект наш небольшой класс для работы с DocX отчетами и добавляем Reference DocumentFormat.OpenXml (необходимо поставить OpenXMLSDKv2).

Добавим пару кнопок на форму. Первая будет просто открывать файл docx для правки шаблона:
DocxReports.ShowTemplate("Reports/TestReport/test.docx");


Вторая будет открывать файл docx с нашими xml данными:

const string xml = @"
Петров
Петр
Петрович
40
30.01.1962
Дело Артамоновых
Горький М.
04.05.2011

Битва железных канцлеров
Пикуль В.
08.05.2011


";

DocxReports.Show("Reports/TestReport/test.docx", xml);


Все запускаем, тестируем. Нажимаем кнопку «открыть шаблон», открывается word документ с нашим шаблоном. Вносим изменения, сохраняем. Запускаем «отчет с данными» и любуемся изменениями, сохраненными в шаблоне.

Логика работы класса

Класс DocxReports не включает в себя ничего сложно, выполняет по сути рекурсивную замену XmlBlock-ов в шаблоне данными из xml.

P.S Конечно у данного подхода есть минусы:
  • У пользователя на компьютере обязательно должен стоять Word или OpenOffice, поддерживающий формат docx
  • отчет используется только для подстановки данных, т.е произвести какие-либо вычисления в самом отчете не получится, придется подсчитывать в самой программе и отправлять в отчет уже готовое значение


Спасибо за внимание, буду рад выслушать критику, рекомендации. Исходники проекта
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.