Add FPdfFormMerge to enable MergePdfFilesWithForms or TPdfFormMergeHelper.MergeFilesWithForms
The helper stages selected page imports and field grafting, removes orphaned imported widgets and independently reopens the saved result before replacing the caller document; errors and cancellation preserve the destination
pagcpReject rejects a duplicate fully qualified field name, pagcpRename adds a deterministic collision-free prefix and suffix, and pagcpNamespace inserts a real parent field to isolate each source
pagcpMergeCompatible joins compatible terminal text or choice fields so their widgets share one value; it requires equal flags, values, defaults, options and self-contained font semantics and rejects field actions, rich text and incompatible field types
Selected-page filtering prunes unused widgets and fields and preserves the filtered, deduplicated calculation order; default resources are isolated and default appearance names rewritten while cloned appearance streams retain their own resources
Combined field/widgets are normalized before joining compatible fields; independent names remain independently editable after saving and reopening
InsertAt is a zero-based insertion index; -1 appends pages; Default limits are 10,000 total pages and 256 MiB per document, with graft limits of 100,000 objects and depth 128
Hard graft limits are 1,000,000 objects, depth 256 and 4,096 root fields; repeated selected pages, XFA sources or destinations, signed sources or destinations and encrypted destinations are rejected
Source passwords may decrypt a source for the staged merge; the result is unencrypted, so apply an explicit encryption workflow afterward when required
The legacy GraftPdfAcroForm overload retains its reject policy; the overload accepting TPdfAcroFormGraftOptions exposes the same collision and resource policies at stream level
This form helper does not preserve source outlines or named destinations; use the navigation helper for its declared navigation workflow
Options := TPdfFormMergeOptions.Default; Options.GraftOptions.CollisionPolicy := pagcpNamespace; if not MergePdfFilesWithForms(Pdf, Sources, Options, Report) then raise EPdfError.Create(Report.ErrorMessage);
type
TPdfFormMergeOptions= record
GraftOptions: TPdfAcroFormGraftOptions;
InsertAt: Integer;
MaxPages: Integer;
MaxDocumentBytes: Int64;
CancellationToken: IPdfCancellationToken;
class function Default: TPdfFormMergeOptions; static;
end;
TPdfFormMergeReport= record
Succeeded, Cancelled: Boolean;
ImportedSourceCount, ImportedPageCount: Integer;
GraftedFieldCount, RenamedFieldCount, MergedFieldCount: Integer;
FilteredFieldCount, FilteredWidgetCount, ResourceRenameCount: Integer;
ErrorMessage: string;
end;
function MergePdfFilesWithForms(Destination: TPdf;
const Sources: TPdfBatchMergeSources; const Options: TPdfFormMergeOptions;
out Report: TPdfFormMergeReport): Boolean;
type
TPdfFormMergeHelper= class helper for TPdf
function MergeFilesWithForms(const Sources: TPdfBatchMergeSources;
const Options: TPdfFormMergeOptions;
out Report: TPdfFormMergeReport): Boolean;
end;