打印DIV的内容


335

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



1
印刷是什么意思?就像在物理打印机上一样?
Yuriy Faktorovich

像在打印机上一样“打印”?或文件?
Ed Schembor

我找到了迄今为​​止由etimbo github.com/etimbo/jquery-print-preview-plugin
MaxI

3
就像任何尝试搜索此打印div问题的解决方案的人的参考一样。我发现以下答案非常有用:stackoverflow.com/a/7532581/405117
Vikram 2012年

Answers:


517

与早期版本相比有轻微更改-已在CHROME上测试

function PrintElem(elem)
{
    var mywindow = window.open('', 'PRINT', 'height=400,width=600');

    mywindow.document.write('<html><head><title>' + document.title  + '</title>');
    mywindow.document.write('</head><body >');
    mywindow.document.write('<h1>' + document.title  + '</h1>');
    mywindow.document.write(document.getElementById(elem).innerHTML);
    mywindow.document.write('</body></html>');

    mywindow.document.close(); // necessary for IE >= 10
    mywindow.focus(); // necessary for IE >= 10*/

    mywindow.print();
    mywindow.close();

    return true;
}

8
这是一个快速的解决方案。理想的解决方案是使用单独的CSS进行打印。也许您可以详细说明问题的细节(要求)。
Bill Paetzke

6
您可以在弹出窗口中引用样式表。在<head>标签之间添加另一行代码:mywindow.document.write('<link rel =“ stylesheet” href =“ main.css” type =“ text / css” />');
Bill Paetzke'2

5
@Rahil将其更改为:mywindow.document.close(); mywindow.focus(); mywindow.print(); mywindow.close();
ROFLwTIME

3
^添加newwindow.focus(); 启用跨浏览器打印。
JackMahoney13年

7
如果无法加载打印预览,有时会发生这种情况,也许是在要打印的内容很大时(我只在Chrome中注意到它,而在Firefox中同一页面的打印性能不错,但是我不排除它可能在Firefox或其他浏览器中也发生)。我发现最好的方法是仅在Windows加载后才运行打印(并关闭)。因此,之后:mywindow.document.write(data);添加以下内容:mywindow.document.write('<script type="text/javascript">$(window).load(function() { window.print(); window.close(); });</script>');并删除:mywindow.print();mywindow.close();
Fabius

164

我认为有更好的解决方案。使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;
    }
}

完美,比弹出窗口好得多。
GreenWebDev'2

5
不幸的是,它会在IE浏览器不工作,很符合市场预期,看到这一点:stackoverflow.com/questions/975129/...
jarek.jpa

16
应该溢出到多个页面上的内容在Chrome中似乎被截断了。
Ishmael Smyrnow

