当前位置: 首页 > news >正文

NodeJs实现脚本:将xlxs文件输出到json文件中

文章目录

    • 前期工作和依赖
    • 笔记
    • 功能
    • 代码
    • 输出

最近有一个功能,将json文件里的内容抽取到一个xlxs中,然后维护xlxs文件。当要更新json文件时,就更新xlxs的内容并把它传回json中。这个脚本主要使用NodeJS写。

以下是完成此功能时做的一些笔记。

前期工作和依赖

js文件中要使用import,因此需要在package.json中设置:"type": "module"

依赖:

import xlsx from 'xlsx';
import path, { dirname } from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import md5 from 'blueimp-md5';

相关文档:
API 参考 | SheetJS 中文网 (nodejs.cn)
xlsx - npm (npmjs.com)

笔记

获取此文件目录名:

const __dirname = dirname(fileURLToPath(import.meta.url));

组合文件名:

const outPath = path.join(__dirname, './fileName.xlsx');

读取一个目录下的所有文件名:

const files = fs.readdirSync(dirName);

读取一个文件:

const enJson = fs.readFileSync(fileName, 'utf8');

将二维数组转换为xlxs工作表:

const sheet = xlsx.utils.aoa_to_sheet(sheetData);

将工作表添加到工作簿:

xlsx.utils.book_append_sheet(workBook, sheet, sheetName);

将工作表输出到xlsx文件中:

xlsx.writeFile(workBook, outPath, { bookType: 'xlsx' });

将数组输出到xlxs:data是数组。

const sheet = xlsx.utils.json_to_sheet(data); //将 JS 对象数组转换为工作表
const workBook= xlsx.utils.book_new();// 创建一个工作簿对象
xlsx.utils.book_append_sheet(workBook, sheet, 'sheetName'); // 将工作表添加到工作簿:
xlsx.writeFile(workBook, path, {bookType: 'xlsx',
}); // 输出到xlsx

功能

维护一个xlsx文档,里面包含国际化的所有翻译,如下:第一行 为 语言

enkojafr
英文翻译韩文翻译日文翻译法文翻译

有英文json翻译文件如下:src/locales/en/fileName1.json

其中key值为i18n的标记,value值为对应的翻译。

{"inviter": "Inviter","worth": "Worth ${{value}}","countDownTips": "Rewards Countdown"
}

默认语言为英语,我们需要以它为例子生成对应的其他语言文件,如生成:src/locales/fr/fileName1.json

{"inviter": "法文翻译1","worth": "法文翻译2","countDownTips": "法文翻译3"
}

所有的翻译都在xlsx中。因此我们需要读取xlsx文件,遍历src/locales/en下的对应文件(参数pageNames),将对应翻译生成到对应文件夹。若无对应翻译,则用英文兜底。

中途使用md5加密后的en翻译为key,将对应xlsx文件中的翻译(那一行)保存到set中,是因为xlsx中没有i18n标记,只有各语言翻译

将xlsx翻译文件输出到locales/[language]/[fileName]的功能封装成一个函数,参数如下:

读入的en文件夹上级为pagePath
参数:
pageNames:要维护的文件名列表,如 invite 对应locale/en/invite
filePath:xlsx文件路径
pagePath:locale文件路径
option:选项,包括
- outputKey:输出为json的某一个key值的value,没有就不填 (这个功能的代码很死板,像是硬编码,需求如此,先写着!)
- languageArray:传入一个数组,包含要求的语言,没有就不填,会默认xlsx里的所有文件

参数填错了就会报错,这个代码的健壮性并不强,只是一个加快工作效率的工具 / 练手代码。 所以建议严格按照参数要求调用函数。不要做那种:“没有outputKey应该不传,但我就传个空串”,可能会报奇怪的错误!

代码

