Primeng: Template support for DataTable CSV Export

Created on 2 Aug 2017  路  4Comments  路  Source: primefaces/primeng

I'm submitting a ... (check one with "x")

[x] bug report => Search github for a similar issue or PR before submitting
[ ] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap
[ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35

Plunkr Case (Bug Reports)
http://plnkr.co/edit/hDuyiwFrus0St8n1T4Oh?p=preview

Current behavior
I have a simple data table using ng-template. When exporting data, only columns without ng-template gets exported.

Expected behavior
I would expect to have data from all columns exported, which contain simple string values or divs, spans.

Minimal reproduction of the problem with instructions
Click on the button in the Plunkr example. The CSV file contains only the first column.

What is the motivation / use case for changing the behavior?

  • Angular version: 2.0.X
    4.3.1

  • PrimeNG version: 2.0.X
    4.1.2

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    all

Most helpful comment

Just a quick example, the columns-Array defines the columns which you want to export (tested in Edge, FF and Chrome)

 exportToCSV(datatable: DataTable, columns: number[], name: string): void {
        let headerString = '';
        const headers = datatable.el.nativeElement.querySelectorAll('.ui-column-title');
        for (const column of columns) {
            headerString += headers[column - 1].innerText + ';';
        }
        const tableRows = datatable.el.nativeElement.querySelectorAll('TR');
        const rowsString: string[] = [];
        for (let i = 1; i < tableRows.length; i++) {
            let rowString = '';
            const tableRow = tableRows[i].querySelectorAll('.ui-cell-data');
            for (const column of columns) {
                rowString +=  tableRow[column - 1].innerText.replace(/[\n\r]+/g, '').replace(/\s{2,}/g, ' ').trim() + ';';
            }
            rowsString.push(rowString);
        }
        let csv = headerString + '\n';
        for (const row of rowsString) {
            csv += row + '\n';
        }
        const blob = new Blob(['\uFEFF', csv], {type: 'text/csv'});
        const link = document.createElement('a');
        link.setAttribute('href', window.URL.createObjectURL(blob));
        link.setAttribute('download', name + '.csv');
        document.body.appendChild(link); // Required for FF
        link.click();
    }

Use it like this:

<p-dataTable #dt>
   <p-header>
      <button (click)="exportToCSV(dt, [1,2,3,4,5,6], 'CSVName');">Export CSV</button>
   </p-header>      
...
</p-dataTable>

All 4 comments

Not sure if it is possible to access the ng-template content so this is a limitation, feel free to drop a comment if you are aware of a way.

One could iterate over the DOM tree and use QuerySelector to get the correct elements?

Just a quick example, the columns-Array defines the columns which you want to export (tested in Edge, FF and Chrome)

 exportToCSV(datatable: DataTable, columns: number[], name: string): void {
        let headerString = '';
        const headers = datatable.el.nativeElement.querySelectorAll('.ui-column-title');
        for (const column of columns) {
            headerString += headers[column - 1].innerText + ';';
        }
        const tableRows = datatable.el.nativeElement.querySelectorAll('TR');
        const rowsString: string[] = [];
        for (let i = 1; i < tableRows.length; i++) {
            let rowString = '';
            const tableRow = tableRows[i].querySelectorAll('.ui-cell-data');
            for (const column of columns) {
                rowString +=  tableRow[column - 1].innerText.replace(/[\n\r]+/g, '').replace(/\s{2,}/g, ' ').trim() + ';';
            }
            rowsString.push(rowString);
        }
        let csv = headerString + '\n';
        for (const row of rowsString) {
            csv += row + '\n';
        }
        const blob = new Blob(['\uFEFF', csv], {type: 'text/csv'});
        const link = document.createElement('a');
        link.setAttribute('href', window.URL.createObjectURL(blob));
        link.setAttribute('download', name + '.csv');
        document.body.appendChild(link); // Required for FF
        link.click();
    }

Use it like this:

<p-dataTable #dt>
   <p-header>
      <button (click)="exportToCSV(dt, [1,2,3,4,5,6], 'CSVName');">Export CSV</button>
   </p-header>      
...
</p-dataTable>

p-dataTable is deprecated and will be removed in favor of the new p-table (aka TurboTable) of 5.1.0 so closing the issue. Please try the new p-table once 5.1.0 is released.

Was this page helpful?
0 / 5 - 0 ratings