在IE上,您需要隐藏文档的其余部分。进行如下修改将起作用:@media print {body * {display:none; } .myDivToPrint {display:block; 背景颜色:白色;高度:100%; 宽度:100%; 位置:固定;最高:0; 左:0;边距:0; 填充:15px; font-size:14px; 行高:18px; }
罗恩·布莱克(RonnBlack)2015年

2
您可能需要输入z-index:9999999;如果您将其他元素放置在较高位置。
亚当M.16年

43

尽管@gabe已经说过了,但是如果您使用的是jQuery,则可以使用我的printElement插件。

有一个样品在这里,和有关该插件的详细信息在这里

用法很简单,只需使用jQuery选择器获取一个元素并打印即可:

$("#myDiv").printElement();

希望对您有所帮助!


14
8年后,这将产生“ a.browser is undefined”,因为.browser调用已在jquery 1.9中删除
KingsInnerSoul

1
@KingsInnerSoul对jQuery用户并不那么粗鲁,这些时间对他们来说足够严酷; p
Alexandre Daubricourt

@AlexandreDaubricourt哈哈
KingsInnerSoul

22

使用Jquery,只需使用以下功能:

<script>
function printContent(el){
var restorepage = $('body').html();
var printcontent = $('#' + el).clone();
$('body').empty().html(printcontent);
window.print();
$('body').html(restorepage);
}
</script>

您的打印按钮将如下所示:

<button id="print" onclick="printContent('id name of your div');" >Print</button>

编辑:如果您确实有需要保留的表单数据,克隆不会复制该数据,因此您只需要获取所有表单数据并在还原后按如下方式替换它们:

<script>
function printContent(el){
var restorepage = $('body').html();
var printcontent = $('#' + el).clone();
var enteredtext = $('#text').val();
$('body').empty().html(printcontent);
window.print();
$('body').html(restorepage);
$('#text').html(enteredtext);
}
</script>
<textarea id="text"></textarea>

$('body')。html(restorepage); 将无法使用,因为当时没有body元素可用。因此最好用location.reload()替换它;
调试器

否。如果您重新加载页面,您将删除表格中的任何信息或可能需要的其他任何设置。它工作得很好。如果花时间查看代码,您会看到var restorepage DOES具有所有可用于进行替换的页面信息。停止尝试编辑我的代码,或者自己进行测试,或者了解函数的每个部分的功能。
Gary Hayes

这个更好。它包括在打印时的页面设计,与上面提到的页面设计不同,在该页面中,我仍然需要放置标题中的CSS链接等。谢谢!
Jorz

您通过的方式el很糟糕,尤其是自从使用jQ以来。更好地通过selector并摆脱硬编码会更好#
RozzA

今天我一直使用这种方法,我注意到它在android设备(Google Chrome)上无法正常工作。页面的可打印区域每次都会更改,并且包含一些多余的部分el。我认为在恢复机身时会发送打印命令。
Ali Sheikhpour'1

18

从这里http://forums.asp.net/t/1261525.aspx

<html>

<head>
    <script language="javascript">
        function printdiv(printpage) {
            var headstr = "<html><head><title></title></head><body>";
            var footstr = "</body>";
            var newstr = document.all.item(printpage).innerHTML;
            var oldstr = document.body.innerHTML;
            document.body.innerHTML = headstr + newstr + footstr;
            window.print();
            document.body.innerHTML = oldstr;
            return false;
        }
    </script>
    <title>div print</title>
</head>

<body>
    //HTML Page //Other content you wouldn't like to print
    <input name="b_print" type="button" class="ipt" onClick="printdiv('div_print');" value=" Print ">

    <div id="div_print">

        <h1 style="Color:Red">The Div content which you want to print</h1>

    </div>
    //Other content you wouldn't like to print //Other content you wouldn't like to print
</body>

</html>

1
需要修改以将footerStr分为2部分。因为brwoser使用“ </ body>”作为当前页面的主要结尾。var footstr1 =“ </”; var footstr2 =“ body>”; var footerstr = footstr1 + footstr12;
mirzaei 2013年

13

我使用Bill Paetzke答案来打印包含图像的div,但不适用于谷歌浏览器

我只需要添加此myWindow.onload=function(){行使其起作用,这是完整的代码

<html>
<head>
    <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"> </script>
    <script type="text/javascript">
        function PrintElem(elem) {
            Popup($(elem).html());
        }

        function Popup(data) {
            var myWindow = window.open('', 'my div', 'height=400,width=600');
            myWindow.document.write('<html><head><title>my div</title>');
            /*optional stylesheet*/ //myWindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />');
            myWindow.document.write('</head><body >');
            myWindow.document.write(data);
            myWindow.document.write('</body></html>');
            myWindow.document.close(); // necessary for IE >= 10

            myWindow.onload=function(){ // necessary if the div contain images

                myWindow.focus(); // necessary for IE >= 10
                myWindow.print();
                myWindow.close();
            };
        }
    </script>
</head>
<body>
    <div id="myDiv">
        This will be printed.
        <img src="image.jpg"/>
    </div>
    <div>
        This will not be printed.
    </div>
    <div id="anotherDiv">
        Nor will this.
    </div>
    <input type="button" value="Print Div" onclick="PrintElem('#myDiv')" />
</body>
</html>

另外,如果有人只需要打印一个具有id的div,就不需要加载jquery

这是执行此操作的纯JavaScript代码

<html>
<head>
    <script type="text/javascript">
        function PrintDiv(id) {
            var data=document.getElementById(id).innerHTML;
            var myWindow = window.open('', 'my div', 'height=400,width=600');
            myWindow.document.write('<html><head><title>my div</title>');
            /*optional stylesheet*/ //myWindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />');
            myWindow.document.write('</head><body >');
            myWindow.document.write(data);
            myWindow.document.write('</body></html>');
            myWindow.document.close(); // necessary for IE >= 10

            myWindow.onload=function(){ // necessary if the div contain images

                myWindow.focus(); // necessary for IE >= 10
                myWindow.print();
                myWindow.close();
            };
        }
    </script>
</head>
<body>
    <div id="myDiv">
        This will be printed.
        <img src="image.jpg"/>
    </div>
    <div>
        This will not be printed.
    </div>
    <div id="anotherDiv">
        Nor will this.
    </div>
    <input type="button" value="Print Div" onclick="PrintDiv('myDiv')" />
</body>
</html>

我希望这可以帮助某人


这对我有用!尽管最初的答案使用“ mywindow”和“ myWindow”,但骆驼案确实咬住了我。谢谢!
操作码

12
function printdiv(printdivname) {
    var headstr = "<html><head><title>Booking Details</title></head><body>";
    var footstr = "</body>";
    var newstr = document.getElementById(printdivname).innerHTML;
    var oldstr = document.body.innerHTML;
    document.body.innerHTML = headstr+newstr+footstr;
    window.print();
    document.body.innerHTML = oldstr;
    return false;
}

这将打印div您想要的区域,并将内容设置回原样。printdivnamediv要打印的。


需要修改以将footerStr分为2部分。因为brwoser使用“ </ body>”作为当前页面的主要结尾。var footstr1 =“ </”; var footstr2 =“ body>”; var footerstr = footstr1 + footstr12;
mirzaei 2013年

太巧妙了!但是,是的,您确实需要来自mirzaei的破解,否则body标签会损坏,并且格式也将损坏。有了hack,这很好用!您甚至还可以添加自己的内部包装纸,以方便特殊的打印样式。这应该是公认的答案。
user2662680

9

创建一个单独的打印样式表,该样式表隐藏除您要打印的内容以外的所有其他元素。'media="print"加载时使用它进行标记:

<link rel="stylesheet" type="text/css" media="print" href="print.css" />

这使您可以为打印输出加载完全不同的样式表。

如果要强制在页面上显示浏览器的“打印”对话框,则可以在加载时使用JQuery这样执行:

$(function() { window.print(); });

或触发其他任何您想要的事件,例如用户单击按钮。


2
是的,那也行得通;很难-很好,不可能-确切地知道情况是什么。
尖尖的2010年

我同意单独的CSS是理想的解决方案。将div的内容复制到新窗口是一种快速的解决方案。
Bill Paetzke'2

9

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

  1. CSS媒体查询解决方案假定仅要打印一个div。
  2. javascript解决方案仅在某些浏览器上有效。
  3. 销毁父窗口内容并重新创建会造成混乱。

我对上面的解决方案进行了改进。这是我经过测试的,可以很好地发挥以下好处。

  1. 适用于所有浏览器,包括IE,Chrome,Safari和Firefox。
  2. 不会销毁并重新加载父窗口。
  3. 可以在页面中打印任意数量的DIV。
  4. 使用html模板来避免容易出错的字符串连接。

注意事项:

  1. 在新创建的窗口上必须具有onload =“ window.print()”。
  2. 不要从父级调用targetwindow.close()或targetwindow.print()。
  3. 确保您执行targetwindow.document.close()和target.focus()
  4. 我使用的是jquery,但您也可以使用普通的javascript做同样的技术。
  5. 您可以在http://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>http://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>
  


这非常好,跨浏览器的效果比公认的结果好得多!
dama_do_bling

7

我编写了一个插件来解决这种情况。我对那里的插件不满意,并着手进行更广泛的配置。

https://github.com/jasonday/printThis


1
非常感谢Jason的辛苦工作。真的要在我的更多项目中使用。真是个

6

接受的解决方案无效。Chrome浏览器正在打印空白页,因为它没有及时加载图像。此方法有效:

编辑:看来我的帖子发表后,修改了接受的解决方案。为什么要下票?该解决方案也可以正常工作。

    function printDiv(divName) {

        var printContents = document.getElementById(divName).innerHTML;
        w = window.open();

        w.document.write(printContents);
        w.document.write('<scr' + 'ipt type="text/javascript">' + 'window.onload = function() { window.print(); window.close(); };' + '</sc' + 'ript>');

        w.document.close(); // necessary for IE >= 10
        w.focus(); // necessary for IE >= 10

        return true;
    }

4

我知道这是一个老问题,但是我使用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;
    }
  }

