【问题标题】:Returning iTextSharp PDF as memorystream causes StreamNotSupported将 iTextSharp PDF 作为内存流返回会导致 StreamNotSupported
【发布时间】:2014-10-14 10:31:33
【问题描述】:

我正在使用 iTextSharp 中的 PdfStamper 创建 PDF 文件并将 PDF 作为内存流返回 调用函数的对象,然后用于在 Teleriks PDF Viewer Component for WinForms 中显示 PDF。

这就是目标。

现在,创建 PDF 可以正常工作,它会将数据返回给调用函数,在调用函数中,我是否应该将内存流内容写入文件流,然后在 Adob​​e Reader 中打开它很好。

但是,如果我选择在 PDF 查看器控件中显示 PDF,我只会收到“不支持的流类型”错误。

现在,我发现 PDF 数据有问题,所以我决定创建 PDF 文件,将其保存到磁盘,然后将其读取到调用函数中的内存流,并在 PDF 查看器中显示该内存流,然后,一些对我来说未知的原因,有效....

我真的无法理解这一点,需要一些帮助。

所以,这行不通

//The Calling function
private void dlgViewPDF_Load(object sender, EventArgs e)
{
    MemoryStream ms = PDFcreator.GeneratePDFdata(id);

   rPdfView.LoadDocument(ms);
}

//The PDF generator
public static MemoryStream GeneratePDFdata(string id)
{
    MemoryStream ms = new MemoryStream();

    string sTemplate = string.Concat(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\template.pdf");

    PdfReader pdfReader = new PdfReader(sTemplate);
    PdfStamper pdfStamper = new PdfStamper(pdfReader, ms);

    PdfContentByte cb = pdfStamper.GetOverContent(1);

    BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.EMBEDDED);
    BaseFont baseFontBold = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1250, BaseFont.EMBEDDED);
    cb.SetColorFill(iTextSharp.text.Color.BLACK);
    cb.SetFontAndSize(baseFontBold, 14);

    cb.BeginText();
    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "TEST!!", 385, 750, 0);
    cb.EndText();

    cb.SetColorStroke(new CMYKColor(0f, 0f, 0f, 1f));
    cb.SetColorFill(new CMYKColor(0f, 0f, 0f, 1f));

    cb.MoveTo(139, 398);
    cb.LineTo(146, 398);
    cb.LineTo(146, 391);
    cb.LineTo(139, 391);
    cb.ClosePathEoFillStroke();

    pdfStamper.Close();
    pdfReader.Close();

    return ms;
}

但是由于某种原因这确实有效:

//The Calling function
private void dlgViewPDF_Load(object sender, EventArgs e)
{
    MemoryStream ms = new MemoryStream();

    FileStream file = new FileStream(@"c:\temp\testfile.pdf", FileMode.Open, FileAccess.Read);

    byte[] bytes = new byte[file.Length];
    file.Read(bytes, 0, (int)file.Length);
    ms.Write(bytes, 0, (int)file.Length);

    rPdfView.LoadDocument(ms);
}


//The PDF generator 
public static void GeneratePDFdata(string id)
{
    MemoryStream ms = new MemoryStream();

    string sTemplate = string.Concat(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "\\template.pdf");

    PdfReader pdfReader = new PdfReader(sTemplate);

    FileStream fs = new FileStream(@"c:\temp\testfile.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
    PdfStamper pdfStamper = new PdfStamper(pdfReader, fs);

    PdfContentByte cb = pdfStamper.GetOverContent(1);

    BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.EMBEDDED);
    BaseFont baseFontBold = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1250, BaseFont.EMBEDDED);
    cb.SetColorFill(iTextSharp.text.Color.BLACK);
    cb.SetFontAndSize(baseFontBold, 14);

    cb.BeginText();
    cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, "TEST!!", 385, 750, 0);
    cb.EndText();

    cb.SetColorStroke(new CMYKColor(0f, 0f, 0f, 1f));
    cb.SetColorFill(new CMYKColor(0f, 0f, 0f, 1f));

    cb.MoveTo(139, 398);
    cb.LineTo(146, 398);
    cb.LineTo(146, 391);
    cb.LineTo(139, 391);
    cb.ClosePathEoFillStroke();

    pdfStamper.Close();
    pdfReader.Close();
}

但是为什么呢?我宁愿把它全部保存在内存中,如果用户愿意的话,让他/她保存生成的 PDF,而不是把它写到磁盘然后显示它。

【问题讨论】:

  • pdfStamper.Close() 之前尝试pdfStamper.Writer.CloseStream = false
  • 这就像一个魅力。将其添加为回复,我会将其标记为答案。谢谢你的帮助。 :)
  • 如果你想让你的生活更轻松,永远不要传递流,总是通过在 MemoryStream 上调用 ToArray() 传递原始字节。如果您传递字节,则不必担心有人不小心将其关闭或流中的当前位置。

标签: c# winforms pdf telerik itextsharp


【解决方案1】:

对于 iText 7,语法与 mkl's answer 略有不同。

您可以使用SetCloseStream() 方法阻止编写器关闭流:

PdfWriter writer = new PdfWriter(stream);
writer.SetCloseStream(false);

【讨论】:

    【解决方案2】:

    问题出现是因为当 PdfStamper 关闭时内存流被隐式关闭。为了防止这种添加

    pdfStamper.Writer.CloseStream = false;
    

    之前

    pdfStamper.Close();
    

    这指示压模不要关闭流。

    【讨论】:

      猜你喜欢
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2012-10-14
      相关资源
      最近更新 更多