【问题标题】:How do I print an existing PDF from a code-behind page?如何从代码隐藏页面打印现有 PDF?
【发布时间】:2010-11-16 10:48:12
【问题描述】:

我在 SO 上看到过一些类似的问题,但找不到适合我的任何问题。我希望发生的事件链如下:

  1. 用户单击 ASP.NET 按钮控件
  2. 这会触发该按钮的 onclick 事件,这是 C# 代码隐藏中的函数 foo()
  3. foo() 调用了其他一些(不重要的)函数,该函数创建了一个最终保存到服务器磁盘的 PDF。该函数返回 PDF 的路径
  4. 无需任何其他用户交互,一旦生成 PDF,打印对话框就会在用户浏览器中打开以打印该 PDF

我需要做什么才能完成第 4 步?理想情况下,我可以在 foo() 中调用它,传入 PDF 的路径,这将触发用户浏览器中的打印对话框(打印 PDF 而不是触发 onclick 的页面)。

我认为我可以转发到 PDF 文档的 URL,并在 PDF 中嵌入一些 Javascript 来自动打印它,但我宁愿不这样做 - 我不一定想每次都打印 PDF它已打开(在浏览器中)。还有其他好方法吗?

【问题讨论】:

    标签: c# asp.net pdf printing


    【解决方案1】:
    Response.Clear()
    Response.AddHeader("Content-Disposition", "attachment; filename=myfilename.pdf")
    Response.ContentType = "application/pdf"
    Response.BinaryWrite(ms.ToArray())
    

    其中 ms = 包含您的文件的内存流(您不必在中间将其写入磁盘。)

    否则,如果您绝对必须处理来自硬盘的问题,请使用:

    Response.WriteFile("c:\pathtofile.pdf")
    

    【讨论】:

    • 我用过类似的东西,效果很好,没有额外的文件也是一个优点。确保使用如上所示的系统路径而不是本地 Web 路径。
    【解决方案2】:

    感谢 Vdex 的回答。这是 iText/C# 版本。

    PdfAction action = new PdfAction();
    action.Put(new PdfName("Type"), new PdfName("Action"));
    action.Put(new PdfName("S"), new PdfName("Named"));
    action.Put(new PdfName("N"), new PdfName("Print"));
    
    PdfReader reader = new PdfReader(ReportFile.FullFilePath(reportFile.FilePath));
    
    PdfStamper stamper = new PdfStamper(reader, Response.OutputStream);
    stamper.Writer.CloseStream = false;
    stamper.Writer.SetOpenAction(action);
    stamper.Close();
    

    【讨论】:

      【解决方案3】:

      我没有尝试过,但这是一个想法:

      如果您可以读取 PDF 中嵌入的 javascript 中的查询字符串参数,则嵌入 javascript,并使打印函数以 javascript 参数为条件。

      这样,如果您重定向到例如 yourpdf.pdf?print,它将打印,如果在没有打印参数的情况下打开它,它的行为与任何其他普通 PDF 一样。

      【讨论】:

      • 这听起来像是在朝着更复杂的方向发展——它当然可以工作,但我更愿意让 PDF 独立于网页的行为。
      【解决方案4】:

      如果您想在打开后立即打印:

      您可以在 PDF 中插入一个标志,强制它在打开 PDF 后立即打开打印对话框。我在很久以前使用经典 ASP 中的 abcpdf 组件做过这个,代码看起来像:

      Set oDoc = Server.CreateObject("ABCpdf4.Doc")
      oDoc.SetInfo oDoc.Root, "/OpenAction", "<< /Type /Action /S /Named /N /Print >>"
      

      显然,根据您使用的 PDF 创建工具,代码看起来会有所不同......

      【讨论】:

      • 我会告诉用户的浏览器在调用 Response.Redirect("[url to PDF]") 生成 PDF 后打开它吗?
      • 是的,或者您可以 response.writefile 它并设置页面的所有 Response.ContentType 和其他标题以提供 PDF。
      【解决方案5】:

      我得到的解决方案是这样的:

      创建一个新的 ASP.NET Web 表单(我称为 BinaryData.aspx)作为 PDF 的占位符。在后面的代码中,唯一的方法应该是 Page_Load,它看起来像:

      protected void Page_Load(object sender, System.EventArgs e)
      {
          //Set the appropriate ContentType.
          Response.ContentType = "Application/pdf";
          Response.AppendHeader("Pragma", "no-cache"); 
          Response.AppendHeader("Cache-Control", "no-cache");
          //Get the physical path to the file.
          string FilePath = (string)Session["fileLocation"];
          if ( FilePath != null )         
          {
              string FileName = Path.GetFileName(FilePath);
      
              Response.AppendHeader("Content-Disposition", "attachment; filename="+FileName);
      
              //Write the file directly to the HTTP content output stream.
              Response.WriteFile(FilePath);
              Response.End();
          }
      }
      

      PDF 通过名为“fileLocation”的 Session 变量传递到页面。所以,我所要做的就是设置那个变量,然后调用Response.Redirect("BinaryData.aspx")

      它不会自动打印,但它会在不离开当前页面的情况下触发 PDF 的下载(这对我来说已经足够了)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-26
        • 2021-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-03
        • 2012-09-27
        • 1970-01-01
        相关资源
        最近更新 更多