我用eforms
它来创建可以应用数字签名的 PDF。每个文档可能有一个以上的数字签名字段,也就是说,文档可以在人与人之间传递。
这里增加了复杂性,因为根据解析到自定义命令的参数,\mySigField{...}
用户名和标题字段可以编辑也可以不编辑。换句话说,第 4 个和第 5 个参数分别代表姓名和职位。如果这些输入参数为空,则会创建一个可编辑字段,如果它们包含某些内容,则会打印这些内容,并且不会创建任何可编辑字段。
我的问题是,如果至少有一个可编辑的相关字段,那么在特定用户签名后,我该如何锁定该字段。
以下示例输出:
由以下代码生成:
\documentclass{article}
\usepackage{varwidth}
\usepackage{hyperref}
\usepackage[pdftex]{eforms}
\usepackage{xcolor}
\usepackage{xifthen}
\def\colFeat{blue!50!black} %Feature Color 1 for Main Color Theme.
\makeatletter
\def\eq@SigField{\centerWidget\eq@rectH
\if\autoCenter n\eqcenterWidget=0pt\fi
\leavevmode\hbox{\pdfstartlink user{\common@SigFieldCode}%
\lower\eqcenterWidget\Bbox{\eq@rectW}{\eq@rectH}\pdfendlink}%
\endgroup
}
\makeatother
\newcommand{\mySigField}[5]{
\begin{varwidth}{#2}
\textcolor{\colFeat}{
\fcolorbox{black!5!white}{black!5!white}{\sigField{#1}{#2}{#3}}\\[1mm]
\rule{#2+3mm}{2pt}\\[2mm]
\begin{tabular}{rl}
\raggedleft Name: & \ifthenelse{\equal{#4}{}}{\TextField[name=name#1,width=6cm]{}}{#4}\\\\[-3mm]
\raggedleft Position: & \ifthenelse{\equal{#5}{}}{\TextField[name=pos#1,width=6cm]{}} {#5}
\end{tabular}
}
\end{varwidth}
}
\begin{document}
\def\WS{8cm}
\def\HS{2.5cm}
\section{Example of No Related Fields}
\mySigField{PERSONA}{\WS}{\HS}{John Smith}{Garbo}
\section{Example of One Related Field}
\mySigField{PERSONB}{\WS}{\HS}{Jane Doe}{}
\section{Example of Two Related Fields}
\mySigField{PERSONC}{\WS}{\HS}{}{}
\end{document}
答案1
根据PDF 规范(第 446f 页),可以指定一旦签名字段被签名就不再更改的表单字段,即所谓的签名字段锁定字典. 随着eforms
包中,执行此操作的签名字段的代码\mySigField
将是:
\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}
应锁定的表单字段的名称在圆括号中给出。其他可能的规范是\Lock{/Action/All}
锁定所有表单字段,以及\Lock{/Action/Exclude/Fields [(field1)(field2)...]}
锁定除指定字段之外的所有字段。
在您的示例中,如果提供了名称和位置的一个或两个参数,则上述代码将指定不存在的表单字段,因此使用一系列条件可能会更清晰:
\ifthenelse{\equal{#4}{}}%
{\ifthenelse{\equal{#5}{}}%
{\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}}%
{\sigField[\Lock{/Action/Include/Fields [(name#1)]}]{#1}{#2}{#3}}%
}%
{\ifthenelse{\equal{#5}{}}%
{\sigField[\Lock{/Action/Include/Fields [(pos#1)]}]{#1}{#2}{#3}}%
{\sigField{#1}{#2}{#3}}%
}%
不幸的是,我无法测试它是否能按预期工作,因为我没有 Adobe Acrobat 来实际用签名填充其中一个字段。
答案2
我想发布该解决方案的最终代码,该代码由上面的 diabonas 提供。
我既可以在 Adobe Professional 中打开它并签名,也可以将文件拖到 Web 浏览器中并执行相同操作。据推测,这是因为 Adobe Professional 劫持了我的浏览器 pdf 插件。
放入序言中:
\usepackage{eforms}
\makeatletter
\def\eq@SigField{%
\centerWidget\eq@rectH%
\if\autoCenter n\eqcenterWidget=0pt\fi%
\leavevmode\hbox{\pdfstartlink user{\common@SigFieldCode}%
\lower\eqcenterWidget\Bbox{\eq@rectW}{\eq@rectH}\pdfendlink%
}%
\endgroup%
}
\makeatother
\newcommand{\mySigField}[5]{
\begin{varwidth}{#2}
\textcolor{\colFeat}{
\fcolorbox{black!5!white}{black!5!white}{
\ifthenelse{\equal{#4}{}}%
{\ifthenelse{\equal{#5}{}}%
{\sigField[\Lock{/Action/Include/Fields [(name#1)(pos#1)]}]{#1}{#2}{#3}}%
{\sigField[\Lock{/Action/Include/Fields [(name#1)]}]{#1}{#2}{#3}}%
}%
{\ifthenelse{\equal{#5}{}}%
{\sigField[\Lock{/Action/Include/Fields [(pos#1)]}]{#1}{#2}{#3}}%
{\sigField{#1}{#2}{#3}}%
}%
}\\[1mm]
\rule{#2+3mm}{2pt}\\[2mm]
\begin{tabular}{rl}
\raggedleft Name: & \ifthenelse{\equal{#4}{}}{\TextField[name=name#1,width=6cm]{}}{#4}\\\\[-3mm]
\raggedleft Position: & \ifthenelse{\equal{#5}{}}{\TextField[name=pos#1,width=6cm]{}} {#5}
\end{tabular}
}
\end{varwidth}
}
然后在实际文档中:
可以使用以下命令创建签名字段:
\mySigField{\KEY}{\HEIGHT}{\WIDTH}{\NAME}{\POSITION}
注意到:
- 对于多个签名,\KEY 应该定义并且每个签名块都是唯一的
- \HEIGHT 和 \WIDTH ...不言自明。
- \NAME 和 \POSITION 可以留空或填写。如果留空,则会创建一个字段,然后在最终用户签名时锁定该字段。这就是为什么密钥需要唯一的原因,因为字段需要链接到签名。
最终签名面板如下所示:
签名后看起来像这样。 [该字段不可更改]
最后,请注意,我已检查了只有一个字段的行为,并且该单个字段位于任一位置。在这两种情况下,签名后所有内容都会锁定。