2

我正在开发一个应用程序,我需要能够编辑现有的 PDF 表单并以交互方式将 PDF 表单字段拖放到文件上。

表单字段,如下拉、文本、多行文本、单选按钮。目前我正在使用 ActiveX 控件在 Delphi 应用程序中打开 PDF 文件。

但是我只能阅读 PDF 表单,但我希望能够像删除表单字段一样编辑它。

这个想法是在现有的 PDF 表单上添加表单表单并保存它。我尝试过 Gnostice、PowerPDF、quickPDF,但它们不允许像 ADOBE 那样交互式地修改 PDF 文件。这个在线应用程序PDFEscape允许我们以交互方式创建新的和编辑现有的 PDF 表单。

在此处输入图像描述

在 Gnostic 中,我们可以通过编程方式进行编辑,例如:

在此处输入图像描述

问题:

  • 有没有一种方法可以让我们以交互方式编辑 PDF 表单以删除表单字段?
  • 我们可以在 Delphi 中嵌入 Adob​​e 或任何其他软件来编辑现有的 PDF 吗?
4

1 回答 1

7

Acrobat 的完整版包括从 Delphi 代码访问和操作表单域的工具,并支持诸如将表单域添加到文档、通过 OLE 自动化使用代码填充它们以及在不需要它们时删除它们等操作。

您当然可以在自己的应用程序中托管一个 Acrobat 窗口,以便它在 TPanel 中显示 fi。您可以使用OpenInWindowExAcrobat_TLB.Pas 中的 CAcroAVDoc 对象的方法来执行此操作。但是,这仅绘制 PDF 文档(加上注释/注释,iirc),它不提供显示或提供对 Acrobat gui 的访问。我知道从 Delphi 应用程序执行此操作的唯一方法是在 TOleContainer 对象中打开 Pdf 文件,但如果您这样做,Acrobat 的 gui 将在其自己的窗口中打开,而不是托管在您的窗口中。如今,OleContainer 界面在屏幕上看起来非常古老。

因此,如果您想与 Acrobat 的表单域编辑器 gui 交互,我认为您会遇到困难。另一方面,您可以使用自己的 DIY 代码操作表单字段并填写它们 - 请参见下面的示例。

要在代码中操作表单域,您需要将 Acrobat Forms 类型库导入 Delphi。
您需要导入的类型库相当于

D:\Program Files\Adobe\Acrobat 8.0\Acrobat\plug_ins\AcroForm.api 

您可能需要使用 Delphi 的 TRegSvr 实用程序(或 Windows 的 RegSvr32)向 Windows 注册此文件;

这使您可以访问 IAFormApp 对象,该对象是用于处理表单的顶级对象,以及用于创建单个字段的 IField 对象。

如果您有 Acrobat SDK 文档,通过 Ole 自动化使用这些对象的方法在“应用程序间通信 API 参考”(iac_api_reference.pdf) 中进行了描述。我在下面包含了 IFIeld 接口的 Delphi 导入,以便您可以看到可以用它做的各种事情。

“有没有一种方法可以让我们以交互方式编辑 PDF 表单以删除表单字段?”

在 Acrobat 中打开表单后,是的,您可以删除一个字段(如果“删除”是指“删除”)。您可以通过调用RemoveIFields 接口的方法在代码中执行此操作。如果,otoh,您的意思是“我们可以在表单上删除字段”,那么可以,您也可以这样做,方法是创建可用字段列表并从列表中选择一个字段。

“我们可以在 Delphi 中嵌入 Adob​​e 或任何其他软件来编辑现有的 PDF 吗?”

是的,以下示例显示了如何从 Delphi 代码中填写现有字段并添加新字段:

implementation

{$R *.DFM}

uses
  AFORMAUTLib_TLB, Acrobat_TLB;

const
  scDocument = 'D:\delphi\code\acrobat\blank.pdf';

procedure TForm1.FillInForm;
var
  Acrobat : CAcroApp;
  AVDoc : CAcroAVDoc;
  PDDoc : CAcroPDDoc;
  FormApp : IAFormApp;
  Fields : IFields;
  Field : IField;
begin
  Acrobat := CoAcroApp.Create;
  AVDoc := CoAcroAVDoc.Create;
  AVDoc.Open(scDocument, scDocument);
  PDDoc := AVDoc.GetPDDoc as CAcroPDDoc;

  FormApp := CoAFormApp.Create;

  Fields := FormApp.Fields as IFields;
  Field := Fields.Item['Text1'] as IField;
  Field.Value := 'My test';

  Field := Fields.Add('AnotherField', 'text',
  0,
  360,
  790,
  360 + 200,
  790 - 30) as IField;

  Field.Value := 'Added';
end;

顺便说一句,我不确定您是否打算问这个问题,但也可以在 Delphi 应用程序的窗口中托管 Acrobat 的 gui。但是,如果您想了解这一点,则需要在单独的 q 中询问,因为这是一个不同的技术问题。

