一、需求背景
在开发项目时,经常会遇到国际化的需求,有时还会遇到切换主题的需求,这个时候就会先定义一个国际化表格和颜色字段表格等,这个时候就觉得一个一个的添加太过于麻烦,于是就想到了去解析excel表格,根据得到的数据创建json文件,进行压缩下载。
二、实现步骤
1. 安装xlsx
2. xlsx解析excel表格
3. 安装jszip和file-saver,创建文件并下载
三、代码分享
表格格式:
html部分:
<div>
<input type="file" ref="languageInput" @change="change" />
</div>
js部分:
import { read, utils } from "xlsx"
import JSZip from "jszip";
import { saveAs } from "file-saver";
import { ref } from "vue"
const languageInput = ref(null)
const reg = /[\(\(](\w{1,})[\)\)]/
// 定义表格中标题的列表
let keyList = []
// 英语
const en = {}
// 中文
const zh = {}
const change = () => {
const file = languageInput.value!["files"][0]
const fileReader = new FileReader()
fileReader.onload = e => {
const data = e.target!.result
const workbook = read(data, {
type: 'binary',
cellDates: true
})
// 获取所有的工作表名
const sheetList = workbook.SheetNames
// sheet_to_json 把表格解析成json格式
// range 从第几行开始解析
const dataList = utils.sheet_to_json(workbooks.Sheets[sheetList[0]], {range: 1})
keyList = Object.keys(dataList[0])
// 表格中有单元格上下合并的处理,左右合并也可以模仿改方式
// 上下合并后,解析到第一行时,会获取到正常的数据,后面的数据就会缺少合并单元格的字段
// 定义一个有合并的列的标题key
let key = ''
for (let i = 1; i < dataList.length; i++) {
// 如果单元格没有合并,就把数据赋值给key
// 如果单元格被合并了,就使用key
// 我这里的表格是第一列有合并的,所以我只操作了第一列的数据
key = dataList[i][keyList[0]] ? dataList[i][keyList[0]] : key
add(key, dataList[i])
}
// console.log('en', en)
// console.log('\n')
// console.log('zh', zh)
createAndDownloadFile()
languageInput.value.value = null
}
fileReader.readAsBinaryString(file)
}
const add = (key, item) => {
if (!item[keyList[2]]) {
console.log(new Error(`${key}的二级中有一个key为${item[keyList[2]]}`))
}
try {
// 匹配一级的key
key = reg.exec(key)[1]
} catch (error) {
console.log(new Error(`${key}`))
}
en[key] = en[key] ? en[key] : {}
zh[key] = zh[key] ? zh[key] : {}
en[key][item[keyList[2]]] = item[keyList[4]]
zh[key][item[keyList[2]]] = item[keyList[3]]
}
// 创建json文件并下载
const createAndDownloadFile = async () => {
const zip = new JSZip();
zip.file("en.json", JSON.stringify(en));
zip.file("zh.json", JSON.stringify(zh));
zip.generateAsync({ type: "blob" }).then((content) => {
// 下载文件
saveAs(content, "locales.zip");
});
};