Cette page peut contenir du texte traduit automatiquement.

Fusionner des documents PDF en C# et VB.NET

Les entreprises fusionnent souvent des fichiers PDF pour l’archivage de documents. Bien que la fusion de PDF semble simple, elle comporte de nombreux pièges. Vous devez combiner correctement les champs de formulaire, les signets, les calques et les autres objets PDF. Vous devez également éviter les objets dupliqués pour obtenir un fichier de sortie compact.

La bibliothèque Docotic.Pdf gère toutes les subtilités de la fusion. Elle vous permet de combiner des documents PDF en quelques lignes de code C# ou VB.NET.

Fusionner des documents PDF

Docotic.Pdf est fourni avec des licences gratuites et payantes. Obtenez la bibliothèque et une clé de licence gratuite à durée limitée sur la page Télécharger la bibliothèque PDF C# .NET.

Notions de base de la fusion PDF

Les méthodes PdfDocument.Append vous permettent d’ajouter des documents PDF à partir de fichiers, de flux ou de tableaux d’octets. Il existe aussi des options pour ajouter des fichiers protégés et pour fusionner des champs de formulaire.

Combiner deux fichiers PDF

Cet exemple de code montre comment fusionner des fichiers PDF en C# :

using var pdf = new PdfDocument("first.pdf");
pdf.Append("second.pdf");
pdf.Save("merged.pdf");

Essayez l’exemple de code Fusionner deux documents PDF de GitHub.

Combiner des flux PDF

Il est facile d’adapter l’exemple précédent pour travailler avec des flux au lieu de chemins de fichiers. Voici la méthode utilitaire pour fusionner des flux :

void Merge(Stream first, Stream second, Stream result)
{
    using var pdf = new PdfDocument(first);
    pdf.Append(second);
    pdf.Save(result);
}

Combiner plusieurs fichiers PDF

Vous pouvez appeler plusieurs fois la méthode Append pour ajouter plusieurs fichiers PDF :

string[] filesToMerge = ..;
using var pdf = new PdfDocument();
foreach (string file in filesToMerge)
    pdf.Append(file);

// Supprimer la page vide ajoutée par l’appel de PdfDocument()
pdf.RemovePage(0);

pdf.Save(pathToFile);

Combiner des fichiers PDF chiffrés

Il existe des surcharges de Append pour fusionner des documents chiffrés :

using var pdf = new PdfDocument();
pdf.Append("encrypted.pdf", new PdfStandardDecryptionHandler("password"));
pdf.Save("merged.pdf");

Vous trouverez plus d’informations dans l’article Déchiffrer des documents PDF en C# et VB.NET.

Combiner des formulaires PDF

Chaque champ de formulaire dans un document PDF doit avoir un nom unique. Cela peut poser un problème lorsque les documents à fusionner contiennent des champs portant les mêmes noms. Docotic.Pdf fournit les stratégies de fusion suivantes pour les contrôles de formulaire en conflit :

  • Renommer les contrôles ajoutés lorsqu’ils entrent en conflit avec des contrôles existants
  • Fusionner les contrôles ajoutés avec les contrôles existants
  • Aplatir les contrôles ajoutés
  • Ne pas ajouter de contrôles
  • Ajouter les contrôles tels quels

Par défaut, la bibliothèque renomme les contrôles ajoutés en cas de conflit. Vous pouvez choisir une stratégie alternative avec la classe PdfMergingOptions :

using var pdf = new PdfDocument("form.pdf");

var decryptionHandler = new PdfStandardDecryptionHandler(string.Empty);
var mergingOptions = new PdfMergingOptions()
{
    ControlMergingMode = PdfControlMergingMode.CopyAsKids
};
pdf.Append("form.pdf", decryptionHandler, mergingOptions);

pdf.Save("merged.pdf");

Avec le mode CopyAsKids, la bibliothèque fusionne et synchronise les contrôles en conflit. Autrement dit, lorsque vous modifiez un contrôle, le second aura la même valeur.

Réduire le fichier PDF fusionné

