Qt中Sql查询语句查询Excel表,带where语句中各种嵌套关系以及各种逻辑表达式

        在诸多场合,需要离线分析excel表格或者xml,就需要把已经完成的程序从对接数据库改为对接xml或者excel表离线分析数据,这个时候,如果按照excel的改法去大改,耗时耗力,而且得不到好结果,这时候就需要直接分析sql语句,把sql语句与excel表关联起来。

        实现思路大致为:所有逻辑运算符使用enum枚举将它们关系从一个运算符转为一个可以存储的类型或者变量。而嵌套关系,在存储的中间件中,则使用链表,可以指向本类的指针,来指向下一个节点或子节点,这样就可以无限指向子节点来维护各种深层次的嵌套关系。这样一个可以存储所有嵌套关系以及逻辑运算符的存储介质就有了。

        接下来是关于实现思路,实现思路大致就是递归处理子节点,最外层只需要实现父节点的所有逻辑关系以及表达式,然后一直递归,递归到子节点指向NULL,则递归停止。所有逻辑关系运算最后打包成一个公式,比如1!=2、1<2、1==2||2<3&&3==3等这种公式(注意:逻辑&&比逻辑||优先级高),然后使用QJsEngine或者QJavaScriptEngine对接javaScript代码来运算逻辑表达式,从而返回筛选结果。

        本章读取Excel使用了libxl,因为涉及到读取xls以及xlsx,这里实现可以使用其他中间件。直接贴出代码:

读取excel的关键类ReadWriteExcel

readwriteexcel.h

#ifndef READWRITEEXCEL_H
#define READWRITEEXCEL_H
#include <wchar.h>
#include <stdlib.h>
#include <iostream>
#include <QString>
#include "libxl.h"
#include <stdlib.h>
#include <QDebug>
#include <QQueue>
#include <QQmlEngine>
#include <QScriptEngine>
#include <QRegularExpression>
#include <stdio.h>
#include <functional>
#include "cdatetime.h"
using namespace libxl;
#ifdef _UNICODE
#define STR2CHAR(input) (QString(input).toStdWString().c_str())
#define CHAR2STR(input) (QString::fromWCharArray(input))
#else
#define STR2CHAR(input) (QString(input).toStdString().c_str())
#define CHAR2STR(input) (QString::fromLocal8Bit(input))
#endif
enum VSTATE{
    DEFAULT,
    EQUAL,      //“==”等于
    UNEQUAL,    //“!=”不等
    LIKE,       //“Like”包含
    IN,         //满足一个则为true,值以“,”隔开
    MORE,       //“>”
    LESS,       //“<”
    MOREEQUAL,       //“>=”
    LESSEQUAL,       //“<=”
};
enum LOGICSTATE
{
    AND,
    OR
};

typedef struct
{
    VSTATE v_state = VSTATE::DEFAULT;
    QPair<QString,QVariant> valueMap;
//    QVariant::Type str_type =QVariant::Invalid;
}VSTATESTR;

// 用于表示逻辑运算符和对应条件的结构体
struct LogicCond;
//把整个where语句串起来
typedef struct LogicCond{
    VSTATESTR m_judege;                         // 本节点
    struct LogicCond* subCondNext = NULL;    // 如果本节点是列表,则为列表
    LOGICSTATE logicState = LOGICSTATE::AND;    // 与下一个LogicCondition的关系
//    struct LogicCond * lastLogicCond = NULL;    //上一个节点
    struct LogicCond * nextLogicCond = NULL;    //下一个节点

}LogicCondition;
enum DBTYPE
{
    unkown,
    UInt,
    Int,
    Double,
    String,
    Data,
    DateTIme
};

class ReadWriteExcel
{
public:
    ReadWriteExcel();
    ~ReadWriteExcel();
    //打开文件
    bool open(QString path);
    //获取所有数据
    QVector<QVector<QString> > GetAllData();
    //传入规则树,传出匹配的行数
    quint64 GetDataCount(LogicCondition logic);
    quint64 GetDataCount(QMap<QString,DBTYPE> dbTypeMap,QString where_order);

