2009-02-19 22 views
7

He recorrido la Web en busca de ejemplos sobre cómo hacer esto. He encontrado algunos que parecen estar un poco más involucrados de lo que deben ser. Entonces mi pregunta es, usando iTextSharp, ¿hay una forma bastante concisa de agregar un documento PDF a otro?¿Existe una forma directa de agregar un documento PDF a otro usando iTextSharp?

De manera óptima esto NO implicaría un tercer archivo. Simplemente abra el primer documento PDF, anexe el segundo documento PDF al primero y luego ciérrelos.

Respuesta

5

Ok, no es sencillo, pero funciona y es sorprendentemente rápido. (Y utiliza un tercer archivo, no existe tal como abrir y anexar). Lo "descubrí" en los documentos/ejemplos. Aquí está el código:

private void CombineMultiplePDFs(string[] fileNames, string outFile) { 
    int pageOffset = 0; 
    ArrayList master = new ArrayList(); 
    int f = 0; 

    Document document = null; 
    PdfCopy writer = null; 
    while (f < fileNames.Length) { 
     // we create a reader for a certain document 
     PdfReader reader = new PdfReader(fileNames[ f ]); 
     reader.ConsolidateNamedDestinations(); 
     // we retrieve the total number of pages 
     int n = reader.NumberOfPages; 
     ArrayList bookmarks = SimpleBookmark.GetBookmark(reader); 
     if (bookmarks != null) { 
      if (pageOffset != 0) { 
       SimpleBookmark.ShiftPageNumbers(bookmarks, pageOffset, null); 
      } 
      master.AddRange(bookmarks); 
     } 
     pageOffset += n; 

     if (f == 0) { 
      // step 1: creation of a document-object 
      document = new Document(reader.GetPageSizeWithRotation(1)); 
      // step 2: we create a writer that listens to the document 
      writer = new PdfCopy(document, new FileStream(outFile, FileMode.Create)); 
      // step 3: we open the document 
      document.Open(); 
     } 
     // step 4: we add content 
     for (int i = 0; i < n;) { 
      ++i; 
      if (writer != null) { 
       PdfImportedPage page = writer.GetImportedPage(reader, i); 
       writer.AddPage(page); 
      } 
     } 
     PRAcroForm form = reader.AcroForm; 
     if (form != null && writer != null) { 
      writer.CopyAcroForm(reader); 
     } 
     f++; 
    } 
    if (master.Count > 0 && writer != null) { 
     writer.Outlines = master; 
    } 
    // step 5: we close the document 
    if (document != null) { 
     document.Close(); 
    } 
} 
1

Sí. He visto una clase llamada PdfManipulation publicada en un foro iText. Sin embargo, usar esa clase implicaría un tercer archivo.

La clase está originalmente en VB.Net. Lo descargué de post on vbforums.com. Al parecer, sin embargo, no tiene la función de archivos de fusión, así que escribí uno basado en el código de esa clase.

Esto fue escrito en una máquina sin iTextSharp. Esto podría tener errores. Ni siquiera estoy seguro de si los números de página están basados ​​en 0 o en 1. Pero pruébalo.

public static void MergePdfFiles(IEnumerable<string> files, string output) { 
    iTextSharp.text.Document doc; 
    iTextSharp.text.pdf.PdfCopy pdfCpy; 

    doc = new iTextSharp.text.Document(); 
    pdfCpy = new iTextSharp.text.pdf.PdfCopy(doc, new System.IO.FileStream(output, System.IO.FileMode.Create)); 
    doc.Open(); 

    foreach (string file in files) { 
     // initialize a reader 
     iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(file); 
     int pageCount = reader.NumberOfPages; 

     // set page size for the documents 
     doc.SetPageSize(reader.GetPageSizeWithRotation(1)); 

     for (int pageNum = 1; pageNum <= pageCount; pageNum++) { 
      iTextSharp.text.pdf.PdfImportedPage page = pdfCpy.GetImportedPage(reader, pageNum); 
      pdfCpy.AddPage(page); 
     } 

     reader.Close(); 
    } 

    doc.Close(); 
} 
+1

números de página se basan-1 –

0

No sé cómo hacerlo para los archivos PDF, pero para PostScript, solo concatenan los archivos. Si tiene pdf2ps y ps2pdf instalados, el siguiente va a hacer el trabajo:

pdf2ps file1.pdf file1.ps 
pdf2ps file2.pdf file2.ps 
cat file1.ps file2.ps > combined.ps 
ps2pdf combined.ps combined.pdf 

No soy un experto en pdf2ps o ps2pdf. Solo he usado ps2pdf, y cuando lo hago, deja el texto como texto (aún puedo seleccionar y copiar texto del pdf resultante). Cuando hago los pasos anteriores (pdf-> ps, combine, ps-> pdf) termino con un pdf resultante que es como una imagen. No tengo idea por qué.

13

Realmente me puede estar faltando algo, pero hice algo mucho más simple. Admito que esta solución probablemente no actualice los marcadores (como en la mejor respuesta aquí hasta ahora), pero funciona perfectamente para mí. Como fusionaba documentos con formularios rellenables, utilicé PdfCopyFields en lugar de PdfCopy.

Aquí está el código (he despojado de todo el manejo para que el código real más visible de error, agrego un try..finally para cerrar los recursos abiertos, si usted planea usar el código):

void MergePdfStreams(List<Stream> Source, Stream Dest) 
    { 
     PdfCopyFields copy = new PdfCopyFields(Dest); 

     foreach (Stream source in Source) 
     { 
      PdfReader reader = new PdfReader(source); 
      copy.AddDocument(reader); 
     } 

     copy.Close(); 
    } 

puede pasar cualquier corriente, ya sea un FileStream, un MemoryStream (útil cuando se lee el archivo PDF desde bases de datos, sin necesidad de archivos temporales, etc.)

Ejemplo uso:

void TestMergePdfStreams() 
    { 
     List<Stream> sources = new List<Stream>() 
     { 
      new FileStream("template1.pdf", FileMode.Open), 
      new FileStream("template2.pdf", FileMode.Open), 
      new MemoryStream((byte[])someDataRow["PDF_COLUMN_NAME"]) 
     }; 

     MergePdfStreams(sources, new FileStream("MergedOutput.pdf", FileMode.Create)); 
    } 
+1

Esto funcionó perfecto para tratar de combinar/agregar dos documentos PDF con campos de formulario. ¡Mucho más simple también! Gracias. –

+0

Esto funcionó increíble para mí. Sugeriría llamar a source.Close() después de la llamada copy.AddDocument para permitir que el archivo se trabaje en otro lugar. – Jason

Cuestiones relacionadas