Imprimer le contenu d'un DIV


337

Quelle est la meilleure façon d'imprimer le contenu d'une DIV?


Essayez d'imprimer l'élément ici
Gabe

1
Qu'entendez-vous par impression? Comme dans une imprimante physique?
Yuriy Faktorovich

"Imprimer" comme dans une imprimante? ou au document?
Ed Schembor

J'ai trouvé le meilleur plugin développé jusqu'à présent par etimbo github.com/etimbo/jquery-print-preview-plugin
MaxI

3
Juste comme référence pour quiconque essaie de chercher une solution à cette question de l'impression d'un div. J'ai trouvé la réponse suivante très utile: stackoverflow.com/a/7532581/405117
Vikram

Réponses:


518

Légers changements par rapport à la version précédente - testé sur 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
Ceci est une solution rapide. La solution idéale consiste à utiliser un CSS distinct pour l'impression. Vous pouvez peut-être élaborer sur les détails (exigences) de votre problème.
Bill Paetzke

6
Vous pouvez référencer la feuille de style dans la fenêtre contextuelle. Ajoutez une autre ligne de code entre les balises <head>: mywindow.document.write ('<link rel = "stylesheet" href = "main.css" type = "text / css" />');
Bill Paetzke

5
@Rahil le changer en ceci: mywindow.document.close (); mywindow.focus (); mywindow.print (); mywindow.close ();
ROFLwTIME

3
^ ajoutez newwindow.focus (); pour activer l'impression multi-navigateur.
JackMahoney

7
Cela se produit parfois si le chargement de l'aperçu avant impression échoue, peut-être lorsque le contenu à imprimer est assez volumineux (je l'ai remarqué uniquement avec Chrome tandis que la même page s'imprime parfaitement dans Firefox, mais je n'exclue pas que cela puisse se produire dans Firefox ou dans d'autres navigateurs également). La meilleure façon que j'ai trouvée est d'exécuter l'impression (et de fermer) uniquement après le chargement de Windows. Donc après: mywindow.document.write(data);Ajoutez ceci: mywindow.document.write('<script type="text/javascript">$(window).load(function() { window.print(); window.close(); });</script>');Et supprimez: mywindow.print();etmywindow.close();
Fabius

164

Je pense qu'il y a une meilleure solution. Faites en sorte que votre div à imprimer couvre tout le document, mais uniquement lorsqu'il est imprimé:

@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;
    }
}

Parfait, bien plus agréable qu'un popup.
GreenWebDev

5
Malheureusement, cela ne fonctionnera pas comme prévu dans IE, voir ceci: stackoverflow.com/questions/975129/…
jarek.jpa

16
Le contenu qui devrait déborder sur plusieurs pages semble être tronqué dans Chrome.
Ishmael Smyrnow

Sur IE, vous devez masquer le reste du document. La modification ci-dessus comme suit fonctionnera: @media print {body * {display: none; } .myDivToPrint {display: block; couleur de fond: blanc; hauteur: 100%; largeur: 100%; position: fixe; en haut: 0; gauche: 0; marge: 0; rembourrage: 15px; taille de police: 14px; hauteur de ligne: 18px; }}
RonnBlack

2
Vous devrez peut-être mettre z-index: 9999999; au cas où vous auriez d'autres éléments positionnés plus haut.
Adam M.

43

Bien que cela ait été dit par @gabe , si vous utilisez jQuery, vous pouvez utiliser mon printElementplugin.

Il y a un exemple ici , et plus d'informations sur le plugin ici .

L'utilisation est assez simple, il suffit de saisir un élément avec un sélecteur jQuery et de l'imprimer:

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

J'espère que ça aide!


14
8 ans plus tard, cela produira «a.browser is undefined» car l'appel .browser a été supprimé dans jquery 1.9
KingsInnerSoul

1
@KingsInnerSoul ne soyez pas si impoli avec les utilisateurs de jQuery, ces temps sont assez durs pour eux; p
Alexandre Daubricourt

22

En utilisant Jquery, utilisez simplement cette fonction:

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

Votre bouton d'impression ressemblera à ceci:

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

Modifier: si vous avez des données de formulaire que vous devez conserver, le clone ne les copiera pas, il vous suffira donc de récupérer toutes les données du formulaire et de les remplacer après la restauration, comme suit:

