Imprimir o conteúdo de um DIV

335

Qual é a melhor maneira de imprimir o conteúdo de um DIV?

usertest
fonte
Tente imprimir o elemento aqui
Gabe
11
O que você quer dizer com imprimir? Como em uma impressora física?
Yuriy Faktorovich 12/02/10
"Imprimir" como em uma impressora? ou para o documento?
Ed Schembor
Eu encontrei o melhor plug-in desenvolvido até agora por etimbo github.com/etimbo/jquery-print-preview-plugin
MaxI
3
Apenas como uma referência para quem tenta procurar uma solução para esta questão de imprimir uma div. Eu encontrei a seguinte resposta muito útil: stackoverflow.com/a/7532581/405117
Vikram

Respostas:

517

Pequenas alterações em relação à versão anterior - testada no 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;
}
Bill Paetzke
fonte
8
Esta é uma solução rápida. A solução ideal é usar um CSS separado para impressão. Talvez você possa elaborar os detalhes (requisitos) do seu problema.
Bill Paetzke
6
Você pode fazer referência à folha de estilo na janela pop-up. Adicione outra linha de código entre as tags <head>: mywindow.document.write ('<link rel = "stylesheet" href = "main.css" type = "text / css" />');
Bill Paetzke
5
@Rahil mude para: mywindow.document.close (); mywindow.focus (); mywindow.print (); mywindow.close ();
ROFLwTIME
3
^ adicione newwindow.focus (); para ativar a impressão em vários navegadores.
JackMahoney
7
Às vezes, acontece que falha ao carregar a visualização de impressão, talvez quando o conteúdo a ser impresso é muito grande (notei apenas no Chrome enquanto a mesma página imprime perfeitamente no Firefox, no entanto, não excluo que isso possa acontecer no Firefox ou em outros navegadores). A melhor maneira que encontrei é executar a impressão (e fechar) somente após o carregamento do Windows. Então, depois: mywindow.document.write(data);Adicione isto: mywindow.document.write('<script type="text/javascript">$(window).load(function() { window.print(); window.close(); });</script>');E remova: mywindow.print();emywindow.close();
Fabius
164

Eu acho que existe uma solução melhor. Faça sua div para imprimir cobrir o documento inteiro, mas somente quando for impresso:

@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;
    }
}
BC.
fonte
Perfeito, muito melhor do que um pop-up.
19412 GreenWebDev
5
Infelizmente, não vai funcionar no IE bastante esperado, consulte o seguinte: stackoverflow.com/questions/975129/...
jarek.jpa
16
O conteúdo que deve transbordar para várias páginas parece ficar truncado no Chrome.
Ishmael Smyrnow
No IE, você precisa ocultar o restante do documento. A modificação acima da seguinte forma funcionará: @media print {body * {display: none; } .myDivToPrint {display: block; cor de fundo: branco; altura: 100%; largura: 100%; posição: fixa; topo: 0; esquerda: 0; margem: 0; preenchimento: 15px; tamanho da fonte: 14 px; altura da linha: 18 px; }}
RonnBlack
2
Você pode precisar colocar o z-index: 9999999; caso você tenha outros elementos posicionados mais alto.
Adam M.
43

Embora isso tenha sido dito por @gabe , se você estiver usando o jQuery, poderá usar o meu printElementplugin.

Há uma amostra aqui e mais informações sobre o plugin aqui .

O uso é bastante simples, basta pegar um elemento com um seletor jQuery e imprimi-lo:

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

Espero que ajude!

Erik
fonte
14
8 anos depois, este irá produzir "a.browser é indefinido" porque a chamada .browser foi removido em jQuery 1.9
KingsInnerSoul
11
@KingsInnerSoul não seja tão rude com os usuários do jQuery, esses tempos são bastante severos para eles; p
Alexandre Daubricourt
@AlexandreDaubricourt lol
KingsInnerSoul
22

Usando o Jquery, basta usar esta função:

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

Seu botão de impressão ficará assim:

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

