excel-json-cli1
Version:
用于把表格数据导成json数据,可支持json、ts和js,或者,用于把json数据导成表格数据,可支持json、ts和js。
164 lines (160 loc) • 5.7 kB
text/typescript
import xlsx, { WorkSheet } from 'node-xlsx';
import * as fs from 'fs-extra';
import { OptionValues } from 'commander';
import chalk from 'chalk';
import { isExportType } from '../constants';
const readDirFilesData = (input: string) => {
// 获取输输入路径及文件类型
const [path, fileOrSuffix] = input.split('**');
const [filename, suffix] = fileOrSuffix.split('.');
console.log('数据读取中,请稍后...');
// 读取文件夹文件列表
const files = fs.readdirSync(path || './').filter((item: string) => {
if (filename) {
const d = fs.statSync(path + item)
return d.isDirectory();
}
return item.endsWith(suffix);
})
let data:any = {};
// 将文件数据转成json数据
files.forEach(async (file: string) => {
const checkFile = fs.existsSync(filename ? path + file + fileOrSuffix : path + file);
if (checkFile) {
let fileData = fs.readFileSync(filename ? path + file + fileOrSuffix : path + file, { flag: 'r', encoding: 'utf-8' });
fileData = fileData.replace(/\;/g, '');
try {
const fns = file.split('.');
data[fns.splice(0, fns.length - 1).join('.') || file] = isExportType.includes(suffix) ? eval('(' + fileData.split('export default ')[1] + ')') : JSON.parse(fileData);
} catch (error) {
console.error(chalk.red(file, '该文件不是json,无法导出'))
}
}
});
return data;
}
const multilevelObjectDeconstruct = (
fileData: WorkSheet<string>[],
data: { [x: string]: any; },
datakeys: string[],
pKey: string,
langi: number
) => {
Object.keys(data).forEach(item => {
if (typeof data[item] === 'object') {
multilevelObjectDeconstruct(fileData, data[item], datakeys, `${pKey}.${item}`, langi);
return ;
}
const dataIndex = fileData[0].data.findIndex(di => di[0] === `${pKey}.${item}`);
// 初始每行数据,加入对应可以值
if(dataIndex === -1) {
const data = new Array(langi + 1).fill('');
data[0] = `${pKey}.${item}`;
fileData[0].data.push(data);
};
const di = dataIndex !== -1 ? dataIndex : (fileData[0].data?.length - 1);
// 补充缺少数据
if (langi + 1 > fileData[0].data[di].length) {
const notDataNum = langi + 1 - fileData[0].data[di].length;
const data = new Array(notDataNum).fill('');
fileData[0].data[di] = fileData[0].data[di].concat(data);
}
// 设置对应key的数据值
fileData[0].data[di].push(data[item]);
});
}
const writeFileToExcel = (data: { [x: string]: { [x: string]: any; }; }, {
output,
isMoToSo
}: {
output: string;
isMoToSo: boolean
}) => {
// 表格初始数据
const fileData: WorkSheet<string>[] = [{
name: 'all data',
data: [],
options: {}
}];
// 表格首行数据
let firstRow = ['key'];
// 记入第一个文件的数据key
let datakeys = Object.keys(data[Object.keys(data)[0]]);
Object.keys(data).forEach((key, i) => {
// 设置表格首行数据
firstRow.push(key);
// 合并补充第一个文件不存在的key
datakeys = datakeys.concat(Object.keys(data[key]).filter(
dk => !datakeys.includes(dk) && ((typeof data[key][dk] !== 'object' && isMoToSo) || !isMoToSo)
));
Object.keys(data[key]).forEach(item => {
if (typeof data[key][item] === 'object') {
// 对象数据处理
if (isMoToSo) {
multilevelObjectDeconstruct(fileData, data[key][item], datakeys, item, i);
} else {
data[key][item] = JSON.stringify(data[key][item]);
}
return ;
}
const dataIndex = fileData[0].data.findIndex(di => di[0] === item);
// 初始每行数据,加入对应可以值
if(dataIndex === -1) {
const data = new Array(i + 1).fill('');
data[0] = item;
fileData[0].data.push(data);
};
const di = dataIndex !== -1 ? dataIndex : (fileData[0].data?.length - 1);
// 补充缺少数据
if (i + 1 > fileData[0].data[di].length) {
const notDataNum = i + 1 - fileData[0].data[di].length;
const data = new Array(notDataNum).fill('');
fileData[0].data[di] = fileData[0].data[di].concat(data);
}
// 设置对应key的数据值
fileData[0].data[di].push(data[key][item]);
});
});
console.log('文件写入中,请稍后...');
// 合并首行数据
fileData[0].data.unshift(firstRow);
// 将数据转成文件buffer
const buffer = xlsx.build(fileData);
// 查看文件夹是否存在
let paths = output.split('/');
paths = paths.splice(0, paths.length - 1);
const path = paths.join('/') || './';
fs.stat(path, async (_, stats) => {
if (!stats) {
// 不存在创建文件夹
await fs.mkdir(path, {recursive: true}, err => {
if (err) {
console.error(chalk.red(err));
} else {
// 文件写入
fs.writeFile(output, Buffer.from(buffer), (err: any) => {
if (err) {
console.error(chalk.red(err));
}
});
}
});
} else {
// 文件写入
fs.writeFile(output, Buffer.from(buffer), (err: any) => {
if (err) {
console.error(chalk.red(err));
}
});
}
});
}
export function json2excel(options: OptionValues) {
// 读取文件夹数据
const filesData = readDirFilesData(options.input);
// 将数据写入excel文件
writeFileToExcel(filesData, {
output: options.output,
isMoToSo: options.multilevelObjectDeconstruct
});
}