代码
const { promisify } = require('util');
const fs = require('fs');
const path = require('path');
const JSZip = require('jszip');
const xml2js = require('xml-js');
const config = require('../config.json');
class ToolMainOne {
constructor(xmlDir, outputDir) {
this.XML_DIR = xmlDir;
this.OUTPUT_DIR = outputDir;
this.fs = fs;
this.path = path;
this.JSZip = JSZip;
this.interfaceString
}
// 解析xml转化为json
async parseXmlToJson(xmlFilePath) {
const readFile = promisify(this.fs.readFile);
const writeFile = promisify(this.fs.writeFile);
const xmlData = await readFile(xmlFilePath, { encoding: 'utf-8' });
var res = xml2js.xml2js(xmlData, { compact: true, spaces: 0, ignoreComment: true, ignoreDeclaration: true, instructionHasAttributes: false });
var fileName = this.path.basename(xmlFilePath, this.path.extname(xmlFilePath));
var res2 = {};
var defobj = res["def"];
if (defobj) {
var unitArr = defobj["unit"];
if (!unitArr.length || unitArr.length == 0) {
unitArr = [unitArr];
defobj["unit"] = unitArr;
}
res2[fileName] = unitArr;
} else {
res2[fileName] = res;
}
var noAttArr = [];
var unitObj = {};
var unit_child_obj = { "_attributes": {} };
var res3 = res2[fileName] || [];
for (var i = 0; i < res3.length; i++) {
var element = res3[i];
var ao = element["_attributes"];
noAttArr.push(ao);
// unitObj = ao;
for (var key in ao) {
if (key == "_attributes") {
continue;
}
if (unitObj[key] == undefined) {
unitObj[key] = ao[key];
}
}
if (element.child && !element.child.length) {
element.child = [element.child];
// console.log(`单数组·······························`);
// console.log(element);
}
var child = element.child;
if (child && child.length > 0) {
// unit_child_obj = child[0];
ao.child = [];
child.map((c) => {
ao.child.push(c["_attributes"]);
for (var key in c["_attributes"]) {
if (unit_child_obj["_attributes"][key] == undefined) {
unit_child_obj["_attributes"][key] = c["_attributes"][key];
console.log(key + "*********************")
}
}
})
}
}
if (!res3.length) {
var element = res3;
var ao = element["_attributes"];
noAttArr.push(ao);
// unitObj = ao;
for (var key in ao) {
if (key == "_attributes") {
continue;
}
if (unitObj[key] == undefined) {
unitObj[key] = ao[key];
console.log(key + " !res3.length ")
}
}
var child = element.child;
if (child && child.length > 0) {
// unit_child_obj = child[0];
child.map((c) => {
for (var key in c["_attributes"]) {
if (unit_child_obj["_attributes"][key] == undefined) {
unit_child_obj["_attributes"][key] = c["_attributes"][key];
console.log(key + " !res3.length*********************")
}
}
})
}
}
if (unitObj) {
var iname = `T_${fileName}_Unit`;
var atts = "";
for (var key in unitObj) {
if (key == "child") {
continue;
}
atts += `\t${key}?:any;\r\n`
}
if (unit_child_obj) {
atts += `\tchild?:T_${fileName}_child[];\r\n`
}
var interStr = `//${fileName}.xml 表中unit条目的结构定义 \r\ninterface ${iname} {\r\n${atts}}\r\n`;
this.interfaceString += interStr;
}
if (unit_child_obj) {
var iname2 = `T_${fileName}_child`;
var atts2 = "";
for (var key in unit_child_obj["_attributes"]) {
atts2 += `\t${key}?:any;\r\n`
}
var interStr2 = `//${fileName}.xml 表中child条目的结构定义 \r\ninterface ${iname2} {\r\n${atts2}}\r\n`;
this.interfaceString += interStr2;
// this.interfaceString+=interfaceContents
}
const jsonFileName = this.path.basename(xmlFilePath, this.path.extname(xmlFilePath)) + '.json';
const jsonFilePath = this.path.resolve(this.OUTPUT_DIR, jsonFileName);
try {
await writeFile(jsonFilePath, JSON.stringify(noAttArr), { encoding: 'utf-8' });
} catch (err) {
console.log(err);
}
}
//写入ts文件
async writeTs() {
const writeFile = promisify(this.fs.writeFile);
const jsonFileName = 'interface.ts';
const jsonFilePath = this.path.resolve(this.OUTPUT_DIR, jsonFileName);
await writeFile(jsonFilePath, JSON.parse(JSON.stringify(this.interfaceString)), { encoding: 'utf-8' });
}
// 判断文件路径
async convertAllXmlToJson(xmlDirPath) {
const readdir = promisify(this.fs.readdir);
const stat = promisify(this.fs.stat);
// const fileStatAll=stat(xmlDirPath)
// if(fileStatAll.isDirectory()){
const files = await readdir(xmlDirPath);
for (const file of files) {
const filePath = this.path.resolve(xmlDirPath, file);
const fileStat = await stat(filePath);
if (fileStat.isDirectory()) {
await this.convertAllXmlToJson(filePath);
} else if (fileStat.isFile() && this.path.extname(file) === '.xml') {
await this.parseXmlToJson(filePath);
}
}
}
// 清空文件夹
async clearOutputDir(outputDirPath) {
const readdir = promisify(this.fs.readdir);
const unlink = promisify(this.fs.unlink);
const files = await readdir(outputDirPath);
for (const file of files) {
const filePath = this.path.resolve(outputDirPath, file);
await unlink(filePath);
}
}
// 打包
async packJsonFilesToZip(outputDirPath) {
const readdir = promisify(this.fs.readdir);
const stat = promisify(this.fs.stat);
const zip = new this.JSZip();
const jsonFiles = await readdir(this.OUTPUT_DIR);
for (const jsonFile of jsonFiles) {
const jsonFilePath = this.path.resolve(this.OUTPUT_DIR, jsonFile);
const jsonFileStat = await stat(jsonFilePath);
if (jsonFileStat.isFile() && this.path.extname(jsonFile) === '.json') {
const jsonData = await promisify(this.fs.readFile)(jsonFilePath, { encoding: 'utf-8' });
zip.file(jsonFile, jsonData);
}
}
const zipData = await zip.generateAsync({ type: 'nodebuffer' });
const zipFilePath = this.path.resolve(outputDirPath, 'output.zip');
await promisify(this.fs.writeFile)(zipFilePath, zipData);
}
async processXmlFiles() {
try {
if (!this.fs.existsSync(this.OUTPUT_DIR)) {
this.fs.mkdirSync(this.OUTPUT_DIR);
}
await this.clearOutputDir(this.OUTPUT_DIR);
await this.convertAllXmlToJson(this.XML_DIR);
await this.packJsonFilesToZip(this.OUTPUT_DIR);
try {
await this.writeTs()
} catch (error) {
console.log(error);
}
} catch (err) {
console.log('出错', err);
}
}
}
const xmlDir = config.xlsx.xmlPath;
const outputDir = config.xlsx.exportPath;
const tool = new ToolMainOne(xmlDir, outputDir);
tool.processXmlFiles();