Есть ли простой способ добавить один документ PDF в другой с помощью iTextSharp?

Я прошерстил Интернет в поисках примеров того, как это сделать. Я нашел несколько, которые кажутся немного более вовлеченными, чем они должны быть. Итак, мой вопрос: используя iTextSharp, есть ли довольно краткий способ добавить один PDF-документ в другой?

В идеале это НЕ будет включать третий файл. Просто откройте первый документ PDF, добавьте второй документ PDF к первому, а затем закройте их оба.


person Danno    schedule 19.02.2009    source источник


Ответы (4)


Я действительно могу что-то упустить, но я сделал что-то намного проще. Я допускаю, что это решение, вероятно, не будет обновлять закладки (как в лучшем ответе здесь до сих пор), но оно работает безупречно для меня. Поскольку я объединял документы с заполняемыми формами, я использовал PdfCopyFields вместо PdfCopy.

Вот код (я удалил всю обработку ошибок, чтобы сделать фактический код более заметным, добавьте try..finally, чтобы закрыть открытые ресурсы, если вы планируете использовать код):

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

Вы можете передать любой поток, будь то FileStream, MemoryStream (полезно при чтении PDF из баз данных, нет необходимости во временных файлах и т. д.)

Пример использования:

    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));
    }
person Loudenvier    schedule 03.03.2010
comment
Это отлично сработало для попытки объединить / добавить два PDF-документа с полями формы! Так же намного проще! Спасибо. - person Matt Thomas; 27.01.2012
comment
Это сработало для меня потрясающе. Я бы предложил вызывать source.Close() после вызова copy.AddDocument, чтобы разрешить работу с файлом в другом месте. - person Jason; 11.05.2015

Хорошо, это не просто, но работает и на удивление быстро. (И он использует третий файл, а не открытие и добавление.) Я «обнаружил» это в документах/примерах. Вот код:

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();
    }
}
person Danno    schedule 20.02.2009

Да. Я видел класс под названием PdfManipulation, опубликованный на форуме iText. Однако использование этого класса потребует третьего файла.

Класс изначально находится в VB.Net. Я скачал его из сообщения на vbforums.com. Однако, по-видимому, у него нет функции слияния файлов, поэтому я написал ее на основе кода этого класса.

Это было написано на машине без iTextSharp. Это может иметь ошибки. Я даже не уверен, номера страниц отсчитываются от 0 или от 1. Но попробуйте.

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();
}
person configurator    schedule 19.02.2009
comment
номера страниц начинаются с 1 - person Sergey Malyutin; 01.03.2016
comment
моя проблема заключалась в том, что я не понимал, что мне нужно использовать третий файл, потому что я не могу читать/записывать в файл, который я уже читал, поэтому я создал третий файл и поместил туда вывод, затем удалил старый исходный файл и заменил это с выходным файлом. на случай, если кто-то столкнется с той же проблемой - person Niklas; 12.08.2020

Я не знаю, как это сделать для PDF-файлов, но для PostScript вы просто объединяете файлы. Если у вас установлены pdf2ps и ps2pdf, выполните следующие действия:

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

Я не эксперт по pdf2ps или ps2pdf. Я когда-либо использовал только ps2pdf, и когда я это делаю, он оставляет текст как текст (я все еще могу выбирать и копировать текст из полученного PDF-файла). Когда я выполняю вышеуказанные шаги (pdf-> ps, comb, ps-> pdf), я получаю в результате PDF-файл, похожий на изображение. Не знаю, почему.

person KeyserSoze    schedule 19.02.2009