3

尽管@BC答案是最好的打印一页。

但是,使用ctrl + P同时打印多页A4尺寸的页面可能会有所帮助。

@media print{
html *{
    height:0px!important;
    width:0px !important;
    margin: 0px !important;
    padding: 0px !important;
    min-height: 0px !important;
    line-height: 0px !important;
    overflow: visible !important;
    visibility: hidden ;


}


/*assing myPagesClass to every div you want to print on single separate A4 page*/

 body .myPagesClass {
    z-index: 100 !important;
    visibility: visible !important;
    position: relative !important;
    display: block !important;
    background-color: lightgray !important;
    height: 297mm !important;
    width: 211mm !important;
    position: relative !important;

    padding: 0px;
    top: 0 !important;
    left: 0 !important;
    margin: 0 !important;
    orphans: 0!important;
    widows: 0!important;
    overflow: visible !important;
    page-break-after: always;

}
@page{
    size: A4;
    margin: 0mm ;
    orphans: 0!important;
    widows: 0!important;
}}

2
  • 开启新视窗
  • 打开新窗口的文档对象,并向其中写入一个简单的文档,其中仅包含您拥有的div和必要的html标头等-您可能还希望将文档放入样式表中,具体取决于您的内容是
  • 将脚本放在新页面中以调用window.print()
  • 触发脚本

