Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 12x 11x 11x 14x 22x 22x 20x 20x 5x 15x 11x 11x 11x 11x 11x 11x 12x 12x | /**
* Download data as a CSV file.
*/
export function downloadCsv(
data: Record<string, unknown>[],
filename: string,
) {
if (data.length === 0) return;
const headers = Object.keys(data[0]);
const rows = data.map((row) =>
headers
.map((h) => {
const val = row[h];
if (val === null || val === undefined) return "";
const str = String(val);
// Escape quotes and wrap in quotes if contains comma, newline, or quote
if (str.includes(",") || str.includes("\n") || str.includes('"')) {
return `"${str.replace(/"/g, '""')}"`;
}
return str;
})
.join(","),
);
const csv = [headers.join(","), ...rows].join("\n");
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename.endsWith(".csv") ? filename : `${filename}.csv`;
a.click();
URL.revokeObjectURL(url);
}
|