如何打印 ExtJS 组件?

6
如何弹出打印对话框并在确认后打印组件?
6个回答

8
                    var targetElement = Ext.getCmp('PrintablePanelId');
                    var myWindow = window.open('', '', 'width=200,height=100');
                    myWindow.document.write('<html><head>');
                    myWindow.document.write('<title>' + 'Title' + '</title>');
                    myWindow.document.write('<link rel="Stylesheet" type="text/css" href="http://dev.sencha.com/deploy/ext-4.0.1/resources/css/ext-all.css" />');
                    myWindow.document.write('<script type="text/javascript" src="http://dev.sencha.com/deploy/ext-4.0.1/bootstrap.js"></script>');
                    myWindow.document.write('</head><body>');
                    myWindow.document.write(targetElement.body.dom.innerHTML);
                    myWindow.document.write('</body></html>');
                    myWindow.print();

将您的ExtJS可打印组件写入文档中。

+1 我采用了这种方法并对其进行了扩展(请参见下面的答案) - Peter


2

我喜欢Gopal Saini的答案!我采用了他的方法,并为我的一个应用程序编写了一个函数。这是代码。已在FF和Safari上进行测试。尚未在IE上尝试,但应该可以工作。

print: function(el){

    var win = window.open('', '', 'width='+el.getWidth()+',height='+el.getHeight());
    if (win==null){
        alert("Pop-up is blocked!");
        return;
    }


    Ext.Ajax.request({

        url: window.location.href,
        method: "GET",
        scope: this,
        success: function(response){

            var html = response.responseText;
            var xmlDoc;
            if (window.DOMParser){
                xmlDoc = new DOMParser().parseFromString(html,"text/xml");
            }
            else{
                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async = false;
                xmlDoc.loadXML(html);
            }


            win.document.write('<html><head>');
            win.document.write('<title>' + document.title + '</title>');


            var xml2string = function(node) {
               if (typeof(XMLSerializer) !== 'undefined') {
                  var serializer = new XMLSerializer();
                  return serializer.serializeToString(node);
               } else if (node.xml) { 
                  return node.xml;
               }
            }


            var links = xmlDoc.getElementsByTagName("link");
            for (var i=0; i<links.length; i++){
                win.document.write(xml2string(links[i]));
            }

            win.document.write('</head><body>');
            win.document.write(el.dom.innerHTML);
            win.document.write('</body></html>');
            win.print();
        },
        failure: function(response){
            win.close();
        }
    });
}

1

在ExtJS中打印并不是特别容易。我发现关于如何使组件可打印的最佳资源可以在Sencha architect's blog上找到。该文章描述了如何为组件设置自定义打印渲染器以及有关打印的其他细节。然而,这些信息适用于ExtJS 3.x;可能ExtJS 4已经使打印变得更加容易。


那个 Sencha 架构师的链接已经失效了。 - Blaise
我已经更新了链接,使用 Wayback Machine 的博客文章副本。 - NT3RP

1
你还可以添加一个具有modal属性设置为true的组件到Ext.window.Window,然后打开一个标准的打印对话框,只会打印所需的组件。
var view = this.getView();
var extWindow = Ext.create('Ext.window.Window', { modal: true });
extWindow.add(component); // move component from the original panel to the popup window
extWindow.show();

window.print(); // prints only the content of a modal window

// push events to the event queue to be fired on the print dialog close
setTimeout(function() {
    view.add(component); // add component back to the original panel
    extWindow.close();
}, 0);

这对我有用 - 我还创建了一个函数来循环遍历组件。我检查了面板高度,并在需要分页时插入了一个空的 div。 - Nate Anderson

0
另一个要考虑的选项是将组件渲染为图像或PDF。虽然弹出窗口/打印选项很好,但有些浏览器无法正确打印。它们倾向于忽略背景图像、某些CSS属性等。为了使组件在弹出窗口中显示的方式完全打印出来,我最终编写了一些服务器端代码将HTML转换为图像。
以下是客户端代码的样子:
print: function(el){

    var waitMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
    waitMask.show();


  //Parse current url to set up the host and path variables. These will be
  //used to construct absolute urls to any stylesheets.
    var currURL = window.location.href.toString();
    var arr = currURL.split("/");
    var len = 0;
    for (var i=0; i<arr.length; i++){
        if (i<3) len+=(arr[i].length+1);
    }
    var host = currURL.substring(0, len);
    if (host.substring(host.length-1)=="/") host = host.substring(0, host.length-1);

    var path = window.location.pathname;
    if (path.lastIndexOf("/")!=path.length-1){
        var filename = path.substring(path.lastIndexOf("/")+1);
        if (filename.indexOf(".")!=-1){
            path = path.substring(0, path.lastIndexOf("/")+1);
        }
        else{
            path += "/";
        }
    }


  //Start constructing an html document that we will send to the server
    var html = ('<html><head>');
    html += ('<title>' + document.title + '</title>');


  //Insert stylesheets found in the current page. Update href attributes
  //to absolute URLs as needed.
    var links = document.getElementsByTagName("link");
    for (var i=0; i<links.length; i++){
        var attr = links[i].attributes;
        if (attr.getNamedItem("rel")!=null){

            var rel = attr.getNamedItem("rel").value;
            var type = attr.getNamedItem("type").value;
            var href = attr.getNamedItem("href").value;

            if (href.toLowerCase().indexOf("http")!=0){
                if (href.toString().substring(0, 1)=="/"){
                    href = host + href;
                }
                else{
                    href = host + path + href;
                }
            }

            html += ('<link type="' + type + '" rel="' + rel+ '" href="' + href + '"/>');
        }
    }

    html += ('</head><body id="print">');
    html += (el.dom.innerHTML);
    html += ('</body></html>');


  //Execute AJAX request to convert the html into an image or pdf -
  //something that will preserve styles, background images, etc.
  //This, of course, requires some server-side code. In our case,
  //our server is generating a png that we return to the client.
    Ext.Ajax.request({

        url: "/WebServices/Print?action=submit",
        method: "POST",
        rawData: html,
        scope: this,
        success: function(response){
            var url = "/WebServices/Print?action=pickup&id="+response.responseText;
            window.location.href = url;
            waitMask.hide();
        },
        failure: function(response){
            win.close();
            waitMask.hide();
            var msg = (response.responseText.length>0 ? response.responseText : response.statusText);
            alert(msg);
        }
    });
}

再次强调,这需要一些服务器端的魔法来将HTML转换为图片。在我的情况下,我实现了一个“打印”服务。客户通过“提交”操作提交作业请求,并通过“取货”操作检索输出产品。

要将HTML转换为图片,我最终使用了一个免费的命令行应用程序,名为Web Screen Capture。它只能在Windows上运行,而且我不知道它的可扩展性如何,所以请自行权衡风险后使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接