Очерк по поводу создания PDF-файлов. Добавляем в программу просмотр PDF с помощью ActiveX Открытие pdf на определенной странице delphi

27.06.2020

Существует два основных способа организовать в программе просмотр документов в формате PDF.

  • Использование технологии ActiveX;
  • Использование специальных компонентов.

Компоненты для работы с PDF есть не во всех выпусках Delphi и чаще всего их нужно искать и устанавливать дополнительно. В тоже время, для использования ActiveX необходимо всего лишь наличие на компьютере пользователя соответствующего программного обеспечения. В данном случае Adobe Acrobat Reader (бесплатная) или Adobe Acrobat.

Работу с ActiveX можно условно разделить на два этапа.

  • Импорт библиотеки типов или компонентов;
  • Собственно, использование импортированных средств в приложении.
Импорт компонентов ActiveX

Для импорта компонентов используется команда «Component» – «Import Component» в главном меню Delphi. Сам процесс импорта реализован в виде мастера.

На первой странице мастера выбираем «Import ActiveX Control».

После этого необходимо решить, как поступить с импортируемыми компонентами. Так как планируется их использование в виде компонентов Delphi, выбираем «Install to New Package».

Теперь остаётся только указать имя вновь создаваемого пакета.

После нажатия на кнопку «Finish», компоненты ActiveX для просмотра PDF будут импортированы в Delphi.

Просмотр PDF в приложении

Для создания просмотра PDFфайлов в приложении средствами ActiveX необходим компонент TAcroPDF. Процесс его импорта подробно описан выше.

В качестве примера создадим следующее приложение. Поместим на форму компоненты TAcroPDF, TOpenDialog и TButton как показано на скриншоте ниже.

При нажатии на кнопку вызываем диалог открытия файла для выбора файла PDF для просмотра.

Для этого примера нам будут необходимы следующие компоненты, которые находятся во вкладке Rave. И так, приступим к установке нужных нам компонентов, а именно:

  • TRvNDRWriter
  • TRvRenderPdf
  • TButton

Предлагаю немного остановиться на этих компонентах и понять для чего они служат. Кстати о них я вычил информацию из пару книг которые приобрел progbook.ru . Поэтому если хотите приобрести достойные книги по Delphi, то милости прошу в данный магазин.

Итак, первым у нас идет компонент TRvNDRWriter. Этот компонент необходим нам для записи в pdf-файл информации, не важно какой, текстовой или графической, через поток.

Procedure TForm1.Button1Click(Sender: TObject); var Streams:TMemoryStream; begin Streams:=TMemoryStream.create; RvNDrWriter1.Stream:=Streams; RvNDRWriter1.Execute; RvRenderPdf1.PrintRender(Streams, "test.pdf"); ShellExecute(Handle, nil, "test.pdf", "", "", SW_SHOW); FreeAndNil(Streams); end;

Следующий компонент это TRvRenderPdf. Он необходим нам для создания, а точнее для отрисовки информации, будь то текстовая или графическая. Соответственно после нажатия кнопки, мы запишем нужную нам информацию в наш pdf-файл.

Но не будем сильно разглагольствовать, а перейдем сразу к интересующей нас теме, а именно к программированию:)

Для начала нам необходимо создать обычный пустой pdf-файл и разместить его в корневой папке нашей программы.

Собственно данным кодом мы создаем поток, где будем отрисовывовать нужную нам информацию, после чего запускаем отрисовку, указываем наш конечный pdf-файл, в который будет производиться отрисовка данных и в конце закрываем поток.

После выполнения данного когда, нам необходимо событие, которое возникает при прорисовке данных, в этом событии мы будем выводить нужную нам информацию.

Разберем код. Для начала я загружаю картинку *.bmp, создаем переменную bmp, и объект класса TBitmap. Загружаю я ее для того, чтобы потом рисовать в нашем pdf-файле.

Я думаю дальше особо описывать не стоит все понятно и так, процедура PrintHeader - добавляет надпись в заголовок документа, процедура PrintFooter - добавляет надпись в конец документа. Процедура PrintBitmap - добавляет изображение в документ, процедура SetFont - задает необходимый шрифт документа, процедура FontColor - задает нужный цвет шрифта документа.

Все последующие графические функции и процедуры, точно такие же, как и при выводе графической информации на Canvas других компонентов.

Функцию NewPage я использую для создания нового листа в документе. Все что будет добавлено после нее на вывод информации, будет выводиться на новом листе документа.

Важно , что бы все модули: RpRender, RpRenderPDF, RpDefine, RpBase, RpFiler, RpRave, RpCon были подключены к проекту!

Возможности компонента, заявленные разработчиками:

  • Поддержка векторной и растровой графики в 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$ (!!!) с исходниками
5-XE4
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

В списке ищем библиотеку

Импортируем, создаем новый проект и подключаем в 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 if gtPDFDocument1. IsLoaded then begin gtPDFDocument1. TextOut ( "Привет, Мир!" , 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


До встречи в онлайне!

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

Для этого нам понадобятся компоненты с вкладки Rave . Давайте же установим, необходимые нам, для работы компоненты, а это:

  • TRvNDRWriter
  • TRvRenderPdf
  • TButton

Компонент TRvNDRWriter предназначен для записи в pdf -файл информацию (текстовую, графическую), через поток.

Компонент TRvRenderPdf предназначен для создания, отрисовки информации (текстовой, графической и так далее). Ну и по нажатию на кнопку, мы будем что-то заносить в наш pdf -файл.

Из теории много писать ничего не будем, а сразу перейдем к программированию, но необходимо еще сперва создать обычный пустой pdf -файл и положить его в корень с программой. Дальше на событие OnClick нашей кнопки мы напишем следующий код:

procedure TForm1. Button1Click (Sender: TObject ) ; var Streams: TMemoryStream; begin Streams: = TMemoryStream. create ; RvNDrWriter1. Stream : = Streams; RvNDRWriter1. Execute ; RvRenderPdf1. PrintRender (Streams, "test.pdf" ) ; ShellExecute(Handle, nil , "test.pdf" , "" , "" , SW_SHOW) ; FreeAndNil (Streams) ; end ;

Создаем поток, в котором и будем отрисовывовать всю информацию, затем запускаем отрисовку, указываем файл, в который будет производиться отрисовка данных и в конце уничтожаем поток.

Все теперь, нам необходимо событие, которое возникает при отрисовке данных, в нем мы и будем выводить всю нашу информацию. Выделяем компонент TRvNDRWriter и переходим список событий данного компонента, после чего, находим событие OnPrint и в данной событие пишем следующий код:

procedure TForm1. Print (Sender: TObject ) ; begin bmp: = TBitmap. Create ; bmp. LoadFromFile ("test.bmp" ) ; with RvNDRWriter1 do begin SetFont("Arial" , 16) ; FontColor: = clGreen; Print("Test Text" ) ; PrintHeader("Begin PDF File" , pjCenter) ; PrintFooter("End PDF File" , pjCenter) ; LineTo(10, 10) ; PrintBitmap(1, 1, 1, 1, bmp) ; end ; FreeAndNil (bmp) ; end ;

Ну, сперва, мы загружаем картинку *.bmp , естественно переменная bmp , у нас объект класса TBitmap . Загружаем мы для того, чтобы потом ее отрисовать в нашем pdf -документе.

А дальше, я думаю все понятно, процедура PrintHeader - выводит надпись в заголовок документа (страницы), процедура PrintFooter - выводит надпись в конец документа (страницы). Процедура PrintBitmap - выводит изображение в документ, процедура SetFont - устанавливает шрифт документа, процедура FontColor - устанавливает цвет шрифта документа.