JSON与EXL文件互转

Z.yping 2024-10-16 13:35:14 阅读 52

功能:实现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文件名

 原代码:

<code>#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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。