114 lines
3.9 KiB
JavaScript
114 lines
3.9 KiB
JavaScript
const ExcelJS = require('exceljs');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
// example: npm run genrate:lang public/lang.xlsx(读取excel文件的路径) src/lang(输出文件路径)
|
||
|
||
function resolve(dir) {
|
||
return path.resolve(__dirname, '..', dir);
|
||
}
|
||
const rawArgv = process.argv.slice(2);
|
||
|
||
let excelFilePath;
|
||
let jsonFilePath;
|
||
if (rawArgv.length === 0) {
|
||
console.log('请输入Excel文件路径');
|
||
process.exit(1);
|
||
}
|
||
|
||
if (rawArgv.length === 1) {
|
||
console.log('请输入语言包导出的文件路径');
|
||
process.exit(1);
|
||
}
|
||
|
||
// 文件路径
|
||
excelFilePath = resolve(rawArgv[0]);
|
||
jsonFilePath = resolve(rawArgv[1]);
|
||
const langFileNameEnum = {
|
||
简体中文: 'zh-CN',
|
||
English: 'en-US',
|
||
};
|
||
const keyIndex = 1; // 键值所在列
|
||
const headerRowIndex = 1; // 标题行所在行索引
|
||
|
||
// 创建一个新的工作簿实例
|
||
const workbook = new ExcelJS.Workbook();
|
||
// 读取Excel文件
|
||
workbook.xlsx
|
||
.readFile(excelFilePath)
|
||
.then(async () => {
|
||
// 生成json映射文件,new Map(){sheetName:{ lang:jsonData}}
|
||
const dataMap = getJsonDataMap(workbook)
|
||
// 生成json文件
|
||
await generateJsonFiles(dataMap)
|
||
})
|
||
.catch((error) => {
|
||
console.error('Error reading Excel file:', error);
|
||
});
|
||
|
||
/**
|
||
* 从工作簿中获取JSON数据映射表
|
||
* @param {object} workbook - Excel工作簿对象,用于遍历工作表和工作表数据
|
||
* @returns {Map} dataMap - 包含工作表名称和对应数据对象的映射表,其中数据对象是语言文件名枚举和其键值对的映射
|
||
*/
|
||
function getJsonDataMap(workbook) {
|
||
const dataMap = new Map();
|
||
workbook.eachSheet(function (worksheet) {
|
||
// 初始化工作表名和文件对象
|
||
const sheetName = worksheet._name;
|
||
const fileObjects = {};
|
||
const cellIndexMap = {};
|
||
// 遍历每一行,首先处理表头,然后处理数据行
|
||
worksheet.eachRow((row, rowNumber) => {
|
||
if (rowNumber === headerRowIndex) {
|
||
// 处理表头,建立语言文件名和列索引的映射
|
||
row.eachCell((cell, colNumber) => {
|
||
if (colNumber !== keyIndex) {
|
||
fileObjects[langFileNameEnum[cell.value]] = {};
|
||
cellIndexMap[colNumber] = langFileNameEnum[cell.value];
|
||
}
|
||
});
|
||
} else {
|
||
// 处理数据行,根据列索引映射填充语言文件的数据键值对
|
||
Object.keys(cellIndexMap)
|
||
.map((item) => Number(item))
|
||
.map((colNumber) => {
|
||
const key = row.getCell(keyIndex).value;
|
||
const value = row.getCell(colNumber).value || '';
|
||
const lang = cellIndexMap[colNumber];
|
||
fileObjects[lang][key] = value;
|
||
});
|
||
}
|
||
});
|
||
// 将工作表数据对象映射到工作表名称
|
||
dataMap.set(sheetName, fileObjects);
|
||
});
|
||
return dataMap;
|
||
}
|
||
|
||
// 导出语言包文件到指定目录
|
||
async function generateJsonFiles(dataMap) {
|
||
// 清空文件输出目录
|
||
const exist = fs.existsSync(jsonFilePath)
|
||
exist && await fs.rmSync(jsonFilePath, { recursive: true }, () => { })
|
||
// 逐个生成目录和文件
|
||
for (const [modules, objs] of dataMap.entries()) {
|
||
for (const [lang, jsonData] of Object.entries(objs)) {
|
||
const path = resolve(jsonFilePath + `/${lang}/${modules}.json`);
|
||
await writeJsonToFile(jsonData, path);
|
||
}
|
||
}
|
||
console.log('Excel file has been converted to JSON and saved to', jsonFilePath);
|
||
}
|
||
|
||
// 异步创建文件夹并写入JSON数据
|
||
async function writeJsonToFile(jsonData, filePath) {
|
||
const dirPath = path.dirname(filePath); // 获取文件路径的目录部分
|
||
try {
|
||
await fs.mkdirSync(dirPath, { recursive: true }, () => { }); // 如果目录不存在,会递归创建
|
||
await fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2), 'utf8', () => { }); // 异步写入JSON数据
|
||
console.log(`JSON data written to ${filePath}`);
|
||
} catch (err) {
|
||
console.error(`Error writing JSON data to ${filePath}:`, err);
|
||
}
|
||
}
|