PDFsharp and MigraDoc Foundation (Основы)

в 14:44, , рубрики: .net, PDF, PDFSharp, метки: ,

Так как статья, из-за которой я получил инвайт куда-то пропала, хочу опубликовать ее снова.

Ввиду небольшого количества бесплатных библиотек для работы с PDF в .Net а также недостаточного освещения их на русском языке хочу рассказать о работе с такой замечательной библиотекой как PDFsharp and MigradDoc

Пожалуй начнем с самого начала — исходники можно скачать здесь или здесь
Теперь добавим ссылки в свой проект:

using MigraDoc;
using PdfSharp;

using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
using PdfSharp.Pdf;

Создаем новый документ

Document document = new Document();

Каждый документ MigraDoc состоит из независимых секций, которые могут иметь свой формат.
Создание секции:

Section section = document.AddSection();

после такой инициализации, работая с section — мы работаем с частью документа document.
Секции имеет функции для работы с информацией, такие как Add,AddParagraph(), AddImage(),AddTable() и т.д., а также класс для изменения формата самой секции PageSetup.
Изменение формата:

section.PageSetup.PageFormat = PageFormat.А5;//стандартный размер страницы
section.PageSetup.Orientation = Orientation.Portrait;//ориентация
section.PageSetup.BottomMargin = 10;//нижний отступ
section.PageSetup.TopMargin = 10;//верхний отступ

Добавление информации происходит либо с помощью Add(Param), где Param — параграф(Paragraph), рисунок(Image), таблица(Table), график(Chart) или текстовая рамка(TextFrame)

Paragraph paragraph =new Paragraph();
section.Add(paragraph);

либо по примеру добавления секции

Paragraph paragraph = section.AddParagraph();

При чем для каждого параграфа также возможно установить индивидуальный формат (класс Format) и стиль (класс Style):

paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);

К каждому параграфу можно добавить информацию:

Text text = new Text("text");
paragraph.AddText("text");//текст
paragraph.AddFormattedText("formatted text", styleName);// форматированный текст
paragraph.Add(text);//добавление любого из перечисленых ниже
paragraph.AddBookmark("Bookmark");//закладка
paragraph.AddChar('c');//символ
paragraph.AddDateField("10.10.2010");//дата
paragraph.AddFootnote("Footnote");//нижняя подпись
//и еще много чего

Основу мы собрали, теперь осталось превратить ее в полноценный PDF документ, для чего используется PdfDocumentRenderer:

pdfRenderer = new PdfDocumentRenderer(true, PdfFontEmbedding.Always);
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save(filePath);// сохраняем

Возможно понадобится использовать в документе шрифты не установленные по умолчанию в ОС, например DejaVuSansMono.ttf. Это можно сделать так, предварительно поместив файл вышеуказанного шрифта в туже папку где и исполняемы файл:

Uri uri = new Uri(@"file://" + System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"DejaVuSansMono.ttf");
XPrivateFontCollection pfc = XPrivateFontCollection.Global;
try
{
      pfc.Add(uri, "./#DejaVu Sans Mono");
}
catch (Exception)
{}
pdfRenderer.DocumentRenderer.PrivateFonts = pfc;

Если нужно вывести созданный документ в своем приложение, нам поможет MigraDoc.Rendering.Windows.DocumentPreview — контрол для вывода созданных в MigraDoc документов. Вначале нужно поместить его на форму или WPF-окно, после чего использовать такой код:

Document doc = new Document();
doc = oDocument.Clone();
preview.Ddl = DdlWriter.WriteToString(doc);

Возможность выводить уже созданные PDF-документы к сожалению отстутсвует.
Рекомендую обратить внимание на функцию Clone(), которая важна при присваивании любых объектов MigraDoc(документов, секций, параграфов и т.д.), если ее не использовать то при изменении первого объекта будет изменятся и тот, который первому присвоили.
Для печати MigraDoc документов можно использовать MigraDocPrintDocument:

MigraDocPrintDocument migraDocPrint = new MigraDocPrintDocument(preview.Renderer);
migraDocPrint.Print();

Но замечена такая проблема, что данный способ не работает при печати через сервер, печать через локальный принтер нормальна.
Поэтому как вариант можно использовать для печати Foxit Reader:

pdfDocumentRenderer.PdfDocument.Save(@"temp.pdf");
Process.Start(@"ResourcesFoxit Reader.exe", @"/p temp.pdf"); 

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

Автор: Rubka


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js