Editar: se você tiver dados de formulário que você precisa manter, o clone não os copiará; portanto, você só precisará pegar todos os dados do formulário e substituí-los após a restauração da seguinte maneira:

<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>
Gary Hayes
fonte
$ ('corpo'). html (restorepage); não funcionará porque naquele momento não há elemento corporal disponível. portanto, será melhor substituí-lo por location.reload ();
Debugger
Não. Se você recarregar a página, excluirá todas as informações nos formulários ou outras configurações que precisem estar lá. Funciona perfeitamente bem. Se você reservar um tempo para analisar o código, verá que var restorepage TEM todas as informações da página disponíveis para fazer a substituição. Pare de tentar editar meu código e teste você mesmo ou aprenda o que cada uma das partes da função faz.
Gary Hayes
Isto é melhor. Ele inclui o design da página durante a impressão, ao contrário dos mencionados acima, onde eu ainda preciso colocar links css no cabeçalho etc. Obrigado!
Jorz
a maneira como você passou elé terrível, especialmente desde o uso do jQ. Muito melhor do que simplesmente passar o selectore se livrar do codificado#
ROZZA
Eu sempre usei esse método hoje, notei que ele não está funcionando corretamente no dispositivo Android (Google Chrome). A área imprimível da página muda sempre e contém algumas peças extras el. Eu acho que o comando de impressão é enviado quando o corpo está sendo restaurado.
Ali Sheikhpour 01/01/19
18

A partir daqui 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>
huston007
fonte
11
é necessária uma modificação para dividir footerStr em 2 partes. porque o brwoser usa "</body>" como o final principal da página atual. var footstr1 = "</"; var footstr2 = "corpo>"; var footerstr = footstr1 + footstr12;
Mirzaei
13

eu usei Bill Paetzkeresposta para imprimir uma div conter imagens, mas não funcionou com o google chrome

eu só precisava adicionar esta linha myWindow.onload=function(){para fazê-la funcionar e aqui está o código completo

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

Além disso, se alguém só precisa imprimir uma div com id, ele não precisa carregar o jquery

aqui está o código javascript puro para fazer isso

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

espero que isso possa ajudar alguém

Robert
fonte
Isso funcionou para mim! A camelcase realmente me mordeu, já que a resposta original usa "mywindow" vs. "myWindow". Obrigado!
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;
}

Isso imprimirá a divárea desejada e retornará o conteúdo como estava. printdivnameé o divque será impresso.

Techie
fonte
é necessária uma modificação para dividir footerStr em 2 partes. porque o brwoser usa "</body>" como o final principal da página atual. var footstr1 = "</"; var footstr2 = "corpo>"; var footerstr = footstr1 + footstr12;
Mirzaei
Isso é engenhoso! Mas sim, você precisa do hack do mirzaei, caso contrário a tag body quebra e a formatação é interrompida. Com o hack, isso funciona muito bem! Você também pode adicionar seu próprio invólucro interno para facilitar estilos de impressão especiais. Essa deve ser a resposta aceita.
user2662680
9

Crie uma folha de estilo de impressão separada que oculte todos os outros elementos, exceto o conteúdo que você deseja imprimir. Sinalize-o usando 'media="print"quando você o carrega:

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

Isso permite que você tenha uma folha de estilo completamente diferente carregada para impressões.

Se você deseja forçar a caixa de diálogo de impressão do navegador para aparecer na página, faça-o desta maneira em carregamento usando o JQuery:

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

ou acionado de qualquer outro evento que você deseja, como um usuário clicando em um botão.

Carl Russmann
fonte
2
Sim, isso funcionaria também; é difícil - bem, impossível - saber exatamente qual é o cenário.
Pointy
Concordo que um CSS separado é a solução ideal. E copiar o conteúdo da div para uma nova janela é uma solução rápida.
Bill Paetzke
9

Penso que as soluções propostas até agora têm os seguintes inconvenientes:

  1. As soluções de consulta de mídia CSS assumem que há apenas uma div para imprimir.
  2. As soluções javascript funcionam apenas em determinados navegadores.
  3. Destruir o conteúdo da janela pai e recriar que cria uma bagunça.

Eu melhorei nas soluções acima. Aqui está algo que eu testei que funciona muito bem com os seguintes benefícios.

  1. Funciona em todos os navegadores, incluindo IE, Chrome, Safari e Firefox.
  2. Não destrói e recarrega a janela principal.
  3. Pode imprimir qualquer número de DIVs em uma página.
  4. Usa modelos html para evitar concatenação de cadeias propensas a erros.

Pontos-chave a serem observados:

  1. Tem que ter um onload = "window.print ()" na janela recém-criada.
  2. Não chame targetwindow.close () ou targetwindow.print () do pai.
  3. Certifique-se de fazer targetwindow.document.close () e target.focus ()
  4. Estou usando jquery, mas você pode fazer a mesma técnica usando javascript simples também.
  5. Você pode ver isso em ação aqui http://math.tools/table/multiplication . Você pode imprimir cada tabela separadamente, clicando no botão Imprimir no cabeçalho da caixa.

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

dors
fonte
Isso foi excelente e funcionou em vários navegadores muito melhor do que os resultados aceitos!
Dama_do_bling
7

Eu criei um plugin para resolver esse cenário. Fiquei insatisfeito com os plugins existentes e decidi criar algo mais extenso / configurável.

https://github.com/jasonday/printThis

Jason
fonte
11
Muito obrigado pelo seu trabalho duro Jason ..... !! Realmente vou usar em meus mais projetos. O que é um plug-in
6

A solução aceita não estava funcionando. O Chrome estava imprimindo uma página em branco porque não estava carregando a imagem a tempo. Essa abordagem funciona:

Edit: Parece que a solução aceita foi modificada após o meu post. Por que o voto negativo? Esta solução também funciona.

    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;
    }
amor ao vivo
fonte
4

Sei que essa é uma pergunta antiga, mas resolvi esse problema com o 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;
    }
  }
Jazzy
fonte
3

Embora a resposta @BC tenha sido a melhor para imprimir uma única página.

Mas Imprimir várias páginas de tamanho A4 ao mesmo tempo com as teclas Ctrl + P a seguir pode ajudar.

@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;
}}
arslan
fonte
2
  • Abra uma nova janela
  • Abra o objeto de documento da nova janela e escreva nele um documento simples que não contenha nada além da div que você possui e do cabeçalho html necessário, etc.
  • Coloque um script na nova página para chamar window.print ()
  • Acionar o script
Pontudo
fonte
2

Aqui está o meu plugin jquery print

(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);
karaxuna
fonte
2

Se você deseja ter todos os estilos do documento original (incluindo estilos embutidos), pode usar esta abordagem.

  1. Copie o documento completo
  2. Substitua o corpo pelo elemento que você deseja imprimir.

Implementação:

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)
  }   
}
Stefan Norberg
fonte
2
Não sei se essa é a melhor solução, mas funcionou perfeitamente. Obrigado!
BRGers
Se funcionar, é tem que ser o melhor :)
Stefan Norberg
2

Nota: Isso funciona apenas com sites habilitados para jQuery

É muito simples com esse truque legal. Funcionou para mim no navegador Google Chrome . O Firefox não permitirá que você imprima em PDF sem um plug-in.

  1. Primeiro, abra o inspetor usando (Ctrl + Shift + I) / (Cmd + Option + I).
  2. Digite este código no 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. Inicia a caixa de diálogo de impressão. Faça uma impressão física ou salve-a em PDF (no chrome). Feito!

A lógica é simples. Estamos criando uma nova tag de script e anexando-a na frente da tag body de fechamento. Injetamos uma extensão de impressão jQuery no HTML. Alterar myDivWithStyles com seu próprio ID de tag Div. Agora é preciso preparar uma janela virtual imprimível.

Experimente em qualquer site. Às vezes, apenas uma ressalva é que CSS complicado pode causar a falta de estilos. Mas obtemos o conteúdo na maioria das vezes.

Naren Yellavula
fonte
1

No Opera, tente:

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

Aqui está uma solução IFrame que funciona para IE e 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);
}
kofifus
fonte
1

Criou algo genérico para usar em qualquer elemento 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();

Espero que isto ajude.

Gaurav
fonte
1

Modifiquei a resposta @BillPaetski para usar querySelector, adicione CSS opcional, remova a tag H1 forçada e torne o título opcionalmente especificado ou puxado da janela. Ele também não imprime mais automaticamente e expõe os internos, para que possam ser trocados na função wrapper ou conforme desejado.

Os únicos dois vars privados são tmpWindow e tmpDoc, embora eu acredite que o acesso ao título, css e elem possa variar; deve-se assumir que todos os argumentos da função são privados.

Código:
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;
}
Uso:
DOMPrinter = PrintElem('#app-container');
DOMPrinter.print();
MrMesees
fonte
Além disso, ele não copia os valores dos <input>elementos. Como posso usar isso, incluindo o que o usuário digitou?
Malcolm Salvador
@ Malky.Kid, pense no que está perguntando. Se você quiser imprimir um formulário, você precisa ligar borrão eventos em elementos de formulário, e definir o valor do atributo, selecionado, padrão e innerText de <input>, <select>, <textarea>compontents para ser seu valor de tempo de execução. Existem alternativas, mas esse não é um problema com esse script, mas um problema com o modo como os navegadores funcionam e obtêm innerHTMLpropriedades de documentos com entradas, telas etc.
MrMesees
Já cheguei a uma solução via .attr('value',). Eu até fiz isso para a área de texto (anexando) e as caixas de seleção ( .attr('checked',)). Me desculpe se eu não estava pensando o suficiente sobre o que estava perguntando.
Malcolm Salvador
Gostaria de compartilhar com a classe? talvez uma essência ou algo nos comentários. Eu vou votar.
MrMesees
0

O código abaixo copia todos os nós relevantes que são direcionados pelo seletor de consulta, copia seus estilos como visto na tela, pois muitos elementos pai usados ​​para direcionar os seletores de css estarão ausentes. Isso causa um pouco de atraso se houver muitos nós filhos com muitos estilos.

Idealmente, você teria uma folha de estilo de impressão pronta, mas isso é para casos de uso em que não há uma folha de estilo de impressão a ser inserida e você deseja imprimir como visto na tela.

Se você copiar os itens abaixo no console do navegador nesta página, ele imprimirá todos os trechos de código desta página.

+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')
Tschallacka
fonte
0

Este é realmente um post antigo, mas aqui está uma atualização que fiz usando a resposta correta. Minha solução também usa jQuery.

O objetivo é usar a exibição de impressão adequada, incluir todas as folhas de estilo para a formatação correta e também ser suportada na maioria dos navegadores.

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

Mais tarde, você simplesmente precisa de algo como isto:

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

Tente.

Ivijan Stefan Stipić
fonte
-1

O mesmo que a melhor resposta, caso você precise imprimir a imagem como eu fiz:

Caso você queira imprimir uma imagem:

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;
    }
Goran Jakovljevic
fonte
Está faltando um loadevento no pop-up. Sem ele, você imprimirá uma página em branco, pois a imagem não está carregada. =>$(popup).load(function(){ popup.focus(); popup.print(); });
Tim Vermaelen
-4

A melhor maneira de fazer isso seria enviar o conteúdo da div para o servidor e abrir uma nova janela onde o servidor poderia colocar esse conteúdo na nova janela.

Se essa não for uma opção, você pode tentar usar uma linguagem do lado do cliente, como javascript, para ocultar tudo na página, exceto essa div, e imprimir a página ...

Sonny Boy
fonte
11
Não há necessidade de devolvê-lo ao servidor. Você pode abrir uma janela do navegador, definir o conteúdo e chamar o comando de impressão.
Jonathon Faust
Você pode criar uma nova janela a partir do cliente.
Pointy
11
Jonathon: Eu gosto dessa solução. Você tem algum código de exemplo?
usertest