我如何在线流pdf
本文关键字:pdf 在线 何在线 | 更新日期: 2023-09-27 18:12:20
我正在使用itextSharp生成一个pdf文档,这就是我如何保存我的pdf:string file = "C:/MyDoc/FileName.pdf";
。如果我在网络上运行这个程序,那么文件路径可能会变化。在做了大量的研究之后,我发现我可以这样做:
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;" + "filename=FileName.pdf");
Response.Write(document);
Response.OutputStream.Flush();
Response.OutputStream.Close();
问题是我如何在上面的代码中声明string file
。这样做的原因是,稍后我将插入页码到pdf文件变量传递,例如
似乎没有任何内容依赖于物理文件的存在。在我看来,您应该能够创建一个MemoryStream
,用它来代替MemoryStream
,然后将MemoryStream
的内容写入响应。在某些情况下,您甚至可以直接写入.OutputStream
(避免MemoryStream
),但这取决于它是否需要查找等。但是让我们假设我们必须缓冲:
using(MemoryStream ms = new MemoryStream()) {
CreatePdf(ms); // uses this stream instead of new FileStream(...)
// not shown: set response headers
var data = ms.GetBuffer();
Response.OutputStream.Write(data, 0, (int)ms.Length);
}
我只是想扩展一下Marc的回答。PdfWriter
和PdfStamper
都使用抽象类System.IO.Stream
。您发布的示例使用了System.IO.FileStream
和System.Web.HttpResponse.OutputStream
,这两个子类都是System.IO.Stream
。这两个是绝对有效的,但是它们是最终的和专门的。还有一个子类没有那么final,因为它在内存中工作,那就是System.IO.MemoryStream
。
您可以将PdfWriter
绑定到MemoryStream
,完成所有工作,然后说"给我一个代表PDF的字节数组"。然后,PdfReader
有一个构造函数重载,它接受一个字节数组,因此您可以直接将字节传递回该数组。所以把new PdfReader(filepath)
改成new PdfReader(bytes)
。
我鼓励您在处理pdf时使用此模式:
- 创建
MemoryStream
- 使用该流创建PDF
- 完成后获取原始字节
- 处理字节。写入磁盘,发送到
HttpResponse
,发送回步骤#2,等等。
前三个步骤的优点是您不必考虑文件路径甚至ASP。网络本身。该代码100%可从桌面移植到服务器。第四步是唯一针对具体情况的步骤,也就是"好了,我制作了一个PDF,现在我要用它做什么?"
请参阅下面的代码和注释,以获得展示这一点的示例:
//Instead of writing to a file, we're going to just keep a byte array around
//that we can work with and/or write to something else
//At the start, this array is not initialized to anything
Byte[] bytes;
//Create a very basic PDF using a MemoryStream
using (var ms = new MemoryStream()) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
doc.Add(new Paragraph("Hello World"));
doc.Close();
}
}
//When the "PDF stuff" is done but before we dispose of the MemoryStream, grab the raw bytes
bytes = ms.ToArray();
}
//At this exact point, the variable "bytes" is an array of bytes that
//represents a PDF. This could be sent to the browser via Response.BinaryWrite(bytes).
//It could also be written to disk using System.IO.File.WriteAllBytes(myFilePath, bytes).
//It could also be read back into a PdfReader directly via the code below
//Create a new PDF based on the old PDF
using (var ms = new MemoryStream()) {
//Bind a reader to our previously created array
using (var reader = new PdfReader(bytes)) {
//Very simple stamper, could be much more complex, just draws a rectangle
using (var stamper = new PdfStamper(reader, ms)) {
var cb = stamper.GetOverContent(1);
cb.Rectangle(50, 50, 200, 200);
cb.SetColorFill(BaseColor.RED);
cb.Fill();
}
}
//Once again, grab the bytes before closing the MemoryStream but after the "PDF stuff"
bytes = ms.ToArray();
}
//Once again, the "bytes" variable represents a PDF at this point
//The above can be repeated as many times as needed
我自己生成Word/PDF文件时遇到了一些问题。这些生成不使用相对路径。我的解决方案如下(在VBA,但它应该是类似的c#):
创建文件
Dim getInfo As System.IO.FileInfo
用所需文件的(相对)路径填充fileinfo:
getInfo = My.Computer.FileSystem.GetFileInfo("Pathname")
使用fileinfo来获取完整的绝对路径,而不是相对路径(getInfo.FullName)。
PdfCopy copyPdf = new PdfCopy(copyDoc, new FileStream(getInfo.FullName, FileMode.Create));