从 AFORMAUTLib_TLB.Pas 中提取:

*********************************************************************//
    // Interface: IField
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {673E8454-7646-11D1-B90B-00A0C9259304}
    // *********************************************************************//
      IField = interface(IDispatch)
        ['{673E8454-7646-11D1-B90B-00A0C9259304}']
        // getters amd setters omitted
        procedure SetBorderColor(const bstrColorSpace: WideString; GorRorC: Single; GorM: Single; 
                                 BorY: Single; K: Single); safecall;
        procedure SetBackgroundColor(const bstrColorSpace: WideString; GorRorC: Single; GorM: Single; 
                                     BorY: Single; K: Single); safecall;
        procedure SetJavaScriptAction(const bstrTrigger: WideString; const bstrTheScript: WideString); safecall;
        procedure SetSubmitFormAction(const bstrTrigger: WideString; const bstrTheURL: WideString; 
                                      theFlags: Integer; arrFields: OleVariant); safecall;
        procedure SetResetFormAction(const bstrTrigger: WideString; theFlags: Integer; 
                                     arrFields: OleVariant); safecall;
        procedure SetButtonIcon(const bstrFace: WideString; const bstrFullPath: WideString; 
                                pageNum: Smallint); safecall;
        procedure SetForegroundColor(const bstrColorSpace: WideString; GorRorC: Single; GorM: Single; 
                                     BorY: Single; K: Single); safecall;
        procedure PopulateListOrComboBox(arrItems: OleVariant; arrExportVal: OleVariant); safecall;
        procedure SetButtonCaption(const bstrFace: WideString; const bstrCaption: WideString); safecall;
        property Name: WideString read Get_Name;
        property Value: WideString read Get_Value write Set_Value;
        property IsHidden: WordBool read Get_IsHidden write Set_IsHidden;
        property IsTerminal: WordBool read Get_IsTerminal;
        property Type_: WideString read Get_Type_;
        property IsReadOnly: WordBool read Get_IsReadOnly write Set_IsReadOnly;
        property IsRequired: WordBool read Get_IsRequired write Set_IsRequired;
        property PrintFlag: WordBool read Get_PrintFlag write Set_PrintFlag;
        property BorderWidth: Smallint read Get_BorderWidth write Set_BorderWidth;
        property Alignment: WideString read Get_Alignment write Set_Alignment;
        property CharLimit: Smallint read Get_CharLimit write Set_CharLimit;
        property DefaultValue: WideString read Get_DefaultValue write Set_DefaultValue;
        property IsMultiline: WordBool read Get_IsMultiline write Set_IsMultiline;
        property IsPassword: WordBool read Get_IsPassword write Set_IsPassword;
        property CalcOrderIndex: Smallint read Get_CalcOrderIndex write Set_CalcOrderIndex;
        property BorderStyle: WideString read Get_BorderStyle write Set_BorderStyle;
        property Editable: WordBool read Get_Editable write Set_Editable;
        property Highlight: WideString read Get_Highlight write Set_Highlight;
        property Style: WideString read Get_Style write Set_Style;
        property TextFont: WideString read Get_TextFont write Set_TextFont;
        property TextSize: Smallint read Get_TextSize write Set_TextSize;
        property ButtonLayout: Smallint read Get_ButtonLayout write Set_ButtonLayout;
        property NoViewFlag: WordBool read Get_NoViewFlag write Set_NoViewFlag;
      end;

2021 年 11 月 11 日更新

我正在更新此答案以响应已删除的非答案,该答案要求提供有关如何在较新版本的 Delphi 中生成导入单元 Acrobat_Tlb.Pas 和 AFORMAUTLib_TLB.Pas 的确切详细信息。

以下方法适用于从 Adob​​e 在线商店和 Delphi 10.4.2 购买并安装的“Adobe Acrobat Standard 2020”。

对于 Acrobat_Tlb.Pas

  1. 创建一个新的 VCL 项目并保存该项目及其表单文件。

  2. 在 IDE 中,转到组件 | 导入组件并选择导入类型库

  3. 单击下一步,然后在注册类型库选项卡上,放大描述列的宽度,以便查看完整描述。

  4. 向下滚动到其描述只是 Acrobat 的条目。单击向导的其余选项卡,如果您有正确的项目,则下一个选项卡上的 ClassName(s) 框将包含“AcroApp=TAcroApp, AcroAVDocs=...”

    在下一个选项卡上,选择 Create Unit 单选按钮。然后单击完成,将创建 Acrobat_Tlb.Pas。

对于 AFORMAUTLib_Tlb.Pas

对 Acrobat_Tlb.Pas 重复这些步骤,并进行以下更改:

  1. 在第 4 步中,您想要的描述是 AFormAut 1.0 类型库,下一个选项卡上的 ClassName(s) 框应包含“AFormApp=TAFormApp,Fields= ...”,生成的导入单元应为 AFORMAUTLib_TLB.Pas
于 2016-03-21T08:29:40.227 回答