Я хочу напечатать шаблон HTML в angular 2. Я исследовал об этом, я получил решение в angularjs 1 Печать шаблона Html в Angularjs 1
Любое предложение будет оценено
Я хочу напечатать шаблон HTML в angular 2. Я исследовал об этом, я получил решение в angularjs 1 Печать шаблона Html в Angularjs 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) и большего количества готовых к использованию контролируемых и защищенных вариантов печати.
В случае, если кто-то еще сталкивается с этой проблемой, если вы уже выложили страницу, я бы рекомендовал использовать медиа-запросы для настройки вашей страницы печати. Затем вы можете просто прикрепить функцию печати к кнопке 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.
вы можете сделать это в 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>
РЕДАКТИРОВАТЬ: обновлены фрагменты для более общего подхода
Так же, как расширение принятого ответа,
Чтобы получить существующие стили для сохранения внешнего вида целевого компонента, вы можете:
сделать запрос, чтобы извлечь элементы <style>
и <link>
из документа верхнего уровня
вставьте его в строку 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) он должен выглядеть как фрагмент существующего экрана.
Служба печати
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);
}
}
Не лучший выбор, но работает.
Я столкнулся с той же проблемой и нашел другой способ сделать это. В моем случае это сработало, так как это было относительно небольшое приложение.
Сначала пользователь нажимает кнопку в компоненте, который необходимо распечатать. Это установит флаг, к которому может получить доступ компонент приложения. Вот так
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;}
}
Самое короткое решение - назначить окно переменной машинописного текста, а затем вызвать метод print, как показано ниже.
в файле шаблона
<button ... (click)="window.print()" ...>Submit</button>
и в машинописном файле
window: any;
constructor() {
this.window = window;
}
Лучший вариант, который я нашел, чтобы решить эту проблему без проблем со своими стилями, - использовать отдельный маршрут для вывода на печать и загрузить этот маршрут в 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);
}
}
Приложения Windows обычно поставляются со встроенной возможностью печати, но для веб-приложения я бы предпочел просто сгенерировать файл PDF.
Самый простой способ, который я нашел, - это сгенерировать файл PDF с помощью PDFMake (www.pdfmake.org). После этого вы можете предложить пользователю открыть или загрузить созданный файл PDF.
Используйте библиотеку 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>
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;