mirror of
https://github.com/VickScarlet/lifeRestart.git
synced 2025-07-16 09:03:55 +08:00
update xlsxTransform
This commit is contained in:
@@ -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 |
|
||||
|
Reference in New Issue
Block a user