Unir documentos PDF con .NET

Actualización (19/07/2007): Luis Ruiz Pavón comenta una forma más sencilla de unir documentos usando iTextDotNet.

Una pequeña clase que hace uso de iText# (Software Libre) para unir dos o más documentos PDF en uno solo.

csharp:
using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class PdfMerge
{
    private BaseFont baseFont;
    private bool enablePagination = false;
    private readonly List<PdfReader> documents;
    private int totalPages;

    public BaseFont BaseFont
    {
        get { return baseFont; }
        set { baseFont = value; }
    }

    public bool EnablePagination
    {
        get { return enablePagination; }
        set
        {
            enablePagination = value;
            if (value && baseFont == null)
                baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
        }
    }

    public List<PdfReader> Documents
    {
        get { return documents; }
    }

    public void AddDocument(string filename)
    {
        documents.Add(new PdfReader(filename));
    }
    public void AddDocument(Stream pdfStream)
    {
        documents.Add(new PdfReader(pdfStream));
    }
    public void AddDocument(byte[] pdfContents)
    {
        documents.Add(new PdfReader(pdfContents));
    }
    public void AddDocument(PdfReader pdfDocument)
    {
        documents.Add(pdfDocument);
    }

    public void Merge(string outputFilename)
    {
        Merge(new FileStream(outputFilename, FileMode.Create));
    }
    public void Merge(Stream outputStream)
    {
        if (outputStream == null || !outputStream.CanWrite)
            throw new Exception("OutputStream es nulo o no se puede escribir en éste.");

        Document newDocument = null;
        try
        {
            newDocument = new Document();
            PdfWriter pdfWriter = PdfWriter.GetInstance(newDocument, outputStream);

            newDocument.Open();
            PdfContentByte pdfContentByte = pdfWriter.DirectContent;

            if (EnablePagination)
                documents.ForEach(delegate(PdfReader doc)
                                  {
                                      totalPages += doc.NumberOfPages;
                                  });

            int currentPage = 1;
            foreach (PdfReader pdfReader in documents)
            {
                for (int page = 1; page <= pdfReader.NumberOfPages; page++)
                {
                    newDocument.NewPage();
                    PdfImportedPage importedPage = pdfWriter.GetImportedPage(pdfReader, page);
                    pdfContentByte.AddTemplate(importedPage, 0, 0);

                    if (EnablePagination)
                    {
                        pdfContentByte.BeginText();
                        pdfContentByte.SetFontAndSize(baseFont, 9);
                        pdfContentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER,
                            string.Format("{0} de {1}", currentPage++, totalPages), 520, 5, 0);
                        pdfContentByte.EndText();
                    }
                }
            }
        }
        finally
        {
            outputStream.Flush();
            if (newDocument != null)
                newDocument.Close();
            outputStream.Close();
        }
    }

    public PdfMerge()
    {
        documents = new List<PdfReader>();
    }
}

Si bien es cierto que hay muchas cosas por mejorar, creo que para escenarios no muy complejos basta y sobra.

Pueden descargar la solución creada en Visual Studio 2005 que -- incluye el ensamblado iText# y -- como ejemplo une dos papers bastante interesantes ("Composable Memory Transactions" y "Static Typing Where Posible, Dynamic Typing When Needed: The End of The Cold War Between Programming Languages").

Nota: La clase está basada en el artículo Merge PDF files with iText.

10 Replies to “Unir documentos PDF con .NET”

  1. Un poquito más sencillo con iTextDotNet:

    csharp:

    using com.lowagie.tools;

    string [] lista = new string[]{"fichero1.pdf","ficheron.pdf","result.pdf"}
    concat_pdf.main(lista);
     

    Salu2

  2. Hola a todos:
    Tengo un problema al utilizar este código para unir pdf con orientación horizontal, ya que en el pdf resultado me los muestra en vertical. Me podríais ayudar para que me saliesen en horizontal?
    Muchas gracias

  3. Hola Adriana, cual fue la solución para unir pdf con orientación horizontal? 🙂 Coincide que yo tengo el mismo problema.

    Un saludo.

  4. Hola Adriana, cual fue la solución para unir pdf con orientación horizontal? Tengo el mismo problema y no le encuentro la solucion.

    Saludos

  5. Para que cada página respete su orientacón hay que hacer

    CODE:

     newDocument.SetPageSize ( pdfReader.GetPageSizeWithRotation(page));
     

    antes de newDocument.NewPage();

  6. Muchísimas gracias!!!. Me estaba volviendo loco intentando unir pdfs. En realidad lo que quería es imprimir desde mi app muchos pdfs, unos 300 documentos pero algunos no los imprimía (lo normal seria que si acrobat o la impresora están ocupados encole documentos pero no que no los imprima), desesperado he optado por generar un único pdf de 300 paginas usando tu código y luego imprimirlo y ya me funciona todo perfectamente.

    Un saludo

  7. Use el ejemplo que expones para poder unir reportes pdf que genero con crystal reports y me funciona muy bien en un equipo, pero al llevarlo a otro equipo no imprime la parte superior de los reportes, alguien sabe por que podrias ser esto?

  8. Hola

    No me respeta la orientacion, tengo dos pdf en formato horizontal y automaticamente me los rota.
    Como se puede respetar eso??
    Saludos

Comments are closed.