// 入口
import xlsx from "xlsx";
import md5 from "blueimp-md5";
import fs from "node:fs";
import path from "node:path";// 删去前后空格 特判str为undefined
const trim = (str) => (str || "").replace(/^\s+|\s+$/g, "");// 生成一个set,key是en的翻译,value是对应row
function transSheetToMap(sheetData) {const map = new Map();for (const row of sheetData) {const key = md5(trim(row.en));map.set(key, row); // 加密后en的value为key,整个row为value}return map;
}/*
读入的en文件夹上级为pagePathpageNames:要维护的文件名列表,如 invite 对应locale/en/invite 
filePath:xlsx文件路径
pagePath:locale文件路径
option:选项,包括- outputKey:输出为json的某一个key值的value,没有就不填- languageArray:传入一个数组,包含要求的语言缩写,没有就不填,会默认xlsx里的所有文件
*/
function xlsxToJson(pageNames, filePath, pagePath, option) {let outputKey = undefined;if (option.outputKey) {outputKey = option.outputKey;}const workBook = xlsx.readFile(filePath);const firstWorksheet = workBook.SheetNames[0]; // 全都放在第一个sheet中const sheet = workBook.Sheets[firstWorksheet];const sheetData = xlsx.utils.sheet_to_json(sheet); // 数组,每个项是对象,key为语言value为翻译const languages = option.languageArray? option.languageArray: Object.keys(sheetData[0]); // 所有语言const dictions = transSheetToMap(sheetData);for (const pageName of pageNames) {// 英文文件const pageEnJson = JSON.parse(fs.readFileSync(path.join(pagePath, "en", `${pageName}.json`),"utf8"));// key 为 i18n标记const pageEnKeys = outputKey? Object.keys(pageEnJson[outputKey]): Object.keys(pageEnJson);for (const language of languages) {// 深拷贝英文样本const translatedJson = JSON.parse(JSON.stringify(pageEnJson));// translatedJson生成为对应语言,en兜底for (const key of pageEnKeys) {const translatedKey = outputKey? md5(trim(pageEnJson[outputKey][key])): md5(trim(pageEnJson[key]));const translation = dictions.get(translatedKey);if (outputKey) {translatedJson[outputKey][key] =translation[language] || translation["en"];} else {translatedJson[key] =translation[language] || translation["en"];}}const filePath = path.join(pagePath, language, `${pageName}.json`);// 若文件夹不存在则创建if (!fs.existsSync(path.join(pagePath, language))) {fs.mkdirSync(path.join(pagePath, language));}fs.writeFileSync(filePath, JSON.stringify(translatedJson, null, 4));}}
}export default xlsxToJson;
xlsxToJson(["invite", "player"],"C:/Users/somePath/i18n-all.xlsx","C:/Users/somePath/locales",{outputKey: "key",languageArray: ["de"],}
);

输出

调用:要翻译的文件为invite,输出到json文件的key属性中,只翻译到de德文。

xlsxToJson(["invite"],"C:/Users/somePath/i18n-all.xlsx","C:/Users/somePath/locales",{outputKey: "key",languageArray: ["de"],}
);

对应英文json如下:(有outputKey一定要填!没有的话一定不填!不然输出会很奇怪。)

// locales/en/invite.json
{"key": {"ogDesc": "Download Now!","inviter": "Inviter"}
}

结果输出locales/de/invite.json

在这里插入图片描述

可能会封装一个npm包,可能会维护。笔记先写在这吧!

http://www.lryc.cn/news/367242.html

相关文章:

  • 【启程Golang之旅】网络编程与反射
  • nginx location正则表达式+案例解析
  • 【YOLO系列】YOLOv10论文超详细解读(翻译 +学习笔记)
  • 植物大战僵尸杂交版2024潜艇伟伟迷
  • 白话解读网络爬虫
  • 支持向量机(SVM): 从理论到实践的指南(1)
  • 万字长文|OpenAI模型规范(全文)
  • 微服务架构-正向治理与治理效果
  • normalizing flows vs 直方图规定化
  • vite打包优化常用的技巧及思路
  • k8s学习--kubernetes服务自动伸缩之水平收缩(pod副本收缩)HPA详细解释与案例应用
  • 台式机ubuntu22.04安装nvidia驱动
  • C++ 11 【线程库】【包装器】
  • 可视化数据科学平台在信贷领域应用系列四:决策树策略挖掘
  • 数据查询深分页优化方案
  • Redis的主从复制
  • 网络安全实战基础——实战工具与攻防环境介绍
  • vue2组件封装实战系列之tag组件
  • VBA实战(Excel)(4):实用功能整理
  • nginx mirror流量镜像详细介绍以及实战示例
  • Android14 WMS-窗口添加流程(二)-Server端
  • 【传知代码】DETR[端到端目标检测](论文复现)
  • Edge浏览器十大常见问题,一次性解决!
  • lubuntu / ubuntu 配置静态ip
  • 15、matlab绘图汇总(图例、标题、坐标轴、线条格式、颜色和散点格式设置)
  • 调试环境搭建(Redis 6.X 版本)
  • postgres数据库报错无法写入文件 “base/pgsql_tmp/pgsql_tmp215574.97“: 设备上没有空间
  • 力扣2762. 不间断子数组
  • OpenCV学习(4.8) 图像金字塔
  • 【TB作品】msp430f5529单片机,dht22,温湿度传感器,OLED显示屏