17 lines
656 B
TypeScript
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')
|
|
}
|