Подтвердить что ты не робот

Распечатайте шаблон Html в Angular 2 (ng-print в Angular 2)

Я хочу напечатать шаблон HTML в angular 2. Я исследовал об этом, я получил решение в angularjs 1 Печать шаблона Html в Angularjs 1

Любое предложение будет оценено

4b9b3361

Ответ 1

Вот как я это сделал в angular2 (это похоже на это урезанное решение) В вашем HTML файле:

<div id="print-section">
  // your html stuff that you want to print
</div>
<button (click)="print()">print</button>

и в вашем файле TS:

print(): void {
    let printContents, popupWin;
    printContents = document.getElementById('print-section').innerHTML;
    popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
    popupWin.document.open();
    popupWin.document.write('
      <html>
        <head>
          <title>Print tab</title>
          <style>
          //........Customized style.......
          </style>
        </head>
    <body onload="window.print();window.close()">${printContents}</body>
      </html>'
    );
    popupWin.document.close();
}

ОБНОВИТЬ:

Вы также можете сократить путь и использовать простую библиотеку ngx-print для менее противоречивого кодирования (смешивания JS и TS) и большего количества готовых к использованию контролируемых и защищенных вариантов печати.

Ответ 2

В случае, если кто-то еще сталкивается с этой проблемой, если вы уже выложили страницу, я бы рекомендовал использовать медиа-запросы для настройки вашей страницы печати. Затем вы можете просто прикрепить функцию печати к кнопке html и в вызове компонента window.print();

component.html:

<div class="doNotPrint">
    Header is here.
</div>

<div>
    all my beautiful print-related material is here.
</div>

<div class="doNotPrint">
    my footer is here.
    <button (click)="onPrint()">Print</button>
</div>

component.ts:

onPrint(){
    window.print();
}

component.css:

@media print{
  .doNotPrint{display:none !important;}
}

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

Вы можете изменить поля документа и все в запросе на печать, что делает его довольно мощным. Есть много статей в Интернете. Вот тот, который кажется всеобъемлющим: https://www.sitepoint.com/create-a-customized-print-stylesheet-in-minutes/ Это также означает, что вам не нужно создавать отдельный скрипт для создания версии для печати. 'страницы или используйте много javascript.

Ответ 3

вы можете сделать это в angular 2

в файле ts

 export class Component{          
      constructor(){
      }
       printToCart(printSectionId: string){
        let popupWinindow
        let innerContents = document.getElementById(printSectionId).innerHTML;
        popupWinindow = window.open('', '_blank', 'width=600,height=700,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
        popupWinindow.document.open();
        popupWinindow.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + innerContents + '</html>');
        popupWinindow.document.close();
  }

 }

в html

<div id="printSectionId" >
  <div>
    <h1>AngularJS Print html templates</h1>
    <form novalidate>
      First Name:
      <input type="text"  class="tb8">
      <br>
      <br> Last Name:
      <input type="text"  class="tb8">
      <br>
      <br>
      <button  class="button">Submit</button>
      <button (click)="printToCart('printSectionId')" class="button">Print</button>
    </form>
  </div>
  <div>
    <br/>
   </div>
</div>

Ответ 4

РЕДАКТИРОВАТЬ: обновлены фрагменты для более общего подхода

Так же, как расширение принятого ответа,

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

  1. сделать запрос, чтобы извлечь элементы <style> и <link> из документа верхнего уровня

  2. вставьте его в строку HTML.

Чтобы получить тег HTML:

private getTagsHtml(tagName: keyof HTMLElementTagNameMap): string
{
    const htmlStr: string[] = [];
    const elements = document.getElementsByTagName(tagName);
    for (let idx = 0; idx < elements.length; idx++)
    {
        htmlStr.push(elements[idx].outerHTML);
    }

    return htmlStr.join('\r\n');
}

Тогда в существующем фрагменте:

const printContents = document.getElementById('print-section').innerHTML;
const stylesHtml = this.getTagsHtml('style');
const linksHtml = this.getTagsHtml('link');

const popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
popupWin.document.open();
popupWin.document.write('
    <html>
        <head>
            <title>Print tab</title>
            ${linksHtml}
            ${stylesHtml}
            ^^^^^^^^^^^^^ add them as usual to the head
        </head>
        <body onload="window.print(); window.close()">
            ${printContents}
        </body>
    </html>
    '
);
popupWin.document.close();

Теперь с использованием существующих стилей (угловые компоненты создают собственный стиль), а также существующих стилей (например, Bootstrap, MaterialDesign, Bulma) он должен выглядеть как фрагмент существующего экрана.

Ответ 5

Служба печати

import { Injectable } from '@angular/core';

@Injectable()
export class PrintingService {

public print(printEl: HTMLElement) {
    let printContainer: HTMLElement = document.querySelector('#print-container');

    if (!printContainer) {
      printContainer = document.createElement('div');
      printContainer.id = 'print-container';
    } 

    printContainer.innerHTML = '';

    let elementCopy = printEl.cloneNode(true);
    printContainer.appendChild(elementCopy);
    document.body.appendChild(printContainer);

    window.print();
  }
}

Компонент, который я хочу распечатать

@Component({
  selector: 'app-component',
  templateUrl: './component.component.html',
  styleUrls: ['./component.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class MyComponent {
  @ViewChild('printEl') printEl: ElementRef;

  constructor(private printingService: PrintingService) {}

  public print(): void {
    this.printingService.print(this.printEl.nativeElement);
 }

}

Не лучший выбор, но работает.

Ответ 6

Я столкнулся с той же проблемой и нашел другой способ сделать это. В моем случае это сработало, так как это было относительно небольшое приложение.

Сначала пользователь нажимает кнопку в компоненте, который необходимо распечатать. Это установит флаг, к которому может получить доступ компонент приложения. Вот так

HTML файл

<button mat-button (click)="printMode()">Print Preview</button>

файл .ts

  printMode() {
    this.utilities.printMode = true;
  }

В html компонента приложения мы скрываем все, кроме роутера. Что-то вроде ниже

<div class="container">       
  <app-header *ngIf="!utilities.printMode"></app-header>
  <mat-sidenav-container>
    <mat-sidenav *ngIf="=!utilities.printMode">
      <app-sidebar></app-sidebar>
    </mat-sidenav>
    <mat-sidenav-content>
      <router-outlet></router-outlet>
    </mat-sidenav-content>
  </mat-sidenav-container>
</div>

С аналогичными условиями ngIf мы также можем настроить html-шаблон компонента так, чтобы он отображал или скрывал только объекты в printMode. Таким образом, пользователь будет видеть только то, что необходимо распечатать, при нажатии кнопки предварительного просмотра.

Теперь мы можем просто напечатать или вернуться в обычный режим с кодом ниже

HTML файл

<button mat-button class="doNotPrint" (click)="print()">Print</button>
<button mat-button class="doNotPrint" (click)="endPrint()">Close</button>

файл .ts

  print() {
    window.print();
  }

  endPrint() {
    this.utilities.printMode = false;
  } 

файл .css (чтобы кнопки печати и закрытия не печатались)

@media print{
   .doNotPrint{display:none !important;}
 }

Ответ 7

Самое короткое решение - назначить окно переменной машинописного текста, а затем вызвать метод print, как показано ниже.

в файле шаблона

<button ... (click)="window.print()" ...>Submit</button>

и в машинописном файле

window: any;
constructor() {
  this.window = window;
}

Ответ 8

Лучший вариант, который я нашел, чтобы решить эту проблему без проблем со своими стилями, - использовать отдельный маршрут для вывода на печать и загрузить этот маршрут в iframe.

Мой окружающий компонент отображается в виде вкладки.

@Component({
  template: '<iframe id="printpage" name="printpage" *ngIf="printSrc" [src]="printSrc"></iframe>',
  styleUrls: [ 'previewTab.scss' ]
})
export class PreviewTabPage {
  printSrc: SafeUrl;

  constructor(
    private navParams: NavParams,
    private sanitizer: DomSanitizer,
  ) {
    // item to print is passed as url parameter
    const itemId = navParams.get('itemId');

    // set print page source for iframe in template
    this.printSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.getAbsoluteUrl(itemId));
  }

  getAbsoluteUrl(itemId: string): string {
    // some code to generate an absolute url for your item
    return itemUrl;
  }
}

Iframe просто загружает маршрут печати, который отображает компонент печати в приложении. На этой странице печать может быть запущена после полной инициализации представления. Другим способом может быть кнопка печати в родительском компоненте, которая запускает печать в iframe с помощью window.frames["printpage"].print(); ,

@Component({
  templateUrl: './print.html',
  styleUrls: [ 'print.scss' ]
})
export class PrintPage implements AfterViewInit {

  constructor() {}

  ngAfterViewInit() {
    // wait some time, so all images or other async data are loaded / rendered.
    // print could be triggered after button press in the parent component as well.
    setTimeout(() => {
      // print current iframe
      window.print();
    }, 2000);
  }

}

Ответ 9

Приложения Windows обычно поставляются со встроенной возможностью печати, но для веб-приложения я бы предпочел просто сгенерировать файл PDF.

Самый простой способ, который я нашел, - это сгенерировать файл PDF с помощью PDFMake (www.pdfmake.org). После этого вы можете предложить пользователю открыть или загрузить созданный файл PDF.

Ответ 10

Используйте библиотеку ngx-print.

Установка:

yarn add ngx-print
or
npm install ngx-print --save

Измените свой модуль:

import {NgxPrintModule} from 'ngx-print';
...
imports: [
    NgxPrintModule,
...

Шаблон:

<div id="print-section">
  // print content
</div>
<button ngxPrint printSectionId="print-section">Print</button>

Подробнее

Ответ 11

import { Directive, ElementRef, Input,HostListener,AfterViewInit } from '@angular/core';
declare const jQuery :  any;

@Directive({ selector: '[printDirective]' })

export class PrintDirective implements AfterViewInit { 

constructor(public e:ElementRef){}
@Input() printelement: string;

button = this.e.nativeElement;

ngAfterViewInit(){


    let self = this;
    jQuery(this.button).on("click", function(){ 

       var html = jQuery("#"+self.printelement).prop('outerHTML');

        let sheets = document.styleSheets;
        let array = [];
        for(var c = 0; c < sheets.length; c++) {

            array.push(sheets[c].href);

        }

        let printStyles:any="";

        array.forEach(function(value:any,index:any){
            var res = value.substring(value.indexOf(":") + 1);
            printStyles = "<link rel='stylesheet' type='text/css'  href="+value+" media='print'>\n"+printStyles ;

        });

        let printContents =  html;

        let  popupWin;

        popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
        popupWin.document.open();
        popupWin.document.write(`
        <html>
            <head>
            <title>Print tab</title>


            ${printStyles}

            </head>
        <body onload="window.print();window.close()">${printContents}</body>
        </html>`
        );
        popupWin.document.close();


        }

)}; 






 }

Это можно сделать так. Я сделал директиву для печати html-страницы. Он просто принимает идентификатор элемента ввода как входной сигнал из шаблона компонента.

app.component.html

<div id="print">
     <div id="mydiv">Hello 1st div</div>
     <div id="seconddiv">Hello second div</div>
<img src="pic.jpg">
<div id="main">
    <div>Hello ...how are you
        <p> demo demo</p>
    </div>
    <div>JHADVSJVCJHCSJHB</div>
    <div>CJHAEV</div>
</div>

   <button [printelement]="'print'" printDirective>print</button>

Это способ использовать его в шаблоне. Протестировано на angular 4 на хроме. В firefox цвет фона может быть добавлен, если отсутствует css:

 background-color: red !important;
-webkit-print-color-adjust: exact;
color-adjust: exact;