我正在使用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,其中传递了文件变量,例如。
答案 0 :(得分:4)
那里的任何东西似乎都不依赖于物理文件的存在。在我看来,您应该能够创建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);
}
答案 1 :(得分:1)
我只是想扩展Marc的答案。 PdfWriter
和PdfStamper
都使用抽象类System.IO.Stream
。您发布的示例同时使用了System.IO.FileStream
和System.Web.HttpResponse.OutputStream
,两者都是System.IO.Stream
的子类。这两个绝对有效,但它们是最终的和专业的。还有另一个子类,它不是最终的,因为它在内存中运行,而且是System.IO.MemoryStream
。
您可以将PdfWriter
绑定到MemoryStream
,完成所有工作,然后说“给我一个代表PDF的字节数组”。然后,PdfReader
有一个带有字节数组的构造函数重载,所以你可以直接将你的字节传递给它。因此,您可以说new PdfReader(filepath)
而不是new PdfReader(bytes)
。
我建议您在使用PDF时使用此模式:
MemoryStream
HttpResponse
,发送回第2步,等等。前三个步骤的优点是您不必考虑文件路径甚至ASP.Net本身。该代码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
答案 2 :(得分:0)
我自己生成Word / PDF文件时遇到了一些问题。这些生成不适用于相对路径。我的解决方案如下(在VBA中,但在C#中应该类似):
创建fileinfo
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));