use*_*031 3 forms pdf perl cpan postscript
有没有人有任何示例演示如何使用三种方法之一创建一个简单的 PDF 表单(单个文本输入框或单个单选按钮)并在单击时“通过 HTTP post 提交 field_name/value 对”到服务器?
PDFMARK
注释嵌入到Postscript文件中,然后通过Adobe distiller或ghostscript将Postscript文件转换为PDF?我阅读了 PDFMARK 文档,它只简单提到一个“操作”可以发送到“表单提交”。但文档非常缺乏该实现的真正细节。通常 Adobe 的文档都非常出色,但作者一定是被迫在真正完成该章之前完成该章的。缺乏细节的是 PDF 表单实际上可能会向服务器提交最多四种不同类型的数据包,但这些都没有提及。同样,“表单提交”操作的实际语法甚至没有呈现。PDF::API2
3 个 PDF 操作库。作者已经提供了低级函数调用,他认为这些函数调用有足够的可能性来实际实现这一目标,但遗憾的是,他并没有实际使用他的库来完成这项特定任务。有没有人知道如何用他的图书馆做到这一点?我问这个问题是因为我主要是 Perl 程序员。在 PostScript 语言程序中使用 pdfmark
\n\n首先,我将解决您问题的第 1 部分:通过 Adobe Acrobat Distiller 等运行带有 pdfmark 表达式的 PostScript 语言程序来创建这样的 PDF 表单文件。请参阅下面的示例程序。
\n\n我认为您阅读的“PDFMARK 文档”是pdfmark Reference 。我的副本日期为 2006 年 11 月。您需要的代码几乎都在此处,位于第 70-75 页的示例 5.11 在文档目录中定义 AcroForm 字典和 5.12定义 Widget 注释(它们也是此表单的字段字典)。仔细阅读那里的代码,将其复制到源文件中并进行提炼,进行修改以适应。这就是我的样本所基于的。
\n\n请务必仔细阅读第 1 章简介(第 9-16 页),这将帮助您阅读示例 5.11 和 5.12 中的 pdfmark 语法。命名对象(第 12-16 页)部分对于理解如何引用示例中的字体和编码非常重要。
\n\n但你还需要阅读PDF语言规范。Adobe 的规范副本已被 ISO 标准PDF 32000-1:2008 文档管理 \xe2\x80\x94 可移植文档格式 \xe2\x80\x94 第 1 部分:PDF 1.7 阅读第 12.7节交互式表单(pp . 430-456),您会经常参考第 12.5 节注释(第 381-414 页)来控制表单字段的外观。
\n\n需要理解的重要一点是,大多数表单字段将由以 PostScript 语言表达式传递的键值对定义[ ... /ANN pdfmark
。键值对是在 PDF 规范中指定的,而不是在 pdfmark 规范中指定的。但在阅读 PDF 规范时编辑 pdfmark 表达式很容易。
以下程序将提取为带有表单字段的 PDF 文件:
\n\n% Simple pdfmark form example\n% by Jim DeLaHunt, jdlh.com, 3. March 2012\n%\n% This PostScript language code, when converted to PDF by \n% Adobe Acrobat Distiller or the like, creates a PDF file with form\n% fields, and a Submit button which sends the values of the fields\n% via an HTTP POST request.\n%\n% In reply to Stack Overflow question, "How can I create a PDF form \n% using PDFMARK and/or PERL cpan module PDF::API2?",\n% http://stackoverflow.com/questions/9440930/\n%\n\n% Define stubs for interpreters without pdfmark support\n% From pdfMark reference, Example 1.2, p.10\n/pdfmark where {\n % pdfmark is built-in\n % define {code} ?pdfmark - : exec modal PDF code.\n pop globaldict /?pdfmark /exec load put\n}{\n globaldict begin\n /?pdfmark /pop load def% pdfmark is absent: ignore code.\n /pdfmark /cleartomark load def\n end\n} ifelse\n%%EndProlog\n\n% This code makes the example clearer. It isn\'t part of the AcroForm.\n<</PageSize [300 300]>> setpagedevice % smaller page (~ 10cm x 10cm)\n\nclippath 0.9 setgray fill % light grey background, to show widgets.\n/Helvetica-Bold 12 selectfont 0 setgray % for labels\n/showlabel { % (text) x y showlabel - \n % shows (text) top-justified at x,y, moves down one line\n -12 add moveto % x y -12 add moveto -\n gsave show grestore\n 0 -3 rmoveto % leading (space between lines)\n} def\n/showcomment { % (text) showcomment - \n % shows (text) top-justified at current point, moves down 1 line\n 0 -10 rmoveto \n gsave /Helvetica 10 selectfont show grestore\n 0 -2 rmoveto % leading (space between lines)\n} def\n\n(Simple pdfmark form example) 10 290 showlabel\n\n\n% AcroForm dictionary setup. From pdfmark Reference, Example 5.11, p.70\n%\n% Read also PDF specification PDF32000:2008 \n% "Document management \xe2\x80\x94 Portable document format \xe2\x80\x94 Part 1: PDF 1.7",\n% Section 12.7 "Interactive Forms", p.430\n% To understand the syntax: [/_objdef {foo} /type /dict /OBJ pdfmark\n% read carefully pdfMark reference, "User-defined named objects", p.13.\n\n% Define font objects for the widgets to use\n[ /_objdef {ZaDb} /type /dict /OBJ pdfmark\n[ {ZaDb} <<\n /Type /Font\n /Subtype /Type1\n /Name /ZaDb\n /BaseFont /ZapfDingbats\n>> /PUT pdfmark\n[ /_objdef {Helv} /type /dict /OBJ pdfmark\n[ {Helv} <<\n /Type /Font\n /Subtype /Type1\n /Name /Helv\n /BaseFont /Helvetica\n % /Encoding {pdfDocEncoding} % for simplicity, use font\'s own encoding\n % pdfmark Reference, Example 5.11, p.70, provides an Encoding\n % array defining PDFDocEncoding\n>> /PUT pdfmark\n\n[ /_objdef {aform} /type /dict /OBJ pdfmark\n\n% Define Fields array of Acroform dictionary. It will contain entries for\n% each of the widgets defined below.\n% NOTE: It is not necessary to explicitly assign the widget annotations\n% to the Fields array; Acrobat does it automatically when the file is\n% opened. \n\n[ /_objdef {afields} /type /array /OBJ pdfmark\n[ {aform} <<\n /Fields {afields}\n /DR << /Font << /ZaDb {ZaDb} /Helv {Helv} >> >>\n /DA (/Helv 0 Tf 0 g)\n /NeedAppearances true\n % "/NeedAppearances true" tells reader \'to construct appearance\n % streams and appearance dictionaries for all widget annotations\n % in the document...\' --PDF32000:2008 Table 218 p.431\n>> /PUT pdfmark\n\n% Put Acroform entry in catalog dictionary\n[ {Catalog} << /AcroForm {aform} >> /PUT pdfmark\n\n\n% Example 5.12 Define the Widget annotations\n% pdfmark Reference pp. 72-75, with clarifications by Jim DeLaHunt\n%\n% These Widget annotations are also field dictionaries for this form.\n% This is the collection of all individual widget annotations. \n% It is possible to have multiple instances of these sections, such as\n% for defining a single widget on each instance.\n%\n% See PDF32000:2008 Section 12.5.6.19 "Widget Annotations", p.408\n% especially tables 188 and 189.\n\n(/Tx text field) 10 260 showlabel\n(with Javascript) showcomment (validation) showcomment\n[ /Subtype /Widget\n /Rect [100 223 245 260]\n /F 4\n /T (SL Text)\n /FT /Tx\n /DA (/Helv 14 Tf 0 0 1 rg)\n /V (5)\n /AA <<\n /K << \n /S /JavaScript \n /JS (AFNumber_Keystroke\\(2, 0, 0, 0, "$", true\\);)\n >>\n /F << \n /S /JavaScript \n /JS (AFNumber_Format\\(2, 0, 0, 0, "$", true\\);)\n % pdfmark Reference p.72 seems to omit closing ")" above. Oops.\n >>\n >>\n/ANN pdfmark\n\n(/Btn field) 10 208 showlabel\n(Check Box) showcomment\n[ /Subtype /Widget\n /Rect [100 172 136 208]\n /F 4\n /T (Check Box)\n /FT /Btn\n /DA (/ZaDb 0 Tf 0 g)\n /AS /Off\n /MK << /CA (4)>>\n /AP << /N << /Oui /null >> >>\n/ANN pdfmark\n\n(/Ch field) 10 160 showlabel\n(List Box) showcomment\n[ /Subtype /Widget\n /Rect [100 87 137 160]\n /F 4\n /T (List Box)\n /FT /Ch\n /DA (/Helv 10 Tf 1 0 0 rg)\n /Opt [(1)(2)(3)(4)(5)]\n /DV (3)\n /V (3)\n /MK <<\n /BG [1 1 1] % Background: white\n /BC [0 0 0] % Border colour: black\n >>\n % MK is \'An appearance characteristics dictionary (see Table 189)\'\n % --PDF32000:2008 Table 188 p.408\n % Without an /MK entry, Acrobat Pro 8.0 complains of an error\n % when displaying this field, and some entries aren\'t displayed.\n\n/ANN pdfmark\n\n(/Btn button) 160 85 showlabel\n(/S /SubmitForm action) showcomment\n% Example of how the /MK dictionary is used.\n[ /Subtype /Widget\n /Rect [ 130 10 270 50 ]\n /F 4\n /T (Submit)\n /FT /Btn\n /H /P\n /A << \n /S /SubmitForm \n /F (http://posttestserver.com/post.php) % Thanks, Henry!\n /Flags 16#6 % IncludeNoValueFields, ExportFormat\n >>\n /DA (/HeBo 18 Tf 0 0 1 rg)\n /Ff 65536\n /MK <<\n /BC [ 1 0 0 ]\n /BG [ 0.75 0.45 0.75 ]\n /CA (Submit)\n /AC (Submitted!)\n >>\n /BS <<\n /W 3\n /S /I\n >>\n/ANN pdfmark\n\n% When pressing the Submit button in Adobe Acrobat Professional 8.3.1,\n% there is a pause, and then Acrobat displays a PDF file with the\n% results of the HTTP POST operation. This is text like,\n% Successfully dumped 3 post variables. View it at\n% http://www.posttestserver.com/data/2012/03/04/01.29.271751566025 \n% Post body was 0 chars long.\n%\n% Browse to that URL, and you will see diagnostics with the following:\n% ....\n% Post Params:\n% key: \'Check_Box\' value: \'Oui\'\n% key: \'List_Box\' value: \'4\'\n% key: \'SL_Text\' value: \'3.14\'\n% Empty post body.\n\nshowpage % make sure a page gets produced\n
Run Code Online (Sandbox Code Playgroud)\n\n在 PDF 阅读器中打开生成的 PDF 文档。更改表单中的值。请注意,顶部文本字段将您限制为具有两位小数的数字,并且它$
在数字前面放置了一个符号。它使用 Javascript 代码来完成此操作。Oui
有一个复选框,选中时会发送值。
当您单击该Submit
按钮时,PDF 阅读器会获取每个表单字段的键以及该字段的值,并通过调用将它们发送到 URL HTTP POST
。我使用的目的地是Henry 的 HTTP Post Dumping Server。服务器返回对 POST 的文本回复,并提供一个 URL,您可以在其中查看服务器收到的内容。Adobe Acrobat Professional 将此回复转换为 PDF 文件,这可能需要几秒钟的时间。访问该 URL,您可以看到您要查找的 field_name/value 对。
使用 PERL 模块 PDF::API2
\n\n我对 Perl 不太有经验,也从未使用过PDF::API2 模块。然而,从代码检查来看,我怀疑使用 PDF::API2 生成 PDF 表单并不简单。
\n\nPDF ::API2::Annot子模块看起来确实很有前途。但为了使用上面示例程序的方法,必须创建/Subtype /Widget
. 看来PDF::API2::Annot不支持这一点。
查看PDF::API2::Annot的源代码,可以看到它如何处理其他注释类型的示例。例如,链接注释类型部分是由如下代码创建的:
\n\n$self->{Subtype}=PDFName(\'Link\');\n
Run Code Online (Sandbox Code Playgroud)\n\n如果支持 Widget 注释,人们会期望看到类似$self->{Subtype}=PDFName(\'Widget\')
. Widget
但此模块(版本 2.019)中没有该字符串的实例。因此,可能需要对此模块进行扩展以支持 Widget 注释。
现在注释只是具有特定内容的 PDF 词典。可能可以使用PDF::API2::Basic::PDF::Dict从基本部分构造 Widget 注释。但是,我猜测这比扩展PDF::API2::Annot还要更多工作。
\n\n以这个问题及其吸引的赏金作为一个标志:如果有人将 Widget 注释支持添加到PDF::API2::Annot,并且也许制作一个PDF::API2::Form模块,将会非常高兴!
\n