【发布时间】:2014-10-14 10:31:33
【问题描述】:
我正在使用 iTextSharp 中的 PdfStamper 创建 PDF 文件并将 PDF 作为内存流返回 调用函数的对象,然后用于在 Teleriks PDF Viewer Component for WinForms 中显示 PDF。
这就是目标。
现在,创建 PDF 可以正常工作,它会将数据返回给调用函数,在调用函数中,我是否应该将内存流内容写入文件流,然后在 Adobe 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