Использование pdfmark в программе на языке PostScript
Во-первых, я рассмотрю часть 1 вашего вопроса: создание такого файла формы PDF, запустив языковую программу PostScript с выражениями pdfmark через Adobe Acrobat Distiller или тому подобное. См. пример программы ниже.
«Документация по PDFMARK», которую вы прочитали, была справочником по pdfmark. , я понимаю. Моя копия датирована ноябрем 2006 года. Код, который вам нужен, почти весь там, в примерах 5.11 Определение словаря AcroForm в каталоге документов и 5.12 Определение аннотаций виджета, которые также являются полевыми словарями. для этой формы на страницах 70–75. Внимательно прочитайте код, скопируйте его в исходный файл и перегоните его, модифицируйте по своему усмотрению. На этом основана моя выборка.
Обязательно внимательно прочитайте главу 1 Введение (стр. 9-16), которая поможет вам понять синтаксис pdfmark в примерах 5.11 и 5.12. Раздел Именованные объекты (стр. 12–16) важен для понимания того, как ссылаются на шрифты и кодировки в примерах.
Но вам также необходимо прочитать спецификацию языка PDF. Копия спецификации Adobe была заменена стандартом ISO PDF 32000-1. :2008 Управление документами — Формат переносимых документов — Часть 1: PDF 1.7 Прочтите раздел 12.7 Интерактивные формы (стр. 430–456), который часто будет отсылать вас к разделу 12.5. Аннотации (стр. 381–414) для управления внешним видом полей формы.
Важно понимать, что большинство полей формы будут определяться парами ключ-значение, представленными в выражениях языка PostScript [ ... /ANN pdfmark
. Пары ключ-значение указаны в спецификации PDF, а не в спецификации pdfmark. Но легко редактировать выражения pdfmark во время чтения спецификации PDF.
Следующая программа преобразуется в файл PDF с полями формы:
% Simple pdfmark form example
% by Jim DeLaHunt, jdlh.com, 3. March 2012
%
% This PostScript language code, when converted to PDF by
% Adobe Acrobat Distiller or the like, creates a PDF file with form
% fields, and a Submit button which sends the values of the fields
% via an HTTP POST request.
%
% In reply to Stack Overflow question, "How can I create a PDF form
% using PDFMARK and/or PERL cpan module PDF::API2?",
% http://stackoverflow.com/questions/9440930/
%
% Define stubs for interpreters without pdfmark support
% From pdfMark reference, Example 1.2, p.10
/pdfmark where {
% pdfmark is built-in
% define {code} ?pdfmark - : exec modal PDF code.
pop globaldict /?pdfmark /exec load put
}{
globaldict begin
/?pdfmark /pop load def% pdfmark is absent: ignore code.
/pdfmark /cleartomark load def
end
} ifelse
%%EndProlog
% This code makes the example clearer. It isn't part of the AcroForm.
<</PageSize [300 300]>> setpagedevice % smaller page (~ 10cm x 10cm)
clippath 0.9 setgray fill % light grey background, to show widgets.
/Helvetica-Bold 12 selectfont 0 setgray % for labels
/showlabel { % (text) x y showlabel -
% shows (text) top-justified at x,y, moves down one line
-12 add moveto % x y -12 add moveto -
gsave show grestore
0 -3 rmoveto % leading (space between lines)
} def
/showcomment { % (text) showcomment -
% shows (text) top-justified at current point, moves down 1 line
0 -10 rmoveto
gsave /Helvetica 10 selectfont show grestore
0 -2 rmoveto % leading (space between lines)
} def
(Simple pdfmark form example) 10 290 showlabel
% AcroForm dictionary setup. From pdfmark Reference, Example 5.11, p.70
%
% Read also PDF specification PDF32000:2008
% "Document management — Portable document format — Part 1: PDF 1.7",
% Section 12.7 "Interactive Forms", p.430
% To understand the syntax: [/_objdef {foo} /type /dict /OBJ pdfmark
% read carefully pdfMark reference, "User-defined named objects", p.13.
% Define font objects for the widgets to use
[ /_objdef {ZaDb} /type /dict /OBJ pdfmark
[ {ZaDb} <<
/Type /Font
/Subtype /Type1
/Name /ZaDb
/BaseFont /ZapfDingbats
>> /PUT pdfmark
[ /_objdef {Helv} /type /dict /OBJ pdfmark
[ {Helv} <<
/Type /Font
/Subtype /Type1
/Name /Helv
/BaseFont /Helvetica
% /Encoding {pdfDocEncoding} % for simplicity, use font's own encoding
% pdfmark Reference, Example 5.11, p.70, provides an Encoding
% array defining PDFDocEncoding
>> /PUT pdfmark
[ /_objdef {aform} /type /dict /OBJ pdfmark
% Define Fields array of Acroform dictionary. It will contain entries for
% each of the widgets defined below.
% NOTE: It is not necessary to explicitly assign the widget annotations
% to the Fields array; Acrobat does it automatically when the file is
% opened.
[ /_objdef {afields} /type /array /OBJ pdfmark
[ {aform} <<
/Fields {afields}
/DR << /Font << /ZaDb {ZaDb} /Helv {Helv} >> >>
/DA (/Helv 0 Tf 0 g)
/NeedAppearances true
% "/NeedAppearances true" tells reader 'to construct appearance
% streams and appearance dictionaries for all widget annotations
% in the document...' --PDF32000:2008 Table 218 p.431
>> /PUT pdfmark
% Put Acroform entry in catalog dictionary
[ {Catalog} << /AcroForm {aform} >> /PUT pdfmark
% Example 5.12 Define the Widget annotations
% pdfmark Reference pp. 72-75, with clarifications by Jim DeLaHunt
%
% These Widget annotations are also field dictionaries for this form.
% This is the collection of all individual widget annotations.
% It is possible to have multiple instances of these sections, such as
% for defining a single widget on each instance.
%
% See PDF32000:2008 Section 12.5.6.19 "Widget Annotations", p.408
% especially tables 188 and 189.
(/Tx text field) 10 260 showlabel
(with Javascript) showcomment (validation) showcomment
[ /Subtype /Widget
/Rect [100 223 245 260]
/F 4
/T (SL Text)
/FT /Tx
/DA (/Helv 14 Tf 0 0 1 rg)
/V (5)
/AA <<
/K <<
/S /JavaScript
/JS (AFNumber_Keystroke\(2, 0, 0, 0, "$", true\);)
>>
/F <<
/S /JavaScript
/JS (AFNumber_Format\(2, 0, 0, 0, "$", true\);)
% pdfmark Reference p.72 seems to omit closing ")" above. Oops.
>>
>>
/ANN pdfmark
(/Btn field) 10 208 showlabel
(Check Box) showcomment
[ /Subtype /Widget
/Rect [100 172 136 208]
/F 4
/T (Check Box)
/FT /Btn
/DA (/ZaDb 0 Tf 0 g)
/AS /Off
/MK << /CA (4)>>
/AP << /N << /Oui /null >> >>
/ANN pdfmark
(/Ch field) 10 160 showlabel
(List Box) showcomment
[ /Subtype /Widget
/Rect [100 87 137 160]
/F 4
/T (List Box)
/FT /Ch
/DA (/Helv 10 Tf 1 0 0 rg)
/Opt [(1)(2)(3)(4)(5)]
/DV (3)
/V (3)
/MK <<
/BG [1 1 1] % Background: white
/BC [0 0 0] % Border colour: black
>>
% MK is 'An appearance characteristics dictionary (see Table 189)'
% --PDF32000:2008 Table 188 p.408
% Without an /MK entry, Acrobat Pro 8.0 complains of an error
% when displaying this field, and some entries aren't displayed.
/ANN pdfmark
(/Btn button) 160 85 showlabel
(/S /SubmitForm action) showcomment
% Example of how the /MK dictionary is used.
[ /Subtype /Widget
/Rect [ 130 10 270 50 ]
/F 4
/T (Submit)
/FT /Btn
/H /P
/A <<
/S /SubmitForm
/F (http://posttestserver.com/post.php) % Thanks, Henry!
/Flags 16#6 % IncludeNoValueFields, ExportFormat
>>
/DA (/HeBo 18 Tf 0 0 1 rg)
/Ff 65536
/MK <<
/BC [ 1 0 0 ]
/BG [ 0.75 0.45 0.75 ]
/CA (Submit)
/AC (Submitted!)
>>
/BS <<
/W 3
/S /I
>>
/ANN pdfmark
% When pressing the Submit button in Adobe Acrobat Professional 8.3.1,
% there is a pause, and then Acrobat displays a PDF file with the
% results of the HTTP POST operation. This is text like,
% Successfully dumped 3 post variables. View it at
% http://www.posttestserver.com/data/2012/03/04/01.29.271751566025
% Post body was 0 chars long.
%
% Browse to that URL, and you will see diagnostics with the following:
% ....
% Post Params:
% key: 'Check_Box' value: 'Oui'
% key: 'List_Box' value: '4'
% key: 'SL_Text' value: '3.14'
% Empty post body.
showpage % make sure a page gets produced
Откройте полученный PDF-документ в программе для чтения PDF-файлов. Измените значения в формах. Обратите внимание, что верхнее текстовое поле ограничивает вас числом с двумя десятичными знаками и ставит знак $
перед числом. Это делается с помощью кода Javascript. Есть флажок, который отправляет значение Oui
при проверке.
Когда вы нажимаете кнопку Submit
, программа чтения PDF берет ключи для каждого поля формы и значение этого поля и отправляет их на URL-адрес с помощью вызова HTTP POST
. Местом назначения, которое я использовал, является Henry's HTTP Post Dumping Server. Сервер возвращает текстовый ответ на POST, предоставляя URL-адрес, по которому вы можете увидеть, что сервер получил. Adobe Acrobat Professional преобразует этот ответ в файл PDF, что может занять несколько секунд. Посетите этот URL-адрес, и вы увидите пары field_name/value, которые вы ищете.
Использование модуля PERL PDF::API2
У меня нет большого опыта работы с Perl, и я никогда не использовал PDF:: Модуль API2. Однако из проверки кода я подозреваю, что генерировать PDF-формы с помощью PDF::API2 будет непросто.
PDF::API2:: Подмодуль Annot выглядит многообещающе. Но чтобы использовать метод примера программы выше, необходимо создать PDF-аннотации /Subtype /Widget
. Похоже, PDF::API2::Annot не поддерживает это.
Просмотр исходного кода PDF::API2::Annot можно увидеть примеры того, как он обрабатывает другие типы аннотаций. Например, тип аннотации «Ссылка» частично создается таким кодом:
$self->{Subtype}=PDFName('Link');
Если бы аннотации виджетов поддерживались, можно было бы ожидать появления утверждений вроде $self->{Subtype}=PDFName('Widget')
. Но в этом модуле (версия 2.019) нет экземпляра строки Widget
. Следовательно, вероятно, потребуется расширение этого модуля для поддержки аннотаций виджетов.
Теперь аннотации — это только словари PDF с определенным содержимым. Вероятно, можно использовать PDF::API2::Basic::PDF::Dict для создания аннотаций виджета из основных частей. Однако я предполагаю, что это будет даже больше работы, чем расширение PDF::API2::Annot .
Воспринимайте этот вопрос и вознаграждение, которое он привлек, как знак: будет много радости, если кто-то добавит поддержку аннотаций виджета в PDF::API2::Annot и, возможно, создаст PDF: Модуль :API2::Form!
person
Jim DeLaHunt
schedule
04.03.2012