ngx-print спрятать mat-paginator и распечатать все записи - PullRequest
0 голосов
/ 15 апреля 2020

Я использую ngx-print для печати HTML содержимого в виде PDF документа в приложении Angular 9. Я использую Angular Компоненты и Bootstrap для стайлинга. Я использую mat-table с опциями сортировки, фильтрации и разбиения на страницы для представления данных пользователю. По умолчанию mat-table разбит на страницы по 10 записей на страницу и может быть изменен при необходимости.

  1. Таким образом, всякий раз, когда пользователь нажимает кнопку Печать (ngx-print), которая связана с mat-table, нумерацией страниц , должна исчезать, и все записи из источника данных для печати. ​​
  2. После печати должна появиться пагинация с последними использованными параметрами

1 Ответ

0 голосов
/ 15 апреля 2020

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

добавленные свойства:

  @Input() printSectionId: string;

  @Input() matTableDataSource: MatTableDataSource<any>;

  @Input() paginator: MatPaginator;

  @Input() paginatorId: string;

  @Input() hidePaginator: boolean;

модифицированный метод печати и 2 новых метода

  @HostListener('click')
  public print(): void
  {
    if(this.matTableDataSource.paginator!==undefined && this.matTableDataSource.paginator!==null && this.hidePaginator)
    {
      this.matTableDataSource.paginator=null;
    }

    setTimeout(() =>
    {
      this.hideMatPaginatorBeforePrinting();

      // Do something after
      let printContents, popupWin, styles = '', links = '';

      if (this.useExistingCss)
      {
        styles = this.getElementTag('style');
        links = this.getElementTag('link');
      }

      printContents = document.getElementById(this.printSectionId).innerHTML;
      popupWin = window.open('', '_blank', 'top=0,left=0,height=auto,width=auto');
      popupWin.document.open();
      popupWin.document.write(`
      <html>
        <head>
          <title>${this.printTitle ? this.printTitle : ''}</title>
          ${this.returnStyleValues()}
          ${this.returnStyleSheetLinkTags()}
          ${styles}
          ${links}
        </head>
        <body>
          ${printContents}
          <script defer>
            function triggerPrint(event) {
              window.removeEventListener('load', triggerPrint, false);
              setTimeout(() => {
                window.print();
                setTimeout(function() { window.close(); }, 0);
              }, ${this.printDelay});
            }
            window.addEventListener('load', triggerPrint, false);
          </script>
        </body>
      </html>`);

      popupWin.document.close();

      //Revert back the paginator after printing
      this.showMatPaginatorAfterPrinting();

    }, 1000); //1 second timeout to hide paginator

  }

  //hide Mat Paginator before Printing
  private hideMatPaginatorBeforePrinting()
  {
    document.getElementById(this.paginatorId).style.display='none';
  }

  //Show Mat Paginator after Printing
  private showMatPaginatorAfterPrinting()
  {
    this.matTableDataSource.paginator=this.paginator;
    document.getElementById(this.paginatorId).style.display='block';
  }

И подача необходимых входных данных с помощью кнопки ngxPrint

<button *ngIf="records!==undefined" id="ngxPrintControl"  [matTableDataSource]="reportDataSource" [paginator]="paginator" paginatorId="mat-paginator" [hidePaginator]="true" mat-raised-button useExistingCss="true"    type="button"   printSectionId="report_id"      ngxPrint> Print</button>

Вот новый код директивы ngx-print.directive.ts. Просто скопируйте код директивы в проект и используйте его вместо ngx-print plugin

ngx-print.directive.ts

import {Directive, HostListener, Input} from '@angular/core';
import {MatPaginator} from '@angular/material/paginator';
import {MatTableDataSource} from '@angular/material/table';

@Directive({
  selector: 'button[ngxPrint]'
})
export class NgxPrintDirective
{

  /**
   *
   *
   * @memberof NgxPrintDirective
   */
  @Input() printSectionId: string;

  @Input() matTableDataSource: MatTableDataSource<any>;

  @Input() paginator: MatPaginator;

  @Input() paginatorId: string;

  @Input() hidePaginator: boolean;

