是否可以修改PDF表单字段名称?

ncy*_*kee 8 .net pdf abcpdf itextsharp

这是情况.我有一个带有自动生成的pdf表单字段名称的PDF.问题是这些名称不是非常用户友好.它们看起来像:topmostSubform [0] .Page1 [0] .Website_Address [0]

我希望能够更改它们,使它们像WebsiteAddress.我可以访问ABCPDF并且我有使用iTextSharp的经验,但我尝试使用这些API来执行此操作(访问表单字段并尝试重命名),但似乎不可能.

有没有人尝试通过某种API(最好是开源)尝试这样做.代码也是.Net.

Jay*_*ggs 10

好消息:您可以在iTextSharp中更改字段名称.

但您无法实际编辑PDF.您已阅读现有PDF,在内存中更新您的字段名称,然后写出您修改后的PDF.要更改字段名称,请调用AcroFields.RenameField方法.

这是一个片段:

PdfReader reader = new PdfReader(PDF_PATH);
using (FileStream fs = new FileStream("Test Out.pdf", FileMode.Create)) {
    PdfStamper stamper = new PdfStamper(reader, fs);
    AcroFields fields = stamper.AcroFields;
    fields.RenameField("oldFieldName", "newFieldName");
    stamper.Close();
}
Run Code Online (Sandbox Code Playgroud)

现在是坏消息:在重命名的字段中可以使用的字符似乎有限制.

我使用您的示例字段名称测试了上面的代码段,但它无法正常工作.删除期间虽然它确实有效.我不确定是否有解决方法,但这对您来说可能是一个问题,


小智 6

AcroForm字段的全名未明确存储在字段中.它实际上是从一个字段层次结构派生出来的,左边是一个以点分隔的祖先列表.

只需将"topmostSubform [0] .Page1 [0] .Website_Address [0]'中的字段重命名为'WebsiteAddress'就不太可能产生正确的结果.

你会发现PDF参考的第8.6.2节"字段字典"提供了字段命名如何工作的一个很好的解释;-)

基本上,AcroForm中的每个字段都由字典定义,字典可能包含与字段名称相关的某些可选条目.

  • 键'/ T'指定部分名称.在您的问题中,'topmostSubform [0]','Page1 [0]'和Website_Address [0]都代表部分名称.

  • 键'/ TU'为字段指定替代的"用户友好"名称,可用于代替实际字段名称以标识用户界面中的字段.

考虑添加/ TU条目,而不是重命名有问题的字段!

下面的示例使用ABCpdf迭代AcroForm中的所有字段,并根据其部分名称在字段中插入备用名称.

VBScript中:

Set theDoc = CreateObject("ABCpdf7.Doc")
theDoc.Read "myForm.pdf"

Dim theFieldIDs, theList
theFieldIDs = theDoc.GetInfo(theDoc.Root, "Field IDs")
theList = Split(theFieldIDs, ",")

For Each fieldID In theList
    thePartialName = theDoc.GetInfo(fieldID, "/T:text")
    theDoc.SetInfo fieldID, "/TU:text", thePartialName
Next

theDoc.Save "output.pdf"
theDoc.Clear
Run Code Online (Sandbox Code Playgroud)

更改"/TU:text""/T:text"将设置字段的部分名称.

用C#和VB.NET编写的函数可以在这里找到: Doc.GetInfo,Doc.SetInfo.另请参阅有关对象路径的文档.


Sol*_*nde 6

我昨天遇到了问题,在论坛和其他人中尝试了答案之后却没有取得任何进展.我的代码看起来像这样.

// Open up the file and read the fields on it.
var pdfReader = new PdfReader(PATH_TO_PDF);
var fs = new FileStream(pdfFilename, FileMode.Create, FileAccess.ReadWrite)
var stamper = new PdfStamper(pdfReader, fs);
var pdfFields = stamper.AcroFields;

//I thought this next line of code I commented out will do it
//pdfFields.RenameField("currentFieldName", "newFieldName");

// It did for some fields, but returned false for others.
// Then I looked at the AcroFields.RenameField method in itextSharp source and noticed some restrictions. You may want to do the same.
//  So I replaced that line  pdfFields.RenameField(currentFieldName, newFieldName); with these 5 lines

AcroFields.Item item = pdfFields.Fields[currentFieldName];
PdfString ss = new PdfString(newFieldName, PdfObject.TEXT_UNICODE);
item.WriteToAll(PdfName.T, ss, AcroFields.Item.WRITE_VALUE | AcroFields.Item.WRITE_MERGED);
item.MarkUsed(pdfFields, AcroFields.Item.WRITE_VALUE);
pdfFields.Fields[newFieldName] = item;
Run Code Online (Sandbox Code Playgroud)

这就完成了工作