forked from Creditra/Creditra-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcsv.ts
More file actions
54 lines (47 loc) · 1.54 KB
/
Copy pathcsv.ts
File metadata and controls
54 lines (47 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* Small, dependency-free CSV helpers.
*
* We keep export logic local to the app to avoid adding a third-party
* CSV dependency for a narrow, security-sensitive use case.
*/
export type CsvCell = string | number | boolean | null | undefined;
/**
* Escape one CSV field according to RFC 4180-style rules.
*
* Fields containing commas, quotes, carriage returns, or newlines are
* wrapped in double quotes. Embedded quotes are doubled.
*/
export function escapeCsvCell(value: CsvCell): string {
const normalized = value == null ? "" : String(value);
const escaped = normalized.replace(/"/g, '""');
return /[",\r\n]/.test(normalized) ? `"${escaped}"` : escaped;
}
/**
* Convert a header row and data rows into a CSV string.
*/
export function toCsv(
headers: readonly CsvCell[],
rows: ReadonlyArray<readonly CsvCell[]>,
): string {
return [headers, ...rows]
.map((row) => row.map(escapeCsvCell).join(","))
.join("\r\n");
}
/**
* Trigger a browser download for a UTF-8 CSV file.
*
* A BOM is prepended to improve spreadsheet compatibility for users who
* open the file in Excel or similar tools.
*/
export function downloadCsv(filename: string, csv: string): void {
const blob = new Blob(["\uFEFF", csv], { type: "text/csv;charset=utf-8" });
const url = URL.createObjectURL(blob);
const anchor = document.createElement("a");
anchor.href = url;
anchor.download = filename;
anchor.rel = "noopener";
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
URL.revokeObjectURL(url);
}