通过Response发送在内存中生成的.PDF文件

时间:2015-03-06 15:40:23

标签: c# http itextsharp servicestack httpresponse

所以我遇到了Resposne文件的问题。我可以发送一些文件,但它已损坏。我知道我的pdf librabry工作正常(在控制台应用程序上检查)

    public void Get(ClaimExportRequest exportRequest)
    {
               var str = ExportToPdf(claimDataTable);
            using (var streams = new MemoryStream(str))
            {
                base.Response.AddHeader("Content-Disposition", "attachment; filename=report.pdf");
                base.Response.AddHeader("Content-Length", str.Length.ToString(CultureInfo.InvariantCulture));
                base.Response.ContentType = "application/octet-stream";
                streams.WriteTo(base.Response.OutputStream);
            }
            base.Response.EndRequest(true);
    }


    public byte[] ExportToPdf(DataTable dt)
    {

        var mem = new MemoryStream();
        var doc = new Document(new Rectangle(100f, 300f));
        PdfWriter.GetInstance(doc, mem);
        doc.Open();
        doc.Add(new Paragraph("This is a custom size"));
        return mem.ToArray();
    }

我还有另一个创建CSV文件的部分,那个很好!

        using (var streamOfCsvString = 

GenerateStreamFromString(csvBodyFromDt))
            {
                base.Response.UseBufferedStream = true;
                base.Response.AddHeader("Content-Disposition", "attachment; filename=data.csv");
                base.Response.AddHeader("Content-Length", streamOfCsvString.Length.ToString(CultureInfo.InvariantCulture));
                base.Response.ContentType = "text/csv";
                streamOfCsvString.CopyTo(base.Response.OutputStream);
            }
  base.Response.EndRequest(true);

我也尝试过这种方法,将数据更改为pdf。

在第一次获取中有什么问题吗?我知道有些线路是不必要的,但我尝试了我发现的所有内容

客户端

 downloadURL: function(url) {
    var hiddenIFrameID, iframe;
    hiddenIFrameID = 'hiddenDownloader';
    iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
      iframe = document.createElement('iframe');
      iframe.id = hiddenIFrameID;
      iframe.style.display = 'none';
      document.body.appendChild(iframe);
    }
    return iframe.src = url;
  }

修改

我制作的代码在harddrive上创建了相同的文件来检查

  var doc = new Document(new Rectangle(100f, 300f));
            using (var fileStream = new FileStream("c:\\my.pdf", FileMode.Create))
            {

                PdfWriter.GetInstance(doc, fileStream);
                doc.Open();
                doc.Add(new Paragraph("This is a custom size"));
                base.Response.AddHeader("Content-Disposition", "attachment; filename=report.pdf");
                base.Response.AddHeader("Content-Length",
                    fileStream.Length.ToString(CultureInfo.InvariantCulture));
                base.Response.ContentType = "application/octet-stream";
                fileStream.CopyTo(base.Response.OutputStream); //WriteTo 
                doc.Close();
            }

            base.Response.EndRequest(true);

文件很好但是,当缺少doc.Close()时,硬盘驱动器上的文件已损坏。但是在服务器端,我现在得到0 kB文件(空文件)

2 个答案:

答案 0 :(得分:3)

从您的示例代码中,只需添加doc.Close()就可以解决这个问题。

public byte[] ExportToPdf(DataTable dt)
{

    var mem = new MemoryStream();
    var doc = new Document(new Rectangle(100f, 300f));
    PdfWriter.GetInstance(doc, mem);
    doc.Open();
    doc.Add(new Paragraph("This is a custom size"));
    doc.Close();
    return mem.ToArray();
}

编辑:就像我在评论中说的那样,你应该将MemoryStream括在一个使用中,如下所示:

public byte[] ExportToPdf(DataTable dt)
{
    using (var mem = new MemoryStream())
    {
        var doc = new Document(new Rectangle(100f, 300f));
        PdfWriter.GetInstance(doc, mem);
        doc.Open();
        doc.Add(new Paragraph("This is a custom size"));
        doc.Close();
        return mem.ToArray();
    }
}

答案 1 :(得分:2)

您的代码应如下所示:

using (var dataStream = ...)
{
    ...
    dataStream.CopyTo(base.Response.OutputStream);  
}
base.Response.EndRequest(true);

using阻止的结尾将是FlushClose,然后是Dispose dataStream。对Flush的调用将确保将复制仍在缓冲区中的任何数据,而不是等待可能的更多数据。只有在数据完全写入EndRequest后才应调用OutputStream,因此应在using阻止Flush dataStream {{1}}后调用{{1}}