我如何在线传输pdf

时间:2014-07-09 13:22:28

标签: c# pdf itextsharp itext

我正在使用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,其中传递了文件变量,例如。

3 个答案:

答案 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的答案。 PdfWriterPdfStamper都使用抽象类System.IO.Stream。您发布的示例同时使用了System.IO.FileStreamSystem.Web.HttpResponse.OutputStream,两者都是System.IO.Stream的子类。这两个绝对有效,但它们是最终的和专业的。还有另一个子类,它不是最终的,因为它在内存中运行,而且是System.IO.MemoryStream

您可以将PdfWriter绑定到MemoryStream,完成所有工作,然后说“给我一个代表PDF的字节数组”。然后,PdfReader有一个带有字节数组的构造函数重载,所以你可以直接将你的字节传递给它。因此,您可以说new PdfReader(filepath)而不是new PdfReader(bytes)

我建议您在使用PDF时使用此模式:

  1. 创建MemoryStream
  2. 使用该流创建PDF
  3. 完成后抓取原始字节
  4. 用字节做一些事情。写入磁盘,发送到HttpResponse,发送回第2步,等等。
  5. 前三个步骤的优点是您不必考虑文件路径甚至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));