功能:实现json到excel文件的相互转换(支持json多选版)
目的:编码与语言对应,方便大家使用
页面设计:
介绍:
1.选择文件栏目选择想要转换的文件
2.生成路径是转换后文件所在目录
3.小方框勾选与不勾选分别代表exl到json和json到exl两种类型的转换
使用方法:
1.点击选择按钮,选择要解析的文件(json转exl支持多选文件,按ctrl或shift键)
- 同样选择一个生成的路径,点击转换按钮。不选路径则会弹出错误提示。
3.点击exl转json复选框,则会清除之前所选的json文件,切换能够所选的文件类型
4.选好所需转换的文件和和生成路径,点击转换按钮。转换完成后会弹出提示框。
5.找到目录下转换好的文件并打开查看。
(1)单个json转exl,生成文件为json文件的原名字。多选转换名字为JsonToExl。
(2)转换后第一行第一列固定为key,第一行其他列标题对应的各个json文件名字。
(3)多转情况下,有的文件中没有key其对应内容,则填充为Null值。(下图1)
(4)若转换的json文件中包含多层json对象,每层添加标识符“#¥&”(下图3)
6.excel转json也是同理,勾上对钩,选择要转换的excel文件,点击转换。根据exl中的首行标题名,生成的json文件名
原代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qfiledialog.h"
#include <QDebug>
#include <QtWidgets/QMessageBox>
#include <QCoreApplication>
#include <qprogressbar.h>
#include <QProgressDialog.h>
#include <QMetaType>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->progressBar->hide();
ui->version->setText(APP_VERSION);
workThread = new QThread;
ConvertWork = new ConvertThread;
ConvertWork->moveToThread(workThread);
qRegisterMetaType<eConvertType>("eConvertType");//需注册 参数含有枚举类型,否则将无法进入槽函数
connect(ConvertWork, &ConvertThread::Sig_Result, this, &MainWindow::on_Progress);
connect(this, &MainWindow::Sig_SetConvert, ConvertWork, &ConvertThread::setConvert);
}
MainWindow::~MainWindow()
{
workThread->quit();
ConvertWork->deleteLater();
workThread->deleteLater();
delete ui;
}
//转换按钮点击
void MainWindow::on_ConvertButton_clicked()
{
if(ui->FileNameText->toPlainText().isEmpty())
{
QMessageBox *msgBox;
msgBox = new QMessageBox("","请选择转换目标文件",QMessageBox::NoIcon,QMessageBox::Ok | QMessageBox::Default,NULL,0);
msgBox->setWindowFlags(Qt::WindowStaysOnTopHint);
msgBox->show();
return;
}
if(ui->GeneratePathText->toPlainText().isEmpty())
{
QMessageBox *msgBox;
msgBox = new QMessageBox("","请选择生成路径",QMessageBox::NoIcon,QMessageBox::Ok | QMessageBox::Default,NULL,0);
msgBox->setWindowFlags(Qt::WindowStaysOnTopHint);
msgBox->show();
return;
}
if(!workThread->isRunning())
{
workThread->start();
}
if(ui->checkBox->isChecked())
{
emit Sig_SetConvert(emConvert_ExcelToJson, m_SelectFile, m_GeneratePath);
}
else
{
emit Sig_SetConvert(emConvert_JsonToExcel, m_SelectFile, m_GeneratePath);
}
}
//选择生成目录按钮点击
void MainWindow::on_GenerateButton_clicked()
{
//选择文件路径
m_GeneratePath = QFileDialog::getExistingDirectory();
if(!m_GeneratePath.isEmpty())
{
//填入文本框
ui->GeneratePathText->setText(m_GeneratePath);
}
}
//选择解析文件按钮点击
void MainWindow::on_SelectButton_clicked()
{
m_SelectFile.clear();
//选择要解析的文件
if(ui->checkBox->isChecked())
{
//exl文件只做单选
m_SelectFile.append(QFileDialog::getOpenFileName(this, tr("选择转码文件"), "/", "xls (*.xls)"));
}
else
{
m_SelectFile = QFileDialog::getOpenFileNames(this, tr("选择转码文件"), "/", "json (*.json);;txt(*.txt)");
}
ui->FileNameText->clear();
foreach (QString SelectFile, m_SelectFile)
{
//填入文本框
ui->FileNameText->append(SelectFile);
}
}
//复选框响应
void MainWindow::on_checkBox_clicked()
{
if(ui->checkBox->isChecked())
{
if((ui->FileNameText->toPlainText().contains(".json")||ui->FileNameText->toPlainText().contains(".txt")))
ui->FileNameText->clear();
}
else
{
if(ui->FileNameText->toPlainText().contains(".xls"))
ui->FileNameText->clear();
}
}
void MainWindow::on_Progress(eConvertType ConvertType, int nProgress, const QString &strMsg)
{
QString strConvertType = "";
if (emConvert_JsonToExcel == ConvertType)
{
strConvertType = "JsonToExcel";
}
else if (emConvert_ExcelToJson == ConvertType)
{
strConvertType = "ExcelToJson";
}
if(100 == nProgress)
{
ui->progressBar->hide();
QMessageBox *msgBox;
msgBox = new QMessageBox(strConvertType, strMsg, QMessageBox::NoIcon,QMessageBox::Ok|QMessageBox::Default, NULL, 0);
msgBox->setWindowFlags(Qt::WindowStaysOnTopHint);
msgBox->show();
}
else if(0 == nProgress)
{
ui->progressBar->show();
ui->progressBar->setOrientation(Qt::Horizontal); // 水平方向
ui->progressBar->setMinimum(0); // 最小值
ui->progressBar->setMaximum(0); // 最大值
}
else
{
ui->progressBar->hide();
QMessageBox *msgBox;
msgBox = new QMessageBox(strConvertType, strMsg, QMessageBox::NoIcon,QMessageBox::Ok|QMessageBox::Default, NULL, 0);
msgBox->setWindowFlags(Qt::WindowStaysOnTopHint);
msgBox->show();
}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include "convertThread.h"
namespace Ui {
class MainWindow;
}
/**主页面**/
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_ConvertButton_clicked();//生成
void on_SelectButton_clicked();//选择解析文件
void on_GenerateButton_clicked();//选择生成路径
void on_checkBox_clicked();//复选框
void on_Progress(eConvertType ConvertType, int nProgress, const QString &strMsg);//进度条信号槽
private:
Ui::MainWindow *ui;
QStringList m_SelectFile;//选择解析文件
QString m_GeneratePath;//选择生成路径
QThread *workThread;
ConvertThread *ConvertWork;
signals:
void Sig_SetConvert(eConvertType ConvertType, const QStringList SelectFile, const QString GeneratePath);
};
#endif // MAINWINDOW_H
#include "convertThread.h"
#include "qfiledialog.h"
#include <QDebug>
#include <QJsonParseError>
#include <ActiveQt/QAxObject>
#include <qjsonobject.h>
#include <qjsonarray.h>
#include <QDateTime>
ConvertThread::ConvertThread()
{
m_eConvertType = emConvert_JsonToExcel;
m_SelectFileList.clear();
m_GeneratePath = "";
m_Identifier = "#$&";
m_BlankGrid = "";
m_GenerateFileList.clear();
m_NodeDataList.clear();
}
ConvertThread::~ConvertThread()
{
}
void ConvertThread::setConvert(eConvertType ConvertType, const QStringList SelectFile, const QString GeneratePath)
{
QMutexLocker locker(&lock);
m_eConvertType = ConvertType;
m_SelectFileList = SelectFile;
m_GeneratePath = GeneratePath;
m_NodeDataList.clear(); //清空
m_GenerateFileList.clear();
emit Sig_Result(m_eConvertType, 0, "start");
if(m_eConvertType == emConvert_JsonToExcel)
{
int FileOrder = 0;
foreach (QString SelectFile, m_SelectFileList)
{
//JSON转EXL
if(analysisJson(SelectFile, FileOrder)==true)
{
for(stNodeData &NodeData : m_NodeDataList)
{
while(NodeData.m_value.size() <= FileOrder)
{
NodeData.m_value.append(m_BlankGrid);
}
}
FileOrder++;
}
else
{
return;
}
}
addToExcel();
}
else if(m_eConvertType == emConvert_ExcelToJson)
{
foreach (QString SelectFile, m_SelectFileList)
{
//EXL转JSON
bool result=analysisExcel(SelectFile);
if(!result)
{
return;
}
}
addToJson();
}
}
//解析json字符
bool ConvertThread::analysisJson(QString FileName, int FileOrder)
{
//采用普通方式打开文件,并且存入allDada中,注意这是一种QByteArray格式
QFile loadFile(FileName);
if(loadFile.open(QIODevice::ReadOnly))
{
//开始进行一系列JSON相关的处理
QByteArray allData = loadFile.readAll();//读取文件所有数据
loadFile.close();//关闭文件
QJsonParseError json_error;
QJsonDocument::fromJson(allData, &json_error);//根据读取的数据检查json文件是否出错
if(json_error.error != QJsonParseError::NoError)
{
emit Sig_Result(m_eConvertType, -1, FileName + "文件解析出错");
return false;
}
//顺序获取key值
QString jsonString(allData);//将数据转为QString
bool ok;
QVariantJsonList QVariantJsonList = QtJson::parse(jsonString, ok);
if(QVariantJsonList.isEmpty())
{
emit Sig_Result(m_eConvertType, -1, FileName + "文件为空");
return false;
}
foreach (stJsonNodeData JsonNodeData, QVariantJsonList)
{
QList<stNodeData> NodeDataList = analysisValue(JsonNodeData.m_value, JsonNodeData.m_key, FileOrder);
if(!NodeDataList.isEmpty())
m_NodeDataList.append(NodeDataList);
}
/* key值自动排序 */
// QJsonParseError json_error;
}
else
{
emit Sig_Result(m_eConvertType, -1, "Json文件打开失败");
return false;
}
return true;
}
//解析json节点
QList<stNodeData> ConvertThread::analysisValue(const QJsonValue OneValue, QString Key, int FileOrder)
{
stNodeData team = {};
QList<stNodeData> teamList = {};
if(!OneValue.isObject())
{
for(stNodeData &NodeData : m_NodeDataList)
{
if(NodeData.m_key == Key)
{
while(NodeData.m_value.size() < FileOrder)
{
NodeData.m_value.append(m_BlankGrid);
}
NodeData.m_value.append(OneValue.toString());
return teamList;
}
}
//里面没有再包一层直接添加数据
team.m_key.append(Key);
while(FileOrder > 0)
{
team.m_value.append(m_BlankGrid);
FileOrder--;
}
team.m_value.append(OneValue.toString());
teamList.append(team);
}
else
{
// 转换成对象类型
QJsonObject serialOneObj = OneValue.toObject();
for(QJsonObject::iterator it = serialOneObj.begin(); it != serialOneObj.end(); ++it)
{
team = {};
//用#$&标识符区分每一层节点
team.m_key = Key + m_Identifier +it.key();
//根据value是否对象类型判断是否继续递归调研
if(it.value().isObject())
{
QList<stNodeData> NodeDataList = analysisValue(it.value(), team.m_key, FileOrder);
if(!NodeDataList.isEmpty())
teamList.append(NodeDataList);
}
else
{
bool exist = false;
for(stNodeData &NodeData : m_NodeDataList)
{
if(NodeData.m_key == team.m_key)
{
while(NodeData.m_value.size() < FileOrder)
{
NodeData.m_value.append(m_BlankGrid);
}
NodeData.m_value.append(it.value().toString());
exist = true;
break;
}
}
if(exist)
continue;
while(FileOrder > 0)
{
team.m_value.append(m_BlankGrid);
FileOrder--;
}
team.m_value.append(it.value().toString());
teamList.append(team);
}
}
}
return teamList;
}
QList<stNodeData> ConvertThread::analysisValue(const QVariant OneValue, QString Key, int FileOrder)
{
stNodeData team = {};
QList<stNodeData> teamList = {};
QVariantJsonList JsonList = OneValue.value<QVariantJsonList>();
if(JsonList.isEmpty())
{
for(stNodeData &NodeData : m_NodeDataList)
{
if(NodeData.m_key == Key)
{
while(NodeData.m_value.size() < FileOrder)
{
NodeData.m_value.append(m_BlankGrid);
}
NodeData.m_value.append(OneValue.toString());
return teamList;
}
}
//里面没有再包一层直接添加数据
team.m_key.append(Key);
while(FileOrder > 0)
{
team.m_value.append(m_BlankGrid);
FileOrder--;
}
team.m_value.append(OneValue.toString());
teamList.append(team);
}
else
{
// 转换成对象类型
foreach (stJsonNodeData JsonNode, JsonList)
{
team = {};
//用#$&标识符区分每一层节点
team.m_key = Key + m_Identifier + JsonNode.m_key;
//根据value是否对象类型判断是否继续递归调研
if(JsonNode.m_value.value<QVariantJsonList>().isEmpty())
{
bool exist = false;
for(stNodeData &NodeData : m_NodeDataList)
{
if(NodeData.m_key == team.m_key)
{
while(NodeData.m_value.size() < FileOrder)
{
NodeData.m_value.append(m_BlankGrid);
}
NodeData.m_value.append(JsonNode.m_value.toString());
exist = true;
break;
}
}
if(exist)
continue;
while(FileOrder > 0)
{
team.m_value.append(m_BlankGrid);
FileOrder--;
}
team.m_value.append(JsonNode.m_value.toString());
teamList.append(team);
}
else
{
QList<stNodeData> NodeDataList = analysisValue(JsonNode.m_value, team.m_key, FileOrder);
if(!NodeDataList.isEmpty())
teamList.append(NodeDataList);
}
}
}
return teamList;
}
//添加到excel表格中
bool ConvertThread::addToExcel()
{
QAxObject *excel = new QAxObject(this);
excel->setControl("Excel.Application");//连接Excel控件
excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体
excel->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似"文件已修改,是否保存"的提示
QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
workbooks->dynamicCall("Add");//新建一个工作簿
QAxObject *workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
QAxObject *worksheets = workbook->querySubObject("Sheets");//获取工作表集合
QAxObject *worksheet = worksheets->querySubObject("Item(int)",1);//获取工作表集合的工作表1,即sheet1
//宽度自适应
auto range = worksheet->querySubObject("UsedRange");
QAxObject * cells = range->querySubObject("Columns");
if (cells)
{
cells->dynamicCall("AutoFit");
}
//Json文件转换得到的列标题
QList<QVariant> oRowdata;
QList<QString> aline;
aline.append("key");
for (QString &SelectFile:m_SelectFileList)
{
QStringList list = SelectFile.split("/");
QString Title = list.last();
if(Title.contains(".json"))
Title.remove(".json");
else if(Title.contains(".txt"))
Title.remove(".txt");
aline.append(Title);
}
oRowdata.append(QVariant(aline));
char endCol = 'A' + m_SelectFileList.size();
QString strRange = "A"+ QString::number(1) + ":" + QString(endCol) + QString::number(1);//需写入数据的表格范围
QAxObject *oRange = worksheet->querySubObject("Range(QString)", strRange);
if (oRange)
{
oRange->setProperty("HorizontalAlignment", -4108);//设置单元格内容居中
oRange->setProperty("NumberFormatLocal", "@");//设置单元格格式(文本)
oRange->setProperty("Value2", oRowdata);//设置单元格值
}
//Key与对应内容
oRowdata.clear();
foreach (stNodeData NodeData, m_NodeDataList)
{
aline.clear();
aline.append(NodeData.m_key);
foreach (QString value, NodeData.m_value)
{
aline.append(value);
}
oRowdata.append(QVariant(aline));
}
QVariant oData(oRowdata);
strRange = "A"+ QString::number(2) + ":" + QString(endCol) + QString::number(m_NodeDataList.size() + 1);
oRange = worksheet->querySubObject("Range(QString)", strRange);
if (oRange)
{
oRange->setProperty("HorizontalAlignment", -4131);
oRange->setProperty("NumberFormatLocal", "@");
oRange->setProperty("Value2", oData);
}
QString filepath= m_SelectFileList.at(0);
//单个json文件转excel,文件命名为源文件名字,多转一命名为JsonToExl
if(m_SelectFileList.size()==1)
{
QStringList list = m_SelectFileList.at(0).split("/");
QString FileName =list.last();
if(FileName.contains(".txt"))
{
FileName=FileName.remove(".txt");
}
else if(FileName.contains(".json"))
{
FileName=FileName.remove(".json");
}
filepath = m_GeneratePath+"\\" + FileName+".xls";
}
else if(m_SelectFileList.size()>1)
{
filepath = m_GeneratePath + "\\JsonToExl.xls";
}
workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(filepath));//保存至filepath,注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
workbook->dynamicCall("Close()");//关闭工作簿
excel->dynamicCall("Quit()");//关闭excel
delete excel;
excel = NULL;
emit Sig_Result(m_eConvertType, 100, "转换完成");
return true;
}
//解析excel文件
bool ConvertThread::analysisExcel(QString FileName)
{
QAxObject* excel = new QAxObject("Excel.Application");
if (!excel) {
emit Sig_Result(m_eConvertType, -1, "无法创建 Excel 对象");
return false;
}
// 打开工作簿
QAxObject* workbooks = excel->querySubObject("Workbooks");
QAxObject* workbook = workbooks->querySubObject("Open(const QString&)", FileName);
// 获取第一个工作表
QAxObject* sheets = workbook->querySubObject("Worksheets");
QAxObject* sheet = sheets->querySubObject("Item(int)", 1);
QAxObject *rangeAx = sheet->querySubObject("UsedRange"); //直接读整个表
QVariant rangeData = rangeAx ->dynamicCall("Value2()");
QVariantList rangeDataList = rangeData.toList();
bool first = true;
foreach (QVariant rowData, rangeDataList)
{
QVariantList rowDataList = rowData.toList() ;
stNodeData NodeData = {};
for(int i = 0; i < rowDataList.size(); i++)
{
QString cellValue = rowDataList[i].toString();
if(0 == i)
NodeData.m_key = cellValue;
else
NodeData.m_value.append(cellValue);
}
if(first)
{
first = false;
m_GenerateFileList = NodeData.m_value;
}
else
{
m_NodeDataList.append(NodeData);
}
}
// 关闭并释放资源
workbook->dynamicCall("Close()");
excel->dynamicCall("Quit()");
delete sheet;
delete sheets;
delete workbook;
delete workbooks;
delete excel;
excel = NULL;
return true;
}
//生成Json对象
void ConvertThread::generateValue(QJsonObject &pageObject, stNodeData NodeData, int FileOrder)
{
//正数是从左到右切的字符串,从0开始,负数从右到左切,从-1开始 注意:数字代表字符串位置,不是字符位置!
QString subStr1 = NodeData.m_key.section(m_Identifier, 0, 0);//取去除#$&后的第一段的字符内容
QString subStr2 = NodeData.m_key.section(m_Identifier, 1, -1);//取去除#$&后得第2段到最后一段的内容
if(!subStr1.isEmpty() && subStr2.isEmpty())//只有一层
{
if(NodeData.m_value.at(FileOrder) != m_BlankGrid)
pageObject.insert(NodeData.m_key, NodeData.m_value.at(FileOrder));//直接插入对应的key,value
}
else if(!subStr2.isEmpty())
{
//判断是不是第一次添加这个结点
stNodeData uNodeData = {subStr2, NodeData.m_value};//不含标识符的后半段结点数据
for (int k = 0; k < pageObject.keys().size(); k++)//循环子对象所含的key的数量
{
if(subStr1 == pageObject.keys().at(k))//曾添加过该结点
{
QJsonObject uJsonObject = pageObject.value(subStr1).toObject();//根据字符找到对应的value值并将其转为object对象
generateValue(uJsonObject, uNodeData, FileOrder);//递归
pageObject[subStr1] = QJsonValue(uJsonObject);
return;
}
}
//str2不为空进行深层递归
QJsonObject json;
generateValue(json, uNodeData, FileOrder);
pageObject.insert(subStr1, QJsonValue(json));
}
}
//生成Json串
void ConvertThread::generateValue(stJsonNodeData &JsonNode, stNodeData NodeData, int FileOrder)
{
//正数是从左到右切的字符串,从0开始,负数从右到左切,从-1开始 注意:数字代表字符串位置,不是字符位置!
QString subStr1 = NodeData.m_key.section(m_Identifier, 0, 0);//取去除#$&后的第一段的字符内容
QString subStr2 = NodeData.m_key.section(m_Identifier, 1, -1);//取去除#$&后得第2段到最后一段的内容
if(!subStr1.isEmpty() && subStr2.isEmpty())//只有一层
{
if(NodeData.m_value.at(FileOrder) != m_BlankGrid)
{
stJsonNodeData Node = {};
Node.m_key = NodeData.m_key;
Node.m_value = NodeData.m_value.at(FileOrder);
QVariantJsonList NodeList = JsonNode.m_value.value<QVariantJsonList>();
NodeList.append(Node);
JsonNode.m_value = QVariant::fromValue(NodeList);
}
}
else if(!subStr2.isEmpty())
{
stNodeData uNodeData = {subStr2, NodeData.m_value};//不含标识符的后半段结点数据
//判断是不是第一次添加这个结点
QVariantJsonList JsonList = JsonNode.m_value.value<QVariantJsonList>();
for(int i = 0; i < JsonList.size(); i++)
{
if(subStr1 == JsonList[i].m_key)
{
generateValue(JsonList[i], uNodeData, FileOrder);
JsonNode.m_value = QVariant::fromValue(JsonList);
QVariantJsonList aaa = JsonNode.m_value.value<QVariantJsonList>().at(i).m_value.value<QVariantJsonList>();
return;
}
}
stJsonNodeData Node = {};
Node.m_key = subStr1;
generateValue(Node, uNodeData, FileOrder);
QVariantJsonList NodeList = JsonNode.m_value.value<QVariantJsonList>();
NodeList.append(Node);
JsonNode.m_value = QVariant::fromValue(NodeList);
}
}
QString ConvertThread::jsonDatatoString(stJsonNodeData JsonData, int level, bool last)
{
QString jsonString;
QString indentation;
int i = level;
while (i)
{
indentation += " ";
i--;
}
jsonString += indentation;
if(!JsonData.m_key.isEmpty())
{
jsonString += "\"" + JsonData.m_key + "\": ";
}
QVariantJsonList JsonNodeList = JsonData.m_value.value<QVariantJsonList>();
if(JsonNodeList.isEmpty())
{
if(last)
jsonString += "\"" + JsonData.m_value.toString() + "\"\n\n";
else
jsonString += "\"" + JsonData.m_value.toString() + "\",\n";
}
else
{
QString NodeString;
int count = 0;
for(stJsonNodeData &NodeData : JsonNodeList)
{
count++;
if(count == JsonNodeList.size())
NodeString += jsonDatatoString(NodeData, level + 1, true);
else
NodeString += jsonDatatoString(NodeData, level + 1, false);
}
NodeString.chop(1);
if(last)
jsonString += "{\n" + NodeString + indentation + "}\n\n";
else
jsonString += "{\n" + NodeString + indentation + "},\n";
}
return jsonString;
}
//添加到json文件中
bool ConvertThread::addToJson()
{
int FileOrder = 0;
foreach (QString GenerateFile, m_GenerateFileList)
{
/* 固定读取顺序 */
stJsonNodeData JsonData;
foreach (stNodeData NodeData, m_NodeDataList)
{
generateValue(JsonData, NodeData, FileOrder);
}
QString jsonString = jsonDatatoString(JsonData);
/* key值自动排序 */
// QJsonObject pageObject;
// foreach (stNodeData NodeData, m_NodeDataList)
// {
// generateValue(pageObject, NodeData, FileOrder);
// }
// QJsonDocument document;
// document.setObject(pageObject);
// QString jsonString = document.toJson(QJsonDocument::Indented);
// 打开文件准备写入
QString filePath = m_GeneratePath + "/" + GenerateFile + ".json";
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate))
{
emit Sig_Result(m_eConvertType, -1, "写入打开Json文件失败");
return false;
}
// 写入文件
file.write(jsonString.toUtf8());
file.close();
FileOrder++;
}
emit Sig_Result(m_eConvertType, 100, "转换完成");
return true;
}
#ifndef CONVERTTHREAD_H
#define CONVERTTHREAD_H
#include <QObject>
#include <QMutex>
#include <QMutexLocker>
#include "json.h"
/**节点数据类型**/
struct stNodeData
{
QString m_key;
QList<QString> m_value;
};
/**文件转换类型**/
enum eConvertType {
emConvert_JsonToExcel = 0,
emConvert_ExcelToJson =1
};
/**文件转换线程**/
class ConvertThread : public QObject
{
Q_OBJECT
public:
ConvertThread();
~ConvertThread();
public slots:
void setConvert(eConvertType ConvertType, const QStringList SelectFile, const QString GeneratePath);
private:
bool analysisJson(QString FileName, int FileOrder);//解析json
QList<stNodeData> analysisValue(const QJsonValue OneValue, QString Key, int FileOrder);//解析数据节点
QList<stNodeData> analysisValue(const QVariant OneValue, QString Key, int FileOrder);//解析数据节点
bool addToExcel();//生成EXL文件
bool analysisExcel(QString FileName);//解析excel
void generateValue(QJsonObject &pageObject, stNodeData NodeDataList, int FileOrder);//生成Json对象
void generateValue(stJsonNodeData &JsonNodeList, stNodeData NodeDataList, int FileOrder);//生成Json串
QString jsonDatatoString(stJsonNodeData JsonData, int level = 0, bool last = true);
bool addToJson();//生成JSON文件
private:
eConvertType m_eConvertType;//转换类型
QString m_BlankGrid;//空白格填充字符
QStringList m_SelectFileList;//选择解析文件列表
QString m_GeneratePath;//选择生成路径
QString m_Identifier;//结点连接标识符
QStringList m_GenerateFileList;//生成文件列表
QList<stNodeData> m_NodeDataList;//对象类型存储列表
QMutex lock;
signals:
void Sig_Result(eConvertType ConvertType, int nProgress, const QString &strMsg);
};
#endif // CONVERTTHREAD_H
#include <QDateTime>
#include <QStringList>
#include <QMetaType>
#include <qjsonobject.h>
#include "json.h"
namespace QtJson {
static QVariant parseValue(const QString &json, int &index, bool &success);
static QVariant parseObject(const QString &json, int &index, bool &success);
static QVariant parseArray(const QString &json, int &index, bool &success);
static QVariant parseString(const QString &json, int &index, bool &success);
static void eatWhitespace(const QString &json, int &index);
static int lookAhead(const QString &json, int index);
static int nextToken(const QString &json, int &index);
/**
* parse
*/
QVariantJsonList parse(const QString &json, bool &success) {
success = true;
QVariantJsonList JsonList;
if (!json.isNull() || !json.isEmpty()) {
QString data = json;
int index = 0;
QVariant Variant = parseValue(data, index, success);
JsonList = Variant.value<QVariantJsonList>();
}
return JsonList;
}
/**
* \enum JsonToken
*/
enum JsonToken {
JsonTokenNone = 0,//
JsonTokenCurlyOpen = 1,//{
JsonTokenCurlyClose = 2,//}
JsonTokenSquaredOpen = 3,//[
JsonTokenSquaredClose = 4,//]
JsonTokenColon = 5,//:
JsonTokenComma = 6,//,
JsonTokenString = 7//"
};
/**
* parseValue
*/
static QVariant parseValue(const QString &json, int &index, bool &success) {
switch(lookAhead(json, index)) {
case JsonTokenString:
return parseString(json, index, success);
case JsonTokenCurlyOpen:
return parseObject(json, index, success);
case JsonTokenSquaredOpen:
return parseArray(json, index, success);
case JsonTokenNone:
break;
}
success = false;
return QVariant();
}
/**
* parseObject解析 { 后的数据
*/
static QVariant parseObject(const QString &json, int &index, bool &success) {
QVariantJsonList JsonList;
int token;
nextToken(json, index);
bool done = false;
while (!done) {
token = lookAhead(json, index);
if (token == JsonTokenNone) {
success = false;
return QVariant();
} else if (token == JsonTokenComma) {
nextToken(json, index);
} else if (token == JsonTokenCurlyClose) {
nextToken(json, index);
return QVariant::fromValue(JsonList);
} else {
QString key = parseString(json, index, success).toString();
if (!success) {
return QVariant();
}
token = nextToken(json, index);
if (token != JsonTokenColon) {
success = false;
return QVariant::fromValue(JsonList);
}
QVariant value = parseValue(json, index, success);
if (!success) {
return QVariant();
}
stJsonNodeData JsonNode = {key, value};
JsonList.append(JsonNode);
}
}
return QVariant::fromValue(JsonList);
}
/**
* parseArray
*/
static QVariant parseArray(const QString &json, int &index, bool &success) {
QVariantList list;
nextToken(json, index);
bool done = false;
while(!done) {
int token = lookAhead(json, index);
if (token == JsonTokenNone) {
success = false;
return QVariantList();
} else if (token == JsonTokenComma) {
nextToken(json, index);
} else if (token == JsonTokenSquaredClose) {
nextToken(json, index);
break;
} else {
QVariant value = parseValue(json, index, success);
if (!success) {
return QVariantList();
}
list.push_back(value);
}
}
return QVariant(list);
}
/**
* parseString
*/
static QVariant parseString(const QString &json, int &index, bool &success) {
QString s;
QChar c;
eatWhitespace(json, index);
c = json[index++];
bool complete = false;
while(!complete) {
if (index == json.size()) {
break;
}
c = json[index++];
if (c == '\"') {
complete = true;
break;
} else if (c == '\\') {
if (index == json.size()) {
break;
}
c = json[index++];
if (c == '\"') {
s.append('\"');
} else if (c == '\\') {
s.append('\\');
} else if (c == '/') {
s.append('/');
} else if (c == 'b') {
s.append('\b');
} else if (c == 'f') {
s.append('\f');
} else if (c == 'n') {
s.append('\n');
} else if (c == 'r') {
s.append('\r');
} else if (c == 't') {
s.append('\t');
} else if (c == 'u') {
int remainingLength = json.size() - index;
if (remainingLength >= 4) {
QString unicodeStr = json.mid(index, 4);
int symbol = unicodeStr.toInt(0, 16);
s.append(QChar(symbol));
index += 4;
} else {
break;
}
}
} else {
s.append(c);
}
}
if (!complete) {
success = false;
return QVariant();
}
return QVariant(s);
}
/**
* eatWhitespace
*/
static void eatWhitespace(const QString &json, int &index) {
for(; index < json.size(); index++) {
if (QString(" \t\n\r").indexOf(json[index]) == -1) {
break;
}
}
}
/**
* lookAhead
*/
static int lookAhead(const QString &json, int index) {
int saveIndex = index;
return nextToken(json, saveIndex);
}
/**
* nextToken
*/
static int nextToken(const QString &json, int &index) {
eatWhitespace(json, index);
if (index == json.size()) {
return JsonTokenNone;
}
QChar c = json[index];
index++;
switch(c.toLatin1()) {
case '{': return JsonTokenCurlyOpen;
case '}': return JsonTokenCurlyClose;
case '[': return JsonTokenSquaredOpen;
case ']': return JsonTokenSquaredClose;
case ',': return JsonTokenComma;
case '"': return JsonTokenString;
case ':': return JsonTokenColon;
}
index--;
return JsonTokenNone;
}
} //end namespace
#ifndef JSON_H
#define JSON_H
#include <QVariant>
#include <QString>
#include <QQueue>
#include <qjsonobject.h>
struct stJsonNodeData
{
QString m_key;
QVariant m_value;
};
typedef QList<stJsonNodeData> QVariantJsonList;
Q_DECLARE_METATYPE(QVariantJsonList)//QVariant可以支持自定义的数据类型,使用Q_DECLARE_METATYPE()宏注册此类
namespace QtJson {
QVariantJsonList parse(const QString &json, bool &success);
}
#endif //JSON_H