Les documents PDF peuvent contenir des objets identiques, comme des polices ou des images. Lorsque vous fusionnez de tels documents, le document résultant contiendra des copies des mêmes objets. Utilisez la méthode PdfDocument.ReplaceDuplicateObjects() pour optimiser le résultat de la fusion :

using var pdf = new PdfDocument("2024-05-28.pdf");
pdf.Append("2024-05-29.pdf");

// accélérer l’écriture des documents intermédiaires
pdf.ReplaceDuplicateObjects();

pdf.Save("merged.pdf");

Vous pouvez réduire davantage la taille du fichier de sortie. Par exemple, vous pouvez supprimer les glyphes de police inutilisés ou compresser les images. Consultez l’article Compresser des documents PDF en C# et VB.NET pour connaître les options de compression prises en charge.

Personnaliser la fusion PDF

Docotic.Pdf fournit des méthodes pour extraire, réordonner ou supprimer des pages PDF. Vous pouvez les utiliser avec la méthode Append pour implémenter des tâches personnalisées de fusion PDF.

Ajouter des pages PDF spécifiques

Docotic.Pdf permet aussi de fusionner une partie d’un document PDF. Il existe différentes façons de le faire. Par exemple, vous pouvez fractionner un document PDF ajouté et ajouter les pages extraites. L’utilitaire C# suivant ajoute les pages sélectionnées au PdfDocument :

private static void AppendPart(PdfDocument pdf, string filePath, params int[] pagesToAppend)
{
    using var streamToAppend = new MemoryStream();
    using var other = new PdfDocument(filePath);
    using var extracted = other.CopyPages(pagesToAppend);
    var options = new PdfSaveOptions
    {
        UseObjectStreams = false
    };
    extracted.Save(streamToAppend, options);

    pdf.Append(streamToAppend);
}

Ou vous pouvez ajouter un document PDF entier et supprimer les pages inutiles. L’exemple de code suivant ajoute les deux premières pages de second.pdf :

using var pdf = new PdfDocument(@"first.pdf");

int pageCountBefore = pdf.PageCount;
pdf.Append(@"second.pdf");
pdf.RemovePages(pageCountBefore + 2);

pdf.Save(pathToFile);

Une autre solution concerne l’imposition PDF. Vous pouvez en lire plus dans la section correspondante.

Ajouter un PDF au début

Les méthodes Append ajoutent toujours des pages à la fin du document courant. Comment fusionner des fichiers PDF dans un ordre différent ? Parfois, vous pouvez modifier l’ordre des appels Append. Autrement dit, utilisez

pdf.Append("first.pdf");
pdf.Append("second.pdf");

au lieu de

pdf.Append("second.pdf");
pdf.Append("first.pdf");

Ou vous pouvez réordonner les pages après la fusion. Ce code C# déplace le document PDF ajouté au début :

using var pdf = new PdfDocument(@"second.pdf");

int pageCountBefore = pdf.PageCount;
pdf.Append(@"first.pdf");
pdf.MovePages(pageCountBefore, pdf.PageCount - pageCountBefore, 0);

pdf.Save(pathToFile);

Pour plus d’informations sur le réordonnancement des pages PDF, consultez :

Imposition PDF

Docotic.Pdf vous permet de combiner plusieurs pages PDF sur une seule page. Utilisez la méthode PdfDocument.CreateXObject(PdfPage) pour créer un objet PdfXObject basé sur une page existante. Dessinez ensuite cet objet avec l’échelle souhaitée. Exemple de code :

using var src = new PdfDocument(@"src.pdf");
using var dest = new PdfDocument();
PdfXObject firstXObject = dest.CreateXObject(src.Pages[0]);
PdfXObject secondXObject = dest.CreateXObject(src.Pages[1]);

PdfPage page = dest.Pages[0];
page.Orientation = PdfPaperOrientation.Landscape;
double halfOfPage = page.Width / 2;
page.Canvas.DrawXObject(firstXObject, 0, 0, halfOfPage, page.Height, 0);
page.Canvas.DrawXObject(secondXObject, halfOfPage, 0, halfOfPage, page.Height, 0);

dest.Save("result.pdf");

Testez le projet d’exemple associé Créer XObject à partir de la page sur GitHub.

