csv-resolver
Version:
read csv and analyse
133 lines (124 loc) • 3.28 kB
text/typescript
const unit8ArrayToChar = (array: Uint8Array) => {
const len = array.length;
let result = "";
let i = 0;
let char2;
let char3;
while (i < len) {
const c = array[i++];
/* eslint-disable no-bitwise */
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
result += String.fromCharCode(c);
break;
case 12:
case 13:
char2 = array[i++];
result += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
break;
case 14:
char2 = array[i++];
char3 = array[i++];
result += String.fromCharCode(
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
/* eslint-enable */
);
break;
default:
break;
}
}
return result;
};
export default class CSVFormatter {
/**
* _csv csv 内容
*/
private _csv: string = "";
/**
* _wordArray 文件中每一个单词的存储, row[column]
*/
private _wordArray: string[][] = [[]];
/**
* _rowNum 当前行数 - 1
*/
private _rowNum: number = 0;
/**
* _subStr 当前读入子字符
*/
private _subStr: string = "";
constructor() {}
async loadFile(file?: any) {
if (!file) throw new Error("CSVFormatter: file not exist.");
const { value } = await file.stream().getReader().read();
1;
this._csv = unit8ArrayToChar(value);
}
async analyse(
validator: (
label: string,
value: string,
position: { row: number; column: number }
) => Promise<string>
): Promise<{ [key: string]: string }[]> {
let result: { [key: string]: string }[] = [];
// 去除空格, 并根据换行符和逗号分隔字符串
for (const str of this._csv) {
if (str === "\n") {
this._wordArray[this._rowNum].push(this._subStr);
this._subStr = "";
this._wordArray.push([]);
this._rowNum += 1;
continue;
} else {
switch (str.trim()) {
case ",":
this._wordArray[this._rowNum].push(this._subStr);
this._subStr = "";
break;
case "":
break;
default:
this._subStr += str;
break;
}
}
}
// 最后一段数据有可能没有换行符
if (this._subStr) {
this._wordArray[this._rowNum].push(this._subStr);
this._subStr = "";
}
if (this._wordArray[this._rowNum].length === 0) {
this._wordArray.pop();
}
for (let i = 1; i < this._wordArray.length; i++) {
const row = this._wordArray[i];
result.push({});
for (let index = 0; index < row.length; index++) {
const key = this._wordArray[0][index].trim();
const validateRes = await validator(key, row[index], {
row: i + 1,
column: index + 1,
});
if (validateRes) {
// 如果字符串不为空, 有错误信息, 抛出
return Promise.reject(new Error(validateRes));
}
result[i - 1][key] = row[index];
}
}
// 对内容做判断
if (result.length === 0) {
return Promise.reject(new Error("文件为空"));
}
return Promise.resolve(result);
}
}