Пообещал я на днях одному многоуважаемому человеку, что на выходных гляну исходник клиента для DelphiFeeds.ru в плане сборки этого приложения под iOS в Delphi XE4. Собственно, глянуть-то я его глянул, но толкового решения в плане безболезненного переноса по iOS так и не нашел (и переделывание интерфейса оказалась не такой уж и большой проблемой в сравнении с другими). Вообще, перенос проектов FireMonkey с Delphi XE3 на Delphi XE4 -заслуживает отдельного поста, но, в целях соблюдения политкорректности, я оставляю эту тему кому-нибудь другому. Зато обнаружил, что сервис по созданию PDF-файлов из HTML-страниц успешно «загнулся» и теперь в клиенте создаются только mht-файлы. Это обстоятельство и привело к написанию этого небольшого обзора компонентов и решений для создания PDF-файлов в Delphi.
Помня некоторые из замечаний по поводу обзора «23 решения для локализации и интернационализации приложений«, сразу оговорюсь:
- Вся информация относительно цены, лицензии, поддерживаемых версий Delphi берётся исключительно с официальных сайтов разработчиков на момент написания этого обзора. Дата обзора 10 июня 2013 года.
- Если Вы сейчас читаете этот пост и точно знаете, что какой-либо компонент из обзора прекрасно поддерживает работу в XE6/7/8 и т.д., а в обзоре сказано только про XE3, то сегодня точно не 2013 год и, следовательно, см. п.1.
- Работа всех компонентов проверялась на Delphi XE3 и только на Delphi XE3
1. Synopse PDF Engine
- Стоимость: Free
- Лицензия: MPL/GPL/LGPL tri-license.
- Поддерживаемые версии Delphi: 5-XE3
- Страница загрузки: http://synopse.info/fossil/wiki?name=PDF+Engine
Возможности, заявленные разработчиками:
- Чистый Delphi-код без использования сторонних DLL
- Маленький размер, создаваемых pdf-файлов
- Быстрая генерация pdf с минимальным использованием памяти
- Доступ к TCanvas для рисования линий, кривых, текста и т.д.
- Поддержка Unicode
- Создание PDF/A-1 файлов.
При работе с Synopse PDF Engine ничего устанавливать не требуется — достаточно указать в проекте путь к модулям Synopse и подключить модуль synpdf.pas в uses.
Пример использования:
var lPdf : TPdfDocument; begin lPdf := TPdfDocument.Create;//создали документ try lPdf.Info.Author := 'Tester';//задали автора lPdf.Info.CreationDate := Now;//задали дату создания документа lPdf.DefaultPaperSize := psA4;//указали формат страниц (А4) lPDF.AddPage;//добавили страницу в документ lPDF.Canvas.SetFont('Helvetica',10.0,[]);//указали параметры шрифта {записываем текст в документ} lPdf.Canvas.BeginText; try lPdf.Canvas.TextOut(0, 700, 'Это текст в PDF-документе...'); lPdf.Canvas.TextOut(0, 686, 'Это текст на другой строке в PDF-документе...'); finally lPdf.Canvas.EndText; end; //сохраняем полученный файл lPdf.SaveToFile('c:\temp\test.pdf'); finally lPdf.Free; end; end;
В результате выполнения этого кода у меня получился PDF-документ вот с таким содержимым:
Как видно на рисунке, при вводе в PDF юникодного текста возможно появление каких-то непонятных символов.
Что касается печати PDF из HTML-страниц, то, судя по описанию возможностей Synopse PDF Engine на официальном сайте, сделать это возможно, но с использованием других компонентов из набора Synopse. Поэтому я отложил Synopse PDF Engine в сторонку (может потом пригодиться) и начал искать другие решения.
2. PowerPDF
- Стоимость: Free
- Лицензия: Mozilla Public License 1.1 (MPL 1.1).
- Поддерживаемые версии Delphi: 2007-XE3
- Страница загрузки: http://sourceforge.net/projects/powerpdf/
PowerPDF представляет собой набор визуальных компонентов для создания PDF-документов. В набор входит несколько компонентов, таких как TPDFImage, TPDFText, TPDFAnnotation и т.д. После установки компонентов на палитре появится закладка PowerPDF с которой нам и предстоит в дальнейшем работать.
В zip-архиве с библиотекой PowerPDF Вы также найдете массу различных примеров использования PowerPDF, в т.ч. создания PDF-файлов с картинками, различные способы работы с текстом, шрифтами, выгрузка данных из БД и т.д.
В целом PowerPDF выглядит довольно презентабельно и серьезно, но для решения моей задачи мало подходит, т.к. мне необходим именно невизуальный компонент для создания PDF из web-странички. Если же Вам нужны бесплатные компоненты для создания отчетов в PDF-формате, то посмотрите PowerPDF — вполне возможно, что эти компоненты Вам подойдут.
Пример PDF-документа:
3. HotPDF
Стоимость: от 110 до 300$
Поддерживаемые версии Delphi: 7-XE4
Страница загрузки trial-версии: http://www.loslab.com/HotPDF.html
Возможности компонента, заявленные разработчиками:
- Поддержка векторной и растровой графики в PDF-документах
- Защита PDF-документов паролем
- Поддержки AcroForms/PDF-форм
- Водяные знаки
- Генерация PDF документов с внутренними и внешними ссылками, веб-ссылками и закладками
- Полная поддержка Unicode
- Поддержка различных шрифтов, форматирование текста, расположение текста в несколько столбцов
- Поддержка TCanvas
- Встроенный архиватор для сжатия текстовой и графической информации в документе
- Преобразование TIFF в PDF
В качестве примера, я решил собрать демонстрационное приложение, идущее в комплекте вместе с компонентом THotPDF. Приложение довольно простенькое — генерирует PDF-ку с двумя ссылками и простым текстом. Код тоже простой и понятный:
procedure TForm1.HelloWorldButtonClick(Sender: TObject); begin HPDF.BeginDoc; HPDF.CurrentPage.PrintHyperlink(20, 35, 'Website: ' + MainEdit.Text, MainEdit.Text); HPDF.CurrentPage.SetFont( 'Times New Roman', [], 16 ); HPDF.CurrentPage.SetRGBHyperlinkColor(clRed); HPDF.CurrentPage.PrintHyperlink(20, 50, 'Order page: ' + BuyEdit.Text, BuyEdit.Text); HPDF.CurrentPage.SetFont( 'Times New Roman', [], 14 ); HPDF.CurrentPage.TextOut(20, 75, 0, 'Click the link to navigate'); HPDF.EndDoc; end;
Даже не вдаваясь в тонкости работы компонента можно понять, что и как происходит в этом демонстрационном примере. Запускаем, смотрим на внешний вид сгенерированного документа:
Вот эти два синих прямоугольника в документе — ссылки на две страниц…а простого текста «Click the link to navigate» вообще не наблюдается нигде. Хотя, надо отдать должное, при клике по прямоугольнику ссылка действительно открывается. В общем, то ли разработчики поторопились заявить поддержку Delphi вплоть до XE3, то ли это так интересно работает trial-версия, но после запуска этого демонстрационного примера у меня как-то отпало желание использовать THotPDF даже за бесплатно. Двигаемся далее.
4. PDF Creator Pilot
Стоимость: от 450$ без исходников до 9950$ (!!!) с исходниками
Поддерживаемые версии Delphi: 5-XE4
Страница загрузки trial-версии: http://www.colorpilot.com/pdflibrary.html#download
Библиотека стоимостью почти как Delphi XE3 Professional…Ну да ладно, посмотрим, что представляет из себя эта библиотечка.
Возможности, заявленные разработчиками:
- Расширенный набор методов и свойств для легкого создания PDF;
- Чтение и слияние существующих PDF-документов;
- Добавление и удаление страниц PDF-документа;
- Поддержка юникода;
- Создание водяных знаков для каждой страницы;
- Добавление эскизов для PDF-документа;
- Использование и встраивание шрифтов (TrueType, OpenType, Type1 и т.д.);
- Создание интерактивных PDF-документов, используя JavaScript и гиперссылки;
- Поддержка интерактивных элементов AcroForm: текстовые поля ввода, кнопки, радио-кнопки, выпадающие списки, флажки;
- шифрование и защита паролем созданных PDF-документов;
- Создания и управление содержанием документа;
- Доступ к HDC для рисования на PDF-страницах с помощью WinAPI функций.
- Использование изображений в различных форматах (JPEG, TIFF, PNG, BMP, GIF);
- Создание и использование аннотаций;
- Создание PDF-документов на диске или в памяти;
- Извлечения текста из PDF документов;
В общем, довольно внушительный список возможностей. Посмотрим как некоторые из этих возможностей работают на практике. Скачиваем демонстрационную версию, устанавливаем.
После установки запускаем Delphi (в моем случае — это Delphi XE3) и переходим в меню:
Component — Import Component — Import Type Library
В списке ищем библиотеку PDFCreatorPilot:
Импортируем, создаем новый проект и подключаем в uses модуль PDFCreatorPilotLib_TLB.
Теперь можем протестировать работу библиотеки на каком-нибудь живом примере. Вначале попробуем сгенерировать документ с простым текстом:
procedure TForm1.Button1Click(Sender: TObject); var fnt: integer; begin { initialization } PDF := TPDFDocument4.Create(nil); PDF.SetLicenseData('demo', 'demo'); fnt := pdf.AddFont('Verdana', false, false, false, false, fcANSI); PDF.UseFont(fnt, 14); PDF.ShowTextAt(20, 40, 'HELLO, PDF!'); { save } PDF.SaveToFile('HelloPDF.pdf', true); PDF.Destroy; end;
Запускаем приложение и смотрим на созданный PDF-документ:
Теперь попробуем записать русский текст в файл:
procedure TForm1.Button1Click(Sender: TObject); begin { initialization } {...} PDF.ShowTextAt(20, 40, 'Привет, PDF!'); { save } {...} end;
Может где-то в свойствах класса надо что-то настроить, вызвать какой-нибудь метод, который включит-таки поддержку юникода, НО за такие бабки хотелось бы получить библиотеку, которая заработает сразу «из коробки» без всяких заморочек с настройками и подкрутками…Кстати, метод для вставки ссылки (AddHyperLink) тоже не сработал — документ остался девственно чист несмотря на то, что ссылка якобы вставилась. Но, надо отдать должное, попытка вставить в новый документ уже ранее созданную PDF-ку — сработал на ура — документ вставился на новую страничку как надо, без косяков.
5. PDFtoolkit VCL v4.0.1.293
Стоимость: от 349$ без исходников до 499$ с исходниками
Поддерживаемые версии Delphi: 6-XE4
Страница загрузки trial-версии: http://www.gnostice.com/PDFtoolkit_VCL.asp?show=downloads
Про эту библиотеку компонентов от Gnostice имеется довольно много положительных отзывов в Сети.
По возможностям PDFtoolkit практически 1 в 1 соответствует PDF Creator Pilot, т.е. умеет «склеивать» PDF-ки, распознавать текст, вставлять ссылки, проводить поиск в документах и т.д. Но, в отличие от PDF Creator Pilot, PDFtoolkit во-первых, представляет из себя набор визуальных и невизуальных компонентов для работы с PDF, а во-вторых, предназначен для работы с уже созданными документами. В комплекте поставляется небольшой вьювер PDF-ок, невизуальный компонент для работы с PDF, визуальный компонент для организации поиска в PDF-документах и т.д.
Работа с PDFtoolkit довольна простая, например, ниже представлен код вставки простенького HTML-кода в PDF-документ:
gtPDFDocument1 := TgtPDFDocument.Create(Nil); try //Загружаем документ gtPDFDocument1.LoadFromFile('sample_doc.pdf'); //проверяем, что документ успешно загружен if gtPDFDocument1.IsLoaded then begin gtPDFDocument1.TextOut( '<i>Привет, <b>Мир!</b></i>', IntToStr(gtPDFDocument1.PageCount),//диапазон страниц в который будет вставлен текст gtPDFDocument1.GetPageSize(gtPDFDocument1.PageCount, muPixels).Width/2,//вставляем текст в центр страницы gtPDFDocument1.GetPagesize(gtPDFDocument1.PageCount, muPixels).Height/2); {сохраняем документ} gtPDFDocument1.SaveToFile('modified_doc.pdf'); end; finally gtPDFDocument1.Free end;
Конечно, применительно к моей задаче PDFtoolkit оказывается практически бесполезным, т.к. меня интересует именно создание с нуля PDF-ки, но для тех, кто пишет собственный вьювер PDF-ок, думаю, эта библиотека должна подойти более чем.
Итак, что имеем в итоге. Есть 5 различных решений для создания и работы с PDF-документами в Delphi. Каждое решение имеет как свои достоинства (бесплатность, «навороченность»), так и недостатки (конская стоимость, проблемы с юникодом и т.д.). Применительно к моей задаче надо всеми решениями придётся «работать напильником». С другой стороны, в Сети есть куча платных и бесплатных сервисов для генерации PDF, но, памятуя о том, что такие сервисы имеют свойство вдруг брать и умирать, то как-то не тянет с ними связываться. Есть, конечно, ещё одно решение — самописное и не совсем в тему Delphi, но об этом как-нибудь в следующий раз, а пока пойду подумаю что же делать с клиентом для DelphiFeeds
Чувствуется разница между коммерческими и фришными версиями. Коммерческие очень чутко реагируют на новые версии базового продукта.
Александр Божко, есть такое дело. Но, блин, ценник иногда весьма сильно кусается :)
TPrintPDF 2.0 http://rusfolder.com/25215525 procedure TForm1.Button1Click(Sender:TObject); var pdf: TPrintPDF; begin pdf := TPrintPDF.Create( Self ); with pdf do begin FileName:= 'c:\MyPDF.pdf'; // Имя файла Title := 'PDF title'; // Заголовок документа PageWidth := 400; // Ширина страницы PageHeight := 500; // Высота страницы BeginDoc; // Начало документа LineWidth := 1; //Установим строку // Установим шрифт Font.Name := poTimesRoman; Font.Size := 12; MemoOut( 10, 10, Memo1 ); // Записываем содержание Memo NewPage; // Начинаем новую страницу Draw( 10, 10, Image1 ); // Рисуем изображение по координатам x, y NewPage; TextOut( 10, 10, 'This is the end...' ); // Выводим строку EndDoc; //… Подробнее »
надо только tnpdf.pas подправить для поддержки нужной версии Delphi, но это не должно вызвать никаких затруднений
У гностиков нужно рассматривать связку eDocEngine VCL + PDFToolkit. Причем, первая документы создает, вторая — обрабатывает!
Смотрю вы копите на ipad..
Отсюда вывод — клиента тестировать будете на виртуальном устройстве?
Если нет, интересует сборка под iOS «для себя» без покупки лицензии разработчика.
Есть ли какие законные и неочень варианты?
Игорь, такими темпами как я коплю на iPad, я куплю его видимо через лет тридцать будучи стариком :)) Для меня пока, что mac, что iOS — игрушки и не более. Поэтому, если даже что-то и пишу под OS от Apple, то тестирую на виртуальной машине на которой стоит симулятор iOS. Сборка под iOS «для себя», на сколько я могу понять, невозможна без Jailbreak или без оплаты $$ за лицензию разработчика (или чего там яблочники выдают)
На основе Synopse PDF Engine есть утилита htm2pdf.
http://synopse.info/forum/viewtopic.php?id=58
Юникод там неплохо поддерживается, есть даже китайские пользователи. С русскими символами у меня проблем не возникало.
Chaa, спасибо. Гляну, может и подойдет для меня
Есть еще неплохая библиотека Debenu Quick PDF Library. Не бесплатная к сожалению.
http://www.debenu.com/products/development/debenu-pdf-library/
Никак не могу подключить SinPdf.pas путь к модулям указал, в uses указал, а все равно пишет что File not found: ‘SinPdf.dcu’, а такого файла вообще нет. Помогите пожалуйста с проблемой, а то в гугле о таком не знают.
моя ошибка, неверно указал файл) можно удалять комментарий.
У кого-нибудь получилось с Synopse PDF Engine добавить текст или картинку в уже существующий pdf-файл? Так чтобы можно было что-то дописать, а не затереть имеющуюся информацию в нем.
Добавить он не может, в нем функций чтения PDF. Он может только новый создать.
Не согласен что у него только функции чтения, я с ним еще и новые документы создавал, вот только с существующими никак не получается, чтобы просто дописать их.
А есть какие-нибудь опенсорсные либы которые могут добавлять в существующий документ?
Прошу прощения, следует читать «в нем нет функций чтения PDF».
Есть еще llPDFLib http://www,sybrex.com
Для работы с русскими шрифтами необходимо использовать в строке:
fnt := pdf.AddFont(‘Verdana’, false, false, false, false, fcANSI); вместо fcANSI параметр fcRussian
Эх, раньше не увидел этой статьи… Но лучше позже. Обидно, что FastReport даже не рассматривается. Вот по случаю написал статью как сделать и PDF и PDF/A и из Delphi и из Lazarus (да, FastReport VCL 6)