NuGrid supports exporting data to Excel files with formatting, using the write-excel-file library.
Install the optional dependency:
pnpm add write-excel-file
npm install write-excel-file
Export data using the grid ref:
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
function exportToExcel() {
gridRef.value?.exportToExcel({
filename: 'users',
})
}
</script>
<template>
<UButton @click="exportToExcel">
Export to Excel
</UButton>
<NuGrid ref="grid" :data="data" :columns="columns" />
</template>
interface ExcelExportOptions {
filename?: string
sheetName?: string
includeHeaders?: boolean
columns?: string[]
dateFormat?: string
}
| Option | Type | Default | Description |
|---|---|---|---|
filename | string | 'export' | File name (without extension) |
sheetName | string | 'Sheet1' | Excel sheet name |
includeHeaders | boolean | true | Include column headers |
columns | string[] | All columns | Columns to export |
dateFormat | string | 'YYYY-MM-DD' | Date format |
Export specific columns:
<script setup lang="ts">
function exportToExcel() {
gridRef.value?.exportToExcel({
filename: 'user-emails',
columns: ['name', 'email'], // Only export these columns
})
}
</script>
Columns can define their export format:
const columns: NuGridColumn<Product>[] = [
{
accessorKey: 'name',
header: 'Product Name',
},
{
accessorKey: 'price',
header: 'Price',
// Excel will format as currency
exportFormat: '$#,##0.00',
},
{
accessorKey: 'createdAt',
header: 'Created',
// Excel date format
exportFormat: 'YYYY-MM-DD',
},
{
accessorKey: 'quantity',
header: 'Quantity',
// Integer format
exportFormat: '#,##0',
},
]
Export only visible (filtered) data:
<script setup lang="ts">
function exportFiltered() {
gridRef.value?.exportToExcel({
filename: 'filtered-users',
// Only exports rows that pass current filters
filteredOnly: true,
})
}
</script>
Export only selected rows:
<script setup lang="ts">
function exportSelected() {
gridRef.value?.exportToExcel({
filename: 'selected-users',
selectedOnly: true,
})
}
</script>
<template>
<div>
<UButton
:disabled="!hasSelection"
@click="exportSelected"
>
Export Selected
</UButton>
<NuGrid
ref="grid"
v-model:row-selection="rowSelection"
:data="data"
:columns="columns"
selection="multi"
/>
</div>
</template>
Export with group structure:
<script setup lang="ts">
const grouping = ref(['category'])
function exportWithGroups() {
gridRef.value?.exportToExcel({
filename: 'grouped-products',
includeGroups: true, // Include group headers
})
}
</script>
<template>
<NuGrid
ref="grid"
v-model:grouping="grouping"
:data="data"
:columns="columns"
/>
</template>
For full control, access the data directly:
<script setup lang="ts">
import writeXlsxFile from 'write-excel-file'
async function customExport() {
const grid = gridRef.value
const rows = grid?.tableApi?.getFilteredRowModel().rows ?? []
const schema = [
{
column: 'Name',
type: String,
value: (row) => row.original.name,
},
{
column: 'Email',
type: String,
value: (row) => row.original.email,
},
{
column: 'Salary',
type: Number,
format: '$#,##0.00',
value: (row) => row.original.salary,
},
]
await writeXlsxFile(rows, {
schema,
fileName: 'custom-export.xlsx',
})
}
</script>
Create a reusable export button:
<!-- components/GridExportButton.vue -->
<script setup lang="ts">
defineProps<{
gridRef: any
filename?: string
}>()
</script>
<template>
<UDropdownMenu
:items="[
{
label: 'Export All',
icon: 'i-lucide-file-spreadsheet',
onSelect: () => gridRef?.exportToExcel({ filename }),
},
{
label: 'Export Filtered',
icon: 'i-lucide-filter',
onSelect: () => gridRef?.exportToExcel({ filename, filteredOnly: true }),
},
{
label: 'Export Selected',
icon: 'i-lucide-check-square',
onSelect: () => gridRef?.exportToExcel({ filename, selectedOnly: true }),
},
]"
>
<UButton variant="outline" icon="i-lucide-download">
Export
</UButton>
</UDropdownMenu>
</template>
Usage:
<template>
<div>
<GridExportButton :grid-ref="gridRef" filename="my-data" />
<NuGrid ref="gridRef" :data="data" :columns="columns" />
</div>
</template>
<script setup lang="ts">
const gridRef = useTemplateRef('grid')
const toast = useToast()
const columns: NuGridColumn<Product>[] = [
{ accessorKey: 'id', header: 'ID' },
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'category', header: 'Category' },
{
accessorKey: 'price',
header: 'Price',
exportFormat: '$#,##0.00',
},
{
accessorKey: 'stock',
header: 'Stock',
exportFormat: '#,##0',
},
{
accessorKey: 'createdAt',
header: 'Created',
exportFormat: 'YYYY-MM-DD',
},
]
async function exportAll() {
try {
await gridRef.value?.exportToExcel({
filename: 'products',
sheetName: 'Products',
})
toast.add({ title: 'Exported', color: 'success' })
} catch (error) {
toast.add({ title: 'Export failed', color: 'error' })
}
}
async function exportSelected() {
const selected = gridRef.value?.getSelectedRows()
if (!selected?.length) {
toast.add({ title: 'No rows selected', color: 'warning' })
return
}
await gridRef.value?.exportToExcel({
filename: 'selected-products',
selectedOnly: true,
})
}
</script>
<template>
<div class="space-y-4">
<div class="flex gap-2">
<UButton icon="i-lucide-download" @click="exportAll">
Export All
</UButton>
<UButton
variant="outline"
icon="i-lucide-check-square"
@click="exportSelected"
>
Export Selected
</UButton>
</div>
<NuGrid
ref="grid"
v-model:row-selection="rowSelection"
:data="data"
:columns="columns"
selection="multi"
/>
</div>
</template>