背景介绍
在做国际化时,运营或者产品往往会给到 Excel 版的多语言包,少则几个,多则十几个,而且经常会频繁的修改语言包的内容。而前端要根据 Excel 文件转成对应的 JSON 或者 JS 文件,手动处理显然是不现实的,一来费时费力,效率低下,二来容易出错,最重要的是不符合程序员的做事风格,机械的事情当然要交给机器去做了。
基础准备
- Node.js 环境
- node-xlsx 依赖包,一个强大的 Excel 文件处理库
- Node.js API
- fs.writeFile
- fs.stat
- fs.mkdir
- util.inspect
测试数据
下面以一个示例文件开始代码编写
这是模拟的多语言 Excel 文件,注意第一列是根据最终语言包的格式自己添加上去的,第一行的表格头中 % 也是自己添加的,主要是用来生成对应的 JS 文件名

这是最终生成的 JS 文件

开始
初始化环境
创建一个文件夹并初始化 Node.js 项目,我这里创建了一个名为excel-to-js的文件夹。
npm init -y

安装 node-xlsx 依赖包
npm install node-xlsx --save
主代码逻辑
新建一个 JS 文件如 app.js,并添加如下代码
const fs = require('fs');
const path = require('path');
const util = require('util');
const xlsx = require('node-xlsx');
const sheets = xlsx.parse('./file/langes.xlsx');
/**
* sheets是一个数组,数组中的每一项对应 langes.xlsx 这个文件里的多个表格
* 如sheets[0]对应 Sheet1 这个表格
* sheets[1]对应 Sheet2 这个表格
*/
const sheet = sheets[0]; // 我们这里只取第一个表
const filePath = './lang' // 多语言生成后会存放在此目录下
let obj = {}
const col = sheet['data'][0] // 表格中的第一行,用来获取多语言名称以生成对应的 js 文件
for (let j = 3; j < col.length; j++) {
// sheet 是一个 json 对象,格式为{name:"Sheet1",data:[]},我们想要的数据就存储在data里
let key = ''
// i 对应 excel 文件里的行,根据自己的表格修改
for (let i = 1; i < sheet["data"].length; i++) {
let row = sheet['data'][i];
if (row && row.length > 0) {
let title = row[0].split('.')
// 获取表格中的一级模块和二级模块
if (title.length > 1) {
key = title[0]
key2 = title[1]
} else {
key2 = title[0]
}
!obj[key] && (obj[key] = {})
obj[key][key2] = row[j]
}
}
const fileName = col[j].split('%')[1]
creatFile(obj, fileName)
}
/**
* 将数据写入文件
* @param {string} 要写入的内容
* @param {string} 要保存的文件名
*/
async function creatFile(con, name) {
const str = 'export default '
// con 中的内容如果不处理的话写入文件后会显示成 [object Object]
const data = util.inspect(con, { showHidden: false, depth: null })
const isExists = await getStat(filePath) // 判断路径是否存在
if (!isExists) {
await mkdir(filePath) // 创建文件目录
}
const file = path.join(filePath, name + '.js')
fs.writeFile(file, str + data, (err) => {
if (err) throw err;
console.log(name + ' 保存成功!');
});
}
/**
* 判断目录是否存在
* @param {string} dir 目录
*/
function getStat(dir) {
return new Promise((resolve, reject) => {
fs.stat(dir, (err, stats) => {
if (err) {
resolve(false)
} else {
resolve(stats)
}
})
})
}
/**
* 创建文件夹
* @param {string} dir 要创建的文件夹路径
*/
function mkdir(dir) {
return new Promise((resolve, reject) => {
fs.mkdir(dir, (err) => {
if (err) {
resolve(false)
} else {
resolve(true)
}
})
})
}
在命令行中执行如下命令
node app.js
查看 lang 文件夹下是否生成对应的文件。
如果手动创建了多语言文件夹的话,上面代码中两个函数 getStat,mkdir可以省略,然后修改 creatFile 函数为如下代码即可:
function creatFile(con, name) {
const str = 'export default '
// con 中的内容如果不处理的话写入文件后会显示成 [object Object]
const data = util.inspect(con, { showHidden: false, depth: null })
// 以下代码删除
// const isExists = await getStat(filePath) // 判断路径是否存在
// if (!isExists) {
// await mkdir(filePath) // 创建文件目录
// }
const file = path.join(filePath, name + '.js')
fs.writeFile(file, str + data, (err) => {
if (err) throw err;
console.log(name + ' 保存成功!');
});
}