Questa pagina può contenere testo tradotto automaticamente.

Unisci documenti PDF in C# e VB.NET

Le aziende spesso uniscono i file PDF per l'archiviazione dei documenti. Anche se l’unione di PDF sembra un compito semplice, ci sono molte insidie qui. Dovresti combinare correttamente campi modulo, segnalibri, livelli e altri oggetti PDF. Dovresti anche evitare oggetti duplicati per ottenere un file di output compatto.

Libreria Docotic.Pdf gestisce tutte le sfumature della fusione. Ti consente di combinare documenti PDF in poche righe di codice C# o VB.NET.

Unisci documenti PDF

Docotic.Pdf viene fornito con licenze gratuite e a pagamento. È possibile scaricare la libreria e ottenere una chiave di licenza di valutazione nella pagina di download di Docotic.Pdf.

Libreria Docotic.Pdf 9.4.17467-dev Test di regressione Ne sono passati 14,760 Download totali di NuGet 4,415,970

Nozioni di base sull'unione di PDF

I metodi PdfDocument.Append consentono di aggiungere documenti PDF da file, flussi o array di byte. Sono inoltre disponibili opzioni per aggiungere file protetti e per unire i campi del modulo.

Combina due file PDF

Questo codice di esempio mostra come unire file PDF in C#:

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

Prova l'esempio di codice Unisci due documenti PDF da GitHub.

Combina flussi PDF

È facile adattare l'esempio precedente per lavorare con i flussi invece che con i percorsi dei file. Ecco il metodo di supporto per unire i flussi:

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

Combina più file PDF

Puoi chiamare ripetutamente il metodo Append per aggiungere più file PDF:

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

// Rimuove la pagina vuota aggiunta dalla chiamata PdfDocument()
pdf.RemovePage(0);

pdf.Save(pathToFile);

Combina file PDF crittografati

Esistono sovraccarichi Append per l'unione di documenti crittografati:

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

Puoi trovare maggiori informazioni nell'articolo Decrittografare documenti PDF in C# e VB.NET.

Combina moduli PDF

Ogni campo modulo in un documento PDF deve avere un nome univoco. Ciò potrebbe causare un problema quando i documenti da unire contengono campi con gli stessi nomi. Docotic.Pdf fornisce le seguenti strategie di unione per i controlli dei moduli in conflitto:

  • Rinominare i controlli aggiunti quando sono in conflitto con i controlli esistenti
  • Unisci i controlli aggiunti ai controlli esistenti
  • Appiattire i controlli aggiunti
  • Non aggiungere alcun controllo
  • Aggiungi i controlli così come sono

Per impostazione predefinita, la libreria rinomina i controlli aggiunti in caso di conflitto. Puoi scegliere una strategia alternativa con 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");

Con la modalità CopyAsKids, la libreria unisce e sincronizza i controlli in conflitto. Cioè, quando cambi un controllo, il secondo avrà lo stesso valore.

Riduci il file PDF unito

I documenti PDF possono contenere oggetti identici, come caratteri o immagini. Quando unisci tali documenti, il documento risultante conterrà copie degli stessi oggetti. Utilizzare il metodo PdfDocument.ReplaceDuplicateObjects() per ottimizzare il risultato dell'unione:

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

pdf.ReplaceDuplicateObjects();

pdf.Save("merged.pdf");

Puoi ridurre ulteriormente la dimensione del file di output. Ad esempio, puoi rimuovere glifi dei caratteri inutilizzati o comprimere immagini. Leggi le opzioni di compressione supportate nell'articolo Comprimi documenti PDF in C# e VB.NET.

Personalizza l'unione dei PDF

Docotic.Pdf fornisce metodi per estrarre, riordinare o rimuovere pagine PDF. Puoi usarli con il metodo Append per implementare attività di unione PDF personalizzate.

Aggiungi pagine PDF specifiche

Docotic.Pdf ti consente anche di unire una parte di un documento PDF. Ci sono diversi modi per farlo. Ad esempio, puoi dividere un documento PDF aggiunto e aggiungere le pagine estratte. Il seguente helper C# aggiunge le pagine selezionate a 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);
}

Oppure puoi aggiungere un intero documento PDF e rimuovere le pagine non necessarie. Il seguente esempio di codice aggiunge le prime due pagine di second.pdf:

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

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

pdf.Save(pathToFile);

Un'altra soluzione riguarda l'imposizione PDF. Puoi leggerlo nella sezione corrispondente.

Anteponi PDF

I metodi Append aggiungono sempre le pagine alla fine del documento corrente. Come unire i file PDF in ordine diverso? A volte puoi cambiare l'ordine delle chiamate Append. Cioè, usa

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

invece di

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

Oppure puoi riordinare le pagine dopo l'unione. Questo codice C# sposta il documento PDF aggiunto all'inizio:

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

Esempi di codice correlati per riordinare le pagine PDF:

Imporre PDF

Docotic.Pdf allows you to combine multiple PDF pages on a single page. Use the PdfDocument.CreateXObject(PdfPage) method to create a PdfXObject object based on an existing page. Then, draw this object with desired scaling. Sample 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");

Testare il progetto di esempio Crea XObject dalla pagina correlato da GitHub.

Unisci come allegato

A volte, potrebbe essere necessario incorporare un file PDF in un altro come allegato. Anche questo è possibile. Puoi anche aggiungere collegamenti al file incorporato nelle pagine 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");

È possibile trovare esempi di codice correlati nel gruppo Allegati PDF su GitHub.

Unisci in thread paralleli

Quando si uniscono molti file PDF, è possibile parallelizzare il codice. La classe PdfDocument non è thread-safe. Quindi, dobbiamo utilizzare oggetti PdfDocument separati in thread diversi. Per ulteriori dettagli, vedere l'esempio di codice Unisci documenti PDF in thread paralleli.

Questo codice mostra come combinare flussi PDF parallelamente:

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 // velocizzare la scrittura di documenti intermedi
    };
    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;
    }
}

Il codice precedente divide i documenti di input in gruppi della dimensione rangeSize. Quindi, il codice unisce ciascun gruppo in documenti intermedi in parallelo. Il processo continua finché il numero di documenti di input non è sufficientemente piccolo per la semplice fusione.

La soluzione parallela non è necessariamente più veloce della versione a thread singolo. I risultati possono variare a seconda del numero di documenti in ingresso e delle loro dimensioni. Nel codice di esempio, il valore ottimale del parametro rangeSize potrebbe essere maggiore o minore. Dovresti confrontare la tua applicazione per trovare l'implementazione più efficace.

Conclusione

È possibile utilizzare la libreria Docotic.Pdf per combinare documenti PDF in C# e VB.NET. Ti consente di unire file, flussi o array di byte. Puoi unire file crittografati, moduli PDF, pagine PDF specifiche. Docotic.Pdf ti aiuta anche a comprimere i file risultanti e a risparmiare spazio su disco.

Prova gli esempi di codice dal repository di esempi Docotic.Pdf su GitHub. È possibile ottenere una chiave di licenza di valutazione e scaricare la libreria nella pagina di download di Docotic.Pdf.