c# 如何动态生成 pdf 文件并将其流式传输到浏览器,而无需写入本地目录

本文关键字:浏览器 传输 动态 何动态 文件 pdf | 更新日期: 2023-09-27 18:37:16

我正在编写一个简单的 asp.net,它将用户下载对象列表作为PDF文档。单击"获取pdf"按钮时,客户端浏览器应询问用户希望将文件保存在哪里。仅此而已。很简单。

我找到了几个指南来解释如何从数据表生成PDF,但所有这些似乎都需要您将pdf保存到某种临时文件中,并在此过程中将其存储在本地。

PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c://sample.pdf", FileMode.Create));

这真的有必要在本地保存文件然后将其传递给用户,然后谁可以选择再次保存文件?我在这里错过了什么吗?有没有办法在文件上生成 PDF,然后将其传递给客户端浏览器?

编辑:

要指定,我在这里谈论的可能是将流直接发送到客户端浏览器,该文件完全是动态生成的。在用户收到"是否要下载此文件"提示之前,没有本地存储。

c# 如何动态生成 pdf 文件并将其流式传输到浏览器,而无需写入本地目录

如果使用iText(就像你看起来一样),这个函数调用将接受任何类型的流,例如,以下内容将返回一个字节数组,然后你可以流式传输到客户端,而无需写入磁盘:

using (MemoryStream ms = new MemoryStream())
{
    Document doc = new Document(PageSize.A4, 50, 50, 15, 15);
    PdfWriter writer = PdfWriter.GetInstance(doc, ms);
    //You need to actually write something to the document here...
    return ms.ToArray();
}

这个问题令人困惑,因为不清楚"本地"是什么意思。

通常,当您在服务器上("远程")创建PDF时,您不需要将PDF存储在服务器的文件系统上。您只需在内存中创建PDF并将字节传递给Response.OutputStream就像在StackOverflow上的许多其他示例中所做的那样。

字节被发送到客户端,在那里它们被"本地"存储在最终用户的磁盘上。最终用户可能不会注意到文件存储在本地,因为它存储在临时目录中。为什么它存储在本地?因为 PDF 查看器需要磁盘上的文件。PDF 查看器在结束时开始读取文件。这就是交叉引用表的位置。交叉引用表包含 PDF 中每个对象的字节偏移量。PDF 查看器需要随机访问文件才能使用这些对象。另请参阅在 Adobe PDF 阅读器中禁用保存按钮和隐藏 IE 窗口中的菜单栏

您需要将其保存到 Response.OutputStream 中,而不是将文档保存到文件中。在编写PDF内容之前,您还应该注意不要向浏览器写入任何内容。还应将响应流的内容类型设置为 PDF MIME 类型。为了方便用户使用,您应该添加一个标题,指定 PDF 文件的名称。这将确保浏览器打开文件保存对话框。

Response.Clear();
// Tell server to cache output until asked to flush
Response.BufferOutput = true;
// Set the mime type - tells the browser that a
// PDF document is on the way
Response.ContentType = "application/pdf";
// Give the document a name
Response.AddHeader(
    "content-disposition",
    "attachment; filename=pdf_doc.pdf");

然后将您的PDF写入响应流,正如Paddy给出的那样。我认为您不需要将内存蒸汽更改为数组。我认为您应该能够直接将内存流写入响应。输出流。