2

这是我的jQuery打印插件

(function ($) {

$.fn.printme = function () {
    return this.each(function () {
        var container = $(this);

        var hidden_IFrame = $('<iframe></iframe>').attr({
            width: '1px',
            height: '1px',
            display: 'none'
        }).appendTo(container);

        var myIframe = hidden_IFrame.get(0);

        var script_tag = myIframe.contentWindow.document.createElement("script");
        script_tag.type = "text/javascript";
        script = myIframe.contentWindow.document.createTextNode('function Print(){ window.print(); }');
        script_tag.appendChild(script);

        myIframe.contentWindow.document.body.innerHTML = container.html();
        myIframe.contentWindow.document.body.appendChild(script_tag);

        myIframe.contentWindow.Print();
        hidden_IFrame.remove();

    });
};
})(jQuery);

2

如果要使用原始文档中的所有样式(包括内联样式),则可以使用此方法。

  1. 复制完整文件
  2. 将主体替换为要打印的元素。

实现方式:

class PrintUtil {
  static printDiv(elementId) {
    let printElement = document.getElementById(elementId);
    var printWindow = window.open('', 'PRINT');
    printWindow.document.write(document.documentElement.innerHTML);
    setTimeout(() => { // Needed for large documents
      printWindow.document.body.style.margin = '0 0';
      printWindow.document.body.innerHTML = printElement.outerHTML;
      printWindow.document.close(); // necessary for IE >= 10
      printWindow.focus(); // necessary for IE >= 10*/
      printWindow.print();
      printWindow.close();
    }, 1000)
  }   
}

2
我不知道这是最好的解决方案,但是效果很好。谢谢!
BRogers

如果
可行

2

注意:这仅适用于启用jQuery的网站

这个很酷的技巧很简单。它在Google Chrome浏览器中对我有用。Firefox不允许您在没有插件的情况下打印为PDF。

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

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
  1. 它启动打印对话框。进行物理打印或将其保存为PDF(镀铬)。做完了!

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

在任何站点上尝试。有时,只有用技巧写CSS才能引起注意,否则可能会导致样式丢失。但是我们大多数时候都会得到内容。


1

在Opera中,尝试:

    print_win.document.write('</body></html>');
    print_win.document.close(); // This bit is important
    print_win.print();
    print_win.close();

1

这是适用于IE和Chrome的IFrame解决方案:

function printHTML(htmlString) {
    var newIframe = document.createElement('iframe');
    newIframe.width = '1px';
    newIframe.height = '1px';
    newIframe.src = 'about:blank';

    // for IE wait for the IFrame to load so we can access contentWindow.document.body
    newIframe.onload = function() {
        var script_tag = newIframe.contentWindow.document.createElement("script");
        script_tag.type = "text/javascript";
        var script = newIframe.contentWindow.document.createTextNode('function Print(){ window.focus(); window.print(); }');
        script_tag.appendChild(script);

        newIframe.contentWindow.document.body.innerHTML = htmlString;
        newIframe.contentWindow.document.body.appendChild(script_tag);

        // for chrome, a timeout for loading large amounts of content
        setTimeout(function() {
            newIframe.contentWindow.Print();
            newIframe.contentWindow.document.body.removeChild(script_tag);
            newIframe.parentElement.removeChild(newIframe);
        }, 200);
    };
    document.body.appendChild(newIframe);
}

