天津储鑫盛钢材现货供应商 发表于 2024-8-27 18:05:05

JSON与EXL文件互转

功能:实现json到excel文件的相互转换(支持json多选版)
目的:编码与语言对应,方便大家利用
页面计划:
https://i-blog.csdnimg.cn/direct/e39d7f7e311344ac87d136ce2da6acbd.png
介绍:
1.选择文件栏目选择想要转换的文件
2.天生路径是转换后文件地点目次
3.小方框勾选与不勾选分别代表exl到json和json到exl两种类型的转换
利用方法:
1.点击选择按钮,选择要剖析的文件(json转exl支持多选文件,按ctrl或shift键)
https://i-blog.csdnimg.cn/direct/6c05187d8cb444249c3a5bf8b0aa3170.png
https://i-blog.csdnimg.cn/direct/31e2b2deba484ed2b79b1d0fdadad42d.png


[*]同样选择一个天生的路径,点击转换按钮。不选路径则会弹出错误提示。
https://i-blog.csdnimg.cn/direct/d2fbb0f0d0f44dae81bc2ffabcd4b6c1.png
https://i-blog.csdnimg.cn/direct/3257c652f29a4108b2a2727880b35b47.png
3.点击exl转json复选框,则会清除之前所选的json文件,切换可以或许所选的文件类型
https://i-blog.csdnimg.cn/direct/267d246c6134450593a12aa983b87860.png
4.选好所需转换的文件和和天生路径,点击转换按钮。转换完成后会弹出提示框。
https://i-blog.csdnimg.cn/direct/88c3c64191074663bf89347cbca122d1.png
https://i-blog.csdnimg.cn/direct/7e1fb1230d4e4fc6b9b0e714d0a542d1.png
5.找到目次下转换好的文件并打开检察。
(1)单个json转exl,天生文件为json文件的原名字。多选转换名字为JsonToExl。
(2)转换后第一行第一列固定为key,第一行其他列标题对应的各个json文件名字。
(3)多转情况下,有的文件中没有key其对应内容,则填充为Null值。(下图1)
(4)若转换的json文件中包罗多层json对象,每层添加标识符“#¥&”(下图3)
https://i-blog.csdnimg.cn/direct/6d13ebc66dd446a7b5708340634f3c4d.png
https://i-blog.csdnimg.cn/direct/416509b71b1c4f258b714c2a55ec3f76.png
https://i-blog.csdnimg.cn/direct/546c862a211a423e9ac2b003586136f8.png

6.excel转json也是同理,勾上对钩,选择要转换的excel文件,点击转换。根据exl中的首行标题名,天生的json文件名
https://i-blog.csdnimg.cn/direct/74776d4c234a483793b0d5e09fe9a1a7.pnghttps://i-blog.csdnimg.cn/direct/470bc21652184964989789bbcab8d4bf.png
 原代码:
#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.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 = 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.m_key)
            {
                generateValue(JsonList, 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;

      bool complete = false;
      while(!complete) {
            if (index == json.size()) {
                break;
            }

            c = json;

            if (c == '\"') {
                complete = true;
                break;
            } else if (c == '\\') {
                if (index == json.size()) {
                  break;
                }

                c = json;

                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) == -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++;
      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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: JSON与EXL文件互转