<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>

$ ('corps'). html (page de restauration); ne fonctionnera pas car à ce moment il n'y a aucun élément de corps disponible. il sera donc préférable de le remplacer par location.reload ();
Débogueur

Non. Si vous rechargez la page, vous supprimerez toutes les informations des formulaires ou tout autre paramètre qui pourrait être nécessaire. Cela fonctionne parfaitement bien. Si vous prenez le temps de regarder le code, vous verrez que var restorepage A TOUTES les informations de page disponibles pour effectuer le remplacement. Arrêtez d'essayer de modifier mon code et testez-le par vous-même ou découvrez ce que chacune des parties de la fonction fait.
Gary Hayes

C'est mieux. Il comprend la conception de la page lors de l'impression contrairement à ceux mentionnés ci-dessus où j'ai encore besoin de mettre des liens CSS à partir de l'en-tête, etc. Merci!
Jorz

la façon dont vous avez réussi elest terrible, surtout depuis que vous utilisez jQ. Beaucoup mieux pour simplement passer le selectoret se débarrasser du codé en dur#
RozzA

J'ai toujours utilisé cette méthode aujourd'hui, j'ai remarqué qu'elle ne fonctionnait pas correctement sur un appareil Android (Google Chrome). La zone imprimable de la page change à chaque fois et contient des parties supplémentaires el. Je pense que la commande d'impression est envoyée lorsque le corps est en cours de restauration.
Ali Sheikhpour

18

À partir d'ici 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
il a fallu une modification pour diviser footerStr en 2 parties. car brwoser utilise "</body>" comme extrémité principale de la page actuelle. var footstr1 = "</"; var footstr2 = "body>"; var footerstr = footstr1 + footstr12;
mirzaei

13

J'ai utilisé la Bill Paetzkeréponse pour imprimer un div contenant des images, mais cela ne fonctionnait pas avec Google Chrome

j'avais juste besoin d'ajouter cette ligne myWindow.onload=function(){pour le faire fonctionner et voici le code complet

<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>

aussi si quelqu'un a juste besoin d'imprimer un div avec id, il n'a pas besoin de charger jquery

voici du code javascript pur pour ce faire

<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>

j'espère que cela peut aider quelqu'un


Cela a fonctionné pour moi! Le chameau m'a mordu car la réponse originale utilise "mywindow" contre "myWindow". Merci!
opcode

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;
}

Cela imprimera la divzone souhaitée et remettra le contenu tel qu'il était. printdivnameest le divà imprimer.


il a fallu une modification pour diviser footerStr en 2 parties. car brwoser utilise "</body>" comme extrémité principale de la page actuelle. var footstr1 = "</"; var footstr2 = "body>"; var footerstr = footstr1 + footstr12;
mirzaei

C'est ingénieux! Mais oui, vous avez besoin du hack de mirzaei, sinon la balise body se casse et vous obtenez un formatage cassé. Avec le hack, cela fonctionne très bien! Vous pouvez également ajouter votre propre emballage intérieur pour faciliter les styles d'impression spéciaux. Ce devrait être la réponse acceptée.
user2662680

9

Créez une feuille de style d'impression distincte qui masque tous les autres éléments à l'exception du contenu que vous souhaitez imprimer. Marquez-le en utilisant 'media="print"lorsque vous le chargez:

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

Cela vous permet de charger une feuille de style complètement différente pour les impressions.

Si vous souhaitez forcer la boîte de dialogue d'impression du navigateur à apparaître pour la page, vous pouvez le faire comme ceci lors du chargement à l'aide de JQuery:

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

ou déclenché à partir de tout autre événement souhaité, tel qu'un utilisateur cliquant sur un bouton.


2
Oui, ça marcherait aussi; il est difficile - enfin, impossible - de savoir exactement quel est le scénario.
Pointy

Je conviens qu'un CSS séparé est la solution idéale. Et copier le contenu du div dans une nouvelle fenêtre est une solution rapide.
Bill Paetzke

9

Je pense que les solutions proposées jusqu'à présent présentent les inconvénients suivants:

  1. Les solutions de requête multimédia CSS supposent qu'il n'y a qu'une seule div à imprimer.
  2. Les solutions javascript ne fonctionnent que sur certains navigateurs.
  3. Détruire le contenu de la fenêtre parent et recréer ce qui crée un gâchis.

