通过iframe将浏览器中的PDF URL发送到打印机

时间:2013-07-11 14:25:43

标签: javascript printing

对于当前的非IE浏览器(Chrome,Firefox,Opera,Safari),我希望在给定该PDF的URL的情况下将PDF文档发送到打印机。

为了避免多余的窗口弹出,我目前正在使用<iframe>执行此操作,但我希望在打印完成后关闭iframe,否则某些浏览器会在尝试离开时弹出对话框页。

这是我到目前为止所提出的(为简单起见使用lodash和jQuery):

var _print_url, _remove_iframe, _set_print;

_print_url = function(src_url) {
  $("<iframe src='" + src_url + "' type='application/pdf'>").css({
    visibility: 'hidden',
    position: 'fixed',
    right: '0',
    bottom: '0'
  }).on('load', _set_print).appendTo(document.body);
};

_remove_iframe = function(iframe) {
  return $(iframe).parent().find(iframe).detach();
};

_set_print = function() {
  this.contentWindow.print();
/* 
 * Where we could do @contentWindow.close() with a window, we must remove the
 * print iframe from the DOM. We have to engage in some async madness
 * it seems, for no apparent reason other than this won't work
 * synchronously (@cw.print above must be async, it seems) - even though 
 * window.close() appears to work synchronously.
 */
  _.delay(_.partial(_remove_iframe, this), 100);
};

有时谷歌浏览器的打印对话框最终会正确显示PDF,但是当选择打印机并确认打印意图时,实际上会将框架父页面的内容发送到打印机而不是PDF本身。

有一个链接suggestions on the Mozilla page,但此文件目前似乎已过时。我能找到的最好的例子是通过对发票的Amazon Web Services打印对话框进行逆向工程,但这会打开一个窗口。

我考虑过的一个替代方案是Google Cloud Print,但显然这需要安装额外的软件或配置Google帐户,除非必要,否则我不希望将其强加给用户。

是否还有其他一些例子,说明如何在给定URL的情况下打印PDF,特别是使用Javascript,而没有其他多余的浏览器插件或诸如Windows弹出的文物?

1 个答案:

答案 0 :(得分:3)

- 请注意,这种方法你永远不会看到弹出窗口阻止程序 -

我在几个月前使用ajax应用程序遇到了类似的问题,我遇到的问题是我需要创建pdf文件并存储才能将其发送到打印,我所做的是以下内容:

我没有使用iframe。此应用程序与php TCPDF一起用于为模板系统创建pdf以及jqueryunderscore

您可以在http://www.screenr.com/Ur07(2:18分钟)

看到演示视频
  1. 通过JSON(ajax)发送信息为了实现这一目标,因为我遇到了一切都在ajax中的问题,所以我无法发布信息,所以我做的是附加一个隐藏的form到DOM然后使用target =“_ blank”将帖子发布到一个新窗口(您将关闭该过程的结束)。
  2. HTML隐藏虚拟表单

    <form method='<%= method %>' 
          action="<%= action %>" 
          name="<%= name %>" 
          id="<%= id %>" 
          target="_blank">
        <input type='hidden' name='json' id='<%= valueId %>' />
    </form>
    

    的Javascript

     function makePost(){
      var _t = _.template(_JS_Templates["print.form.hidden"]); //this the html of the form
    
      var o = {
        method : "POST",
        action : js_WEB_ + "/print.php",
        name : "print_virtual_form",
        id : "print_virtual_form_id",
        valueId : "print_virtual_value"
      }
    
     var form = _t(o);
     $(".warp").append(form); //appending the form to the dom
    
      var json = {
        data : data // some data
      }     
    
     $("#print_virtual_value").val(JSON.stringify(json)); //assing to the hidden input the value and stringify the json
     $("#print_virtual_form_id").submit(); //make the post submmitting the form
     $("#print_virtual_form_id").remove(); //removing the "virtual hidden form"
    
    }
    

    2.-当你在我的情况下收到json使用php你创建了你必须创建的任何东西,我这样做你可以看到这个例子中的PHP代码(是我的答案)

    Generate PDF using TCPDF on ajax call

    3.-最后在这里,很酷的部分来了响应,在这一部分,我使用php文件编写一个javascript代码,说必须关闭父窗口并报告特定的json答案功能,是一种回调。

    switch($_SERVER['REQUEST_METHOD']){
        case "GET":
            echo "Denied";
        break;
    
        case "POST":
            if(isset($_POST["json"])){
                if(!empty($_POST["json"])){
                    $json = $_POST["json"];             
                    $hash = PDF::makePDF($json);
                    echo "<script>
                      function init() {
                            //calling callback
                                            //returning control to the previous browser
                                     window.opener.someclass.finish('".$hash."');
                                     window.close();
                        }
                    window.onload = init;                       
                 </script>";
                }else{
                    echo "not json detected";
                }
            }else{
                echo "not json detected";
            }
        break;
    

    4.-并且在窗口浏览器中你可以使用控件结束。

    var someobject = (function(name){
      //private
      var finish(data){
        //do whatever you want with the json data
      }
    
       //public
       var $r = {};
       $r.finish = function(data){ 
         finish(data); //you will pass the data to the finish function and that is..!! voila!!
       }
    
       return $r;
    })("someobject");
    

    我知道这不是你要求的,但是我认为这个问题稍微复杂一点,我可以保证在很多浏览器中工作,用户会喜欢你喜欢的方式。他们永远不会看到正在发生的事情,他们将下载文件,只是期望这样做,点击一个链接并保存文件。

    只是我的两分钱和快乐的编码。