Returning iTextSharp PDF as memorystream causes StreamNotSupported
我正在使用ITextSharp中的pdfstamper创建一个pdf文件,并将该pdf作为内存流返回对象到调用函数,该函数随后用于在WinForms的Teleriks PDF查看器组件中显示PDF。
这就是目标。
现在,创建PDF工作正常,它将数据返回给调用函数,在调用函数中,我应该将memoryStream内容写入文件流,然后在Adobe Reader中打开它,一切看起来都很好。
但是,如果我选择在PDF查看器控件中显示PDF,我会得到一个"不支持的流类型"错误。
现在,我发现PDF数据有问题,所以我决定创建PDF文件,将其保存到磁盘,然后在调用函数中将其读取到一个memorystream,并在PDF查看器中显示该memorystream,由于一些我不知道的原因,它起作用……
我真的没办法解决这个问题,需要帮助。
所以,这不起作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | //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; } |
然而,这确实是有原因的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | //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时内存流被隐式关闭。阻止此添加
1 | pdfStamper.Writer.CloseStream = false; |
之前
1 | pdfStamper.Close(); |
号
这指示stamper不要关闭流。