将iTextSharp PDF作为内存流返回会导致StreamNotSupported [英] Returning iTextSharp PDF as memorystream causes StreamNotSupported

查看:674
本文介绍了将iTextSharp PDF作为内存流返回会导致StreamNotSupported的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating a PDF file using the PdfStamper in iTextSharp and return the PDF as a memorystream object to the calling function, that is then used to display the PDF in Teleriks PDF Viewer Component for WinForms.

这是目标。

现在,创建PDF可以正常工作,并返回数据我应该将内存流内容写入文件流,然后在Adobe Reader中打开,一切看起来都很好。

Right now, creating the PDF works as it should, and it returns the data to the Calling function, and in the Calling function, should I write the memorystream contents to a file stream and then open it in Adobe Reader Everything looks just fine.

但是,如何调用函数和调用函数如果我选择在PDF Viewer Control中显示PDF,我只会收到不支持的流类型错误。

However, if I choose to display the PDF in the PDF Viewer Control I just get an "Unsupported Stream type" error.

现在,我发现PDF数据出错了所以我决定创建PDF文件,将其保存到磁盘,然后在调用函数中将其读取到内存流,并在PDF查看器中显示该内存流,对于某些我未知的原因,它可以工作....

Now, I figured something was wrong in the PDF data so I decided to create the PDF file, save it to disk, then read it to a memorystream in the Calling function and display that memorystream in the PDF Viewer and that, for some to me unknown reason, works....

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

I really can't get my head around this and need some help.

所以,这个不会工作:

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

然而,由于某种原因,这确实有效:

However THIS does work for some reason:

//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,如果他/她愿意,而不是将其写入磁盘然后显示它。

But why? I'd rather keep it all in memory and let the user save the resulting PDF if he/she so wishes than having to write it to disk and then displaying it.

推荐答案

问题出现是因为当PdfStamper关闭时,内存流会被隐式关闭。为防止此添加

The problem arises because the memory stream gets implicitly closed when the PdfStamper is closed. To prevent this add

pdfStamper.Writer.CloseStream = false;

之前

pdfStamper.Close();

这指示压模不要关闭流。

This instructs the stamper not to close the stream.

这篇关于将iTextSharp PDF作为内存流返回会导致StreamNotSupported的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