2009-02-19 17 views
7

Przeszukałem sieć, szukając przykładów, jak to zrobić. Znalazłem kilka, które wydają się być trochę bardziej zaangażowane niż one muszą być. Więc moim pytaniem jest, używając iTextSharp, czy istnieje dość zwięzły sposób dołączenia jednego dokumentu PDF do innego?Czy istnieje prosty sposób dołączania jednego dokumentu PDF do innego przy użyciu iTextSharp?

Optymalnie nie wymagałoby to trzeciego pliku. Po prostu otwórz pierwszy dokument PDF, dołącz drugi dokument PDF do pierwszego, a następnie zamknij oba.

Odpowiedz

5

OK, to nie jest proste, ale działa i jest zaskakująco szybko. (I używa trzeciego pliku, nie ma czegoś takiego jak open and append.) "Odkryłem" to w dokumentach/przykładach. Oto kod:

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

Tak. Widziałem klasę o nazwie PdfManipulation umieszczoną na forum iText. Używanie tej klasy wiązałoby się jednak z trzecim plikiem.

Ta klasa jest oryginalnie w VB.Net. Pobrałem go z wersji post on vbforums.com. Wygląda jednak na to, że nie ma funkcji scalania plików, więc napisałem ją na podstawie kodu w tej klasie.

Zostało to napisane na komputerze bez iTextSharp. To może mieć błędy. Nie jestem nawet pewien, czy numery stron są oparte na 0, czy na 1. Ale daj mu szansę.

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

strona numery 1 oparte –

0

Nie wiem, jak to zrobić dla plików PDF, ale dla postscriptu po prostu łącz pliki. Jeśli masz pdf2ps i ps2pdf zainstalowany, poniżej będzie wykonać zadanie:

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

Nie jestem ekspertem od pdf2ps lub ps2pdf. Użyłem tylko pliku ps2pdf, a kiedy to zrobię, pozostawiam tekst jako tekst (wciąż mogę wybrać i skopiować tekst z wynikowego pliku pdf). Kiedy wykonuję powyższe kroki (pdf-> ps, Combine, ps-> pdf), otrzymuję wynikowy plik PDF podobny do obrazu. Nie mam pojęcia dlaczego.

13

Naprawdę może mi brakować czegoś, ale zrobiłem coś znacznie prostszego. Przyznam, że to rozwiązanie prawdopodobnie nie zaktualizuje zakładek (jak na razie w najlepszej odpowiedzi), ale działa bezbłędnie. Od czasu scalania dokumentów z formularzami wypełnianymi użyłem PdfCopyFields zamiast PdfCopy.

Oto kod (ja odpędza wszystkie obsługi błędów, aby rzeczywisty kod bardziej widoczne, dodaj try..finally aby zamknąć otwarte zasoby, jeśli planujesz za pomocą kodu):

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

można przekazać dowolny strumień, czy to FileStream, MemoryStream (przydatne podczas czytania plików PDF z baz danych, nie ma potrzeby pliki tymczasowe itp)

Przykładowe użycie:

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

To działało idealnie do prób scalania/dołączania dwóch dokumentów PDF za pomocą pól formularzy! O wiele prostsze! Dziękuję Ci. –

+0

To zadziałało dla mnie niesamowicie. Sugeruję wywołanie metody source.Close() po wywołaniu copy.AddDocument, aby umożliwić pracę z innym plikiem. – Jason

Powiązane problemy