我如何在线流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文件变量传递,例如

我如何在线流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的回答。PdfWriterPdfStamper都使用抽象类System.IO.Stream。您发布的示例使用了System.IO.FileStreamSystem.Web.HttpResponse.OutputStream,这两个子类都是System.IO.Stream。这两个是绝对有效的,但是它们是最终的和专门的。还有一个子类没有那么final,因为它在内存中工作,那就是System.IO.MemoryStream

您可以将PdfWriter绑定到MemoryStream,完成所有工作,然后说"给我一个代表PDF的字节数组"。然后,PdfReader有一个构造函数重载,它接受一个字节数组,因此您可以直接将字节传递回该数组。所以把new PdfReader(filepath)改成new PdfReader(bytes)

我鼓励您在处理pdf时使用此模式:

  1. 创建MemoryStream
  2. 使用该流创建PDF
  3. 完成后获取原始字节
  4. 处理字节。写入磁盘,发送到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));