# Export related data as CSV

This example shows you how to create a Smart Action `"Export orders as CSV"` that allows a user to download all the orders associated to a customer.

![](/files/-MKaZ_wFP5H3ok_hAeeq)

## Requirements

* The [json2CSV](https://www.npmjs.com/package/json2csv) npm package

```javascript
$ npm install json2csv
```

## How it works

### Directory: /models

This directory contains:

* the `customers.js` file where the `customers` model is declared.
* the `orders.js` file where the `orders` model is declared&#x20;

{% code title="customers.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Customers = sequelize.define('customers', {
    firstname: {
      type: DataTypes.STRING,
    },
    lastname: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
    },
    createdAt: {
      type: DataTypes.DATE,
    },
    updatedAt: {
      type: DataTypes.DATE,
    },
  }, {
    tableName: 'customers',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Customers.associate = (models) => {
    Customers.hasMany(models.orders, {
      foreignKey: {
        name: 'customerIdKey',
        field: 'customer_id',
      },
      as: 'orders',
    });
  };

  return Customers;
};

```

{% endcode %}

{% code title="orders.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Orders = sequelize.define('orders', {
    ref: {
      type: DataTypes.STRING,
      primaryKey: true,
      defaultValue: Sequelize.literal('nextval(orders_id_seq::regclass)'),
      allowNull: false,
    },
    shippingStatus: {
      type: DataTypes.ENUM(['In transit', 'Shipped', 'Being processed', 'Ready for shipping']),
    },
    createdAt: {
      type: DataTypes.DATE,
    },
    updatedAt: {
      type: DataTypes.DATE,
    },
    beingProcessedAt: {
      type: DataTypes.DATE,
    },
    readyForShippingAt: {
      type: DataTypes.DATE,
    },
    inTransitAt: {
      type: DataTypes.DATE,
    },
    shippedAt: {
      type: DataTypes.DATE,
    },
  }, {
    tableName: 'orders',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Orders.associate = (models) => {
    Orders.belongsTo(models.customers, {
      foreignKey: {
        name: 'customerIdKey',
        field: 'customer_id',
      },
      as: 'customer',
    });
  };

  return Orders;
};

```

{% endcode %}

### Directory: /forest

This directory contains the `customers.js` file where the smart action `Export orders as CSV` is declared.&#x20;

{% hint style="info" %}
You need to set the attribute `download` as **true** to enable a download
{% endhint %}

{% code title="customers.js" %}

```javascript
const { collection } = require('forest-express-sequelize');

collection('customers', {
  actions: [
    {
      name: 'Export orders as CSV',
      type: 'single',
      download: true,
    },
  ],
  fields: [],
  segments: [],
});

```

{% endcode %}

### Directory: /utils

This directory contains a `csv-exporter.js` file where the method to export the orders as CSV is declared.

{% hint style="info" %}
The `json2csv` package allows you to format the data exported. It can be useful in particular when you have fields of the type JSON that you may want to unwind. You can take a look at the json2csv documentation [here](https://www.npmjs.com/package/json2csv).
{% endhint %}

{% code title="csv-exporter.js" %}

```javascript
const { parse } = require('json2csv');

function exportCustomerOrdersAsCSV(response, data) {
  // set the response header to tell the browser to expect a csv
  response.setHeader('Content-Type', 'text/csv');
  response.setHeader('Content-Disposition', `attachment; filename=cust-${data[0].customerIdKey}-orders.csv`);
  response.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
  // list the fields of the orders that you want to display as columns of the csv
  const fields = [
    'ref',
    'shippingStatus',
    'createdAt',
    'UpdatedAt',
    'beingProcessedAt',
    'readyForShippingAt',
    'inTransitAt',
    'shippedAt',
  ];
  // convert the array of records into a csv
  try {
    const csv = parse(data, { fields });
    return response.send(csv);
  } catch (err) {
    return response.status(500).json({ err });
  }
}

module.exports = exportCustomerOrdersAsCSV;
```

{% endcode %}

###

### Directory: /routes

This directory contains the `customers.js` file where the logic of the smart action is implemented.

{% code title="customers.js" %}

```javascript
const express = require('express');
const { PermissionMiddlewareCreator } = require('forest-express-sequelize');
const { orders } = require('../models');
const exportCustomerOrdersAsCSV = require('../utils/csv-exporter');


const router = express.Router();
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('customers');

router.post('/actions/export-orders-as-csv', permissionMiddlewareCreator.smartAction(), async (req, res) => {
  // Get the current record id
  const recordId = req.body.data.attributes.ids[0];
  // get an array of records that are the orders of the customer and export them
  return orders.findAll({ where: { customerIdKey: recordId } })
    .then((data) => exportCustomerOrdersAsCSV(res, data));
});

module.exports = router;

```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestadmin.com/woodshop/how-tos/export-related-data-as-csv.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
