Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dev/ag-grid-angular/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ if (isDevMode()) {
{
path: 'row-group',
loadComponent: async () => import('./tests/row-group').then((m) => m.DevRowGroup)
},
{
path: 'export',
loadComponent: async () => import('./tests/export.ng').then((m) => m.DevExport)
}
]
};
Expand Down
118 changes: 118 additions & 0 deletions dev/ag-grid-angular/src/tests/export.ng.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqAgGridThemeModule } from '@koobiq/ag-grid-angular-theme';
import { AgGridModule } from 'ag-grid-angular';
import { AllCommunityModule, ColDef, GridApi, GridReadyEvent, ModuleRegistry } from 'ag-grid-community';
import { jsPDF } from 'jspdf';
import { autoTable } from 'jspdf-autotable';
import { utils, writeFile } from 'xlsx';
import { devInjectRowData } from '../row-data';

ModuleRegistry.registerModules([AllCommunityModule]);

const COLUMN_DEFS: ColDef[] = [
{ field: 'athlete', headerName: 'Athlete' },
{ field: 'age', headerName: 'Age' },
{ field: 'country', headerName: 'Country' },
{ field: 'year', headerName: 'Year' },
{ field: 'date', headerName: 'Date' },
{ field: 'sport', headerName: 'Sport' },
{ field: 'gold', headerName: 'Gold' },
{ field: 'silver', headerName: 'Silver' },
{ field: 'bronze', headerName: 'Bronze' },
{ field: 'total', headerName: 'Total' }
];

type ExportTable = {
headers: string[];
rows: string[][];
};

@Component({
standalone: true,
imports: [AgGridModule, KbqAgGridThemeModule],
Comment thread
artembelik marked this conversation as resolved.
selector: 'dev-export',
template: `
<div>
<button type="button" data-testid="e2eDownloadCsvButton" (click)="downloadCsv()">Download CSV</button>
<button type="button" data-testid="e2eDownloadXlsxButton" (click)="downloadXlsx()">Download XLSX</button>
<button type="button" data-testid="e2eDownloadPdfButton" (click)="downloadPdf()">Download PDF</button>
</div>

<ag-grid-angular
data-testid="e2eScreenshotTarget"
kbqAgGridTheme
animateRows="false"
Comment thread
artembelik marked this conversation as resolved.
[rowData]="rowData()"
[columnDefs]="columnDefs"
(gridReady)="onGridReady($event)"
/>
`,
styles: `
:host {
display: flex;
flex-direction: column;
gap: var(--kbq-size-m);
padding: var(--kbq-size-m);
}

ag-grid-angular {
height: 500px;
max-width: 2036px;
}
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DevExport {
protected readonly rowData = devInjectRowData();
protected readonly columnDefs = COLUMN_DEFS;
private api!: GridApi;
private readonly filename = 'export';

/** Stores the grid API once the grid finishes initializing. */
protected onGridReady(event: GridReadyEvent): void {
this.api = event.api;
}

/** Downloads the grid data as a .csv file. */
protected downloadCsv(): void {
this.api.exportDataAsCsv({ fileName: `${this.filename}.csv` });
}
Comment thread
artembelik marked this conversation as resolved.
Comment thread
artembelik marked this conversation as resolved.

/** Downloads the grid data as an .xlsx file. */
protected downloadXlsx(): void {
const table = this.getExportTable();
if (!table) return;
const worksheet = utils.aoa_to_sheet([table.headers, ...table.rows]);
const workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, 'Export');
writeFile(workbook, `${this.filename}.xlsx`);
}

/** Downloads the grid data as a .pdf file. */
protected downloadPdf(): void {
const table = this.getExportTable();
if (!table) return;
const pdf = new jsPDF({ orientation: 'landscape' });
autoTable(pdf, { head: [table.headers], body: table.rows, theme: 'plain' });
pdf.save(`${this.filename}.pdf`);
}

/** Reads the currently displayed columns and rows (respecting filter, sort and formatters). */
private getExportTable(): ExportTable | null {
const columns = this.api.getAllDisplayedColumns();
const headers = columns.map((column) => column.getColDef().headerName ?? column.getColId());
Comment thread
artembelik marked this conversation as resolved.
const rows: string[][] = [];

this.api.forEachNodeAfterFilterAndSort((node) => {
if (!node.data) return;

rows.push(
columns.map(
(column) => this.api.getCellValue({ rowNode: node, colKey: column, useFormatter: true }) ?? ''
)
);
});

return { headers, rows };
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@
"@koobiq/icons": "^10.10.3",
"ag-grid-angular": "^34.3.1",
"ag-grid-community": "^34.3.1",
"jspdf": "^4.2.1",
"jspdf-autotable": "^5.0.8",
"rxjs": "~7.8.0",
"xlsx": "^0.18.5",
"zone.js": "~0.16.2"
},
"devDependencies": {
Expand Down
Loading