lang.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. const ExcelJS = require('exceljs');
  2. const fs = require('fs');
  3. const path = require('path');
  4. // example: npm run genrate:lang public/lang.xlsx(读取excel文件的路径) src/lang(输出文件路径)
  5. function resolve(dir) {
  6. return path.resolve(__dirname, '..', dir);
  7. }
  8. const rawArgv = process.argv.slice(2);
  9. let excelFilePath;
  10. let jsonFilePath;
  11. if (rawArgv.length === 0) {
  12. console.log('请输入Excel文件路径');
  13. process.exit(1);
  14. }
  15. if (rawArgv.length === 1) {
  16. console.log('请输入语言包导出的文件路径');
  17. process.exit(1);
  18. }
  19. // 文件路径
  20. excelFilePath = resolve(rawArgv[0]);
  21. jsonFilePath = resolve(rawArgv[1]);
  22. const langFileNameEnum = {
  23. 简体中文: 'zh-CN',
  24. English: 'en-US',
  25. };
  26. const keyIndex = 1; // 键值所在列
  27. const headerRowIndex = 1; // 标题行所在行索引
  28. // 创建一个新的工作簿实例
  29. const workbook = new ExcelJS.Workbook();
  30. // 读取Excel文件
  31. workbook.xlsx
  32. .readFile(excelFilePath)
  33. .then(async () => {
  34. // 生成json映射文件,new Map(){sheetName:{ lang:jsonData}}
  35. const dataMap = getJsonDataMap(workbook)
  36. // 生成json文件
  37. await generateJsonFiles(dataMap)
  38. })
  39. .catch((error) => {
  40. console.error('Error reading Excel file:', error);
  41. });
  42. /**
  43. * 从工作簿中获取JSON数据映射表
  44. * @param {object} workbook - Excel工作簿对象,用于遍历工作表和工作表数据
  45. * @returns {Map} dataMap - 包含工作表名称和对应数据对象的映射表,其中数据对象是语言文件名枚举和其键值对的映射
  46. */
  47. function getJsonDataMap(workbook) {
  48. const dataMap = new Map();
  49. workbook.eachSheet(function (worksheet) {
  50. // 初始化工作表名和文件对象
  51. const sheetName = worksheet._name;
  52. const fileObjects = {};
  53. const cellIndexMap = {};
  54. // 遍历每一行,首先处理表头,然后处理数据行
  55. worksheet.eachRow((row, rowNumber) => {
  56. if (rowNumber === headerRowIndex) {
  57. // 处理表头,建立语言文件名和列索引的映射
  58. row.eachCell((cell, colNumber) => {
  59. if (colNumber !== keyIndex) {
  60. fileObjects[langFileNameEnum[cell.value]] = {};
  61. cellIndexMap[colNumber] = langFileNameEnum[cell.value];
  62. }
  63. });
  64. } else {
  65. // 处理数据行,根据列索引映射填充语言文件的数据键值对
  66. Object.keys(cellIndexMap)
  67. .map((item) => Number(item))
  68. .map((colNumber) => {
  69. const key = row.getCell(keyIndex).value;
  70. const value = row.getCell(colNumber).value || '';
  71. const lang = cellIndexMap[colNumber];
  72. fileObjects[lang][key] = value;
  73. });
  74. }
  75. });
  76. // 将工作表数据对象映射到工作表名称
  77. dataMap.set(sheetName, fileObjects);
  78. });
  79. return dataMap;
  80. }
  81. // 导出语言包文件到指定目录
  82. async function generateJsonFiles(dataMap) {
  83. // 清空文件输出目录
  84. const exist = fs.existsSync(jsonFilePath)
  85. exist && await fs.rmSync(jsonFilePath, { recursive: true }, () => { })
  86. // 逐个生成目录和文件
  87. for (const [modules, objs] of dataMap.entries()) {
  88. for (const [lang, jsonData] of Object.entries(objs)) {
  89. const path = resolve(jsonFilePath + `/${lang}/${modules}.json`);
  90. await writeJsonToFile(jsonData, path);
  91. }
  92. }
  93. console.log('Excel file has been converted to JSON and saved to', jsonFilePath);
  94. }
  95. // 异步创建文件夹并写入JSON数据
  96. async function writeJsonToFile(jsonData, filePath) {
  97. const dirPath = path.dirname(filePath); // 获取文件路径的目录部分
  98. try {
  99. await fs.mkdirSync(dirPath, { recursive: true }, () => { }); // 如果目录不存在,会递归创建
  100. await fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2), 'utf8', () => { }); // 异步写入JSON数据
  101. console.log(`JSON data written to ${filePath}`);
  102. } catch (err) {
  103. console.error(`Error writing JSON data to ${filePath}:`, err);
  104. }
  105. }