J'ai amélioré les solutions ci-dessus. Voici quelque chose que j'ai testé qui fonctionne très bien avec les avantages suivants.

  1. Fonctionne sur tous les navigateurs, notamment IE, Chrome, Safari et Firefox.
  2. Ne détruit pas et ne recharge pas la fenêtre parent.
  3. Peut imprimer n'importe quel nombre de DIV dans une page.
  4. Utilise des modèles html pour éviter la concaténation de chaînes sujettes aux erreurs.

Points clés à noter:

  1. Doit avoir un onload = "window.print ()" sur la fenêtre nouvellement créée.
  2. N'appelez pas targetwindow.close () ou targetwindow.print () à partir du parent.
  3. Assurez-vous de faire targetwindow.document.close () et target.focus ()
  4. J'utilise jquery mais vous pouvez faire la même technique en utilisant également du javascript simple.
  5. Vous pouvez le voir en action ici http://math.tools/table/multiplication . Vous pouvez imprimer chaque tableau séparément, en cliquant sur le bouton d'impression sur l'en-tête de la boîte.

<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>
  


C'était excellent et cela fonctionnait bien mieux sur tous les navigateurs que les résultats acceptés!
dama_do_bling

7

J'ai créé un plugin pour résoudre ce scénario. Je n'étais pas satisfait des plugins là-bas et j'ai décidé de rendre quelque chose de plus étendu / configurable.

https://github.com/jasonday/printThis


1
Merci beaucoup pour votre travail acharné Jason ..... !! Je vais vraiment l'utiliser dans mes autres projets. Quel plugin

6

La solution acceptée ne fonctionnait pas. Chrome imprimait une page vierge, car elle ne chargeait pas l'image à temps. Cette approche fonctionne:

Modifier: Il semble que la solution acceptée ait été modifiée après mon message. Pourquoi le downvote? Cette solution fonctionne également.

    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

Je sais que c'est une vieille question, mais j'ai résolu ce problème avec 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

Bien que la réponse @BC ait été la meilleure pour imprimer une seule page.

Mais pour imprimer plusieurs pages de format A4 en même temps avec ctrl + P, la solution suivante peut aider.

@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
  • Ouvre une nouvelle fenêtre
  • Ouvrez l'objet document de la nouvelle fenêtre et écrivez-y un document simple ne contenant que le div que vous avez et l'en-tête html nécessaire, etc.
  • Mettez un script dans la nouvelle page pour appeler window.print ()
  • Déclencher le script

2

Voici mon plugin d'impression 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

Si vous souhaitez avoir tous les styles du document d'origine (y compris les styles en ligne), vous pouvez utiliser cette approche.

  1. Copiez le document complet
  2. Remplacez le corps par l'élément que vous souhaitez imprimer.

La mise en oeuvre:

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
Je ne sais pas si c'est la meilleure solution, mais cela a parfaitement fonctionné. Merci!
BRogers

2

Remarque: cela fonctionne uniquement avec les sites compatibles jQuery

C'est très simple avec ce truc cool. Cela a fonctionné pour moi dans le navigateur Google Chrome . Firefox ne vous permettra pas d'imprimer au format PDF sans plugin.

  1. Tout d'abord, ouvrez l'inspecteur à l'aide de (Ctrl + Maj + I) / (Cmd + Option + I).
  2. Tapez ce code dans la console:

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. Il lance la boîte de dialogue d'impression. Prenez une impression physique ou enregistrez-la au format PDF (en chrome). Terminé!

La logique est simple. Nous créons une nouvelle balise de script et l'attachons devant la balise de fermeture du corps. Nous avons injecté une extension d'impression jQuery dans le HTML. Modifiez myDivWithStyles avec votre propre ID de balise Div. Il faut maintenant se soucier de préparer une fenêtre virtuelle imprimable.

Essayez-le sur n'importe quel site. Seule mise en garde est parfois écrite de manière délicate CSS peut entraîner le manque de styles. Mais nous obtenons le contenu la plupart du temps.


1

Dans Opera, essayez:

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

1

Voici une solution IFrame qui fonctionne pour IE et Chrome:

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

