Spaces:
Sleeping
Sleeping
| export const CSV_SEPARATOR = ';' | |
| function formatCsvNumber(value) { | |
| if (typeof value !== 'number' || !Number.isFinite(value)) return '' | |
| const normalized = Object.is(value, -0) ? 0 : value | |
| return normalized.toLocaleString('pt-BR', { | |
| useGrouping: false, | |
| maximumFractionDigits: 15, | |
| }) | |
| } | |
| export function toCsvCell(value, separator = CSV_SEPARATOR) { | |
| let text = '' | |
| if (typeof value === 'number') { | |
| text = formatCsvNumber(value) | |
| } else if (value instanceof Date) { | |
| text = Number.isNaN(value.getTime()) ? '' : value.toISOString() | |
| } else { | |
| text = String(value ?? '') | |
| } | |
| const escaped = text.replace(/"/g, '""') | |
| if (escaped.includes('"') || escaped.includes('\n') || escaped.includes('\r') || escaped.includes(separator)) { | |
| return `"${escaped}"` | |
| } | |
| return escaped | |
| } | |
| export function buildCsvBlob(columns, rows, separator = CSV_SEPARATOR) { | |
| if (!Array.isArray(columns) || columns.length === 0) return null | |
| const header = columns.map((col) => toCsvCell(col, separator)).join(separator) | |
| const lines = [header] | |
| ;(rows || []).forEach((row) => { | |
| const values = columns.map((col, index) => { | |
| if (Array.isArray(row)) return toCsvCell(row[index], separator) | |
| return toCsvCell(row?.[col], separator) | |
| }) | |
| lines.push(values.join(separator)) | |
| }) | |
| const csv = `\uFEFF${lines.join('\n')}` | |
| return new Blob([csv], { type: 'text/csv;charset=utf-8;' }) | |
| } | |
| export function tableToCsvBlob(table, separator = CSV_SEPARATOR) { | |
| if (!table || !Array.isArray(table.columns) || !Array.isArray(table.rows) || table.columns.length === 0) return null | |
| return buildCsvBlob(table.columns, table.rows, separator) | |
| } | |