1

创建通用的东西以用于任何HTML元素

HTMLElement.prototype.printMe = printMe;
function printMe(query){             
     var myframe = document.createElement('IFRAME');
     myframe.domain = document.domain;
     myframe.style.position = "absolute";
     myframe.style.top = "-10000px";
     document.body.appendChild(myframe);
     myframe.contentDocument.write(this.innerHTML) ;
     setTimeout(function(){
        myframe.focus();
        myframe.contentWindow.print();
        myframe.parentNode.removeChild(myframe) ;// remove frame
     },3000); // wait for images to load inside iframe
     window.focus();
}
//usage
document.getElementById('xyz').printMe();
document.getElementsByClassName('xyz')[0].printMe();

希望这可以帮助。


1

我修改了@BillPaetski答案以使用querySelector,添加可选的CSS,删除强制的H1标签,并可选地指定标题或从窗口提取标题。它还不再自动打印并暴露内部构造,因此可以在包装函数中或根据需要将其切换出来。

唯一的两个私有变量是tmpWindow和tmpDoc,尽管我认为title,css和elem访问可能有所不同,但应假定所有函数参数都是私有的。

码:
function PrintElem(elem, title, css) {
    var tmpWindow = window.open('', 'PRINT', 'height=400,width=600');
    var tmpDoc = tmpWindow.document;

    title = title || document.title;
    css = css || "";

    this.setTitle = function(newTitle) {
        title = newTitle || document.title;
    };

    this.setCSS = function(newCSS) {
        css = newCSS || "";
    };

    this.basicHtml5 = function(innerHTML) {
        return '<!doctype html><html>'+(innerHTML || "")+'</html>';
    };

    this.htmlHead = function(innerHTML) {
        return '<head>'+(innerHTML || "")+'</head>';
    };

    this.htmlTitle = function(title) {
        return '<title>'+(title || "")+'</title>';
    };

    this.styleTag = function(innerHTML) {
        return '<style>'+(innerHTML || "")+'</style>';
    };

    this.htmlBody = function(innerHTML) {
        return '<body>'+(innerHTML || "")+'</body>';
    };

    this.build = function() {
        tmpDoc.write(
            this.basicHtml5(
                this.htmlHead(
                    this.htmlTitle(title) + this.styleTag(css)
                ) + this.htmlBody(
                    document.querySelector(elem).innerHTML
                )
            )
        );
        tmpDoc.close(); // necessary for IE >= 10
    };

    this.print = function() {
        tmpWindow.focus(); // necessary for IE >= 10*/
        tmpWindow.print();
        tmpWindow.close();
    };

    this.build();
    return this;
}
用法:
DOMPrinter = PrintElem('#app-container');
DOMPrinter.print();

同样,它不会复制<input>元素的值。如何使用此功能(包括用户键入的内容)?
马尔科姆·萨尔瓦多

@ Malky.Kid请考虑您的要求。如果你想打印表单,需要勾上表单元素模糊事件,并设置属性值,选择默认和的innerText <input><select><textarea>compontents是他们的运行值。有替代方法,但这不是此脚本的问题,而是浏览器的工作方式以及innerHTML通过输入,画布等获取文档属性的问题
。– MrMesees

我已经通过via找到了解决方案.attr('value',)。我什至已经为textarea(通过追加)和复选框(.attr('checked',))完成了此操作。如果我对所问的问题没有足够的思考,我感到抱歉
马尔科姆·萨尔瓦多

愿意与全班分享吗?也许要点或评论中的内容。我会投票赞成。
MrMesees

0

下面的代码复制了查询选择器所针对的所有相关节点,并复制了它们在屏幕上看到的样式,因为缺少了许多用于css选择器的父元素。如果有许多具有许多样式的子节点,这将导致一些滞后。

理想情况下,您已经准备好打印样式表,但这是针对没有插入打印样式表并且您希望按照屏幕显示进行打印的用例。

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

