Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在线传输pdf_C#_Pdf_Itextsharp_Itext - Fatal编程技术网

C# 如何在线传输pdf

C# 如何在线传输pdf,c#,pdf,itextsharp,itext,C#,Pdf,Itextsharp,Itext,我正在使用itextSharp生成pdf文档这是我保存pdf的方式: string file=“C:/MyDoc/FileName.pdf”。如果我在网络上运行这个程序,那么文件路径可能会有所不同。经过大量研究,我发现我可以做到: Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;" + "filename=

我正在使用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();       

问题是如何在上面的代码中声明
字符串文件
。这样做的原因是因为稍后我将页码插入到传递文件变量的pdf中,例如,

我自己在生成Word/pdf文件时遇到一些问题。这些生成不适用于相对路径。我的解决方案如下(在VBA中,但在C#中应该类似):

创建文件信息

Dim getInfo As System.IO.FileInfo      
用所需文件的(相对)路径填充fileinfo:

getInfo = My.Computer.FileSystem.GetFileInfo("Pathname")
使用fileinfo获取完整的绝对路径,而不是相对路径(getInfo.FullName)


我自己生成Word/PDF文件时遇到一些问题。这些生成不适用于相对路径。我的解决方案如下(在VBA中,但在C#中应该类似):

创建文件信息

Dim getInfo As System.IO.FileInfo      
用所需文件的(相对)路径填充fileinfo:

getInfo = My.Computer.FileSystem.GetFileInfo("Pathname")
使用fileinfo获取完整的绝对路径,而不是相对路径(getInfo.FullName)


其中似乎没有任何内容依赖于物理文件的存在。在我看来,您应该能够创建一个
内存流
,用它代替
内存流
,然后将
内存流的内容写入响应。在某些情况下,您甚至可以直接写入
.OutputStream
(避免
内存流
),但这取决于它是否需要查找等。但假设我们必须缓冲:

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);
}

其中似乎没有任何内容依赖于物理文件的存在。在我看来,您应该能够创建一个
内存流
,用它代替
内存流
,然后将
内存流的内容写入响应。在某些情况下,您甚至可以直接写入
.OutputStream
(避免
内存流
),但这取决于它是否需要查找等。但假设我们必须缓冲:

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);
}

我只是想进一步说明马克的答案
PdfWriter
PdfStamper
都使用抽象类
System.IO.Stream
。您发布的示例使用了
System.IO.FileStream
System.Web.HttpResponse.OutputStream
,这两个子类都是
System.IO.Stream
。这两个是绝对有效的,但它们是最终的和专门的。还有另一个不太最终的子类,它在内存中工作,那就是
System.IO.MemoryStream

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

我鼓励您在使用PDF时使用此模式:

  • 创建一个
    MemoryStream
  • 使用该流创建PDF
  • 完成后获取原始字节
  • 对字节做些什么。写入磁盘,发送到
    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
    

    我只是想进一步说明马克的答案
    PdfWriter
    PdfStamper
    都使用抽象类
    System.IO.Stream
    。您发布的示例使用了
    System.IO.FileStream
    System.Web.HttpResponse.OutputStream
    ,这两个子类都是
    System.IO.Stream
    。这两个是绝对有效的,但它们是最终的和专门的。还有另一个不太最终的子类,它在内存中工作,那就是
    System.IO.MemoryStream

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

    我鼓励您在使用PDF时使用此模式:

  • 创建一个
    MemoryStream
  • 使用该流创建PDF
  • 完成后获取原始字节
  • 对字节做些什么。写入磁盘,发送到
    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
    

    您不会在其中显示任何需要物理文件的内容;如果您使用
    MemoryStream
    而不是
    文件流
    ,它是否有效;您当前正在服务器上保存;这是一个非常糟糕的想法你没有显示任何需要物理文件的内容;如果您使用
    MemoryStream
    而不是
    文件流
    ,它是否有效;您当前正在服务器上保存;那真是个好主意