8

これが状況です。自動的に生成された PDF フォーム フィールド名を含む PDF があります。問題は、これらの名前があまりユーザーフレンドリーではないことです。それらは次のようになります: topmostSubform[0].Page1[0].Website_Address[0]

それらを WebsiteAddress のようなものに変更できるようにしたいと考えています。私はABCPDFにアクセスでき、iTextSharpの経験がありますが、これらのAPIを使用してこれを実行しようとしました(フォームフィールドにアクセスして名前を変更しようとしました)が、可能ではないようです.

ある種のAPI(できればオープンソース)を介してこれを試みた経験がある人はいますか。コードも.Netです。

4

9 に答える 9

12

良いニュース: 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();
}

悪いニュース: 名前が変更されたフィールドで使用できる文字に制限があるようです。

上記のスニペットをサンプル フィールド名でテストしましたが、うまくいきませんでした。ただし、ピリオドを削除すると機能します。回避策があるかどうかはわかりませんが、これは問題になる可能性があります。

于 2010-02-27T08:30:09.883 に答える
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 のすべてのフィールドを繰り返し処理し、部分的な名前に基づいてフィールドに代替名を挿入します。

VB スクリプト:

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

に変更"/TU:text"する"/T:text"と、フィールドの部分的な名前が設定されます。

使用される関数の C# および VB.NET で記述された例は、ここにあります: Doc.GetInfoDoc.SetInfoObject Pathsのドキュメントも参照してください。

于 2010-05-27T03:59:48.717 に答える
6

I had the problem yesterday and after trying out answers in the forum and others but made no headway. My code looked like this.

// 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;

And that did the job

于 2012-11-13T10:45:45.603 に答える
3

多分あなたはこれを考えることができます:

  • iText は、独自のソフトウェア環境 (2.1.7 の最後の「無料」バージョン) では無料ではありませ
  • AbcPDFも無料ではありません。

私たちはAbcPDFライセンスを持っており、JavaプロジェクトでもiText 2.1.7を使用していると言わざるを得ません...したがって、以前の回答に同意すると言えますが、この製品を使用/購入できない場合は、 PDF仕様に従って、名前を純粋なpdfコード(プレーンtxtファイルとして)に置き換えてみてください:

署名フィールドの例:

35 0 obj
<<
/AP <<
/N 37 0 R
>>
/DA (/TimesRoman 0 Tf 0 g)
/F 4
/FT /Sig
/P 29 0 R
/Rect [ 86 426 266 501 ]
/Subtype /Widget
/T (FIELD_MODIF)
/Type /Annot
/V 36 0 R
>>
endobj

「FIELD_MODIF」は NEW 名を入れる場所です。

于 2013-04-10T07:08:52.683 に答える
2

JavaScript を使用してフィールドの名前を変更することはできませんが、新しいフィールドを追加したり、既存のフィールドを削除したりできます。ドキュメント間でカット アンド ペーストすることもできます。そう...

1 つ。名前変更スクリプトを作成します。例:

    var doc = app.activeDocs[0];
    var fnames = new Array();
    for ( var i = 0; i < doc.numFields - 1; i++) {      
        fnames[i] = doc.getNthFieldName(i);
    }
    for (var i = 0; i < doc.numFields - 1; i++){        
        var f = doc.getField(fnames[i] + ".0");
        var nfn = fnames[i].replace("1","2");
        var rb = doc.addField(nfn,"radiobutton",0,f.rect)
        for ( var j = 1; j < 9; j++){//Add the other 8
            f = doc.getField(fnames[i] + "." + j);
            doc.addField(nfn,"radiobutton",0,f.rect)
        }
        rb.setExportValues([1,2,3,4,5,6,7,8,9]);
        rb.borderStyle = f.borderStyle;
        rb.strokeColor = f.strokeColor;
        rb.fillColor = f.fillColor;
        doc.removeField(fnames[i]);
        console.println(fnames[i] + " to " + nfn);
    }

注:
フィールドの名前を変更すると、getNthFieldName のフィールドの順序が変わる可能性があるため、最初に取得してください。
ラジオボタンのグループは 1 つのフィールド (getField("Groupname")) です。同じグループの n 番目を取得するには、getField("Groupname.n") を使用します。これらは、位置四角形に必要です。すべてに適用されるプロパティを enmase に設定できます。
addField パラメーターは次のとおりです: フィールド名、フィールド タイプ、ページ、位置四角形)
例では、各グループに 9 つのラジオボタンがあります。

2つ。名前を変更するフィールドを切り取って空白の pdf に貼り付けます (上記の 1 ページを想定しています)。スクリプトを実行します。切り取って貼り付けます。

スクリプトの実行時に両方のドキュメントを開いたままにする場合は、app.activeDocs[0] を app.activeDocs[1] に変更するか、「doc」を「this」に置き換える必要がある場合があります。

于 2013-10-22T23:32:24.350 に答える
0

これは、本「iText in Action」にある Java の例です。

これは、本のサンプル ソース コードから取られたもので、同じ問題で非常に役立ちました。part2.chapter06.ConcatenateForms2

public static void main(String[] args)
    throws IOException, DocumentException {
    // Create a PdfCopyFields object
    PdfCopyFields copy
        = new PdfCopyFields(new FileOutputStream(RESULT));
    // add a document
    PdfReader reader1 = new PdfReader(renameFieldsIn(DATASHEET, 1));
    copy.addDocument(reader1);
    // add a document
    PdfReader reader2 = new PdfReader(renameFieldsIn(DATASHEET, 2));
    copy.addDocument(reader2);
    // Close the PdfCopyFields object
    copy.close();
    reader1.close();
    reader2.close();
}


private static byte[] renameFieldsIn(String datasheet, int i)
    throws IOException, DocumentException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // Create the stamper
    PdfStamper stamper = new PdfStamper(new PdfReader(datasheet), baos);
    // Get the fields
    AcroFields form = stamper.getAcroFields();
    // Loop over the fields
    Set<String> keys = new HashSet<String>(form.getFields().keySet());
    for (String key : keys) {
        // rename the fields
        form.renameField(key, String.format("%s_%d", key, i));
    }
    // close the stamper
    stamper.close();
    return baos.toByteArray();
}
于 2013-05-28T08:11:46.210 に答える
0

はい、フォーム フィールドの名前を変更することは可能です。これに役立つソースコードAPIの経験はありませんが、私の会社のPDF SDKはこれを行うのに役立ちます.少し検索すると、iTextは実際にフォームフィールドの名前を変更できるようです.

于 2010-02-27T08:31:50.073 に答える