#json #angular #typescript #csv
Вопрос:
В интерфейсе моего приложения я хотел проанализировать некоторые данные, связанные с загружаемым ими CSV. С помощью инструмента загрузки файлов я сначала получаю объект списка файлов, а затем извлекаю из него 1 файл.
Я хочу превратить его в объект json, который я мог бы затем повторить. Я думал использовать csv-анализатор пользователя из узла, но я не вижу способа использовать файловый объект, хранящийся в памяти.
Как я могу этого добиться?
Сначала я занимался:
let f = fileList.item(0);
let decoder = new window.TextDecoder('utf-8');
f.arrayBuffer().then( data => {
let _data = decoder.decode(data)
console.log("Dataset", data, _data)
});
И это означало передачу буфера массива и декодирование строки. Хотя я мог бы написать универсальный инструмент, который обрабатывает эти строковые данные на основе n и’, я хотел, чтобы это было немного легче читать.
Я хотел сделать что-то вроде:
let json = csvParser(f)
есть ли способ использовать csv-анализатор пользователя из узла (3.0.0) или есть другой инструмент, который я должен использовать? Я думал, что модули управления на основе браузера ( новое окно.TextDecoder (…)) — плохая форма, так как у него есть возможность потерпеть неудачу.
Есть ли инструмент, который делает это? я пытаюсь создать некоторые примеры данных и, учитывая файл, выбранный из входного типа=»файл», я бы хотел, чтобы это было просто и прямолинейно.
Приведенный ниже пример работает, но я чувствую зависимость от окна, и внутреннее чувство заставляет меня думать, что это наивно.
const f : File = fileList.item(0)
console.log("[FOO] File", f)
let decoder = new window.TextDecoder('utf-8');
f.arrayBuffer().then( data => {
let _data = decoder.decode(data)
console.log("Dataset", data, _data)
let lines = _data.split("n")
let headers = lines[0].split(',')
let results = []
for ( let i = 1; i < lines.length; i ) {
let line = lines[i]
let row = {}
line.split(",").forEach( (item, idx) => {
row[headers[idx]] = item;
})
results.push(row)
}
console.log("JSON ARRAY", results)
})
Проблема, с которой я сталкиваюсь, когда останавливаюсь и делаю: ng serve
заключается в том, что ему не нравится использовать функцию ArrayBuffer и получать доступ к TextDecoder из окна, поскольку эти функции/классы не являются частью файла и окна соответственно во время сборки.
Есть какие-нибудь мысли?
Ответ №1:
Это то, что я в конечном итоге сделал, учитывая ввод файла, передаваемый в эту функцию:
updateTranscoders(project: Project, fileList: FileList, choice: string = 'replace') {
const f: File = fileList.item(0)
//Reads a File into a string.
function readToString(file) : Promise<any> {
const reader = new FileReader();
const future = new Promise( (resolve,reject) => {
reader.addEventListener("load", () => {
resolve(reader.result);
}, false)
reader.addEventListener("error", (event) => {
console.error("ERROR", event)
reject(event)
}, false)
reader.readAsText(file)
});
return future;
}
readToString(f).then( data => {
let lines = data.split("n")
let headers = lines[0].split(',')
let results = []
for (let i = 1; i < lines.length; i ) {
let line = lines[i]
let row = {}
line.split(",").forEach((item, idx) => {
row[headers[idx]] = item;
})
results.push(row)
}
if (choice.toLowerCase() === 'replace'){
let rows = project.csvListContents.toJson().rows.filter( row => row.isDeployed)
rows.push( ...results)
project.csvListContents = CsvDataset.fromJson({ rows: rows })
}else if (choice.toLowerCase() === 'append') {
let r = project.csvListContents.toJson();
r.rows.push(...results);
project.csvListContents = CsvDataset.fromJson(r);
}else {
alert("Invalid option for Choice.")
}
this.saveProject(project)
})
}
Теперь в части ВЫБОРА кода у меня есть двоичный вариант для жесткой замены содержимого CSV или просто добавления к нему. Затем я бы соответственно сохранил проект. Это также означает, что первая строка содержит заголовки столбцов.