Search code examples
angularprintingngx-bootstrapangular-template

Page Break not working with ngFor in Angular 13


I've done some searching around for a solution, but page breaks in an Angular 13 component will not break pages.

I am using a simple ng-template (extra fields removed for readability):

<ng-template #testTemplate let-allTheData>
  <div *ngFor="let dataItem of allTheData" >
    <div><b>ID:</b> {{ dataItem.id }}</div>
    <div style="break-after:always;">&nbsp;</div>  <-- non-working page break
  </div>

The template is setup as a ViewChild like this:

@ViewChild('testTemplate ') testTemplate !: TemplateRef<any>;

The data gets passed in and processed through a loop

 data.forEach(x => {
      theThing = {};
      theThing.id = arrtId;
      this.theData.push(theThing);
    });

And the print dialog gets called with this line (using ngx-print):

this.printer.printAngular(this.testTemplate);

The data shows up fine on the print screen, but the page break in the template does not insert a page break - is the template interfering? I've also tried "break-after: page," "break-after: auto" and even "break-before: page," "break-before: auto" and "break-before: always." I also tried using the CSS media queries I've seen in a few searches and adding "!Important" to the inline CSS. Nothing has yet worked. Does anyone have any ideas? Thank you!


Solution

  • I am guessing the css syntax is a bit off page-break-after: always.

      <div style="page-break-after: always" *ngFor="let dataItem of allTheData" >
        <div><b>ID:</b> {{ dataItem.id }}</div>
      </div>
    
      <button (click)="onPrint()">Print</button>
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
    })
    export class AppComponent {
      name = 'Angular ' + VERSION.major;
      allTheData = [{ id: 1 }, { id: 2 }, { id: 3 }];
      constructor() {}
    
      onPrint() {
        window.print();
      }
    }
    

    Working example: https://stackblitz.com/edit/angular-ivy-9wgfdt?file=src%2Fapp%2Fapp.component.ts

    Sorry, I should have been clearer what's different in my example. I'll improve my comment. If you have applied the correct css syntax then move #testTemplate away from <ng-template> to a <div>, for example. ng-template does not get rendered in template, so you have nothing to reference. Then call this.printer.printAngular(this.testTemplate); in ngAfterViewInit(). <div> with #testTemplate becomes available earliest in this cycle.

    <ng-template let-allTheData>
      <div #testTemplate 
           style="page-break-after: always"
           *ngFor="let dataItem of allTheData">
        <div><b>ID:</b> {{ dataItem.id }}</div>
      </div>
    
    ngAfterViewInit() {
       this.printer.printAngular(this.testTemplate);
    }