finai / apps /web /lib /export.ts
Sandy-sys's picture
Deploy FinAI
db7ef8e verified
Raw History Blame Contribute Delete
1.39 kB
/** CSV / SQL helpers for per-component export & copy. */
export function rowsToCsv(rows: any[]): string {
if (!rows?.length) return "";
const cols = Object.keys(rows[0]);
const esc = (v: any): string => {
if (v == null) return "";
const s = typeof v === "string" ? v : JSON.stringify(v);
if (/[",\n]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
return s;
};
const head = cols.join(",");
const body = rows.map((r) => cols.map((c) => esc(r[c])).join(",")).join("\n");
return head + "\n" + body;
}
export function downloadFile(name: string, content: string, mime = "text/csv") {
const blob = new Blob([content], { type: mime });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, 0);
}
export async function copyToClipboard(text: string): Promise<boolean> {
try {
await navigator.clipboard.writeText(text);
return true;
} catch {
return false;
}
}
export function safeFilename(s: string, ext: string): string {
const base = (s || "export")
.toLowerCase()
.replace(/[^a-z0-9]+/g, "_")
.replace(/^_+|_+$/g, "")
.slice(0, 50);
return `${base || "export"}.${ext}`;
}