Как создать PDF-форму с помощью модуля PDFMARK и/или PERL cpan PDF::API2?

Есть ли у кого-нибудь образец, демонстрирующий, как можно создать простую форму PDF (одно поле ввода текста или один переключатель) и «отправить пары field_name/value через HTTP-сообщение» на сервер при нажатии, используя любой из трех методов?

  1. Встраивая комментарии Adobe PDFMARK в файл Postscript, а затем конвертируя файл Postscript в PDF с помощью Adobe distiller или ghostscript? Я прочитал документацию PDFMARK, и в ней лишь кратко упоминается одно «действие», которое можно отправить для «отправки формы». но документам очень не хватает подробностей об этой реализации. Обычно документы Adobe очень хороши, но автор, должно быть, был вынужден закончить эту главу до того, как он ее закончил. Недостаток подробностей заключается в том, что PDF-формы могут фактически отправлять на сервер до четырех различных типов пакетов, ничего из этого не упоминается. Кроме того, фактический синтаксис действия «отправить форму» даже не представлен.
  2. Используя PERL и бесплатную библиотеку PDF::API2 или 3 для работы с PDF. Автор сделал доступными низкоуровневые вызовы функций, которые, по его мнению, дают достаточно возможностей для достижения этой цели, но, увы, фактически не использовал свою библиотеку для выполнения этой конкретной задачи. Кто-нибудь понял, как это сделать со своей библиотекой? Я спрашиваю, поскольку я прежде всего программист на Perl.
  3. Наконец, если ни один из вышеперечисленных мне ничего не дает, знает ли кто-нибудь о ЛЮБОМ вызываемом методе командной строки Windows, чтобы сделать это с использованием бесплатного или относительно недорогого программного обеспечения (менее 200 долларов США). Я был бы готов выучить другой язык, если бы это могло быть достигнуто с использованием другой среды разработки.

person user1232031    schedule 25.02.2012    source источник
comment
Возможно, это обсуждение будет полезно?   -  person raina77ow    schedule 25.02.2012
comment
Уточнение: вы хотите, чтобы результирующий PDF-файл был заполняемой формой?   -  person Joel Berger    schedule 27.02.2012


Ответы (1)


Использование 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