update xlsxTransform

This commit is contained in:
Vick Scarlet
2021-09-09 13:24:40 +08:00
parent 3a9149e9a4
commit 44e05a166e
7 changed files with 448 additions and 629 deletions

BIN
data/specialthanks-afd.xlsx Normal file

Binary file not shown.

BIN
data/specialthanks-dun.xlsx Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -25,7 +25,6 @@ class App{
json('specialthanks')
]);
this.#specialthanks = specialthanks;
console.table(specialthanks);
this.switch('index');
window.onerror = (event, source, lineno, colno, error) => {
this.hint(`[ERROR] at (${source}:${lineno}:${colno})\n\n${error?.stack||error||'unknow Error'}`, 'error');
@@ -482,8 +481,7 @@ class App{
specialThanksPage.find('#spthx > ul.g2'),
];
groups.forEach(g=>g.empty());
Object
.values(this.#specialthanks)
this.#specialthanks
.sort(()=>0.5-Math.random())
.forEach(({group, name, comment, color})=>groups[--group].append(`
<li>
@@ -576,8 +574,6 @@ class App{
const { judge, grade } = summary(type, value);
return { judge, grade, value };
};
console.table(records);
console.debug(records);
judge.append([
(()=>{

View File

@@ -6,63 +6,154 @@ import { join, extname, dirname } from 'path';
// const XLSX = require('xlsx');
// const { join, extname, dirname } = require('path');
async function transform(filePath) {
const xlsxFileBuffer = await readFile(filePath);
async function read(xlsxPath) {
const xlsxFileBuffer = await readFile(xlsxPath);
const xlsx = XLSX.read(xlsxFileBuffer, {type: 'buffer'});
const sheets = xlsx.Sheets;
const data = {};
for(const sheetName in sheets) {
const sheetRawData = sheets[sheetName];
if(!sheetRawData['!ref']) break;
const rawData = XLSX.utils.sheet_to_json(sheetRawData);
const newData = {};
data[sheetName] = newData;
rawData.shift();
for(const index in rawData) {
const row = rawData[index];
const rowData = {};
let mainKey;
for(let key in row) {
const cell = row[key];
if(key[0] == "$") {
key = key.substr(1);
mainKey = cell;
}
if(key.includes(':')) {
const keys = key.split(':');
const lastKey = keys.pop();
let temp = rowData;
for(const subKey of keys) {
if(!temp[subKey]) temp[subKey] = {};
temp = temp[subKey];
}
if(lastKey.includes('[]')) {
const aKey = lastKey.split('[]')[0];
if(!temp[aKey]) temp[aKey] = [cell];
else temp[aKey].push(cell);
} else {
temp[lastKey] = cell;
}
} else if(key.includes('[]')) {
const aKey = key.split('[]')[0];
if(!rowData[aKey]) rowData[aKey] = [cell];
else rowData[aKey].push(cell);
} else {
rowData[key] = cell;
}
}
if(mainKey===undefined) {
console.warn('[WARN][No Main Key]', filePath, sheetName, parseInt(index), rowData);
continue;
}
if(newData[mainKey]) console.warn('[WARN][Duplicate Key]', mainKey, filePath, sheetName, parseInt(index), '\n\t', JSON.stringify(newData[mainKey]), '\n\t', JSON.stringify(rowData));
newData[mainKey] = rowData;
}
data[sheetName] = XLSX.utils.sheet_to_json(sheetRawData);
}
return data;
}
async function write(sheets) {
for(const sheetName in sheets) {
const { dirname, data, source } = sheets[sheetName];
const savePath = join(dirname, `${sheetName}.json`);
console.info('[Transform] XLSX(', source.map(([p, s])=>`${p}:${s}`).join('\n\t\t '), `) \n\t -> JSON( ${savePath} )`);
await writeFile(
savePath,
JSON.stringify(data, null, 4),
)
}
}
function format(rawSheet, isArray) {
const newSheet = isArray?[]:{};
rawSheet.shift();
for(const index in rawSheet) {
const row = rawSheet[index];
const rowData = {};
let mainKey;
for(let key in row) {
const cell = row[key];
if(key[0] == "$") {
key = key.substr(1);
mainKey = cell;
}
if(key.includes(':')) {
const keys = key.split(':');
const lastKey = keys.pop();
let temp = rowData;
for(const subKey of keys) {
if(!temp[subKey]) temp[subKey] = {};
temp = temp[subKey];
}
if(lastKey.includes('[]')) {
const aKey = lastKey.split('[]')[0];
if(!temp[aKey]) temp[aKey] = [cell];
else temp[aKey].push(cell);
} else {
temp[lastKey] = cell;
}
} else if(key.includes('[]')) {
const aKey = key.split('[]')[0];
if(!rowData[aKey]) rowData[aKey] = [cell];
else rowData[aKey].push(cell);
} else {
rowData[key] = cell;
}
}
if(isArray) {
newSheet.push(rowData);
continue;
}
if(mainKey===undefined) {
console.warn('[WARN][No Main Key]', filePath, sheetName, parseInt(index), rowData);
continue;
}
if(newSheet[mainKey]) console.warn('[WARN][Duplicate Key]', mainKey, filePath, sheetName, parseInt(index), '\n\t', JSON.stringify(newSheet[mainKey]), '\n\t', JSON.stringify(rowData));
newSheet[mainKey] = rowData;
}
return newSheet;
}
function merge(original, rawData, isMerge, isArray, xlsxPath, rawSheetName) {
if(!original)
return {
isMerge,
isArray,
source: [[xlsxPath, rawSheetName]],
data: format(rawData, isArray)
};
if(!isMerge) {
if(original) {
console.warn(`[WARN][Sheet Duplicate] ${xlsxPath}:${rawSheetName}\n\t\t${original.source[0][0]}:${original.source[0][1]}`)
return original;
}
}
if(!original.isMerge) {
console.warn(`[WARN][Sheet Duplicate] ${xlsxPath}:${rawSheetName}\n\t\t${original.source[0][0]}:${original.source[0][1]}`)
return original;
}
if(original.isArray != isArray) {
console.warn(`[WARN][Sheet Format not pair] ${xlsxPath}:${rawSheetName}\n\t\t${original.source[0][0]}:${original.source[0][1]}`)
return original;
}
const formatData = format(rawData, isArray);
original.source.push([xlsxPath, rawSheetName]);
if(isArray) {
original.data = original.data.concat(formatData)
} else {
for(const key in formatData) {
if(original.data[key]) {
console.warn(`[WARN][Duplicate key] ${key} ${xlsxPath}:${rawSheetName} ${JSON.stringify(formatData[key])}\n\t\t${original.source[0][0]}:${original.source[0][1]} ${JSON.stringify(original.data[key])}`);
continue;
}
original.data[key] = formatData[key];
}
}
return original;
}
function transform(rawSheets) {
const sheets = {};
for(const xlsxPath in rawSheets) {
const {dirname: d, data: rawSheetsData} = rawSheets[xlsxPath];
for(const rawSheetName in rawSheetsData) {
const rawData = rawSheetsData[rawSheetName];
if(rawSheetName[0] === "#") continue;
let sheetName = rawSheetName;
const isArray = rawSheetName.substr(-5) === "<arr>";
if(isArray) sheetName = sheetName.substring(0, sheetName.length - 5);
const isMerge = rawSheetName[0] === ">";
if(isMerge) sheetName = sheetName.substr(1);
sheets[sheetName] = merge(
sheets[sheetName],
rawData,
isMerge,
isArray,
xlsxPath,
rawSheetName
);
sheets[sheetName].dirname = d;
}
}
return sheets;
}
async function walk(filePath) {
const xlsxPaths = [];
if(Array.isArray(filePath)) {
@@ -87,18 +178,18 @@ async function main() {
const filePaths = process.argv.slice(2);
if(filePaths.length<0) process.exit(0);
const xlsxs = await walk(filePaths);
const sheets = {};
for(const p of xlsxs) {
const data = await transform(p);
const data = await read(p);
const d = dirname(p);
for(const sheetName in data) {
const savePath = join(d, `${sheetName}.json`);
console.info(`[Transform] XLSX(${p}:${sheetName}) -> JSON(${savePath})`);
await writeFile(
savePath,
JSON.stringify(data[sheetName], null, 4),
);
}
sheets[p] = {
dirname: d,
data
};
}
await write(
transform(sheets)
);
console.info(`
------------------------
| Transform Complete |