Объедините потоки памяти в один документ iText - PullRequest
6 голосов
/ 05 декабря 2011

У меня есть четыре MemoryStreams данных, которые я хочу объединить, а затем открыть pdfDocument, не создавая один файл.

Можно записать их в файлы, а затем объединить, но это будет плохой практикой, что также может вызвать некоторые проблемы, поэтому я хочу этого избежать.

Однако я не могу найти способ объединить MemoryStreams с iText5 для .NET.

Прямо сейчас, вот как я делаю это с файлами:

    private static void ConcatenateDocuments()
    {
        var stream = new MemoryStream();

        var readerFrontPage = new PdfReader(Folder + FrontPageName);
        var readerDocA = new PdfReader(Folder + docA);
        var readerDocB = new PdfReader(Folder + DocB);
        var readerAppendix = new PdfReader(Folder + Appendix);
        var pdfCopyFields = new PdfCopyFields(stream);

        pdfCopyFields.AddDocument(readerFrontPage);
        pdfCopyFields.AddDocument(readerDocA );
        pdfCopyFields.AddDocument(readerDocB);
        pdfCopyFields.AddDocument(readerAppendix);
        pdfCopyFields.Close();

        SavePdf(stream, FilenameReport);
    }

Поскольку мне нужно прекратить использование файлов, я сохраняю MemoryStream, так как различные части создаются из разных ресурсов.,Итак, у меня есть ссылки на эти потоки памяти.

Как это можно сделать?

Ответы [ 2 ]

19 голосов
/ 05 декабря 2011

Ошибка PDF header signature not found может быть исправлена ​​в этом случае путем установки потока Position обратно на 0.Поскольку вы не получаете сообщение об ошибке Cannot access a closed Stream, я предполагаю, что вы уже правильно установили PdfWriter CloseStream на false.

Ниже приведено полнофункциональное приложение WinForm для C # 2010.нацеленный на iTextSharp 5.1.1.0, который создает три файла PDF в формате MemoryStreams и объединяет их.Поскольку у меня нет удобного веб-сервера, я записываю их на диск.

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Create three MemoryStreams
            MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") };

            //I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk
            byte[] bytes;

            //Create our final combined MemoryStream
            using (MemoryStream finalStream = new MemoryStream())
            {
                //Create our copy object
                PdfCopyFields copy = new PdfCopyFields(finalStream);

                //Loop through each MemoryStream
                foreach (MemoryStream ms in streams)
                {
                    //Reset the position back to zero
                    ms.Position = 0;
                    //Add it to the copy object
                    copy.AddDocument(new PdfReader(ms));
                    //Clean up
                    ms.Dispose();
                }
                //Close the copy object
                copy.Close();

                //Get the raw bytes to save to disk
                bytes = finalStream.ToArray();
            }

            //Write out the file to the desktop
            string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf");
            using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                fs.Write(bytes, 0, bytes.Length);   
            }

            this.Close();
        }

        /// <summary>
        /// Helper method to create temporary documents
        /// </summary>
        private MemoryStream CreateDoc(string name)
        {
            MemoryStream ms = new MemoryStream();
            using (Document doc = new Document(PageSize.LETTER))
            {
                using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
                {
                    writer.CloseStream = false;
                    doc.Open();
                    doc.Add(new Paragraph(name));
                    doc.Close();
                }
            }
            return ms;
        }
    }
}
0 голосов
/ 06 декабря 2011

Пока PdfReader не может принять поток, массив потока работает.

var readerFrontPage = new PdfReader (streamFrontPage.ToArray ());

...