网站建设全流程,做内容的网站,网站正在建设中 打不开怎么办,工程合同承包协议书完整版功能#xff1a;实现json到excel文件的相互转换(支持json多选版)
目的#xff1a;编码与语言对应#xff0c;方便大家使用
页面设计#xff1a; 介绍#xff1a;
1.选择文件栏目选择想要转换的文件
2.生成路径是转换后文件所在目录
3.小方框勾选与不勾选分别代表exl到…功能实现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);qRegisterMetaTypeeConvertType(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.hnamespace Ui {
class MainWindow;
}/**主页面**/
class MainWindow : public QMainWindow
{Q_OBJECTpublic: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转EXLif(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转JSONbool resultanalysisExcel(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);//将数据转为QStringbool ok;QVariantJsonList QVariantJsonList QtJson::parse(jsonString, ok);if(QVariantJsonList.isEmpty()){emit Sig_Result(m_eConvertType, -1, FileName 文件为空);return false;}foreach (stJsonNodeData JsonNodeData, QVariantJsonList){QListstNodeData 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节点
QListstNodeData ConvertThread::analysisValue(const QJsonValue OneValue, QString Key, int FileOrder)
{stNodeData team {};QListstNodeData 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()){QListstNodeData 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;
}QListstNodeData ConvertThread::analysisValue(const QVariant OneValue, QString Key, int FileOrder)
{stNodeData team {};QListstNodeData teamList {};QVariantJsonList JsonList OneValue.valueQVariantJsonList();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.valueQVariantJsonList().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{QListstNodeData 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文件转换得到的列标题QListQVariant oRowdata;QListQString 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文件命名为源文件名字,多转一命名为JsonToExlif(m_SelectFileList.size()1){QStringList list m_SelectFileList.at(0).split(/);QString FileName list.last();if(FileName.contains(.txt)){FileNameFileName.remove(.txt);}else if(FileName.contains(.json)){FileNameFileName.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());//关闭exceldelete 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;elseNodeData.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.valueQVariantJsonList();NodeList.append(Node);JsonNode.m_value QVariant::fromValue(NodeList);}}else if(!subStr2.isEmpty()){stNodeData uNodeData {subStr2, NodeData.m_value};//不含标识符的后半段结点数据//判断是不是第一次添加这个结点QVariantJsonList JsonList JsonNode.m_value.valueQVariantJsonList();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.valueQVariantJsonList().at(i).m_value.valueQVariantJsonList();return;}}stJsonNodeData Node {};Node.m_key subStr1;generateValue(Node, uNodeData, FileOrder);QVariantJsonList NodeList JsonNode.m_value.valueQVariantJsonList();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.valueQVariantJsonList();if(JsonNodeList.isEmpty()){if(last)jsonString \ JsonData.m_value.toString() \\n\n;elsejsonString \ 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);elseNodeString jsonDatatoString(NodeData, level 1, false);}NodeString.chop(1);if(last)jsonString {\n NodeString indentation }\n\n;elsejsonString {\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;QListQString m_value;
};/**文件转换类型**/
enum eConvertType {emConvert_JsonToExcel 0,emConvert_ExcelToJson 1
};/**文件转换线程**/
class ConvertThread : public QObject
{Q_OBJECTpublic:ConvertThread();~ConvertThread();
public slots:void setConvert(eConvertType ConvertType, const QStringList SelectFile, const QString GeneratePath);private:bool analysisJson(QString FileName, int FileOrder);//解析jsonQListstNodeData analysisValue(const QJsonValue OneValue, QString Key, int FileOrder);//解析数据节点QListstNodeData analysisValue(const QVariant OneValue, QString Key, int FileOrder);//解析数据节点bool addToExcel();//生成EXL文件bool analysisExcel(QString FileName);//解析excelvoid 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;//生成文件列表QListstNodeData 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.hnamespace 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.valueQVariantJsonList();}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.hstruct stJsonNodeData
{QString m_key;QVariant m_value;
};typedef QListstJsonNodeData QVariantJsonList;Q_DECLARE_METATYPE(QVariantJsonList)//QVariant可以支持自定义的数据类型,使用Q_DECLARE_METATYPE()宏注册此类namespace QtJson {QVariantJsonList parse(const QString json, bool success);
}#endif //JSON_H