多语言管理方案 - Excel导入与导出

8 篇文章 0 订阅
8 篇文章 0 订阅

技术栈:JavaScript + fs + xlsx.js

简介

前篇: Vue-i18n国际化多语言-在线表格翻译
结合本博客之前的国际化多语言的实现与实际业务场景,意识到人工在项目中手动配置、替换多语言花费的人力成本较高,于是衍生出其他的管理方案,解放双手,核心原理就是多语言配置文件与 Excel 文件相互转换、文件读写。

  1. 导出:输入多语言配置数据,输出 Excel文件
  2. 导入: 输入Excel文件,输出多语言配置数据文件
  3. 管理:Excel文件,可采用本地或者云管理。至于在线编辑的功能,就是将Excel文件在在线平台导入导出即可。

因为Vika单词插入记录最多10条,此处就不演示直接与Vika进行多语言管理的实现,代码在博主本地,有需要的可以私。

实现

数据结构

本篇代码适用于双层嵌套的对象多语言配置文本,每个语种为一个文件。

{
	module1: {
		label1: "123",
		label2: "qwe",
	},
	module2: {
		label1: "345",
		label2: "7788",
	},
}

例如法语的配置文件为:
在这里插入图片描述

安装

涉及到 Excel 的解析和文件读写,就分别需要xlsx、fs这两个插件。

npm install xlsx --save
npm install fs --save
# or
yarn add xls
yarn add fs

导出Excel

import XLSX from 'xlsx'
import zh from '../lang/web/zh.js'
import en from '../lang/web/en.js'
import fr from '../lang/web/fr.js'

// 判断数据是否非undefined,因为可能漏配了
const notUndefined = (data) => {
  return !(typeof data === 'undefined')
}

/** 将深层嵌套对象扁平化,对象转数组(以中文为标准,进行补全) */
const objsToExcelData = () => {
  const resArr = []
  const keysWrapper = Object.keys(zh) // 外层label
  keysWrapper.forEach((keyWrap) => {
    if (typeof zh[keyWrap] === 'object') {
      const keysInner = Object.keys(zh[keyWrap]) // 内层label
      typeof zh[keyWrap] === 'object' &&
        keysInner.forEach((keyInn) => {
          const obj = {
            LabelWrapper: keyWrap,
            LabelInner: keyInn,
            zh: zh[keyWrap][keyInn], // 中文
            en: en[keyWrap] && notUndefined(en[keyWrap][keyInn]) ? en[keyWrap][keyInn] : '', // 英文
            fr: fr[keyWrap] && notUndefined(en[keyWrap][keyInn]) ? fr[keyWrap][keyInn] : '' // 法语
          }
          resArr.push(obj)
        })
    }
  })
  console.log(resArr)
  return resArr
}

/** 将数据解析成Excel格式并导出 */
const exportToExcel = (data) => {
  const worksheet = XLSX.utils.json_to_sheet(data) // json数据转Excel表
  const workbook = XLSX.utils.book_new() // 新建Excel文件
  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1') // 将表添加到EXCEL文件
  XLSX.writeFile(workbook, 'exported-data.xlsx') // 导出
}

导入Excel

import * as fs from 'fs'
import XLSX from 'xlsx'

const chartLangLabels = ['zh', 'en', 'fr'] // 表格语言对应的label字段

/** 获取excel数据并解析 */
const getExcelData = (url) => {
  const workBook = XLSX.readFile(url) // 目标文件获取
  let name = workBook.SheetNames[0] // 读取表格中第一个表
  let sheet = workBook.Sheets[name] // 数据获取
  console.log(XLSX.utils.sheet_to_json(sheet)) // 数据格式转换
  return XLSX.utils.sheet_to_json(sheet)
}

/** 处理excel表格的数据 */
const handleExcelData = (data) => {
  // 目标数据结构, 类似于 { zh:{} ,en: {}, fr: {}}
  const resData = {}
  chartLangLabels.forEach((langLabel) => {
    resData[langLabel] = {}
  })
  data.forEach((item) => {
    const labelWrapper = item.LabelWrapper // LabelWrapper 外层label,业务模块
    const labelInner = item.LabelInner // LabelInner 内层label(因为有多个业务模块 所以加了一层嵌套)
    chartLangLabels.forEach((currLang) => {
      if (!resData[currLang][labelWrapper]) resData[currLang][labelWrapper] = {} // 业务模块多语言undefined时,创建{}
      resData[currLang][labelWrapper][labelInner] = item[currLang]
    })
  })
  return resData
}

/** 读写数据 */
const writeData = (targetData) => {
  chartLangLabels.forEach((lang) => {
    let str = `export default {\n    ${outputJSONString(targetData[lang], undefined, 4)}}`
    // 文件写入,文件名与chartLangLabels内保持一致 
    fs.writeFile(`./src/lang/web/${lang}.js`, str, 'utf-8', function (err) {
      if (err) {
        console.log(lang + '写文件操作失败')
        console.log(err)
      } else console.log(lang + '写文件操作成功')
    })
  })
}

应用

导出


const handleData = () => {
  const data = objsToExcelData()
  exportToExcel(data)
}

handleData()

导入

const handleImportData = () => {
  let resData = getExcelData('./src/utils/lang.xlsx') // excel数据路径
  const targetData = handleExcelData(resData) // 得到需要的数据结构
  writeData(targetData) // 文件读写
}

handleImportData()

效果

导出的Excel文件结果
导出的多语言Excel文件结果
按照导出规则写入的js文件结果
导入的多语言js文件结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值