将iTextSharp PDF作为内存流返回会导致StreamNotSupported

时间:2014-08-20 22:15:31

标签: c# winforms pdf telerik itextsharp

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

这是目标。

现在,创建PDF可以正常工作,并将数据返回给Calling函数,在Calling函数中,我应该将内存流内容写入文件流,然后在Adobe Reader中打开它看起来只是细

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

现在,我发现PDF数据出了问题所以我决定创建PDF文件,将其保存到磁盘,然后将其读取到Calling函数中的内存流,并在PDF Viewer中显示该内存流,以及一些对我来说不明原因,有效......

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

所以,赢了工作:

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

2 个答案:

答案 0 :(得分:7)

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

pdfStamper.Writer.CloseStream = false;

pdfStamper.Close();

这指示压模不要关闭流。

答案 1 :(得分:0)

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

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

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