功能:实现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
复制