Search code examples
angularangular-materialmat-table-exporter

How to export data from a table having an input inside the mat-cell?


I have a project in Angular material in which I am trying to export the data from a table to an xlsx file using the MatTableExporter module.

I have the columns ID, Name and actions (edit and delete), but it only shows me the columns ID and actions, the Name column appears empty.

My problem: because the Name column appears empty and how can I make the data show? How can I remove the actions column from the xlsx file?

This is my component.html:

<div class="title">Customers</div>
<mat-divider></mat-divider>

<div fxLayout="column" fxLayoutGap="10px" class="m-3">
  <mat-card class="mat-elevation-z8">
  
    <div>
      <button mat-raised-button
        (click)="exporter.exportTable('xlsx')">Export excel
      </button>
    </div>
    
    <mat-table matTableExporter [dataSource]="clients" #exporter="matTableExporter">
    
      <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef>ID</mat-header-cell>
        <mat-cell *matCellDef="let clients"> {{clients.id}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
        <mat-cell *matCellDef="let clients; let i = index">
          <mat-form-field floatLabel="never" [appearance]="editIndex != i ? 'none' : 'legacy'">
            <input matInput placeholder="{{clients.name}}" [(ngModel)]="clients.name" [readonly]="editIndex!=i">
          </mat-form-field>
        </mat-cell>
      </ng-container>
      </ng-container>
      
      <ng-container matColumnDef="act">
        <mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
        <mat-cell *matCellDef="let element
          <button mat-icon-button matTooltip="Edit" (click)="edit(element)">
            <mat-icon class="icon_edit_button">edit</mat-icon>
          </button>
          <button *ngIf="editIndex != i" mat-icon-button matTooltip="Delete" (click)="delete(element)">
            <mat-icon>delete_forever</mat-icon>
          </button>
        </mat-cell>
      </ng-container>

      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let col; columns: displayedColumns;"></mat-row>

    </mat-table>
    <mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
  </mat-card>
</div>

This is my xlsx file:

enter image description here


Solution

  • To remove the actions column from the XLS you can add this as a hidden column in the mat-table tag. Here you pass in an array of the column indices you want to omit from the XLS:

    <mat-table ... [hiddenColumns]="[2]">
    

    To render the name in the XLS, you can add the line:

    <span class="cdk-visually-hidden">{{clients.name}}</span>
    

    so your second column becomes:

    <mat-cell *matCellDef="let clients; let i = index">
      <span class="cdk-visually-hidden">{{clients.name}}</span>
      <mat-form-field floatLabel="never" [appearance]="editIndex != i ? 'none' : 'legacy'">
        <input matInput placeholder="{{clients.name}}" [(ngModel)]="clients.name" [readonly]="editIndex!=i">
      </mat-form-field>
    </mat-cell>
    

    This adds a hidden field containing the name. Because your using [(ngModel)] you have 2 way binding and any changes the user makes to the name in the input field, will get reflected in hidden field and therefore in the XLS when you export it.

    Here's a StackBlitz showing this working. Just change one (or several) of the name fields and hit the "Export excel" button and you should get this:

    enter image description here