如何使用 asp.net c# 直接打印使用 iTextSharp 动态创建的 PDF?

How to directly print a PDF dynamically created with iTextSharp using asp.net c#?

我环顾四周,似乎找不到适合我的方法。我正在创建一个网站,我有两个按钮,一个下载按钮(工作正常)和一个应该打印 PDF 的打印按钮(或者甚至只是在打开打印对话框的情况下在 adobe 中打开 PDF)。

我的问题与许多其他问题的最大区别在于我不是要创建新文档。我的 PDF 是使用我已经创建的模板 PDF 生成的。

我只需要一种打印文档的方法。我无法将它保存在服务器上,因为我希望客户端能够打印它。我已经尝试过 MemoryStream,但它不起作用(当然我可能没有正确编写它,代码在下面)。 header 是从另一个页面抓取的。

using (var ms = new MemoryStream())
{
    Response.ContentType = "application/octet-stream";
    Response.AppendHeader("Content-Disposition", header);   /

    Response.Buffer = true;
    Response.Clear();
    var bytes = ms.ToArray();
    PdfReader r = new PdfReader(template);         
    using (PdfStamper ps = new PdfStamper(r, Response.OutputStream))    
    {
        AcroFields af = ps.AcroFields;
        ...
        ps.FormFlattening = true;
    }
    Response.OutputStream.Write(bytes, 0, bytes.Length);
    Response.OutputStream.Flush();

同样,我希望能够让客户打印他们单击“打印”按钮后生成的这个 PDF。

在走这条路太远之前,我只想确保正确解释了一些事情。我不知道你的专业水平,所以如果我说的很明显,请不要生气。

首先,你说你有两个按钮,"Download" 和 "Print"。我们知道您打算让这些做什么,但是了解和理解这两个选项都是 "download" 很重要。您的 "Download" 按钮实际上是 "download and (maybe) prompt to save",您的 "Print" 按钮实际上是 "download and then if the person has a PDF renderer configured in their browser (which most modern browsers have) then render the PDF otherwise prompt to save"。这对你来说可能已经很明显了,但我只是想确保它是清楚的。我个人没有将 PDF 渲染器绑定到我的默认浏览器,因此每次都会为我下载所有 PDF。

其次,服务器可以向客户端发送一个且只有一个 "thing" 以响应请求。 "thing" 可以关联元数据 (headers),但相关的标准元键很少。一个关键 (content-disposition) 是相对于发起请求,是否应将此响应视为 "inline" 或 "attachment"。有些浏览器将后者视为 "download and (maybe) prompt to save",但有些浏览器仍会启动关联的应用程序。还有另一个密钥(application/octet-stream 的 mime 类型)有些人用来进一步欺骗浏览器,本质上说 "seriously dude, this thing I'm sending is so weird that it would be impossible for you to figure it out so just save it to disk".

这一切都非常重要,因为没有 "please print this" 您可以从服务器发送符合任何标准规范(或我见过的任何规范)的东西。此外,服务器甚至不能说 "open this in a new tab or browser window"。打印和 window/tab 控件都是 client-side 功能,因此您需要从那个角度进行攻击。

那么现在来谈谈一些选择。这些选项都假定您的客户拥有带有 PDF 渲染器 built-in 并已启用的现代浏览器。

您可以使用的一个选项是 wrap your PDF in an iframe that has some JavaScript that calls window.print() upon loading。 Google 曾经(也许现在仍然)用于他们的日历。您需要使用各种客户端呈现设备对此进行测试,以确保它按预期工作。

另一种选择是尝试 using PDFObject 嵌入 PDF,然后使用上面提到的相同 JavaScript。

最后一个选项是稍微更改您的 PDF 生成代码,然后add JavaScript to your PDF尝试在加载时打印 PDF。 JavaScript PDF 渲染器中的支持不是通用的,因此您需要检查这是否适用于您的客户。此外,此设置在您制作的 PDF 中 "baked",因此如果有人将其保存到磁盘,每次打开它时都会尝试打印,这非常烦人。