csv-export-import
Version:
This package will help converting data objects to csv and vice versa.
190 lines (187 loc) • 7.04 kB
JavaScript
// 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
};