# Data Transformation with onCsvexport

The [`onCsvexport`](https://www.telerik.com/kendo-vue-ui-develop/components/grid/api/gridprops#oncsvexport) callback allows you to transform, filter, or enhance the data before it is exported to CSV. This is useful for formatting values, adding computed fields, filtering records, or applying business logic to the export data.

<CtaPanelOverview></CtaPanelOverview>

## Basic Data Transformation

The `onCsvexport` callback receives the data array and must return a modified array:

[Demo Source](https://demos.telerik.com/kendo-vue-ui/grid/csv-export/filter-transform/source.txt)

In this example, the callback filters out discontinued products and formats the price and stock values before export.

## Common Transformation Scenarios

### Adding Computed Fields

Add calculated or derived fields to the exported data:

```html
<template>
  <Grid :data-items="products" :csv="true" :on-csvexport="handleCsvExport">
    <GridToolbar>
      <GridCsvExportButton />
    </GridToolbar>
    
  </Grid>
</template>

<script setup lang="ts">
const handleCsvExport = (data) => {
    return data.map((product) => ({
        ...product,
        TotalValue: product.UnitPrice * product.UnitsInStock,
        PriceCategory: product.UnitPrice > 50 ? 'Premium' : 'Standard',
        ExportedAt: new Date().toISOString()
    }));
};
</script>
```

### Formatting Date Values

Format date objects into readable strings:

```ts
const handleCsvExport = (data) => {
    return data.map((order) => ({
        ...order,
        OrderDate: order.OrderDate.toLocaleDateString('en-US'),
        ShippedDate: order.ShippedDate ? order.ShippedDate.toLocaleDateString('en-US') : 'Not Shipped'
    }));
};
```

### Filtering Records

Export only records that meet specific criteria:

```ts
const handleCsvExport = (data) => {
    // Export only active products with stock
    return data.filter((product) => !product.Discontinued && product.UnitsInStock > 0);
};
```

### Flattening Nested Objects

Transform nested objects into flat structure:

```ts
const handleCsvExport = (data) => {
    return data.map((product) => ({
        ProductID: product.ProductID,
        ProductName: product.ProductName,
        CategoryName: product.Category?.CategoryName || 'N/A',
        CategoryDescription: product.Category?.Description || '',
        SupplierName: product.Supplier?.CompanyName || 'N/A',
        UnitPrice: product.UnitPrice,
        UnitsInStock: product.UnitsInStock
    }));
};
```

### Applying Business Rules

Apply complex business logic or calculations:

```ts
const handleCsvExport = (data) => {
    return data.map((product) => {
        const stockStatus =
            product.UnitsInStock === 0 ? 'Out of Stock' : product.UnitsInStock < 10 ? 'Low Stock' : 'In Stock';

        const discount = product.UnitPrice > 100 ? 0.1 : 0;
        const discountedPrice = product.UnitPrice * (1 - discount);

        return {
            ...product,
            StockStatus: stockStatus,
            DiscountedPrice: discountedPrice.toFixed(2),
            HasDiscount: discount > 0 ? 'Yes' : 'No'
        };
    });
};
```

## Combining with Custom Column Selection

You can combine data transformation with custom column selection:

```html
<template>
  <Grid :data-items="products" :csv="csvOptions" :on-csvexport="handleCsvExport">
    <GridToolbar>
      <GridCsvExportButton />
    </GridToolbar>
    
  </Grid>
</template>

<script setup lang="ts">
const handleCsvExport = (data) => {
    return data
        .filter((p) => !p.Discontinued)
        .map((p) => ({
            ...p,
            FormattedPrice: `$${p.UnitPrice.toFixed(2)}`
        }));
};

const csvOptions = {
    keys: ['ProductID', 'ProductName', 'FormattedPrice', 'UnitsInStock'],
    names: ['ID', 'Product', 'Price', 'Stock'],
    fileName: 'active-products.csv'
};
</script>
```

## Working with Large Datasets

For large datasets, consider performance optimization:

```ts
const handleCsvExport = (data) => {
    // Limit export size if needed
    const maxRows = 10000;
    const limitedData = data.slice(0, maxRows);

    return limitedData.map((item) => ({
        // Only include necessary fields
        id: item.id,
        name: item.name,
        value: item.value
    }));
};
```

## Suggested Links

* [CSV Export Basics](https://www.telerik.com/kendo-vue-ui-develop/components/grid/csv-export)
* [Customizing Exported Columns](https://www.telerik.com/kendo-vue-ui-develop/components/grid/csv-export/custom-columns)
* [Exporting Custom Data](https://www.telerik.com/kendo-vue-ui-develop/components/grid/csv-export/custom-data)
* [Formula Injection Protection](https://www.telerik.com/kendo-vue-ui-develop/components/grid/csv-export/formula-injection)
* [Vue Data Grid](https://www.telerik.com/kendo-vue-ui-develop/components/grid)
* [API Reference of the Grid](https://www.telerik.com/kendo-vue-ui-develop/components/grid/api/gridprops)
