UNPKG

excel-json-cli1

Version:

用于把表格数据导成json数据,可支持json、ts和js,或者,用于把json数据导成表格数据,可支持json、ts和js。

153 lines (149 loc) 5.99 kB
import xlsx from 'node-xlsx'; import * as fs from 'fs-extra'; import { OptionValues } from 'commander'; import chalk from 'chalk'; import { isExportType, typeToName } from '../constants'; import { format } from 'prettier'; import { prettierConfig } from '../constants/prettierrc'; const stringToObject = (jsonData: any, str: string, value: any) => { const keys = str.split('.'); keys?.reduce((accumulator: any, currentValue: any, currentIndex: number) => { const val = keys.length - 1 === currentIndex ? value : jsonData[currentValue] ?? {}; return accumulator ? accumulator[currentValue] = val : jsonData[currentValue] = val; }, null); } const dataToJson = (data: any[], { rule, key: isKey, notMatchFilename, isSoToMo }: { rule: string; key: boolean; notMatchFilename: boolean; isSoToMo: boolean; }) => { /** * excel读取规制解析,文件名为第一行(小写字母-大写字母 或 整个单元格内容) * rule 0:[4,15]表示第一列为语言key,第五列到第十九列为语言包数据,默认为0:[1,整行数据长度] */ const [key, interval] = rule.split(':'); const intervals = interval ? JSON.parse(interval) : [1]; // 记录文件导成json的数据 let jsonData:any = {}; data.forEach(sheet => { // 记录每个标签页的语言key let fileKeys: any[] = []; sheet.data.forEach((row: any[], rowi: number) => { if (rowi === 0) { // 按第一行生成语言对象key row.splice(intervals[0], intervals[1] ?? row.length).forEach((col, coli) => { if (notMatchFilename) { // 记录语言key fileKeys.push(col); } else { fileKeys.push(String(col).match(/[a-z]+-[A-Z]+/g) ? col.match(/[a-z]+-[A-Z]+/g)[0] : col); } jsonData[fileKeys[coli]] = {}; // 设置语言对象key }); } else { // 将第一行以下的数据生成语言json对象 if (isKey) { const data = row.splice(intervals[0], intervals[1] ?? row.length); fileKeys.forEach((filekey, i) => { if(!(data[i] === '' || data[i] === null || data[i] === undefined)) { console.log(chalk.green(`${sheet.name} | ${filekey} | ${row[key as any]} | ${data[i]}`)); // 打印数据日志 if (isSoToMo && key?.includes('.')) { stringToObject(jsonData[filekey], key, data[i]); } else { jsonData[filekey][row[key as any]] = data[i]; } } }); } else { row.splice(intervals[0], intervals[1] ?? row.length).forEach((col, coli) => { if(!fileKeys[coli] || !row[key as any]) return; // 没有文件key 或 数据key,跳过该列 if (!(col === '' || col === null || col === undefined)) { console.log(chalk.green(`${sheet.name} | ${fileKeys[coli]} | ${row[key as any]} | ${col}`)); // 打印数据日志 if (isSoToMo && row[key as any]?.includes('.')) { stringToObject(jsonData[fileKeys[coli]], row[key as any], col); } else { jsonData[fileKeys[coli]][row[key as any]] = col; // 设置每行数据到对应语言对象 } } }); } } }); }); return jsonData; } const writeFile = (jsonData: { [x: string]: any; }, output: string, add: any) => { // 获取输出路径及文件类型,默认为单前文件夹ts文件 const [path, fileOrSuffix] = output.split('**'); const [filename, suffix] = fileOrSuffix.split('.'); Object.keys(jsonData).forEach(key => { console.log('正在写入文件:', path + key + fileOrSuffix); let old = {}; // 增量获取源文件数据 if(add) { try { const fileData = fs.readFileSync(path + key + fileOrSuffix, { flag: 'r', encoding: 'utf-8' }).replace(/\;/g, ''); old = isExportType.includes(suffix) ? eval('(' + fileData.split('export default ')[1] + ')') : JSON.parse(fileData); } catch (error) { console.error(chalk.red('不存在源文件:', path + key + fileOrSuffix, ',改文件只有单前文档数据')) } } // 格式化json数据 const data = (isExportType.includes(suffix) ? 'export default ' : '') + JSON.stringify({...old, ...jsonData[key]}, undefined, ' '); // 查看文件夹是否存在 fs.stat(path + key, async (_, stats) => { if (!stats && filename) { // 不存在创建文件夹 fs.mkdir(path + key, { recursive: true }, err => { if (err) { console.error(chalk.red(err)); } else { // 文件写入 fs.writeFile( path + key + fileOrSuffix, format(data, { parser: typeToName[suffix] ?? 'typescript', ...prettierConfig }), (err: any) => { if (err) { console.error(chalk.red(err)); } } ); } }); } else { // 文件写入 fs.writeFile( path + key + fileOrSuffix, format(data, { parser: typeToName[suffix] ?? 'typescript', ...prettierConfig }), (err: any) => { if (err) { console.error(chalk.red(err)); } } ); } }); }); } export function excel2json(options: OptionValues) { // 读取文件 const workSheetsFromFile = xlsx.parse(options.input); // 将数组转成json对象 const jsonData = dataToJson(workSheetsFromFile, { rule: options.rule, key: options.key, notMatchFilename: options.notMatchFilename, isSoToMo: options.multilevelObjectDeconstruct }); // 将对象写入文件 writeFile(jsonData, options.output, options.add); }