#Help me improve my function for converting json to text/csv

4 messages · Page 1 of 1 (latest)

azure basin
#

I have created a function that converts json data to text/csv but i'm not fully using typescript powers to make it typesafety. Currently using unknown as the type

export const exportToCsv = (filename: string, rows: unknown[]) => {
  if (!rows || !rows.length) {
    return;
  }
  const separator = ",";
  const keys = Object.keys(rows[0]);
  const csvContent =
    keys.join(separator) +
    "\n" +
    rows
      .map((row: any) => {
        return keys
          .map((k) => {
            let cell = row[k] === null || row[k] === undefined ? "" : row[k];
            cell =
              cell instanceof Date
                ? cell.toLocaleString()
                : cell.toString().replace(/"/g, '""');
            if (cell.search(/("|,|\n)/g) >= 0) {
              cell = `"${cell}"`;
            }
            return cell;
          })
          .join(separator);
      })
      .join("\n");
  const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
  if (navigator.msSaveBlob) {
    navigator.msSaveBlob(blob, filename);
  } else {
    const link = document.createElement("a");
    if (link.download !== undefined) {
      const url = URL.createObjectURL(blob);
      link.setAttribute("href", url);
      link.setAttribute("download", filename);
      link.style.visibility = "hidden";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  }
};
merry owl
#

rows: Record<string, unknown>[] (or date|somethingelse instead of unknown if you know the data)

#

and rewrite that cell part to not assign multiple times with different types

#

I'd probably do something like this

const value = row[key] ?? "";
const csvColumn = value instanceof Date ? value.toLocaleString() : value.toString().replace(/"/g, '""');
return /[",\n]/.test(csvColumn) ? `"${csvColumn}"` : csvColumn;