Fusionner en tant que pièce jointe

Parfois, vous pouvez avoir besoin d’incorporer un fichier PDF dans un autre en tant que pièce jointe. C’est aussi possible. Vous pouvez également ajouter des liens vers le fichier incorporé sur des pages PDF :

using var pdf = new PdfDocument();

PdfFileSpecification first = pdf.CreateFileAttachment("first.pdf");
pdf.SharedAttachments.Add(first);

var bounds = new PdfRectangle(20, 70, 100, 100);
PdfFileSpecification fs = pdf.CreateFileAttachment("second.pdf");
pdf.Pages[0].AddFileAnnotation(bounds, fs);

pdf.Save("attachments.pdf");

Vous trouverez des exemples de code associés dans le groupe pièces jointes PDF sur GitHub.

Fusionner en parallèle

Lors de la fusion de nombreux fichiers PDF, il est possible de paralléliser le code. La classe PdfDocument n’est pas thread-safe. Nous devons donc utiliser des objets PdfDocument distincts dans différents threads. Consultez l’exemple de code Fusionner des documents PDF dans des fils de discussion parallèles pour plus de détails.

Ce code montre comment combiner des flux PDF en parallèle :

Stream[] documentsToMerge = ..;

int rangeSize = 50;
while (documentsToMerge.Length > rangeSize)
{
    int partitionCount = (int)Math.Ceiling(documentsToMerge.Length / (double)rangeSize);
    var result = new Stream[partitionCount];

    var partitioner = Partitioner.Create(0, documentsToMerge.Length, rangeSize);
    Parallel.ForEach(partitioner, range =>
    {
        int startIndex = range.Item1;
        int count = range.Item2 - range.Item1;
        result[startIndex / rangeSize] = MergeToStream(documentsToMerge, startIndex, count);
    });
    documentsToMerge = result;
}

using PdfDocument final = GetMergedDocument(documentsToMerge, 0, documentsToMerge.Length);
final.Save("merged.pdf");


private static Stream MergeToStream(Stream[] streams, int startIndex, int count)
{
    using PdfDocument pdf = GetMergedDocument(streams, startIndex, count);

    var result = new MemoryStream();

    var options = new PdfSaveOptions
    {
        UseObjectStreams = false // accélérer l’écriture des documents intermédiaires
    };
    pdf.Save(result, options);
    return result;
}

private static PdfDocument GetMergedDocument(Stream[] streams, int startIndex, int count)
{
    var pdf = new PdfDocument();
    try
    {
        for (int i = 0; i < count; ++i)
        {
            var s = streams[startIndex + i];
            pdf.Append(s);
            s.Dispose();
        }

        pdf.RemovePage(0);

        pdf.ReplaceDuplicateObjects();

        return pdf;
    }
    catch
    {
        pdf.Dispose();
        throw;
    }
}

Le code ci-dessus répartit les documents d’entrée en groupes de taille rangeSize. Ensuite, le code fusionne chaque groupe en documents intermédiaires en parallèle. Le processus continue jusqu’à ce que le nombre de documents d’entrée soit suffisamment faible pour la fusion simple.

La solution parallèle n’est pas nécessairement plus rapide que la version à thread unique. Les résultats peuvent varier selon le nombre de documents d’entrée et leur taille. Dans l’exemple de code, la valeur optimale du paramètre rangeSize peut être plus grande ou plus petite. Vous devez mesurer les performances de votre application pour trouver l’implémentation la plus efficace.

Conclusion

Vous pouvez utiliser la bibliothèque Docotic.Pdf pour combiner des documents PDF en C# et VB.NET. Elle permet de fusionner des fichiers, des flux ou des tableaux d’octets. Vous pouvez fusionner des fichiers chiffrés, des formulaires PDF et des pages PDF spécifiques. Docotic.Pdf vous aide aussi à compresser les fichiers résultants et à économiser de l’espace disque.

Essayez les exemples de code du dépôt d’exemples Docotic.Pdf sur GitHub. Vous pouvez obtenir une clé de licence d’évaluation et télécharger la bibliothèque sur la page de téléchargement Docotic.Pdf.