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

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

问题描述

我正在 iTextSharp 中使用 PdfStamper 创建一个 PDF 文件,并将 PDF 作为内存流返回调用函数的对象,然后用于在 WinForms 的 Teleriks PDF 查看器组件中显示 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 正常工作,并将数据返回给 Calling 函数,在 Calling 函数中,我应该将内存流内容写入文件流,然后在 Adob​​e 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 查看器控件中显示 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:	emp	estfile.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:	emp	estfile.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天全站免登陆