Export a smart collection in csv

Hello :wave:

Feature(s) impacted

smart collection

Observed behavior

I created a route to make a smart collection but when I tried to create the route for the CSV export below:

router.get('/accountingReport.csv', permissionMiddlewareCreator.export(), (request, response, next) => {
    console.log(request.user)
    console.log("--------------")
    console.log(request.query)
    console.log("--------------")
    console.log(accountingReport)
    // Learn what this route does here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#export-a-list-of-records
    const recordsExporter = new RecordsExporter(accountingReport, request.user, request.query);
    recordsExporter.streamExport(response, request.query)
        .catch(next);
});

but I get this error when I press the csv export button on forest

Expected behavior

And I would like to know if there is a way to export a smart collections in csv?

Context

  • Project name: Nostrum Care v2
  • Team name: Operation
  • Environment name: Development
  • Agent (forest package) name & version: “forest-express-sequelize”: “^8.0.0”
  • Database type: Postgres

Thank you in advance

Hello @jacques_liao ! :wave:

That is the default RecordsExporter for default collection (not Smart Collection :confused:).

Unfortunately, for Smart Collection you need to define this by hand. You can use fast-csv or csv-stringify for example.

Here is an example of basic CSV export implementation.

// Lib to create CSV export
const stringify = require('csv-stringify');

router.get('/accountingReport.csv', permissionMiddlewareCreator.export(), (request, response, next) => {

    const filename = `${params.filename}.csv`;

    response.setHeader('Content-Type', 'text/csv; charset=utf-8');
    response.setHeader('Content-disposition', `attachment; filename=${filename}`);
    response.setHeader('Last-Modified', moment());
    response.setHeader('X-Accel-Buffering', 'no');
    response.setHeader('Cache-Control', 'no-cache');

    const CSVHeader = `${params.header}\n`;
    const CSVAttributes = params.fields[modelName].split(',');
    response.write(CSVHeader);

    const CSVLines = [];
    // records is an array of your records to export ! You get them as you did in the list route implementation
    
    records.forEach((record) => {
      const CSVLine = [];
      CSVAttributes.forEach((attribute) => {
        CSVLine.push(record[attribute] || '');
      });
      CSVLines.push(CSVLine);
    });

    csvStringify(CSVLines, CSV_OPTIONS, (error, csv) => {
      response.write(csv);
      response.end();
    });
});

Another way to create CSV exports
import { stringify } from 'csv-stringify/sync';

// records is an array of your records to export ! You get them as you did in the list route implementation

const output = stringify(records, {
      columns: [‘timestamp’, ‘user’, ‘team’, ‘collection’, ‘action’, ‘label’, ‘records’],
      header: true,
    });

Let me know if it helps.

Kind regards,
Morgan

1 Like

Hello @morganperre

Thank you for your answer :slight_smile:
but after several reflexion, I will create a normal collection like that it will be much more simple and fast :slight_smile:

Thank you!

1 Like

:pray:

You’re welcome.

For sure it’s way faster. I forward your feedback to our team so we can improve things to the right direction in the future. :pray:

Kind regards,
Morgan

1 Like