  /**
   *
   *
   * @memberof NgxPrintDirective
   */
  @Input() printTitle: string;
  /**
   *
   *
   * @memberof NgxPrintDirective
   */
  @Input() useExistingCss = false;
  /**
   * A delay in milliseconds to force the print dialog to wait before opened. Default: 0
   *
   * @memberof NgxPrintDirective
   */
  @Input() printDelay = 0;

  public _printStyle = [];

  /**
   *
   *
   * @memberof NgxPrintDirective
   */
  @Input()
  set printStyle(values: { [key: string]: { [key: string]: string } })
  {
    for (let key in values)
    {
      if (values.hasOwnProperty(key))
      {
        this._printStyle.push((key + JSON.stringify(values[key])).replace(/['"]+/g, ''));
      }
    }
    this.returnStyleValues();
  }

  /**
   *
   *
   * @returns html for the given tag
   *
   * @memberof NgxPrintDirective
   */
  private _styleSheetFile = '';

  /**
   * @memberof NgxPrintDirective
   * @param cssList
   */
  @Input()
  set styleSheetFile(cssList: string)
  {
    let linkTagFn = cssFileName =>
        `<link rel="stylesheet" type="text/css" href="${cssFileName}">`;
    if (cssList.indexOf(',') !== -1)
    {
      const valueArr = cssList.split(',');
      for (let val of valueArr)
      {
        this._styleSheetFile = this._styleSheetFile + linkTagFn(val);
      }
    }
    else
    {
      this._styleSheetFile = linkTagFn(cssList);
    }
  }

  /**
   *
   *
   * @returns the string that create the stylesheet which will be injected
   * later within <style></style> tag.
   *
   * -join/replace to transform an array objects to css-styled string
   *
   * @memberof NgxPrintDirective
   */
  public returnStyleValues()
  {
    return `<style> ${this._printStyle.join(' ').replace(/,/g, ';')} </style>`;
  }

  /**
   *
   *
   * @memberof NgxPrintDirective
   */
  @HostListener('click')
  public print(): void
  {
    if(this.matTableDataSource.paginator!==undefined && this.matTableDataSource.paginator!==null && this.hidePaginator)
    {
      this.matTableDataSource.paginator=null;
    }

    setTimeout(() =>
    {
      this.hideMatPaginatorBeforePrinting();

      // Do something after
      let printContents, popupWin, styles = '', links = '';

      if (this.useExistingCss)
      {
        styles = this.getElementTag('style');
        links = this.getElementTag('link');
      }

      printContents = document.getElementById(this.printSectionId).innerHTML;
      popupWin = window.open('', '_blank', 'top=0,left=0,height=auto,width=auto');
      popupWin.document.open();
      popupWin.document.write(`
      <html>
        <head>
          <title>${this.printTitle ? this.printTitle : ''}</title>
          ${this.returnStyleValues()}
          ${this.returnStyleSheetLinkTags()}
          ${styles}
          ${links}
        </head>
        <body>
          ${printContents}
          <script defer>
            function triggerPrint(event) {
              window.removeEventListener('load', triggerPrint, false);
              setTimeout(() => {
                window.print();
                setTimeout(function() { window.close(); }, 0);
              }, ${this.printDelay});
            }
            window.addEventListener('load', triggerPrint, false);
          </script>
        </body>
      </html>`);

      popupWin.document.close();

      //Revert back the paginator after printing
      this.showMatPaginatorAfterPrinting();

    }, 1000); //1 second timeout to hide paginator

  }

  //hide Mat Paginator before Printing
  private hideMatPaginatorBeforePrinting()
  {
    document.getElementById(this.paginatorId).style.display='none';
  }

  //Show Mat Paginator after Printing
  private showMatPaginatorAfterPrinting()
  {
    this.matTableDataSource.paginator=this.paginator;
    document.getElementById(this.paginatorId).style.display='block';
  }

  /**
   * @returns string which contains the link tags containing the css which will
   * be injected later within <head></head> tag.
   *
   */
  private returnStyleSheetLinkTags()
  {
    return this._styleSheetFile;
  }

  private getElementTag(tag: keyof HTMLElementTagNameMap): string
  {
    const html: string[] = [];
    const elements = document.getElementsByTagName(tag);
    for (let index = 0; index < elements.length; index++)
    {
      html.push(elements[index].outerHTML);
    }
    return html.join('\r\n');
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...