打印DIV内容的最佳方法是什么?


当前回答

我知道这是一个老问题,但我用jQuery解决了这个问题。

function printContents(id) {
    var contents = $("#"+id).html();

    if ($("#printDiv").length == 0) {
      var printDiv = null;
      printDiv = document.createElement('div');
      printDiv.setAttribute('id','printDiv');
      printDiv.setAttribute('class','printable');
      $(printDiv).appendTo('body');
    }

    $("#printDiv").html(contents);

    window.print();

    $("#printDiv").remove();
}

CSS

  @media print {
    .non-printable, .fancybox-outer { display: none; }
    .printable, #printDiv { 
        display: block; 
        font-size: 26pt;
    }
  }

其他回答

最好的方法是将div的内容提交给服务器,并打开一个新窗口,服务器可以将这些内容放入新窗口中。

如果这不是一个选项,你可以尝试使用客户端语言,如javascript隐藏页面上的所有内容,除了div,然后打印页面…

注意:这只适用于启用jQuery的站点

这个很酷的技巧非常简单。它在谷歌Chrome浏览器中为我工作。火狐不允许你在没有插件的情况下打印PDF文件。

首先,使用(Ctrl + Shift + I) / (Cmd + Option + I)打开检查器。 在控制台中输入以下代码:


var jqchild = document.createElement('script');
jqchild.src = "https://cdnjs.cloudflare.com/ajax/libs/jQuery.print/1.5.1/jQuery.print.min.js";
document.getElementsByTagName('body')[0].appendChild(jqchild);
$("#myDivWithStyles").print(); // Replace ID with yours

它启动打印对话框。打印出来或者保存成PDF格式(chrome)。完成了!

逻辑很简单。我们正在创建一个新的脚本标记,并将其附加在关闭主体标记的前面。我们在HTML中注入了一个jQuery打印扩展。用你自己的Div标签ID更改myDivWithStyles。现在它负责准备一个可打印的虚拟窗口。

在任何网站上尝试一下。唯一需要注意的是,有时巧妙地编写CSS会导致丢失样式。但大多数时候我们得到的是内容。

下面的代码复制了查询选择器目标的所有相关节点,复制了它们在屏幕上看到的样式,因为许多用于css选择器目标的父元素将会丢失。如果有很多带有很多样式的子节点,这将导致一些延迟。

理想情况下,你应该有一个打印样式表,但这是为用例,没有打印样式表插入,你希望打印在屏幕上看到。

如果您在此页的浏览器控制台中复制以下项目,它将打印此页上的所有代码片段。

