Files

17 lines
656 B
TypeScript

export function escapeCsv(value: string | number | null | undefined): string {
if (value === null || value === undefined) return ''
let str = String(value)
// Prevent CSV formula injection (Excel/LibreOffice execute cells starting with these chars)
if (/^[=+\-@\t\r]/.test(str)) str = "'" + str
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
return `"${str.replace(/"/g, '""')}"`
}
return str
}
export function rowsToCsv(headers: string[], rows: string[][]): string {
const lines = [headers.map(escapeCsv).join(',')]
for (const row of rows) lines.push(row.map(escapeCsv).join(','))
return lines.join('\r\n')
}