【问题标题】:Merge memorystreams to one iText document将内存流合并到一个 iText 文档
【发布时间】:2012-01-13 05:10:27
【问题描述】:

我想要合并四个 MemoryStream 数据,然后打开 pdfDocument,而不创建单个文件。

可以将它们写到文件中,然后合并它们,但这是不好的做法,也会导致一些问题,所以我想避免这种情况。

但是,我找不到将 MemoryStreams 与 iText5 for .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,因为不同的部分是由不同的资源构建的。所以我参考了这些内存流。

如何做到这一点?

【问题讨论】:

  • 你不能使用 var readerFrontPage = new PdfReader(yourMemoryStream);
  • 就是这样,我无法让它工作。我遇到的错误之一是“找不到 PDF 标头签名”。然而,大多数遇到此问题的人都使用文件,这不是一个选项。
  • 虽然它接缝 PdfReader 无法获取流,但流的数组有效。 var readerFrontPage = new PdfReader(streamFrontPage.ToArray());你我还不能回答我自己的问题......

标签: c#-4.0 merge itext memorystream


【解决方案1】:

在这种情况下,可以通过将流的 Position 设置回 0 来修复错误 PDF header signature not found。由于您没有收到错误Cannot access a closed Stream,我假设您已经正确地将PdfWriterCloseStream 设置为false

下面是针对 iTextSharp 5.1.1.0 的完整工作 C# 2010 WinForm 应用程序,它在 MemoryStreams 中创建三个 PDF 并将它们组合在一起。由于我手边没有网络服务器,所以我将它们写入磁盘。

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

【讨论】:

  • 完美。就我而言,我正在做stream.Position = 0,但在错误的地方:在using 语句中。把它移到外面后效果很好。顺便说一句,克里斯:恭喜您在 iTextSharp 方面为社区提供了帮助。上帝祝福你! :)
  • 谢谢,记得在编写器上将 CloseStream 设置为 false 并在使用流之前调用关闭文档时为我工作。
  • 在您的示例中,您将如何打开 pdf 而不是保存到桌面?
  • 我认为现在大多数用户都有 Adob​​e 阅读器?通过将 finalStream 传递给一个新方法并使用“Response.OutputStream”,我得到了我想要的结果,谢谢
  • 我想说的是,与几年前相比,如今安装 Adob​​e Reader 的人数(百分比)有所减少。 Mac OSX 多年来一直拥有可以阅读 PDF 的预览版,而 Windows 8 也内置了预览版。所有主要的现代网络浏览器也都附带原生 PDF 渲染器。每当我看到一个使用“Adobe Reader”图标表示 PDF 的网站时,我仍然觉得很有趣。但如果你只是说大多数人都安装了某种 PDF 渲染器,不一定是 Adob​​e 的,我想我会同意这一点。
【解决方案2】:

虽然 PdfReader 接缝无法获取流,但流的数组可以工作。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 2012-11-30
    • 2015-05-03
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    相关资源
    最近更新 更多