+function() {
    /**
     * copied from  https://stackoverflow.com/questions/19784064/set-javascript-computed-style-from-one-element-to-another
     * @author Adi Darachi https://stackoverflow.com/users/2318881/adi-darachi
     */
    var copyComputedStyle = function(from,to){
        var computed_style_object = false;
        //trying to figure out which style object we need to use depense on the browser support
        //so we try until we have one
        computed_style_object = from.currentStyle || document.defaultView.getComputedStyle(from,null);

        //if the browser dose not support both methods we will return null
        if(!computed_style_object) return null;

            var stylePropertyValid = function(name,value){
                        //checking that the value is not a undefined
                return typeof value !== 'undefined' &&
                        //checking that the value is not a object
                        typeof value !== 'object' &&
                        //checking that the value is not a function
                        typeof value !== 'function' &&
                        //checking that we dosent have empty string
                        value.length > 0 &&
                        //checking that the property is not int index ( happens on some browser
                        value != parseInt(value)

            };

        //we iterating the computed style object and compy the style props and the values
        for(property in computed_style_object)
        {
            //checking if the property and value we get are valid sinse browser have different implementations
                if(stylePropertyValid(property,computed_style_object[property]))
                {
                    //applying the style property to the target element
                        to.style[property] = computed_style_object[property];

                }   
        }   

    };


    // Copy over all relevant styles to preserve styling, work the way down the children tree.
    var buildChild = function(masterList, childList) {
        for(c=0; c<masterList.length; c++) {
           var master = masterList[c];
           var child = childList[c];
           copyComputedStyle(master, child);
           if(master.children && master.children.length > 0) {
               buildChild(master.children, child.children);
           }
        }
    }

    /** select elements to print with query selector **/
    var printSelection = function(querySelector) {
        // Create an iframe to make sure everything is clean and ordered.
        var iframe = document.createElement('iframe');
        // Give it enough dimension so you can visually check when modifying.
        iframe.width = document.width;
        iframe.height = document.height;
        // Add it to the current document to be sure it has the internal objects set up.
        document.body.append(iframe);

        var nodes = document.querySelectorAll(querySelector);
        if(!nodes || nodes.length == 0) {
           console.error('Printing Faillure: Nothing to print. Please check your querySelector');
           return;
        }

        for(i=0; i < nodes.length; i++) {

            // Get the node you wish to print.
            var origNode = nodes[i];

            // Clone it and all it's children
            var node = origNode.cloneNode(true);

            // Copy the base style.
            copyComputedStyle(origNode, node);

            if(origNode.children && origNode.children.length > 0) {
                buildChild(origNode.children, node.children);
            }

            // Add the styled clone to the iframe. using contentWindow.document since it seems the be the most widely supported version.

            iframe.contentWindow.document.body.append(node);
        }
        // Print the window
        iframe.contentWindow.print();

        // Give the browser a second to gather the data then remove the iframe.
        window.setTimeout(function() {iframe.parentNode.removeChild(iframe)}, 1000);
    }
window.printSelection = printSelection;
}();
printSelection('.default.prettyprint.prettyprinted')

我认为目前提出的解决方案有以下缺点:

CSS媒体查询解决方案假设只有一个div要打印。 javascript解决方案只适用于特定的浏览器。 破坏父窗口内容并重新创建会造成混乱。

我改进了上面的解决方案。下面是我测试过的一种方法,效果非常好,有以下好处。

适用于所有浏览器,包括IE, Chrome, Safari和firefox。 不会破坏和重载父窗口。 可以在页面上打印任意数量的DIV。 使用HTML模板避免容易出错的字符串连接。

注意事项:

必须在新创建的窗口上有一个onload="window.print()"。 不要从父类调用targetwindow.close()或targetwindow.print()。 确保执行targetwindow.document.close()和target.focus() 我使用的是jquery,但你也可以使用简单的javascript做同样的技术。 你可以在这里看到它的行动https://math.tools/table/multiplication。通过单击框头上的打印按钮,可以分别打印每个表。

<script id="print-header" type="text/x-jquery-tmpl"> <html> <header> <title>Printing Para {num}</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <style> body { max-width: 300px; } </style> </header> <body onload="window.print()"> <h2>Printing Para {num} </h2> <h4>https://math.tools</h4> </script> <script id="print-footer" type="text/x-jquery-tmpl"> </body> </html> </script> <script> $('.printthis').click(function() { num = $(this).attr("data-id"); w = window.open(); w.document.write( $("#print-header").html().replace("{num}",num) + $("#para-" + num).html() + $("#print-footer").html() ); w.document.close(); w.focus(); //w.print(); Don't do this otherwise chrome won't work. Look at the onload on the body of the newly created window. ///w.close(); Don't do this otherwise chrome won't work }); </script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a class="btn printthis" data-id="1" href="#" title="Print Para 1"><i class="fa fa-print"></i> Print Para 1</a> <a class="btn printthis" data-id="2" href="#" title="Print Para 2"><i class="fa fa-print"></i> Print Para 2</a> <p class="para" id="para-1"> Para 1 : Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p class="para" id="para-2"> Para 2 : Lorem 2 ipsum 2 dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

我认为有更好的解决办法。让你的div打印覆盖整个文档,但只在打印时:

@media print {
    .myDivToPrint {
        background-color: white;
        height: 100%;
        width: 100%;
        position: fixed;
        top: 0;
        left: 0;
        margin: 0;
        padding: 15px;
        font-size: 14px;
        line-height: 18px;
    }
}