UNPKG

csv-export-import

Version:

This package will help converting data objects to csv and vice versa.

190 lines (187 loc) 7.04 kB
// src/csvSimpleExport.ts var simpleExportToCSV = (items, spreadArrays = true, columnSeparator = ",", arraySeparator = "|") => { if (!items || items.length === 0) return ""; if (!columnSeparator || columnSeparator.trim() == "") columnSeparator = ","; if (!arraySeparator || arraySeparator.trim() == "") arraySeparator = "|"; columnSeparator = columnSeparator.trim(); arraySeparator = arraySeparator.trim(); if (columnSeparator == arraySeparator) { columnSeparator = ","; arraySeparator = "|"; } const flattenItem = (item, spreadArrays2) => { const flatItem = {}; for (const key in item) { if (item[key] != null && item[key] != void 0) { if (Array.isArray(item[key])) { if (item[key].every((item2) => typeof item2 !== "object")) { if (spreadArrays2) { item[key].forEach((value, index) => { flatItem[`${key}[${index}]`] = value; }); } else { flatItem[key] = item[key].join("|"); } } else { } } else { flatItem[key] = item[key]; } } } return flatItem; }; const flattenedItems = items.map((item) => flattenItem(item, spreadArrays)); const headers = Array.from(new Set(flattenedItems.flatMap((obj) => Object.keys(obj)))); const csvItems = []; csvItems.push(headers.join(columnSeparator)); flattenedItems.forEach((item) => { const rowData = []; for (const header of headers) { rowData.push(item[header] || ""); } csvItems.push(rowData.join(columnSeparator)); }); const csvContent = csvItems.join("\n"); return csvContent; }; // src/csvExport.ts var exportToCSV = (items, configProperties, exportConfig, dependentData) => { if (!exportConfig) { exportConfig = { "title": null, "includeHeader": true, "columnSeparator": ",", "arraySeparator": "|", "sorroundValuesByString": "", "removePipedArrayHeaderBrackets": false }; } const xConfigProperties = configProperties.map((cp) => cp); xConfigProperties.sort((a, b) => a.order - b.order); xConfigProperties.map((c, i) => c.xOrder = i); xConfigProperties.filter((cp) => cp.spread == true && !cp.isArray).forEach((cp) => cp.isArray = true); if (!exportConfig.sorroundValuesByString) exportConfig.sorroundValuesByString = ""; if (!exportConfig.columnSeparator) exportConfig.columnSeparator = ","; if (!exportConfig.arraySeparator) exportConfig.arraySeparator = "|"; const resultItems = items.map((item, index) => { const result = {}; xConfigProperties.forEach((cp) => { if (!item) return; const values = cp.generateExportDataFn ? cp.generateExportDataFn(item[cp.property], item, index, dependentData) : item[cp.property]; if (values == null || values == void 0) return; else if (!Array.isArray(values) && !cp.isArray) result[cp.header] = `${values}`; else if (!cp.isArray && Array.isArray(values)) result[`${cp.header}[]`] = values.join(exportConfig.arraySeparator); else if (cp.isArray && !cp.spread) result[`${cp.header}[]`] = values.join(exportConfig.arraySeparator); else values.forEach((v, index2) => result[`${cp.header}[${index2}]`] = v); }); return result; }); const headers = Array.from(new Set(resultItems.flatMap((r) => Object.keys(r)))); headers.sort((x, y) => { const a = x.toString(); const b = y.toString(); const { header: headerA, xOrder: orderA } = xConfigProperties.find((cp) => a === cp.header || a.startsWith(`${cp.header}[`)) || {}; const { header: headerB, xOrder: orderB } = xConfigProperties.find((cp) => b === cp.header || b.startsWith(`${cp.header}[`)) || {}; const numA = a.match(/\[(\d+)\]/) ? parseInt(a.match(/\[(\d+)\]/)[1]) : 0; const numB = b.match(/\[(\d+)\]/) ? parseInt(b.match(/\[(\d+)\]/)[1]) : 0; if (orderA < orderB) return -1; if (orderA > orderB) return 1; if (headerA === headerB && numA !== 0 && numB !== 0) { return numA - numB; } return a.localeCompare(b); }); const resultCSVItems = resultItems.map((item, index) => { const rowItem = []; headers.forEach((header) => { var value = item.hasOwnProperty(header) ? item[header] : ""; value = `${exportConfig.sorroundValuesByString}${value}${exportConfig.sorroundValuesByString}`; rowItem.push(value); }); return rowItem.join(exportConfig.columnSeparator); }); if (exportConfig.includeHeader) { if (exportConfig.removePipedArrayHeaderBrackets) { xConfigProperties.forEach((cp) => { const idx = headers.indexOf(`${cp.header}[]`); if (idx >= 0) headers[idx] = `${cp.header}`; }); } resultCSVItems.splice(0, 0, headers.join(exportConfig.columnSeparator)); } if (exportConfig.title) resultCSVItems.splice(0, 0, `${exportConfig.title}`); return resultCSVItems.join("\n"); }; // src/csvImport.ts var importFromCSV = (csv, hasHeader = true, hasTitle = false, includeLineInfo = false) => { const lines = csv.replaceAll("\r\n", "\n").split("\n"); const title = hasTitle ? lines[0] : null; const headerIndex = hasHeader ? hasTitle ? 1 : 0 : null; const headerLine = headerIndex != null ? lines[headerIndex] : null; var headers = headerIndex != null ? lines[headerIndex].split(",") : null; const dataIndex = (hasTitle ? 1 : 0) + (hasHeader ? 1 : 0); const dataLines = lines.slice(dataIndex); const allData = []; dataLines.forEach((line, lineIndex) => { if (line == "" || line.replaceAll(",", "").trim() == "") return; const lineColumns = line.split(","); headers = headers ? headers : Array.apply(null, { length: lineColumns.length }).map((_, idx) => `col${idx + 1}`); const newData = {}; if (includeLineInfo) { newData["_datalinenumber"] = lineIndex + 1; newData["_csvlinenumber"] = lineIndex + 1 + dataIndex; newData["_line"] = line; } headers.forEach((header, index) => { header = header.trim(); if (hasHeader && header.trim().endsWith("[]")) { const headerName = header.trim().slice(0, -2); var values = []; if (lineColumns[index] != "") values = lineColumns[index].split("|"); values = values.filter((v) => v.length > 0); newData[headerName] = values; } else if (hasHeader && header.includes("[") && header.includes("]")) { const headerName = header.slice(0, header.indexOf("[")); const value = lineColumns[index]; if (!newData[headerName]) newData[headerName] = []; if (value && value.trim() != "") newData[headerName].push(value); } else { newData[header] = lineColumns[index]; } }); allData.push(newData); }); return { "title": title, "header": headerLine, "data": allData }; }; export { exportToCSV, importFromCSV, simpleExportToCSV };