I have been looking at the StackBlitz you put together, and it's giving you errors at runtime. For instance, you have a call to exportToExcel, but that's in the app.component.html and there's no corresponding exportToExcel function in app.component.ts. You declare this function in prime-table.component.ts.
If you want us to look at code, please put a working code sample in stackblitz. We will look at it then.
I forked your updated StackBlitz and combined everything into the app.component files to make life simple. In app.component.ts, I added the following lines:
filteredvalues: any[] = [];
onFilter(event) {
this.filteredvalues = event.filteredValue;
}
This event handler is going to take the filtered data and store it (note that I initially set filteredvalues to have all the data when I initialize them in ngOnInit). Then, I replace the references to
this.data
with
this.filteredvalues
in the exportToExcel method. That way, I know I am exporting the filtered data, and not the original dataset. The last part is to hook the filter capability of the table to the
onFilter
event handler. That is done by adding this to the table definition:
(onFilter)="onFilter($event)"
My fork of your repo can be found
here[
^].
To keep the answer in CodeProject, this is what my app.component.ts file now looks like:
import { Component, Input, TemplateRef } from '@angular/core';
import { PrimeNGConfig } from 'primeng/api';
import { Workbook } from 'exceljs';
import { saveAs } from 'file-saver';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [],
})
export class AppComponent {
constructor(private primengConfig: PrimeNGConfig) {}
columns: any[] = [];
data: any[] = [];
dropdownOptions: { [key: string]: any[] } = {};
@Input()
customBodyTemplate!: TemplateRef<any>;
ngOnInit() {
this.primengConfig.ripple = true;
this.dropdownOptions = {
billingStatus: ['Billable', 'Non-Billable'],
client: ['Client1', 'Client2'],
};
this.columns = [
{ field: 'employeeId', header: 'Employee ID' },
{ field: 'employeeName', header: 'Full Name' },
{ field: 'emailId', header: 'Email' },
{ field: 'billingStatus', header: 'Billing Status', type: 'dropdown' },
{ field: 'designation', header: 'Designation' },
{ field: 'client', header: 'Client', type: 'dropdown' },
{ field: '', header: 'Action', type: 'button' },
];
this.data = [
{
employeeId: '123',
employeeName: 'xyz',
emailId: 'xyz',
billingStatus: 'Billable',
designation: 'SSE',
client: 'Client1',
},
{
employeeId: '134',
employeeName: 'pqr',
emailId: 'xyz',
billingStatus: 'Non-Billable',
designation: 'SSE',
client: 'Client2',
},
{
employeeId: '123',
employeeName: 'xyz',
emailId: 'xyz',
billingStatus: 'Billable',
designation: 'SSE',
client: 'Client1',
},
{
employeeId: '134',
employeeName: 'pqr',
emailId: 'xyz1',
billingStatus: 'Non-Billable',
designation: 'SSE',
client: 'Client2',
},
{
employeeId: '123',
employeeName: 'xyz2',
emailId: 'xyz2',
billingStatus: 'Billable',
designation: 'SSE',
client: 'Client1',
},
{
employeeId: '134',
employeeName: 'pqr',
emailId: 'xyz',
billingStatus: 'Non-Billable',
designation: 'SSE',
client: 'Client2',
},
];
this.filteredvalues = this.data;
}
filteredvalues: any[] = [];
onFilter(event) {
this.filteredvalues = event.filteredValue;
}
exportToExcel() {
if (this.filteredvalues && Array.isArray(this.filteredvalues)) {
let data: any[] = [];
this.filteredvalues.forEach((employee: any) => {
const rowData: any = {
'Employee ID': employee.employeeId,
'Full Name': employee.employeeName,
Email: employee.emailId,
'Billing Status': employee.billingStatus,
Designation: employee.designation,
Client: employee.client,
'Billing Start Date': employee.billingStartDate,
};
if (!employee.isActive) {
rowData['Exit Date'] = employee.exitDate;
}
data.push(rowData);
});
if (data.length > 0) {
const header = Object.keys(data[0]);
const headerArray: string[] = [];
header.forEach((val) => {
headerArray.push(val.charAt(0).toUpperCase() + val.slice(1));
});
let workbook = new Workbook();
const worksheet = workbook.addWorksheet();
worksheet.addRow([]);
const headerRow = worksheet.addRow(headerArray);
headerRow.eachCell((cell, number) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
};
});
data.forEach((d) => {
const rowData: any[] = [];
header.forEach((h) => {
rowData.push(d[h] || '');
});
const dataRow = worksheet.addRow(rowData);
dataRow.eachCell((cell, number) => {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
};
if (!cell.value) {
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
};
}
});
});
worksheet.columns.forEach((column) => {
if (column) {
(column as any).eachCell({ includeEmpty: true }, (cell: any) => {
const maxLength = cell.value ? cell.value.toString().length : 0;
column.width = Math.max(column.width || 10, maxLength + 2);
});
}
});
workbook.xlsx.writeBuffer().then((buffer: ArrayBuffer) => {
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
});
saveAs(blob, `${'EmployeeData'}.xlsx`);
});
}
}
}
}
and this is the app.component.html file.
<p-toolbar styleClass="mb-2">
<ng-template pTemplate="left"> </ng-template>
<ng-template pTemplate="center"> </ng-template>
<ng-template pTemplate="right">
<button
type="button"
pButton
pRipple
icon="pi pi-file-excel"
class="p-button-success mr-2"
(click)="exportToExcel()"
pTooltip="XLS"
tooltipPosition="bottom"
></button> </ng-template
></p-toolbar>
<p-table
[showCurrentPageReport]="true"
#dt1
[columns]="columns"
[value]="data"
[paginator]="true"
[rows]="15"
(onFilter)="onFilter($event)"
scrollHeight="410px"
[resizableColumns]="true"
[globalFilterFields]="columns"
responsiveLayout="scroll"
[showCurrentPageReport]="true"
[scrollable]="true"
[rowsPerPageOptions]="[5, 10, 15, 20, data.length]"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
>
<ng-template pTemplate="caption" *ngIf="showInput">
<div class="flex">
<span class="p-input-icon-left ml-auto">
<i class="pi pi-search"></i>
<input
pInputText
type="text"
(input)="dt1.filterGlobal($any($event.target).value, 'contains')"
placeholder="Search"
/>
</span>
</div>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns">
<ng-container *ngIf="col.type !== 'button'">
<p pSortableColumn="{{ col.field }}">
{{ col.header }}
<p-sortIcon field="{{ col.field }}"></p-sortIcon>
</p>
</ng-container>
<ng-container *ngIf="col.type === 'button'">
<!--
{{ col.header }}
</ng-container>
</th>
</tr>
<tr>
<th *ngFor="let col of columns">
<input
pInputText
type="text"
(input)="
dt1.filter($event.target.value, col.field, col.filterMatchMode)
"
/>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<ng-template #defaultTemplate>
<tr>
<td *ngFor="let col of columns">
{{ rowData[col.field] }}
</td>
</tr>
</ng-template>
<ng-container
*ngTemplateOutlet="
customBodyTemplate ? customBodyTemplate : defaultTemplate;
context: { $implicit: rowData }
"
>
</ng-container>
</ng-template>
</p-table>
<ng-template #customBodyTemplate let-rowData>
<tr>
<td *ngFor="let col of columns">
<div *ngIf="!col.type">
{{ rowData[col.field] }}
</div>
<div *ngIf="col.type == 'dropdown'">{{ rowData[col.field] }}</div>
<div *ngIf="col.type == 'date'">{{ formatDate(rowData[col.field]) }}</div>
</td>
</tr>
</ng-template>