Если перед Вами стоит задача — создавать простенькие (или не совсем) pdf документы в вашем приложении — это могут быть и отчеты и рецепты, ну либо вы захотите печатать так информацию о ваших объектах, то для решения этой задачи можно воспользоваться, к примеру, установленным OpenOffice и его возможностями (это тяжеловестно), а можно библиотекой iTextSharp (Free C#-PDF library), вот про это я и хочу поведать небольшой пример, при помощи которого я создам такой вот документ:

Способов создания pdf документов при помощи данной библиотеки множество. Мне больше всего понравился способ описания при помощи xml документа. Создавать такой xml я решил xslt преобразованием, а данные подсовывать xml-документом.
Наши данные будут выглядить вот так:
Следующий шаг: описываем весь код, который будет возвращать нам массив байт нашего pdf документа, комментариями я попытался описать всю последовательность действий:
Еще очень сильно интересует, почему они классы иногда называют с буквы I, в c# так называют интерфейсы. Конечно, я понимаю, что библиотека портирована с java, но все же — меня это ввело сначала в ступор...
Последнее это вывод pdf документа в Responce страницы (если у вас ASP.NET приложение как у меня)
Ссылки по теме:

Способов создания pdf документов при помощи данной библиотеки множество. Мне больше всего понравился способ описания при помощи xml документа. Создавать такой xml я решил xslt преобразованием, а данные подсовывать xml-документом.
Наши данные будут выглядить вот так:
Далее нам необходимо создавать xml для pdf (скажу что ссылка на iText.dtd схему в документе tutorial битая, верную ссылку я привожу внизу), как я и сказал выше для этого мы напишем xslt преобразование:<?xml version="1.0" encoding="utf-8" ?>
<Profile>
<FirstName>Иван</FirstName>
<SecondName>Иванович</SecondName>
<LastName>Иванов</LastName>
<Subtexts>
<Text>Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст. Какой то непонятный текст.</Text>
</Subtexts>
<Subtexts>
<Text>Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст. Другой непонятный текст.</Text>
</Subtexts>
</Profile>
* This source code was highlighted with Source Code Highlighter.
По мне так схему описания они выбрали не самую удачную, уж слишком получается громозкий код для небольшого pdf документа. Так, очень не привычно, описывать цвета red green и blue отдельно друг от друга, уж можно было бы их сделать в HEX записи. Как видно в xslt схеме — в документе есть параметр, который указывает на путь картинки, которая вставится в наш pdf документ, так же там описывается при помощи схемы таблица, состоящая из 3х столбцов и пару параграфов.<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:param name="picturePath"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Profile">
<itext>
<paragraph align="Center">
<phrase fontstyle="bold" size="16.0" >Информация о пользователе</phrase>
</paragraph>
<image >
<xsl:attribute name="url">
<xsl:value-of select="$picturePath"/>
</xsl:attribute>
</image>
<table width="100%" columns="3" cellpadding="1" cellspacing="1" borderwidth="0.5" red="0"
green="0" blue="0" left="true" right="true" top="true" bottom="true" widths="33;33;33">
<row >
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="true" top="false" bottom="true" header="true" horizontalalign="Center">
<phrase size="10.0" >Фамилия</phrase>
</cell>
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="true" top="false" bottom="true" header="true" horizontalalign="Center">
<phrase size="10.0" >Имя</phrase>
</cell>
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="false" top="false" bottom="true" header="true" horizontalalign="Center">
<phrase size="10.0" >Отчество</phrase>
</cell>
</row>
<row >
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="true" top="false" bottom="false" header="false" horizontalalign="Left">
<phrase size="10.0" >
<xsl:value-of select="FirstName"/>
</phrase>
</cell>
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="true" top="false" bottom="false" header="false" horizontalalign="Left">
<phrase size="10.0" >
<xsl:value-of select="SecondName"/>
</phrase>
</cell>
<cell borderwidth="0.5" red="0" green="0" blue="0" left="false"
right="false" top="false" bottom="false" header="false" horizontalalign="Left">
<phrase size="10.0" >
<xsl:value-of select="LastName"/>
</phrase>
</cell>
</row>
</table>
<xsl:apply-templates select="Subtexts"/>
</itext>
</xsl:template>
<xsl:template match="Subtexts">
<paragraph align="Justify">
<phrase size="14.0" >
<xsl:value-of select="Text"/>
</phrase>
</paragraph>
<newline/>
</xsl:template>
</xsl:stylesheet>
* This source code was highlighted with Source Code Highlighter.
Следующий шаг: описываем весь код, который будет возвращать нам массив байт нашего pdf документа, комментариями я попытался описать всю последовательность действий:
Хочу обратить внимание на определение baseFont и установки его в качестве деволтного шрифта для ITextHandler. Если данную процедуру не выполнить, тогда кирилика отображаться не будет. Данный подход позволяет отображать кириллику, но не дает нам возможности использовать несколько шрифтов в одному документе. В их коде (благо есть исходный код) они всегда берут codepage 1252 (прямо жестко зашито в код), потому, если вам необходимо будет использовать несколько шрифтов в одном документе, тогда исправляйте код и собирайте сами библиотеку, либо не используйте xml в качестве исходника данных (но не факт что проблема только в ITextHandler).public byte[] GetPdfRaw()
{
XmlDocument doc = new XmlDocument();
//Загружаем данные их xml файла
doc.Load(MapPath(@"~\Resources\UserProfile.xml"));
XslCompiledTransform xslTransform = new XslCompiledTransform();
//Загружаем схему XSLT преобразований
xslTransform.Load(MapPath(@"~\Resources\ReportProcessor.xslt"));
XsltArgumentList list = new XsltArgumentList();
//Записываем в параметры схемы путь до картинки
list.AddParam("picturePath", string.Empty, MapPath(@"~\Resources\Toco.jpg"));
//Создаем поток в памяти, куда будет писаться наша xml схема для pdf документа
using (MemoryStream stream = new MemoryStream())
{
//Создаем xml схему нашего pdf документа
xslTransform.Transform(doc, list, stream);
//Основной Font для pdf документа
BaseFont baseFont = BaseFont.CreateFont(Environment.ExpandEnvironmentVariables(@"%systemroot%\fonts\Tahoma.TTF"),
"CP1251", BaseFont.EMBEDDED);
//Создаем PDF документ
Document document = new Document();
using (MemoryStream pdfStream = new MemoryStream())
{
PdfWriter.GetInstance(document, pdfStream);
XmlDocument d = new XmlDocument();
string str = Encoding.UTF8.GetString(stream.ToArray()).Substring(1);
d.LoadXml(str);
//Определяем преобразователь из xml в pdf
ITextHandler h = new ITextHandler(document) {DefaultFont = baseFont};
h.Parse(d);
//Возвращаем полученный pdf файл в формате byte[]
return pdfStream.ToArray();
}
}
}
* This source code was highlighted with Source Code Highlighter.
Еще очень сильно интересует, почему они классы иногда называют с буквы I, в c# так называют интерфейсы. Конечно, я понимаю, что библиотека портирована с java, но все же — меня это ввело сначала в ступор...
Последнее это вывод pdf документа в Responce страницы (если у вас ASP.NET приложение как у меня)
Скачать пример... (для работы примера необходимо так же скачать библиотеку itextsharp, пример использует версию 4.1.2.0)protected override void OnLoad(EventArgs e)
{
//Записываем в Response pdf файл, указываем его MIME тип и имя файла
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", "report.pdf"));
byte[] pdfRaw = GetPdfRaw();
HttpContext.Current.Response.OutputStream.Write(pdfRaw, 0, pdfRaw.Length);
}
* This source code was highlighted with Source Code Highlighter
Ссылки по теме:
- iTextSharp на SourceForge
- iTextSharp Tutorial
- iText.dtd (xml схема)