通过 Response 发送内存中生成的 .PDF 文件
Send .PDF file generated in memory via Resposne
所以我的 Resposne 文件有问题。我可以发送一些文件,但它已损坏。我知道我的 pdf 库工作正常(在控制台应用程序上检查)
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。
知道第一个 Get 有什么问题吗?我知道有些台词是不合理的,但我尝试了我发现的一切
客户
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;
}
编辑
我编写了在硬盘驱动器上创建相同文件的代码来检查
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 文件(空文件)
您的代码应如下所示:
using (var dataStream = ...)
{
...
dataStream.CopyTo(base.Response.OutputStream);
}
base.Response.EndRequest(true);
using
块的结尾将Flush
、Close
然后Dispose
dataStream
。对 Flush
的调用将确保仍位于缓冲区中的所有数据都将被复制,而不是等待潜在的更多数据。 EndRequest
应仅在数据已完全写入 OutputStream
后调用,因此应在 using
块之后调用 Flush
dataStream
.
根据您的示例代码,只需添加 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
括在 using 中,如下所示:
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();
}
}
所以我的 Resposne 文件有问题。我可以发送一些文件,但它已损坏。我知道我的 pdf 库工作正常(在控制台应用程序上检查)
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。
知道第一个 Get 有什么问题吗?我知道有些台词是不合理的,但我尝试了我发现的一切
客户
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;
}
编辑
我编写了在硬盘驱动器上创建相同文件的代码来检查
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 文件(空文件)
您的代码应如下所示:
using (var dataStream = ...)
{
...
dataStream.CopyTo(base.Response.OutputStream);
}
base.Response.EndRequest(true);
using
块的结尾将Flush
、Close
然后Dispose
dataStream
。对 Flush
的调用将确保仍位于缓冲区中的所有数据都将被复制,而不是等待潜在的更多数据。 EndRequest
应仅在数据已完全写入 OutputStream
后调用,因此应在 using
块之后调用 Flush
dataStream
.
根据您的示例代码,只需添加 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
括在 using 中,如下所示:
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();
}
}