Ajoutez FPdfMerge à la clause uses pour activer TPdfNavigationMergeHelper.MergeFilesWithNavigation, ou appelez la fonction globale MergePdfFilesWithNavigation avec un document de destination explicite
Le helper prépare l’importation native des pages, reconstruit les signets hiérarchiques, combine les destinations nommées, réassocie les liens de page et rouvre indépendamment le résultat avant de remplacer le document appelant
pmnPreserve conserve la hiérarchie source ; pmnGroupBySource ajoute un titre portant le nom de chaque fichier source
Les titres, relations parentales, styles, couleurs, branches développées, actions URI et destinations internes résolues sont conservés ; les pages sélectionnées, répétées ou réordonnées ciblent leur première occurrence importée, et les destinations vers des pages omises deviennent des titres
Les signets déjà présents dans la destination sont décalés lors de l’insertion des pages ; les fichiers source restent ouverts sans partage en écriture pendant la capture de la navigation et l’importation native
Seule la fusion avec arrêt sur erreur est prise en charge ; les destinations signées, actions de signet non prises en charge et traitements ultérieurs chiffrés sont refusés avec un rapport d’erreur ; un échec ou une annulation préserve le document appelant
Cette API conserve la politique native existante des formulaires ; utilisez FPdfFormMerge pour une gestion avancée des collisions de champs AcroForm et de leurs ressources
PreserveNamedDestinations et PreservePageLinks valent tous deux True par défaut ; mettre une option à False désactive cette partie du traitement de navigation supplémentaire
Les destinations nommées sont lues dans l’ancien dictionnaire /Dests du catalogue et dans l’arbre de noms /Names/Dests, y compris les arbres hiérarchiques, tableaux indirects et dictionnaires contenant /D ; si les deux définissent la même clé, l’arbre de noms est prioritaire
Le résultat utilise un arbre /Names/Dests équilibré et conserve les autres arbres de noms de la destination, notamment /EmbeddedFiles ; les arbres source sans rapport avec les destinations ne sont pas importés
Les clés gardent leurs octets de chaîne PDF originaux, y compris l’encodage UTF-16BE ; le mode d’affichage et ses paramètres sont conservés exactement, notamment /FitH null et /XYZ null 34 null
| Politique | Comportement |
|---|---|
pndReject | Une clé source déjà présente dans la destination fait rejeter toute la transaction |
pndRename | La politique par défaut conserve les noms sans conflit et préfixe les autres avec DestinationPrefix, qui vaut Imported_ par défaut ; les collisions suivantes utilisent des préfixes déterministes tels que 2_Imported_Shared |
pndNamespace | Chaque clé source reçoit DestinationPrefix, l’indice source commençant à un et un tiret bas, comme Imported_1_Shared ; les collisions restantes reçoivent un préfixe numérique déterministe |
DestinationPrefix doit contenir de 1 à 256 caractères ASCII imprimables ; pour une clé UTF-16BE, le préfixe est inséré après le BOM
Les annotations de lien internes utilisant /Dest ou une seule action /A /GoTo sont réécrites en destinations explicites ; les cibles nommées restent donc correctes après un renommage de collision
Les pages propriétaires et cibles des liens existants sont décalées à l’insertion ; chaque occurrence d’une page importée plusieurs fois reçoit une annotation indépendante, tandis que ses cibles internes pointent vers la première occurrence sélectionnée de la page cible
Les destinations vers une page omise sont retirées de l’arbre ; le lien concerné perd son /Dest ou son action GoTo, tout en conservant l’annotation et ses autres propriétés
Les liens URI restent intacts ; les actions chaînées avec /Next sont refusées car leur réassociation dépasse le périmètre actuel du helper
Les arbres malformés ou cycliques, références d’objet indisponibles et clés répétées dans l’arbre de noms font rejeter la transaction ; un échec, une annulation ou un budget dépassé laisse le document appelant intact
Les limites par défaut sont de 10,000 signets, une profondeur de 128, 1,048,576 caractères de titre, 10,000 destinations nommées, 100,000 liens de page et 256 MiB de document ; le plafond d’octets du document ne doit pas dépasser MaxInt
Avec le traitement supplémentaire des destinations ou liens activé, la profondeur configurée est limitée à 256, les destinations nommées à 65,536 et les liens à 1,000,000 ; la capture source limite aussi les octets bruts des clés à 1 MiB
Les clés nommées combinées disposent d’un budget d’octets distinct égal à MaxTitleCharacters ; chaque source est capturée dans les budgets configurés avant le filtrage des pages
PreservedNamedDestinationCount compte les destinations nommées finales, RenamedNamedDestinationCount les clés importées modifiées par la politique et RemovedNamedDestinationCount les cibles nommées non résolues ou omises
RemappedPageLinkCount compte les destinations internes finales des liens existants et importés, et RemovedPageLinkCount celles supprimées ; un lien contenant /Dest et GoTo contribue une fois pour chaque destination
type
TPdfMergeNavigationPolicy= (pmnPreserve, pmnGroupBySource);
TPdfMergeNamedDestinationPolicy= (pndReject, pndRename, pndNamespace);
TPdfNavigationMergeOptions= record
NativeOptions: TPdfBatchMergeOptions;
NavigationPolicy: TPdfMergeNavigationPolicy;
MaxOutlineItems: Integer;
MaxOutlineDepth: Integer;
MaxTitleCharacters: Integer;
MaxDocumentBytes: Int64;
PreserveNamedDestinations, PreservePageLinks: Boolean;
NamedDestinationPolicy: TPdfMergeNamedDestinationPolicy;
DestinationPrefix: string;
MaxNamedDestinations, MaxPageLinks: Integer;
class function Default: TPdfNavigationMergeOptions; static;
end;
TPdfNavigationMergeReport= record
Succeeded: Boolean;
Cancelled: Boolean;
ImportedSourceCount: Integer;
ImportedPageCount: Integer;
PreservedOutlineCount: Integer;
RemovedDestinationCount: Integer;
SourceGroupCount: Integer;
PreservedNamedDestinationCount, RenamedNamedDestinationCount: Integer;
RemovedNamedDestinationCount, RemappedPageLinkCount, RemovedPageLinkCount: Integer;
ErrorMessage: string;
end;
// The caller's document is replaced only after the complete staged result
// has been independently reopened and its outline destinations checked
TPdfNavigationMergeHelper= class helper for TPdf
function MergeFilesWithNavigation(const Sources: TPdfBatchMergeSources;
const Options: TPdfNavigationMergeOptions;
out Report: TPdfNavigationMergeReport): Boolean;
end;
function MergePdfFilesWithNavigation(Destination: TPdf;
const Sources: TPdfBatchMergeSources;
const Options: TPdfNavigationMergeOptions;
out Report: TPdfNavigationMergeReport): Boolean;
FPdfCompress expose CapturePdfNavigation et WritePdfNavigation pour gérer soi-même les importations de pages et révisions PDF clairsemées
TPdfNavigationNamedDestination.NameKey contient les octets bruts de la clé PDF ; les numéros de page sont absolus et commencent à un, zéro désignant une cible non résolue
TPdfNavigationPageLink.PageNumber identifie la page propriétaire ; AnnotationIndex est l’indice commençant à zéro parmi toutes les annotations originales et LinkIndex celui parmi les seules annotations de lien
Le writer identifie les liens par LinkIndex, clone chaque annotation avec sa page propriétaire finale et écrit les cibles et suffixes exacts fournis ; l’appelant doit fournir toute la correspondance nécessaire à ses importations
Le writer exige des flux source et sortie distincts et un document non chiffré et non signé ; le refus d’arguments désignant le même flux préserve la source, tandis que les autres échecs vident le flux de sortie distinct
Ces fonctions de flux n’importent aucune page et ne remplacent pas un document TPdf actif ; utilisez la fonction transactionnelle de niveau supérieur pour fusionner toute la navigation
function CapturePdfNavigation(Source: TStream; MaxNamedDestinations, MaxPageLinks, MaxDepth: Integer; out Names: TPdfNavigationNamedDestinations; out Links: TPdfNavigationPageLinks; out ErrorText: string): Boolean; function WritePdfNavigation(Source, Output: TStream; const Names: TPdfNavigationNamedDestinations; const Links: TPdfNavigationPageLinks; ReplaceNamedDestinations: Boolean; out ErrorText: string): Boolean;