问题与itextsharp

时间:2010-11-26 16:54:25

标签: vb.net itextsharp

我有一个包含数百个字段的PDF文档。所有字段名称都包含句点,例如“page1.line1.something”

我想删除这些句号并将其替换为下划线或(更好)一无所有

在itextsharp库中似乎存在一个错误,如果字段有句点,则renamefield方法不起作用,因此以下内容不起作用(始终返回false)

Dim formfields As AcroFields = stamper.AcroFields
Dim renametest As Boolean
renametest = formfields.RenameField("page1.line1.something", "page1_line1_something")

如果该字段中没有句号,则表示正常。

是否有人遇到此问题并且有解决方法吗?

2 个答案:

答案 0 :(得分:1)

如果您在字段名称中使用句点,则只能重命名最后一部分,例如在page1.line1.something只有“某事”可以重命名。这是因为“page1”和“line1”被adobe视为“某事”字段的父母

我需要删除此层次结构并将其替换为展平结构

我是通过

做到的
  1. 为每个字段创建pdfdictionary对象
  2. 将每个字段所需的注释读入数组
  3. 删除我的(pdfstamper)文档中的字段层次结构
  4. 从我的数组数据中创建一组新字段
  5. 如果你想看看我是怎么做的,我已经为此创建了一些sample code

答案 1 :(得分:1)

这是一个AcroForm表单还是LiveCycle Designer(xfa)表单?

<击>

如果它是XFA(可能是字段名称),iText无法帮助您。它只能在使用XFA时获取/设置字段值。

好的,一个AcroForm。我建议您直接操作现有的字段字典和acroForm字段列表,而不是使用源代码中使用的路径。

对于iText,我是一名Java原生,所以你必须做一些翻译,但是这里有:

A)删除AcroForm的字段数组。如果存在(/ CO),则单独保留计算顺序。我想。

PdfDictionary acroDict = reader.getCatalog().getAsDictionary(PdfName.ACROFORM);
acroDict.remove(PdfName.FIELDS);

B)将所有“顶级”字段附加到新的FIELDS数组。

PdfArray newFldArray = new PdfArray();
acroDict.put(newFldArray, PdfName.FIELDS);

// you could wipe this between pages to speed things up a bit
Set<PdfIndirectReference> radioFieldsAdded = new HashSet<PdfIndirectReference>();

int numPages = reader.getNumberOfPages();
for (int curPg = 1; curPg <= numPages; ++curPg) {
  PdfDictionary curPageDict = reader.getPageN(curPg);
  PdfArray annotArray = curPageDict.getAsArray(PdfName.ANNOTS);
  if (annotArray == null)
    continue;

  for (int annotIdx = 0; annotIdx < annotArray.size(); ++annotIdx) {
    PdfIndirectReference fieldReference = (PdfIndirectReference) annotArray.getAsIndirect(annotIdx);
    PdfDictionary field = (PdfDictionary)PdfReader.getObject(fieldReference);

    // if it's a radio button
    if ((PdfFormField.FF_RADIO & field.getAsNumber(PdfName.FF).intValue()) != 0) {
       fieldReference = field.get(pdfName.PARENT);
       field = field.getAsDict(PdfName.PARENT); // looks up indirect reference for you.

       // only add each radio field once.
       if (radioFieldsAdded.contains(fieldReference)) {
         continue;
       } else {
         radioFieldsAdded.add(fieldReference);
       }
    }

    field.remove(PdfName.PARENT);

    // you'll need to assemble the original field name manually and replace the bits
    // you don't like.  Parent.T + '.' child.T + '.' + ...
    String newFieldName = SomeFunction(field);
    field.put(PdfName.T, new PdfString( newFieldName ) );

    // add the reference, not the dictionary
    newFldArray.add(fieldReference)
  }
}

C)清理

reader.removeUnusedObjects();

缺点:
更多工作。

优点:
维护所有字段类型,属性,外观,并且不会将文件作为一个整体更改。减少CPU和存储器中。

您现有的代码会忽略字段脚本,所有字段标记(只读,隐藏,必需,多行文本等),列表/组合,单选按钮以及其他一些其他的结果。