Créé quelque chose de générique à utiliser sur n'importe quel élément 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();

J'espère que cela t'aides.


1

J'ai modifié la réponse @BillPaetski pour utiliser querySelector, ajouter du CSS facultatif, supprimer la balise H1 forcée et rendre le titre éventuellement spécifié ou extrait de la fenêtre. De plus, il n'imprime plus automatiquement et expose les composants internes afin qu'ils puissent être désactivés dans la fonction wrapper ou comme vous le souhaitez.

Les deux seules variables privées sont tmpWindow et tmpDoc bien que je pense que l'accès au titre, css et elem puisse varier, il faut supposer que tous les arguments de fonction sont privés.

Code:
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;
}
Usage:
DOMPrinter = PrintElem('#app-container');
DOMPrinter.print();

De plus, il ne copie pas les valeurs des <input>éléments. Comment puis-je l'utiliser, y compris ce que l'utilisateur a tapé?
Malcolm Salvador

@ Malky.Kid, pensez à ce que vous demandez. Si vous souhaitez imprimer un formulaire, vous devez connecter flou des événements sur des éléments de formulaire et définissez la valeur d'attribut, sélectionné, par défaut et InnerText <input>, <select>, <textarea>compontents d'être leur valeur d'exécution. Il existe des alternatives, mais ce n'est pas un problème avec ce script, mais un problème avec le fonctionnement des navigateurs, et obtenir la innerHTMLpropriété des documents avec des entrées, du canevas, etc.
MrMesees

J'ai déjà trouvé une solution via .attr('value',). Je l'ai même fait pour les zones de texte (en ajoutant) et les cases à cocher ( .attr('checked',)). Je suis désolé si je ne pensais pas assez à ce que je demandais.
Malcolm Salvador

Envie de partager avec la classe? peut-être une idée ou quelque chose dans les commentaires. Je vais le voter.
MrMesees

0

Le code ci-dessous copie tous les nœuds pertinents qui sont ciblés par le sélecteur de requête, copie sur leurs styles comme vu à l'écran, car de nombreux éléments parents utilisés pour cibler les sélecteurs css seront manquants. Cela provoque un peu de décalage s'il y a beaucoup de nœuds enfants avec beaucoup de styles.

Idéalement, vous auriez une feuille de style d'impression prête, mais c'est pour les cas d'utilisation où il n'y a pas de feuille de style d'impression à insérer et que vous souhaitez imprimer comme vu à l'écran.

Si vous copiez les éléments ci-dessous dans la console du navigateur sur cette page, tous les extraits de code de cette page seront imprimés.

+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

C'est vraiment un ancien post, mais voici ma mise à jour de ce que j'ai fait en utilisant la bonne réponse. Ma solution utilise également jQuery.

Le point de cela est d'utiliser une vue d'impression appropriée, d'inclure toutes les feuilles de style pour la mise en forme appropriée et également d'être pris en charge dans la plupart des navigateurs.

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);
            });
        });
    });
}

Plus tard, vous aurez simplement besoin de quelque chose comme ceci:

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

Essayez-le.


-1

Identique à la meilleure réponse, juste au cas où vous auriez besoin d'imprimer l'image comme je l'ai fait:

Si vous souhaitez imprimer l'image:

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;
    }

Vous manquez un loadévénement dans la fenêtre contextuelle. Sans cela, vous imprimerez une page vierge car l'image n'est pas chargée. =>$(popup).load(function(){ popup.focus(); popup.print(); });
Tim Vermaelen

-4

La meilleure façon de le faire serait de soumettre le contenu de la div au serveur et d'ouvrir une nouvelle fenêtre où le serveur pourrait mettre ce contenu dans la nouvelle fenêtre.

Si ce n'est pas une option, vous pouvez essayer d'utiliser un langage côté client comme javascript pour masquer tout sur la page sauf ce div, puis imprimer la page ...


1
Pas besoin de le renvoyer au serveur. Vous pouvez ouvrir une fenêtre de navigateur et définir le contenu et appeler la commande d'impression.
Jonathon Faust

Vous pouvez créer une nouvelle fenêtre à partir du client.
Pointy

1
Jonathon: J'aime cette solution. Avez-vous un exemple de code?
usertest
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.