2010-11-26 13 views
1

私は数百のフィールドを持つPDF文書を持っています。フィールド名のすべては、私はこれらの期間を削除して、アンダースコアまたは(より良い)のいずれかでそれらを交換したいな「page1.line1.something」、それらにピリオド、itextsharpの問題

を持っているすべての

で何もないように思われますフィールドがそれにピリオドを持っていない場合は、フィールドには期間がある場合renamefieldメソッドは動作しませんので、次は動作しませんitextsharpライブラリのバグ(常にfalseを返します)

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

ことそれはうまく動作します。

誰もがこの問題に遭遇しましたが、回避策がありますか?

答えて

1

これは、AcroFormフォームまたはLiveCycle Designer(xfa)フォームですか?

iTextはXFA(フィールド名が指定されている可能性が高い)の場合、手助けできません。 XFAで作業する場合にのみフィールド値を取得/設定できます。

いいえ、アクロフォームです。ソースで使われているルートを使うのではなく、既存のフィールド辞書と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 &メモリ。

既存のコードでは、フィールドスクリプト、すべてのフィールドフラグ(読み取り専用、非表示、必須、複数行テキストなど)、リスト/コンボ、ラジオボタン、その他のオッズとエンドを無視します。

+0

XFAフォームではありません –

+0

助けてくれてありがとう、返信遅れて申し訳ありません –

1

フィールド名にピリオドを使用すると、最後の部分のみ名前を変更することができます。 page1.line1に何か "something"だけをリネームすることができます。 「ページ1」と「LINE1は、」私はこの階層を削除し、

により平坦化された構造

私はこれをしなかったとそれを置き換えるために必要な

「何か」フィールドに親としてAdobeが扱われるためです

  1. 私は(pdfstamper)文書
  2. のフィールド階層を削除アレイ
  3. に各フィールドに必要な注釈を読み取るフィールドごとpdfdictionaryオブジェクト
  4. を作成あなたは、私はそれをやったかを確認したい場合は
  5. 私は、このためのいくつかのsample codeを作成している

私の配列データから、フィールドの新しいセットを作成します。

関連する問題