72

The JavaScript code window.print() can print the current HTML page.

If I have a div in an HTML page (for example, a page rendered from an ASP.NET MVC view), then I want to print the div only.

Is there any jQuery unobtrusive JavaScript or normal JavaScript code to implement this request?

Making it more clear, suppose the rendered HTML page is like:

<html xmlns="http://www.w3.org/1999/xhtml">

    <head id="Head" runat="server">
        <title>
            <asp:ContentPlaceHolder runat="server" ID="TitleContent" />
        </title>
    </head>

    <body>
            <div id="div1" class="div1">....</div>
            <div id="div2" class="div2">....</div>
            <div id="div3" class="div3">....</div>
            <div id="div4" class="div4">....</div>
            <div id="div4" class="div4">....</div>
        <p>
            <input id="btnSubmit" type="submit" value="Print" onclick="divPrint();" />
        </p>
    </body>
</html>

Then I want to click on the Print button, only printing div3.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KentZhou
  • 24,805
  • 41
  • 134
  • 200

6 Answers6

120

I would go about it somewhat like this:

<html>
    <head>
        <title>Print Test Page</title>
        <script>
            printDivCSS = new String ('<link href="myprintstyle.css" rel="stylesheet" type="text/css">')
            function printDiv(divId) {
                window.frames["print_frame"].document.body.innerHTML=printDivCSS + document.getElementById(divId).innerHTML;
                window.frames["print_frame"].window.focus();
                window.frames["print_frame"].window.print();
            }
        </script>
    </head>

    <body>
        <h1><b><center>This is a test page for printing</center></b><hr color=#00cc00 width=95%></h1>
        <b>Div 1:</b> <a href="javascript:printDiv('div1')">Print</a><br>
        <div id="div1">This is the div1's print output</div>
        <br><br>
        <b>Div 2:</b> <a href="javascript:printDiv('div2')">Print</a><br>
        <div id="div2">This is the div2's print output</div>
        <br><br>
        <b>Div 3:</b> <a href="javascript:printDiv('div3')">Print</a><br>
        <div id="div3">This is the div3's print output</div>
        <iframe name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>
    </body>
</html>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Coding With Style
  • 1,692
  • 1
  • 14
  • 10
  • 1
    But what's the propose of printDivCSS? It seems no need to use it. – KentZhou Jul 13 '09 at 16:52
  • 2
    printDivCSS is just there if you need to format what you're printing with a stylesheet. If you don't want your printed text to be formatted with a stylesheet, then you don't need it. – Coding With Style Jul 13 '09 at 21:58
  • This solution works fine in FF, but not work for IE 7. With IE7, it will print the entire page with blank for the wanted printing area – KentZhou Sep 04 '09 at 19:19
  • 4
    I checked what the situation was. IE7 will print the active frame by default, so I have to focus() the frame. It won't let me focus() "visibility: hidden" content, so I had to remove that bit of style formatting. The frame already has a width, height, and frameborder of 0, so it's hidden even without the style formatting. This way, everything works. Oh, one final note, if a user tries to CTRL+F search the page, it's possible that their search will find matches inside the frame, matches they can't see. You'll have to blank the frame after they are done printing to fix that one. – Coding With Style Sep 05 '09 at 20:46
  • Ah, just to be clear, I edited this answer with the updated code. – Coding With Style Sep 05 '09 at 20:46
  • That's a sick technique. Let me know if you have found a better technique ever since :) – RubyFanatic Jul 27 '12 at 21:30
  • @CodingWithStyle Is there any way to print using the css of the page. My web page is rendered using multiple css files, how do i add it to the printDivCSS – Smith Dec 06 '13 at 00:01
  • 1
    works for me but i cant seem to print the styles its only in black and white mode. – cabaji99 Jun 16 '15 at 21:46
  • This does not work to print a div when the div contains data obtained from the server side:http://stackoverflow.com/questions/34206638/print-a-div-with-data-from-ajax-or-jquery-get – Core_Dumped Dec 11 '15 at 12:58
  • 9
    @CodingWithStyle This answer would be much more useful if you explained your approach/solution rather than just providing the code. – Sean the Bean Jan 26 '16 at 19:57
  • 2
    This doesn't seem to work anymore - in Chrome at least. The print dialog opens before the CSS is applied to the iframe contents. – Turnip Nov 03 '16 at 17:31
  • @Turnip It works if you put a timeout before the print. – Shah Abaz Khan Nov 30 '16 at 04:21
  • 5
    `window.frames["print_frame"].window.focus(); setTimeout(function() { window.frames["print_frame"].window.print(); }, 0);` – Shah Abaz Khan Nov 30 '16 at 04:22
  • 1
    Why it prints first an empty pages ? – Diego Jan 20 '17 at 15:24
  • At the start of section, first time printing doesn't include style in pdf. How should I handle for it? – Nyein Mon Soe Sep 14 '17 at 08:46
32

Along the same lines as some of the suggestions you would need to do at least the following:

  • Load some CSS dynamically through JavaScript
  • Craft some print-specific CSS rules
  • Apply your fancy CSS rules through JavaScript

An example CSS could be as simple as this:

