Обзор C# библиотек для работы с PDF

    topic image
    На написание данной статьи меня подтолкнул топик HTML в PDF, правда по причине того, что он посвящен языку php, лично мне он был мало полезен, т.к. весь опыт работы с php у меня сводился в переводе нескольких скриптов на C#, поэтому я решил сделать небольшой обзор того, что доступно для работы с pdf по средствам языка C#.

    Ко мне в список попало 7 библиотек, о которых я скажу несколько слов, а для самой популярной (судя по ответам на stackoverflow), я напишу, как с помощью неё сделать простейший документ. Сразу скажу, что это iTextSharp и работа с ней будет описана в конце статьи.

    Обзор библиотек


    1. iTextSharp
    Библиотека iText позволяет создавать и манипулировать PDF документами. Она позволяет разработчикам совершенствовать веб и прикладные приложения с помощью динамической генерации и/или манипуляции над PDF документами.

    Разработчики могут использовать iText для:
    — Передачи PDF в браузер
    — Генерировать динамические документы из XML файлов или базы данных
    — Использовать много интерактивных возможностей PDF
    — Добавлять закладки, число страниц, водяные знаки и т.д.
    — Разделять, объединять и манипулировать PDF страницами
    — Автоматизация заполнения PDF форм
    — Добавлять цифровую подпись в PDF файл
    iText доступен для двух языков: Java и C#.

    2. Report.NET
    Report.NET – это мощная библиотека, которая поможет Вам сгенерировать PDF документы в простым и гибким способом. Документ может быть создан с помощью данных, которые были получены из любого ADO.NET data set.

    Возможности библиотеки:
    — Полностью написана на C# для Microsoft .NET framework
    — Очень компактный код (Hello World: 6 строк)
    — Поддерживает графические объекты: текст, линии, прямоугольники, изображения jpeg
    — Легкость выравнивания и трансформации графических объектов
    — ASP.NET может генерировать динамические PDF страницы
    — XML Documentation (Comment Web Pages)

    3. PDFsharp
    PDFsharp — это библиотека на C#, которая очень просто создаёт PDF документы на лету. Похоже на GDI+ рисование процедур, аналогично можно создавать PDF документы, рисовать на экране или отправлять на печать любого принтера. PDFsharp может изменять, объединять и разделять существующие PDF файлы или перемещать страницы из существующих PDF файлов в новые PDF документы.
    PDFsharp – это библиотека с открытым исходным кодом, которая легко создает PDF документы из любого .NET языка.

    4. SharpPDF
    SharpPDF — это C# библиотека, которая может создавать различные объекты в PDF документах за несколько шагов. Она создана для .NET framework 1.1 и может создавать 100% совместимые PDF файлы (протестировано с Acrobat Reader, Ghostscript, JAWS PDF Editor и другими PDF читалками). Самая важная цель библиотеки – это простое использование.

    Возможности библиотеки:
    — Можно использовать с Windows Forms для генерации новых pdf файлов или сохранить их в базу данных.
    — Можно использовать с Web Applications (ASP.NET) для генерации pdf файлов или сразу отправить результат в браузер.

    5. PDFjet Open Source Edition
    PDFjet — библиотека с открытым исходным кодом для динамического создания PDF документов из Java и .NET.

    Возможности библиотеки:
    Рисования: точки, линии, коробки, круги, кривые Безье, многоугольники, звезды, комплекс путей и форм.
    Текст: поддержка юникода, кернинг текста при использовании Helvetica и Times-Roman семейств основных шрифтов, вставка гиперссылок, просто использовать табличный класс с гибкостью отчетных возможностей.
    Поддерживает вставку следующих типов изображений: PNG, JPEG, BMP

    6. ASP.NET FO PDF
    FO PDF похожа на ASP.NET Server Controls, написана на C#. Она получает DataTable и несколько других параметров для генерации XSL FO и рендерит DataGrid как PDF отчёт используя NFOP (Apache FOP Port in J#) PDF Formatter.

    7. PDF Clown
    PDF Clown – это C# 2.0 библиотека для чтения, обработки и записи файлов PDF с несколькими слоями абстракции, чтобы удовлетворить различные стили программирования: от нижнего уровня (PDF Object Model), до высшего (PDF структуры документа и потокового содержания). Его основная целевая платформа является GNU / Linux, но благодаря проекту Mono она практически платформа-независимая.

    Быстрый старт с помощью iTextSharp


    Как я уже писал ранее, данная библиотека была выбрана не из-за того, что я протестировал все описанные и выбрал её, а по причине того, что на неё чаще всего ссылаются и советуют. Итак, переходим на сайт проекта, видим, что можно купить книжку, а также скачать файлы:
    Желания что-то собирать самому, у меня нет, поэтому качаю не исходные коды, а сразу библиотеку itextsharp-5.0.5-dll.zip. С одной библиотекой быстрого старта не выйдет, поэтому качаем примеры iTextSharp.tutorial.01.zip. Открыв архив примеров, я понял, что старт будет гораздо быстрее, чем я думал, т.к. там есть целых 13 глав примеров. Сразу подумал, что на этом можно закончить, но всё же решил сделать небольшое приложение.

    Распишу по шагам, что нужно для использования библиотеки:
    — Я создаю WinForms приложение.
    — Добавляю ссылку на itextsharp.dll.
    — Устанавливаю кнопку на форму и добавляю следующий код в обработчик нажатия:
    var doc = new Document();
    PdfWriter.GetInstance(doc, new FileStream(Application.StartupPath + @"\Document.pdf", FileMode.Create));
    doc.Open();
    iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/images.jpg");
    jpg.Alignment = Element.ALIGN_CENTER;
    doc.Add(jpg);
    PdfPTable table = new PdfPTable(3);
    PdfPCell cell = new PdfPCell(new Phrase("Simple table",
      new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 16,
      iTextSharp.text.Font.NORMAL, new BaseColor(Color.Orange))));
    cell.BackgroundColor = new BaseColor(Color.Wheat);
    cell.Padding = 5;
    cell.Colspan = 3;
    cell.HorizontalAlignment = Element.ALIGN_CENTER;
    table.AddCell(cell);
    table.AddCell("Col 1 Row 1");
    table.AddCell("Col 2 Row 1");
    table.AddCell("Col 3 Row 1");
    table.AddCell("Col 1 Row 2");
    table.AddCell("Col 2 Row 2");
    table.AddCell("Col 3 Row 2");
    jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/left.jpg");
    cell = new PdfPCell(jpg);
    cell.Padding = 5;
    cell.HorizontalAlignment = PdfPCell.ALIGN_LEFT;
    table.AddCell(cell);
    cell = new PdfPCell(new Phrase("Col 2 Row 3"));
    cell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE;
    cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
    table.AddCell(cell);
    jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/right.jpg");
    cell = new PdfPCell(jpg);
    cell.Padding = 5;
    cell.HorizontalAlignment = PdfPCell.ALIGN_RIGHT;
    table.AddCell(cell);
    doc.Add(table);
    doc.Close();


    * This source code was highlighted with Source Code Highlighter.

    Результат работы данного кода:
    example

    Выводы


    По каждой из приведенных библиотек в интернете можно найти уйму информации (начинать рекомендую с сайтов разработчиков), готовя данную подборку библиотек, я встречал разные мнения, хоть все библиотеки, казалось бы, предназначены для работы с pdf, но возможности у них разные, всё зависит от Ваших потребностей. Честно скажу, что все из них я не использовал, я лишь попробовал несколько из них и остановился на iTextSharp.

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

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

      +2
      В закладки однозначно, спасибо
        0
        для HorizontalAlignment в iText есть Element.ALIGN_LEFT, Element.ALIGN_CENTER, Element.ALIGN_RIGHT, у них в api об этом тоже написано
          0
          Спасибо, очень полезная статья! Отличная подборка библиотек, в общем-то сразу видно возможности.
            0
            Спасибо за работу, отличная подборка ссылок.
              0
              Не указано какая из библиотек умеет работать с HTML.
              Опыт показывает, что в этом вопросе — ни все библиотеки одинаково полезны.

              На практике проще/удобнее/быстрее формировать HTML-разметку (в том числе и сложную), а не через объекты библиотеки table.AddCell(«Col 1 Row 1»);
                0
                К сожалению, я физически не могу описать полностью работу всех библиотек, поэтому надеюсь на помощь в комментариях, где люди будут делится своим опытом использования той или иной библиотеки, т.к. в принципе каждая библиотека в отдельности может претендовать на отдельный топик.
                0
                Было бы еще интересно узнать поддерживают .NET компоненты конвертацию из разных форматов (HTML, DOC и т.д.) в PDF
                  +2
                  А мне нравится iTextSharp тем, что там можно стркутуру PDF файла формировать при помощи xml. Итого DataSet в xml, делаем xslt и получаем xml, который и генерирует наш PDF. Легче сопровождать, чем когда это прописано в коде.
                    0
                    Интересует, можно ли с использованием какой-то библиотеки далать pdf из объекта
                    System.Drawing.Printing.PrintDocument (вместо печати генерировать pdf не используя сторонних программ)
                      0
                      А выводы вы не написали потому что их нет, или забыли? Обычно в обзорных статьях это для меня самое интересное. Или вы попробовали только одну? Мы у себя на PdfSharp остановились, очень много перепробовав.
                        0
                        Это обзор, а не тестирование. Если бы я выдвинул какие-то требования, то тогда можно было бы сделать выводы в конце статьи, что эта библиотека занимает почётное первое место, потому-что… Очень многое зависит от потребностей, читал, что человек категорически не хочет использовать тот же iTextSharp, не потому-что он не умеет делать какой-то функционал, а что библиотека слишком «тяжелая» в плане занимаемого места (что в некоторых проектах может быть весомо, если нужен небольшой инсталлятор). Вот Вы пишите, что «Мы у себя на PdfSharp остановились, очень много перепробовав.», почему бы не указать, что для Вас стало решающим в выборе? Думаю, тем, кто будет читать комментарии Ваш опыт может стать полезен.
                        0
                        Можно сделать, чтобы в таблице, в одной ячейке было два текста, один флоатился налево, а другой направо? А если они не вмещаются в одну строку, то правый текст переносится на следующую строку. И как бонус — между этими текстами редкий пунктир.

                        PDFLib забыли упомянуть.
                          0
                          Вот тут есть неплохие уроки по таблицам mikesdotnetting.com думаю разберётесь или обращайтесь к документации.
                          0
                          Заметили, что очень много .NET библиотек последнее время публикуется?

                          Есть еще Google.API для .NET
                          code.google.com/intl/ru-RU/apis/gdata/docs/directory.html

                          Веб-камера
                          sites.google.com/site/webcamlibrarydotnet/home

                          Недавно были OCR
                          code.google.com/p/tesseract-ocr/downloads/list

                          Теперь вот и PDF.

                          Я потратил вчера один час времени и написал программу, которая распознает и переводит текст из веб-камеры, просто подключив 3 библиотеки.
                            +1
                            Круто было бы лицензии указать.
                            iTextSharp, например, под AGPL.
                              0
                              Report.NET — LGPL
                              PDFsharp — LGPL
                              SharpPDF — LGPL
                              PDFjet Open Source Edition — BSD
                              ASP.NET FO PDF — LGPL
                              PDF Clown — LGPL
                            0
                            А какая-нибудь из них может загрузить в себя уже готовый PDF (из памяти, а не из файла) и проделать с ним какие-нибудь манипуляции? Ну, там, посчитать количество страниц и узнать их размеры, например. Найти/заменить текст, картинку?
                              +2
                              Бесплатная прога для манипуляции
                              www.pdflib.com/
                              но по тексту не ищет
                                +1
                                Пример для PDFSharp: Combine Documents на официальном сайте.
                                  0
                                  только в параметрах указать нужно поток
                                0
                                У меня вопрос не совсем по этой теме, но не далеко. Понадобилась мне достаточно нестандартная вещь — создать свой виртуальный принтер PDF. Нужен он для того, чтобы отправлять в существующую систему PDF документы из любого приложения. Чтобы было меньше заморочек, удобнее всего это сделать по средством PDF принтера. Начав искать, я нашел только два опенсорсных проекта данной направленности и оба они написаны на старом VB6. Вопрос, может быть кто-нибудь сталкивался с опенсорсными реализациями PDF принтеров или может быть не слишком дорогой, но функциональной платной реализацией.
                                  0
                                  silverpdf.codeplex.com/

                                  для работы с PDF в сильверлайт…
                                    0
                                    Я использую гибкий и удобный Apitron.PDF.Kit for .NET для редактирования, извлечения текста и создания PDF ( с возможностью добавления своего стиля каждому элементу ). Бесплатная книжка.

                                    Для создания подобной таблицы:
                                    // создали менеджер ресурсов и добавили картинки
                                    ResourceManager resourceManager = new ResourceManager();
                                    resourceManager.RegisterResource(new Apitron.PDF.Kit.FixedLayout.Resources.XObjects.Image("Left", "left.png"));
                                    resourceManager.RegisterResource(new Apitron.PDF.Kit.FixedLayout.Resources.XObjects.Image("Right", "right.png"));
                                    
                                    // создали ПДФ документ  со своим стилем
                                    FlowDocument document = new FlowDocument { Margin = new Thickness(18) };
                                    
                                    // общий стиль для данных в ячейках таблицы
                                    document.StyleManager.RegisterStyle("grid#iApitron", new Style { InnerBorderColor = RgbColors.LightGray, Align = Align.Center, Font = new Font(StandardFonts.Helvetica, 12) });            
                                                
                                    // добавляем стиль для заголовка таблицы
                                    document.StyleManager.RegisterStyle("textblock.h1", new Style { Font = new Font(StandardFonts.HelveticaBold, 20) });
                                    
                                    // сам грид
                                    Grid grid = new Grid(Length.FromPercentage(33), Length.FromPercentage(33), Length.FromPercentage(33)) { Id = "iApitron" };
                                    
                                    // добавляем строки таблицы с данными
                                    grid.Add(new GridRow(Section.Empty, new TextBlock("Ну, заяц!"){Class="h1"}, Section.Empty));
                                    grid.Add(new GridRow(new TextBlock("Col 1 Row 1"),new TextBlock("Col 2 Row 1"),new TextBlock("Col 3 Row 1")));
                                    grid.Add(new GridRow(new TextBlock("Col 1 Row 2"),new TextBlock("Col 2 Row 2"),new TextBlock("Col 3 Row 2")));
                                    grid.Add(new GridRow(new Image("Left"),new TextBlock("Col 2 Row 3"),new Image("Right")));
                                    document.Add(grid);
                                    
                                     // сохраним документ
                                    using (Stream stream = File.Create("Apitron_table.pdf"))
                                    {
                                         document.Write(stream, resourceManager, new PageBoundary(Boundaries.Ledger));
                                    }
                                    

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое