Распечатать содержимое DIV

337

Как лучше всего распечатать содержимое DIV?

usertest
источник
Попробуйте напечатать элемент здесь
Gabe
1
Что вы подразумеваете под печатью? Как в физическом принтере?
Юрий Факторович
«Распечатать» как на принтере? или к документу?
Эд Шембор
Я нашел лучший плагин, разработанный на данный момент etimbo github.com/etimbo/jquery-print-preview-plugin
MaxI
3
Так же, как ссылка для любого, кто пытается найти решение этого вопроса печати div. Я нашел следующий ответ очень полезным: stackoverflow.com/a/7532581/405117
Викрам

Ответы:

518

Небольшие изменения по сравнению с более ранней версией - протестировано на 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 для печати. Возможно, вы сможете уточнить детали (требования) вашей проблемы.
Билл Паецке
6
Вы можете ссылаться на таблицу стилей во всплывающем окне. Добавьте еще одну строку кода между тегами <head>: mywindow.document.write ('<link rel = "stylesheet" href = "main.css" type = "text / css" />');
Билл Паецке
5
@Rahil измените это на следующее: mywindow.document.close (); mywindow.focus (); mywindow.print (); mywindow.close ();
ROFLWTIME
3
^ добавить newwindow.focus (); включить кросс-браузерную печать.
JackMahoney
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();
Фабиус
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
5
К сожалению, в IE он не будет работать так, как ожидалось, смотрите это: stackoverflow.com/questions/975129/…
jarek.jpa
16
Контент, который должен перетекать на несколько страниц, кажется урезанным в Chrome.
Измаил Смирноу
В IE вам нужно скрыть остальную часть документа. Будет работать следующее изменение: @media print {body * {display: none; } .myDivToPrint {display: block; цвет фона: белый; высота: 100%; ширина: 100%; положение: фиксированное; верх: 0; слева: 0; поле: 0; отступы: 15 пикселей; размер шрифта: 14 пикселей; высота строки: 18 пикселей; }}
RonnBlack
2
Возможно, вам придется поставить z-index: 9999999; в случае, если у вас есть другие элементы, расположенные выше.
Адам М.
43

Хотя @gabe и сказал это , если вы используете jQuery, вы можете использовать мой printElementплагин.

Там есть образец здесь , и больше информации о плагине здесь .

Использование довольно простое, просто возьмите элемент с селектором jQuery и напечатайте его:

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

Я надеюсь, что это помогает!

Erik
источник
14
Спустя 8 лет это приведет к тому, что a.browser не определен, поскольку вызов
.browser
1
@ KingsInnerSoul Не будь таким грубым с пользователями jQuery, эти времена достаточно суровы для них; p
Александр Добрикур
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>
Гэри Хейс
источник
$ ( 'тело') HTML (restorepage). не будет работать, потому что в это время нет доступных элементов тела. поэтому будет лучше заменить его на location.reload ();
Отладчик
Нет. Если вы перезагрузите страницу, вы удалите любую информацию в формах или любые другие параметры, которые могут потребоваться. Работает отлично. Если вы потратите время на просмотр кода, то увидите, что var restorepage ДОЛЖЕН иметь всю доступную информацию для замены. Перестаньте пытаться редактировать мой код и либо протестируйте его для себя, либо узнайте, что делает каждая из частей функции.
Гэри Хейс
Это лучше. Он включает в себя дизайн страницы при печати, в отличие от упомянутых выше, где мне все еще нужно поместить ссылки CSS из заголовка и т. Д. Спасибо!
Йорз
путь, который вы прошли el, ужасен, тем более что вы используете jQ. Гораздо лучше просто передать selectorи избавиться от жестко закодированного#
RozzA
Я всегда использовал этот метод сегодня, я заметил, что он не работает должным образом на устройстве Android (Google Chrome). Область печати страницы меняется каждый раз и содержит некоторые дополнительные части el. Я думаю, что команда печати отправляется, когда тело восстанавливается.
Али Шейхпур
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>
huston007
источник
1
нужна модификация, чтобы разделить footerStr на 2 части. потому что brwoser использует «</ body>» в качестве основного конца текущей страницы. var footstr1 = "</"; var footstr2 = "body>"; var footerstr = footstr1 + footstr12;
Мирзаи
13

Я использовал Bill Paetzkeответ, чтобы напечатать div, содержащий изображения, но он не работал с Google Chrome

мне просто нужно было добавить эту строку, 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>

также, если кому-то просто нужно напечатать 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область, которую вы хотите, и вернет содержимое обратно, как было. printdivnameэто divдля печати.

Технарь
источник
нужна модификация, чтобы разделить footerStr на 2 части. потому что brwoser использует «</ body>» в качестве основного конца текущей страницы. var footstr1 = "</"; var footstr2 = "body>"; var footerstr = footstr1 + footstr12;
Мирзаи
Это гениально! Но да, вам нужен взлом от mirzaei, в противном случае тег body сломается, и вы получите неправильное форматирование. С взломом это прекрасно работает! Вы также можете даже добавить свою собственную внутреннюю обертку, чтобы облегчить специальные стили печати. Это должен быть принятый ответ.
user2662680
9

Создайте отдельную таблицу стилей печати, которая скрывает все другие элементы, кроме содержимого, которое вы хотите распечатать. Отметьте его, используя 'media="print"при загрузке:

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

Это позволяет вам иметь совершенно другую таблицу стилей, загруженную для распечаток.

Если вы хотите, чтобы диалоговое окно печати браузера отображалось для страницы, вы можете сделать это при загрузке с помощью JQuery:

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

или вызвал любое другое событие, которое вы хотите, например, пользователь нажимает кнопку.

Карл Руссманн
источник
2
Да, это тоже сработало бы; трудно - ну невозможно - точно знать, каков сценарий.
Заостренный
Я согласен, что отдельный CSS является идеальным решением. А копирование содержимого div в новое окно - это быстрое решение.
Билл Паецке
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>
  

DORS
источник
Это было превосходно, и кросс-браузер работал намного лучше, чем принятые результаты!
dama_do_bling 16.12.15
7

Я создал плагин для решения этого сценария. Я был недоволен плагинами и решил сделать что-то более обширное / настраиваемое.

https://github.com/jasonday/printThis

Джейсон
источник
1
Большое спасибо за ваш тяжелый труд, Джейсон ..... !! На самом деле собираюсь использовать в моих проектах больше. Какой умопомрачительный плагин человек ...... Безмолвный .....
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 лучше всего распечатать на одной странице.

Но для печати нескольких страниц формата A4 одновременно с помощью Ctrl + P может помочь следующее решение.

@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);
karaxuna
источник
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 (в хром). Готово!

Логика проста. Мы создаем новый тег сценария и прикрепляем его перед закрывающим тегом тела. Мы ввели расширение для печати jQuery в HTML. Измените myDivWithStyles с вашим собственным идентификатором тега Div. Теперь он занимается подготовкой печатного виртуального окна.

Попробуйте это на любом сайте. Только предостережение иногда хитро написанным CSS может привести к отсутствию стилей. Но мы получаем контент в большинстве случаев.

Нарен Йеллавула
источник
1

В Opera попробуйте:

    print_win.document.write('</body></html>');
    print_win.document.close(); // This bit is important
    print_win.print();
    print_win.close();
хмурость
источник
1

Вот решение IFrame, которое работает для IE и 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
источник
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();

Надеюсь это поможет.

Gaurav
источник
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();
MrMesees
источник
Также он не копирует значения <input>элементов. Как я могу использовать это, включая то, что набрал пользователь?
Малкольм Сальвадор,
@ Malky.Kid, пожалуйста, подумайте о том, что вы спрашиваете. Если вы хотите напечатать форму, вам нужно подключить размытие события на элементах формы, и установите значение атрибута, выбранного, по умолчанию и InnerText из <input>, <select>, <textarea>compontents быть их значение во время выполнения. Есть альтернативы, но проблема не в этом сценарии, а в том, как работают браузеры и получают innerHTMLсвойство документов с помощью входных данных, холста и т. Д.
MrMesees,
Я уже пришел к решению через .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')
Tschallacka
источник
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
Нет необходимости возвращать его на сервер. Вы можете открыть окно браузера, установить содержимое и вызвать команду печати.
Джонатон Фауст
Вы можете создать новое окно из клиента.
Заостренный
1
Джонатон: мне нравится это решение. У вас есть пример кода?
тест