@media print {
  body * {
    display:none;
  }

  body .printable {
    display:block;
  }
}

Your JavaScript would then only need to apply the "printable" class to your target div and it will be the only thing visible (as long as there are no other conflicting CSS rules -- a separate exercise) when printing happens.

<script type="text/javascript">
  function divPrint() {
    // Some logic determines which div should be printed...
    // This example uses div3.
    $("#div3").addClass("printable");
    window.print();
  }
</script>

You may want to optionally remove the class from the target after printing has occurred, and / or remove the dynamically-added CSS after printing has occurred.

Below is a full working example, the only difference is that the print CSS is not loaded dynamically. If you want it to really be unobtrusive then you will need to load the CSS dynamically like in this answer.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <title>Print Portion Example</title>
    <style type="text/css">
      @media print {
        body * {
          display:none;
        }

        body .printable {
          display:block;
        }
      }
    </style>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  </head>

  <body>
    <h1>Print Section Example</h1>
    <div id="div1">Div 1</div>
    <div id="div2">Div 2</div>
    <div id="div3">Div 3</div>
    <div id="div4">Div 4</div>
    <div id="div5">Div 5</div>
    <div id="div6">Div 6</div>
    <p><input id="btnSubmit" type="submit" value="Print" onclick="divPrint();" /></p>
    <script type="text/javascript">
      function divPrint() {
        // Some logic determines which div should be printed...
        // This example uses div3.
        $("#div3").addClass("printable");
        window.print();
      }
    </script>
  </body>
</html>
Community
  • 1
  • 1
Zack The Human
  • 8,373
  • 7
  • 39
  • 60
  • For FF, this solution will print the entire page with div3. For IE7, this solution will print the entire page but replace div3 with blank. – KentZhou Sep 04 '09 at 19:31
  • Which version of Firefox? When I tested this with IE it was with IE6 and it works correctly -- printing only "Div 3". Firefox 3.5.2 demonstrates the same behavior. Google Chrome 2.0.172.43 also demonstrates the same behavior. Maybe I don't understand your requirements. – Zack The Human Sep 04 '09 at 20:30
  • THANKS. My scenario is: I put your suggest css @media print... into the site.css. My page is render as
    maybe the css is not correct for this case?
    – KentZhou Sep 06 '09 at 20:58
  • It's hard to say without seeing the CSS and page source myself. Can you post it to somewhere like http://jsbin.com? – Zack The Human Sep 07 '09 at 02:39
  • This is the best solution if you need to print part of a page when that part of the page depends on JS, for example content inside tabs – sites May 25 '17 at 22:00
  • It's working fine but the issue is a long page do not print onto multiple pages. Tried different ways like 'page-break-after' in css, setting height and width of the page. But, no solution worked. Any suggestion?? If you need code, I can share that too. – meDeepakJain Jun 07 '17 at 14:22
12

Try this JavaScript code:

function printout() {

    var newWindow = window.open();
    newWindow.document.write(document.getElementById("output").innerHTML);
    newWindow.print();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter S McIntyre
  • 409
  • 4
  • 12
8
<div id="invocieContainer">
    <div class="row">
        ...Your html Page content here....
    </div>
</div>

<script src="/Scripts/printThis.js"></script>
<script>
    $(document).on("click", "#btnPrint", function(e) {
        e.preventDefault();
        e.stopPropagation();
        $("#invocieContainer").printThis({
            debug: false, // show the iframe for debugging
            importCSS: true, // import page CSS
            importStyle: true, // import style tags
            printContainer: true, // grab outer container as well as the contents of the selector
            loadCSS: "/Content/bootstrap.min.css", // path to additional css file - us an array [] for multiple
            pageTitle: "", // add title to print page
            removeInline: false, // remove all inline styles from print elements
            printDelay: 333, // variable print delay; depending on complexity a higher value may be necessary
            header: null, // prefix to html
            formValues: true // preserve input/form values
        });

    });
</script>

For printThis.js souce code, copy and pase below URL in new tab https://raw.githubusercontent.com/jasonday/printThis/master/printThis.js

Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
PK-1825
  • 1,431
  • 19
  • 39
4

You could use a print stylesheet, but this will affect all print functions.

You could try having a print stylesheet externalally, and it is included via JavaScript when a button is pressed, and then call window.print(), then after that remove it.

alex
  • 479,566
  • 201
  • 878
  • 984
  • This would work, but with some modification to allow the page to "reset" after you've printed your target. (As you noted, this would be a problem.) For example, just before printing, open a modal window or some kind of overlay indicating that printing can now occur (or call window.print() right then) and then when user clicks OK or Close, the stylesheets can reset themselves. – Funka Jul 02 '09 at 02:01
  • Oh, also, you don't necessarily need to have an external CSS file loaded dynamically, you could have it pre-loaded but just adjust the classes on your target div or other container when ready to print. (And removing the classes when done.) – Funka Jul 02 '09 at 02:02
0

You could use jquery to do this.

$('#btnSubmit').click(function(){
    var divContent = $("#div3").html();
    var originalContents = $("body").html();

    $("body").empty().html(divContent );
    window.print();
    $("body").html(originalContents);
})