+function() {
    /**
     * copied from  /programming/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')

0

这是很老的帖子,但这是我使用正确答案所做的更新。我的解决方案也使用jQuery。

这样做的目的是使用正确的打印视图,包括所有样式表以进行正确的格式设置,并且在大多数浏览器中也受支持。

function PrintElem(elem, title, offset)
{
    // Title constructor
    title = title || $('title').text();
    // Offset for the print
    offset = offset || 0;

    // Loading start
    var dStart = Math.round(new Date().getTime()/1000),
        $html = $('html');
        i = 0;

    // Start building HTML
    var HTML = '<html';

    if(typeof ($html.attr('lang')) !== 'undefined') {
        HTML+=' lang=' + $html.attr('lang');
    }

    if(typeof ($html.attr('id')) !== 'undefined') {
        HTML+=' id=' + $html.attr('id');
    }

    if(typeof ($html.attr('xmlns')) !== 'undefined') {
        HTML+=' xmlns=' + $html.attr('xmlns');
    }

    // Close HTML and start build HEAD
    HTML+='><head>';

    // Get all meta tags
    $('head > meta').each(function(){
        var $this = $(this),
            $meta = '<meta';

        if(typeof ($this.attr('charset')) !== 'undefined') {
            $meta+=' charset=' + $this.attr('charset');
        }

        if(typeof ($this.attr('name')) !== 'undefined') {
            $meta+=' name=' + $this.attr('name');
        }

        if(typeof ($this.attr('http-equiv')) !== 'undefined') {
            $meta+=' http-equiv=' + $this.attr('http-equiv');
        }

        if(typeof ($this.attr('content')) !== 'undefined') {
            $meta+=' content=' + $this.attr('content');
        }

        $meta+=' />';

        HTML+= $meta;
        i++;

    }).promise().done(function(){

        // Insert title
        HTML+= '<title>' + title  + '</title>';

        // Let's pickup all CSS files for the formatting
        $('head > link[rel="stylesheet"]').each(function(){
            HTML+= '<link rel="stylesheet" href="' + $(this).attr('href') + '" />';
            i++;
        }).promise().done(function(){
            // Print setup
            HTML+= '<style>body{display:none;}@media print{body{display:block;}}</style>';

            // Finish HTML
            HTML+= '</head><body>';
            HTML+= '<h1 class="text-center mb-3">' + title  + '</h1>';
            HTML+= elem.html();
            HTML+= '</body></html>';

            // Open new window
            var printWindow = window.open('', 'PRINT', 'height=' + $(window).height() + ',width=' + $(window).width());
            // Append new window HTML
            printWindow.document.write(HTML);

            printWindow.document.close(); // necessary for IE >= 10
            printWindow.focus(); // necessary for IE >= 10*/
console.log(printWindow.document);
            /* Make sure that page is loaded correctly */
            $(printWindow).on('load', function(){                   
                setTimeout(function(){
                    // Open print
                    printWindow.print();

                    // Close on print
                    setTimeout(function(){
                        printWindow.close();
                        return true;
                    }, 3);

                }, (Math.round(new Date().getTime()/1000) - dStart)+i+offset);
            });
        });
    });
}

后来您简单地需要这样的东西:

$(document).on('click', '.some-print', function() {
    PrintElem($(this), 'My Print Title');
    return false;
});

尝试一下。


-1

与最佳答案相同,以防万一您需要像我一样打印图像:

如果要打印图像:

function printElem(elem)
    {
        Popup(jQuery(elem).attr('src'));
    }

    function Popup(data) 
    {
        var mywindow = window.open('', 'my div', 'height=400,width=600');
        mywindow.document.write('<html><head><title>my div</title>');
        mywindow.document.write('</head><body >');
        mywindow.document.write('<img src="'+data+'" />');
        mywindow.document.write('</body></html>');

        mywindow.print();
        mywindow.close();

        return true;
    }

您在load弹出窗口上缺少一个事件。没有它,您将打印空白页,因为未加载图像。=>$(popup).load(function(){ popup.focus(); popup.print(); });
蒂姆·维尔马伦

-4

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

如果不是这样,您可以尝试使用诸如javascript之类的客户端语言来隐藏除div以外的所有内容,然后打印该页面...


1
无需将其弹回服务器。您可以打开浏览器窗口并设置内容并调用print命令。
乔纳森·浮士德

您可以从客户端创建一个新窗口。
Pointy 2010年

1
乔纳森:我喜欢这种解决方案。您有示例代码吗?
usertest 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.