不使用SOAP,从PDF表单连接数据库
不使用SOAP协议,通过XFDF格式实现PDF表单与数据库交互的方法。该方法兼容免费的Adobe Reader,且无需特殊权限设置。
背景与问题
-
历史方案:
- Adobe曾提供ADBC接口(基于ODBC),但在Acrobat 9后被移除。
- SOAP方案在免费版Reader中无法使用。
-
新方案核心:
使用XFDF(XML版本的FDF)作为数据交换格式,通过PHP脚本作为中间层连接PDF表单与数据库。
FDF与XFDF格式对比
FDF示例
%FDF-1.2
%âãÏÓ
1 0 obj
<</FDF<</F (testXFDF.pdf)/Fields[<</T (Field 1)/V (test data)>>]>>
>>
endobj
XFDF示例
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"><fields><field name="Field 1"><value>test data</value></field></fields>
</xfdf>
优势: XFDF基于XML,更易解析和生成。
实现步骤
1. 提交表单数据到服务器
PDF表单通过submitForm()
方法以XFDF格式提交数据到PHP脚本。
2. 服务器端处理(PHP)
基础接收脚本
<?php$myXFDF = file_get_contents("php://input");echo "Received some data.";
?>
返回数据到表单
<?phpheader('Content-type: application/vnd.adobe.xfdf');$returnXFDF = <<<EOT
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"><fields><field name="Field 1"><value>Updated Value</value></field></fields>
</xfdf>
EOT;echo $returnXFDF;
?>
关键点: URL需附加#XFDF
以告知Acrobat返回格式。
完整PHP解决方案
功能
- 解析接收的XFDF数据。
- 生成数据库唯一序列号。
- 返回更新后的XFDF数据。
核心代码
<?phpfunction getNextSerial($userName) {$mysqli = new mysqli("localhost", "theUser", "thePassword", "serialnumbers");if (mysqli_connect_errno()) {printf("Connect failed: %s\n", mysqli_connect_error());exit();}$query = "INSERT INTO serialnumbers (username, date) VALUES (\"" . $mysqli->real_escape_string($userName) . "\", NOW())";$mysqli->query($query);$idx = $mysqli->insert_id;$mysqli->close();return $idx;}function createXFDF($info, $enc='UTF-8', $file=''){$domtree = new DOMDocument('1.0', $enc);$xmlRoot = $domtree->createElement("xfdf");$xmlRoot->appendChild($domtree->createAttribute('xmlns'))->appendChild($domtree->createTextNode("http://ns.adobe.com/xfdf/"));$xmlRoot = $domtree->appendChild($xmlRoot);$fields = $domtree->createElement("fields");addXFDFData($domtree, $fields, $info);$xmlRoot->appendChild($fields);header('Content-type: application/vnd.adobe.xfdf');echo $domtree->saveXML();}$myXFDF = new DOMDocument('1.0');$myXFDF->load("php://input");$xpath = new DOMXpath($myXFDF);$xpath->registerNameSpace('xfdf', 'http://ns.adobe.com/xfdf/');$elements = $xpath->query("//xfdf:fields/xfdf:field[@name='UserName']")->item(0);$userName = "";if ($elements instanceof DomElement) {$userName = $elements->nodeValue;}if (strcmp($userName, "") !== 0) {$serialNumber = getNextSerial($userName);$info = array("SerialNumber" => $serialNumber);createXFDF($info);}
?>
注意事项
-
浏览器兼容性:
Chrome/Firefox等浏览器内置PDF查看器不支持此功能,必须使用Adobe Acrobat或Reader。 -
安全性:
Acrobat会提示用户确认是否允许提交操作。 -
部署建议:
- 确保服务器支持PHP。
- 根据实际需求调整数据库连接和字段映射。
最后
通过XFDF和PHP中间层,实现了PDF表单与数据库的无缝交互,解决了SOAP和ADBC的限制问题。适用于需要动态填充或提交数据的PDF表单场景。