71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import type { BookType } from 'xlsx'
|
|
import { flatten } from 'flat'
|
|
import {
|
|
ChevronDownIcon,
|
|
DownloadIcon,
|
|
FileSpreadsheetIcon,
|
|
FileTextIcon
|
|
} from 'lucide-react'
|
|
import * as XLSX from 'xlsx'
|
|
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuGroup,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger
|
|
} from './ui/dropdown-menu'
|
|
import { Button } from './ui/button'
|
|
|
|
export function ExportMenu({
|
|
name,
|
|
headers,
|
|
selectedRows = []
|
|
}: {
|
|
name: string
|
|
headers: Record<string, string>
|
|
selectedRows: object[]
|
|
}) {
|
|
const exportFile = (bookType: BookType) => () => {
|
|
if (!selectedRows.length) {
|
|
return
|
|
}
|
|
const header = Object.keys(headers)
|
|
const data = selectedRows.map((data) => {
|
|
const obj: Record<string, string> = flatten(data)
|
|
return Object.fromEntries(header.map((k) => [k, obj?.[k]]))
|
|
})
|
|
const workbook = XLSX.utils.book_new()
|
|
const worksheet = XLSX.utils.json_to_sheet(data, { header })
|
|
|
|
XLSX.utils.sheet_add_aoa(worksheet, [Object.values(headers)], {
|
|
origin: 'A1'
|
|
})
|
|
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
|
|
XLSX.writeFile(workbook, `${name}_${+new Date()}.${bookType}`, {
|
|
bookType,
|
|
compression: true
|
|
})
|
|
}
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="outline" className="cursor-pointer">
|
|
<DownloadIcon /> Baixar <ChevronDownIcon />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent className="w-52" align="start">
|
|
<DropdownMenuGroup className="*:cursor-pointer">
|
|
<DropdownMenuItem onClick={exportFile('xlsx')}>
|
|
<FileSpreadsheetIcon /> Microsoft Excel (.xlsx)
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem onClick={exportFile('csv')}>
|
|
<FileTextIcon /> CSV (.csv)
|
|
</DropdownMenuItem>
|
|
</DropdownMenuGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|