    QList<QVariantHash> GetData(QMap<QString,DBTYPE> dbTypeMap,QString where_order,QPair<QString,bool> orderBy);
    QList<QVariantHash> GetData(QMap<QString,DBTYPE> dbTypeMap,QString where_order,QPair<QString,bool> orderBy,int index,int count);
    LogicCondition *ConvertToLogicCondition(QMap<QString,DBTYPE> dbTypeMap, QString where_order, QMap<QString,QString> excelMap = QMap<QString,QString>());
    void DeleteLogicCondition(LogicCondition* logic);
    void DebugLogicCondition(LogicCondition* logic);
    //关闭文件
    void close();

private:
    bool JudegeEvaluate(LogicCondition* logic, QMap<QString,QString> jedgeMap = QMap<QString,QString>());
    bool JudegeEvaluate(VSTATESTR jedgeValue,QMap<QString,QString> jedgeMap = QMap<QString,QString>());
    QString SplictOutermostBracket(QString text);
    VSTATE GetState(QString str);
    QList<QVariantHash> SortMapValues(QMultiMap<QString,QVariantHash> map,bool isGreater);
private:
    Book* m_book{NULL};
    QString m_path;
    QScriptEngine engine;
};

#endif // READWRITEEXCEL_H

readwriteexcel.cpp

#include "readwriteexcel.h"

ReadWriteExcel::ReadWriteExcel()
{
    m_book = xlCreateBook();
#ifdef Q_OS_WIN
    m_book->setKey(STR2CHAR("GCCG"), STR2CHAR("windows-282123090cc0e6036db16b60a1q3q0i9"));
#else
    book->setKey(STR2CHAR("libxl"), STR2CHAR("linux-i8i3ibi2i8i4iei3i9iaiei8ibx6x5i3"));
#endif
    qRegisterMetaType<CDateTime>("CDateTime");
}

ReadWriteExcel::~ReadWriteExcel()
{
    m_book->release();

}

bool ReadWriteExcel::open(QString path)
{
    if(!m_book->load(STR2CHAR(path)))
    {
        qDebug()<<"load file error:"<<m_book->errorMessage();
        return false;
    }
    m_path = path;
    return true;
}

QVector<QVector<QString> > ReadWriteExcel::GetAllData()
{
    QVector<QVector<QString> > resultList;
    if(m_book->load(STR2CHAR(m_path)))
    {
    libxl::Sheet* sheet = m_book->getSheet(0); // 获取第一个工作表
            if (sheet) {
                int rowCount = sheet->lastRow(); // 获取行数
                int colCount = sheet->lastCol(); // 获取列数
                for (int row = 0; row <= rowCount; ++row) {
                    QVector<QString> resultTempList;
                    for (int col = 0; col <= colCount; ++col) {
                        libxl::CellType cellType = sheet->cellType(row, col); // 获取单元格类型
                        QString value = "";
                        if (cellType == libxl::CELLTYPE_NUMBER) {
                            value = QString::number(sheet->readNum(row, col)); // 读取数字类型单元格的值
                        }
                        else if (cellType == libxl::CELLTYPE_STRING) {

                            value = CHAR2STR(sheet->readStr(row, col)); // 读取字符串类型单元格的值
                        }
                        else {
                        }
                        resultTempList.push_back(value);
                    }
                    resultList.push_back(resultTempList);
                }
            }
//            m_book->release(); // 释放Book对象
    }
    return  resultList;
}

quint64 ReadWriteExcel::GetDataCount(LogicCondition logic)
{
//    QVector<QVector<QString> > resultList;
    quint64 count = 0;
    if(m_book->load(STR2CHAR(m_path)))
    {
        libxl::Sheet* sheet = m_book->getSheet(0); // 获取第一个工作表
        if (sheet) {
            int rowCount = sheet->lastRow(); // 获取行数
            int colCount = sheet->lastCol(); // 获取列数
            QList<QString> headerList;
            for (int row = 0; row <= rowCount; ++row) {
                //                    QVector<QString> resultTempList;
                QMap<QString,QString> value_map;
                for (int col = 0; col <= colCount; &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值