1.基本知识的学习

Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台独立”,既包括操作系统平台,有包括各个数据库平台。另外,我们强调了“基于 SQL”,因为 NoSQL 数据库至今没有一个通用查询方法,所以不可能提供一种通用的 NoSQL 数据库的操作。Qt 的数据库操作还可以很方便的与 model/view 架构进行整合。通常来说,我们对数据库的操作更多地在于对数据库表的操作,而这正是 model/view 架构的长项。

Qt 使用QSqlDatabase表示一个数据库连接。更底层上,Qt 使用驱动(drivers)来与不同的数据库 API 进行交互。Qt 桌面版本提供了如下几种驱动:

qt 开发mysql 数据库软件 qt自带的数据库_数据


 2.小细节

找到系统中所有可用的数据库驱动的名字列表。我们只能使用出现在列表中的驱动。由于默认情况下,QtSql 是作为 Qt 的一个模块提供的。为了使用有关数据库的类,我们必须早 .pro 文件中添加这么一句:

qt 开发mysql 数据库软件 qt自带的数据库_数据库_02


3.QT 的数据库的使用  :qt----QSqlDatabase数据库

建立一个类:

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QSqlDatabase database;//建立了数据库的对象
    void connectDb();//数据库的初始化
    void createTable();//建表
    bool isStudentExist(int);//判断 这个id 是否存在
    int beforeId;
    int beforeAge;

    QString beforeName;
private slots:
    void btnInsterSlot();//添加信息的按键槽函数
    void btnDeleteSlot();//删除信息的按键槽函数
    void btnUpdateSlot();//根据学生信息里面的id  来进行  数据更改
    void btnSelectSlot();//更新ui 设计界面的数据
};

 4.数据库的初始化:

void Dialog::connectDb()//数据库 初始化函数
{
    //使用Sqlite的驱动获得数据库连接的对象
  database = QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库文件的名称
  database.setDatabaseName("Student_info.db");
    //设置用户名 密码
  database.setUserName("she001");//用户名
  database.setPassword("123");//密码
  if(database.open())
  {
      qDebug() << "数据库连接成功";
      //连接成功,建表
    createTable();
  }
  else
  {
      //连接失败
    QSqlError error = database.lastError();
    QMessageBox::critical(this,"错误",error.text());
  }
}

5.增加数据

void Dialog::btnInsterSlot()//添加信息的按键槽函数
{
    QString name = ui->lineEdit_name->text();//提取输入框的信息  (姓名)
    if (name == "")//判断信息是否为空
    {
        QMessageBox::warning(this,"警告","请输入完整的信息");//警告的提示框
        return;
    }
    int id = ui->spinBox_id->value();//提取id 的大小
    int age = ui->spinBox_age->value();//提取的 年龄的大小
    QSqlQuery sq;//创建分类表

    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "INSERT INTO student VALUES(?,?,?)";
    //预处理
    sq.prepare(sql);//绑定函数  因为在prepare()中虽然是标准的SQL指令,但是对于具体的数值类的量不可能在string表示出来
    //占位符数据替换
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(age);


    //执行sql语句
    if(sq.exec())//绑定成功后调用exec()就可以执行插入操作,写入数据库,成功与否就看exec()返回值了。
    {
        btnSelectSlot();//更新ui 设计界面的数据
        QMessageBox::information(this,"通知","添加成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();
        QMessageBox::critical(this,"错误",errorMsg);
    }

}

6.删除数据

void Dialog::btnDeleteSlot()//删除学生的信息
{

    int id = ui->spinBox_id->value();//提取  数据库里面 唯一的key  这个是 删除数据的关键
   //判断是否存在
    if(!isStudentExist(id))
    {
        QMessageBox::warning(this,"警告","此学号的学生不存在");
        return;
    }
    QSqlQuery sq;
    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "DELETE FROM student WHERE id=:id";
    //预处理
    sq.prepare(sql);
    //占位符数据替换
    sq.addBindValue(id);
    //执行sql语句
    if(sq.exec())
    {
         btnSelectSlot();//更新ui 设计界面的数据
        QMessageBox::information(this,"通知","删除成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();//信息错误的字符串
        QMessageBox::critical(this,"删除失败",errorMsg);//错误提示框   加载错误提示信息字符串  弹出提示框
    }
}

7.修改个别的数据

void Dialog::btnUpdateSlot()//根据学生信息里面的id  来进行  数据更改
{
    QString name = ui->lineEdit_name->text();//提取学生的名字
    if (name == "")
    {
        QMessageBox::warning(this,"警告","请输入完整的信息");
        return;
    }
    int id = ui->spinBox_id->value();//提取信息
    int age = ui->spinBox_age->value();
    //判断是否存在
     if(!isStudentExist(id))
     {
         QMessageBox::warning(this,"警告","此学号的学生不存在");
         return;
     }
    QSqlQuery sq;
    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "UPDATE student SET name=:name,age=:age WHERE id=:id";
    //预处理
    sq.prepare(sql);//绑定函数
    //占位符数据替换
    sq.addBindValue(name);
    sq.addBindValue(age);
    sq.addBindValue(id);
    //执行sql语句
    if(sq.exec())
    {
         btnSelectSlot();
        QMessageBox::information(this,"通知","修改成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();
        QMessageBox::critical(this,"修改失败",errorMsg);
    }
}

8.所有的代码:

ui 设计界面

qt 开发mysql 数据库软件 qt自带的数据库_数据库_03

qt 开发mysql 数据库软件 qt自带的数据库_数据_04

SOL .pro

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    dialog.cpp

HEADERS += \
    dialog.h

FORMS += \
    dialog.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QDebug>          //输出文字
#include <QSqlDatabase>   //qt有关数据库操作常用QSqlDatabase这个类来操作,使用这个类时,首先在模块中添加  Qt += sql 然后再添加头文件 #include <QtSql>
#include <QSqlError>      //错误信息提示
#include <QSqlQuery>     //
#include <QMessageBox>    //信息框

//Qt中使用QDialog来实现对话框,QDialog继承自QWidget
//,对话框分为两种,一种是模态对话框、 另一种是非模态对话框。即阻塞和非阻塞对话框,而模态对话框又有两种:
//应用程序级别的和窗口级别的,分别指完成对话框之前阻塞整个应用和阻塞关联窗口。
//exec() 和  open() 分别为应用程序级别和窗口级别的模态对话框,show()则为非模态对话框。

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QSqlDatabase database;//建立了数据库的对象
    void connectDb();//数据库的初始化
    void createTable();//建表
    bool isStudentExist(int);//判断 这个id 是否存在
    int beforeId;
    int beforeAge;

    QString beforeName;
private slots:
    void btnInsterSlot();//添加信息的按键槽函数
    void btnDeleteSlot();//删除信息的按键槽函数
    void btnUpdateSlot();//根据学生信息里面的id  来进行  数据更改
    void btnSelectSlot();//更新ui 设计界面的数据
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) ://构造函数
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    setWindowTitle("数据库增删改查");//改变ui界面窗口的题目
    QWidget::setWindowState(Qt::WindowActive);
    setWindowFlags(Qt::WindowStaysOnTopHint);
    connectDb();//数据库 初始化函数
    connect(ui->pushButton_insert,SIGNAL(clicked()),this,SLOT(btnInsterSlot()));//按键与槽函数连接
    connect(ui->pushButton_delete,SIGNAL(clicked()),this,SLOT(btnDeleteSlot()));
    connect(ui->pushButton_select,SIGNAL(clicked()),this,SLOT(btnSelectSlot()));
    connect(ui->pushButton_update,SIGNAL(clicked()),this,SLOT(btnUpdateSlot()));
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
}

Dialog::~Dialog()//析构函数
{
    //关闭数据库
    if(database.isOpen())
        database.close();
    delete ui;
}

void Dialog::connectDb()//数据库 初始化函数
{
    //使用Sqlite的驱动获得数据库连接的对象
  database = QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库文件的名称
  database.setDatabaseName("Student_info.db");
    //设置用户名 密码
  database.setUserName("she001");//用户名
  database.setPassword("123");//密码
  if(database.open())
  {
      qDebug() << "数据库连接成功";
      //连接成功,建表
    createTable();
  }
  else
  {
      //连接失败
    QSqlError error = database.lastError();
    QMessageBox::critical(this,"错误",error.text());
  }
}

void Dialog::createTable()//建立一个数据表
{
    //创建一个数据库操作对象
    QSqlQuery sq; //创建分类表
    QString sql = "CREATE TABLE Student(id INTEGER PRIMARY KEY,\
                     name TEXT NOT NULL,age INTEGER)";
    if(sq.exec(sql))
        qDebug() << "建表成功";
    else
        qDebug() << sq.lastError().text();//输出错误的原因
}


void Dialog::btnInsterSlot()//添加信息的按键槽函数
{
    QString name = ui->lineEdit_name->text();//提取输入框的信息  (姓名)
    if (name == "")//判断信息是否为空
    {
        QMessageBox::warning(this,"警告","请输入完整的信息");//警告的提示框
        return;
    }
    int id = ui->spinBox_id->value();//提取id 的大小
    int age = ui->spinBox_age->value();//提取的 年龄的大小
    QSqlQuery sq;//创建分类表

    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "INSERT INTO student VALUES(?,?,?)";
    //预处理
    sq.prepare(sql);//绑定函数  因为在prepare()中虽然是标准的SQL指令,但是对于具体的数值类的量不可能在string表示出来
    //占位符数据替换
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(age);


    //执行sql语句
    if(sq.exec())//绑定成功后调用exec()就可以执行插入操作,写入数据库,成功与否就看exec()返回值了。
    {
        btnSelectSlot();//更新ui 设计界面的数据
        QMessageBox::information(this,"通知","添加成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();
        QMessageBox::critical(this,"错误",errorMsg);
    }

}

void Dialog::btnDeleteSlot()//删除学生的信息
{

    int id = ui->spinBox_id->value();//提取  数据库里面 唯一的key  这个是 删除数据的关键
   //判断是否存在
    if(!isStudentExist(id))
    {
        QMessageBox::warning(this,"警告","此学号的学生不存在");
        return;
    }
    QSqlQuery sq;
    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "DELETE FROM student WHERE id=:id";
    //预处理
    sq.prepare(sql);
    //占位符数据替换
    sq.addBindValue(id);
    //执行sql语句
    if(sq.exec())
    {
         btnSelectSlot();//更新ui 设计界面的数据
        QMessageBox::information(this,"通知","删除成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();//信息错误的字符串
        QMessageBox::critical(this,"删除失败",errorMsg);//错误提示框   加载错误提示信息字符串  弹出提示框
    }
}
// 更新固定学号的人
void Dialog::btnUpdateSlot()//根据学生信息里面的id  来进行  数据更改
{
    QString name = ui->lineEdit_name->text();//提取学生的名字
    if (name == "")
    {
        QMessageBox::warning(this,"警告","请输入完整的信息");
        return;
    }
    int id = ui->spinBox_id->value();//提取信息
    int age = ui->spinBox_age->value();
    //判断是否存在
     if(!isStudentExist(id))
     {
         QMessageBox::warning(this,"警告","此学号的学生不存在");
         return;
     }
    QSqlQuery sq;
    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "UPDATE student SET name=:name,age=:age WHERE id=:id";
    //预处理
    sq.prepare(sql);//绑定函数
    //占位符数据替换
    sq.addBindValue(name);
    sq.addBindValue(age);
    sq.addBindValue(id);
    //执行sql语句
    if(sq.exec())
    {
         btnSelectSlot();
        QMessageBox::information(this,"通知","修改成功");
    }
    else
    {
        QString errorMsg = sq.lastError().text();
        QMessageBox::critical(this,"修改失败",errorMsg);
    }
}

void Dialog::btnSelectSlot()//更新ui 设计界面的数据
{
    //清空之前的显示
   ui->tableWidget->setRowCount(0);
    QSqlQuery sq;
    QString sql = "SELECT * FROM student ";
    //执行sql语句
    if(sq.exec(sql))
    {
        //遍历
      while(sq.next())
      {
          int id = sq.value("id").toInt();//获取当前表里面的数据的值  id
          QString name =sq.value("name").toString();//获取当前表里面的数值  name
          int age =sq.value("age").toInt();//获取当前表里面的数值 age
          qDebug() << id << name << age;//在下面的数据输出框 输出当前的提取的数据
          //获取当前表格中的行数
          int rowCount = ui->tableWidget->rowCount();
          //添加空白行
          ui->tableWidget->insertRow(rowCount);
          //给空白行添加数据
          ui->tableWidget->setItem(rowCount,0,new QTableWidgetItem(QString::number(id)));//第几行 添加数据  参数1  行数   参数2 列数  参数3  QTableWidgetItem  指明QTableWidget中的一个Item。Item通常包含文本、图标、checkbox。
          ui->tableWidget->setItem(rowCount,1,new QTableWidgetItem(name));
          ui->tableWidget->setItem(rowCount,2,new QTableWidgetItem(QString::number(age)));
      }
    }
    else
    {
        QString errorMsg = sq.lastError().text();
        QMessageBox::critical(this,"执行失败",errorMsg);
    }
}



bool Dialog::isStudentExist(int id)//判断 这个id 是否存在
{
    QSqlQuery sq;
    //防止sql注入问题,预处理(:id,:name,:age)
    QString sql = "SELECT * FROM student WHERE id=:id";
    //预处理
    sq.prepare(sql);
    //占位符数据替换
    sq.addBindValue(id);
    //执行sql语句
    if(sq.exec())
    {
        return sq.next();
    }
    else
    {
        return false;
    }
}

 mian.cpp

#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}

9.基本操作的提示

1、创建数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("MyBrandDB");
db.setDatabaseName("MyDb.db");
db.setUserName("Liu");
db.setPassword("123456");
if(!db.open())
return false;<br>在使用QSqlDatabase::addDatabase("QOCI","OracleA")函数时,第一个参数是驱动类型主键,第二个是连接名。

2、数据库的增删改查(查询命令就是SQL的通用命令)

1.创建一张表

QSqlQuery query;
//创建分类表
query.exec("create table type_table(id varchar primary key, name varchar)");
query.exec("insert into type_table values('0', '请选择类型')");
query.exec("insert into type_table values('1', '电视')");
query.exec("insert into type_table values('2', '空调')");

2.查询/获取键值

QSqlQuert query;
query.exec(QString("select price from table_name where 条件1='' and 条件2=''"))  
query.next();//在执行完exec()之后会把指针放在记录集中的第一个记录之上,所以需要调用next()来获取第一个数据
int nPrice = query.value(0).toInt();

3.修改/写入数据库

QSqlQuery query;

QSqlDatabase::database().transaction();    //事物操作
bool bResult = query.exec(QString("update table_name set price=2 where 条件1='' and 条件2=''"));
if(bResult)
QSqlDatabase::database().commit();      //提交
else
QSqlDatabase::database().rollback();    //回滚

10.知识的补充

Qt中的Qt SQL模块提供了对数据库的支持,模块中类可分为三层:驱动层,sql接口层,用户层。

驱动层:(QSqlDriver,QSqlDriverCreator,QSqlDriverCreatorBase,QSqlDriverPlugin)为具体的数据库和SQL接口层之间提供了底层的桥梁;

SQL接口层:(QSqlDatabase,QSqlQuery,QSqlError,QSqlRecord)提供了对数据库的访问,其中QSqlDatabase类用来创建连接,QSqlQuery类可以使用SQL语句来实现与数据库交互;

用户接口层:(QSqlTableModel,QSqlQueryModel,QSqlRelationalTableModel)实现了将数据库中的数据链接到窗口部件上,这些类是使用模型/视图框架实现的,它们是更高层次的抽象;

创建一个数据库

格式为:create database 数据库名;

例:create database test;

创建一个表

格式为:create table 表名(内容 类型);

例:create table student(number int , name char(32), score double);

向表中插入信息

格式为:insert into 表名 values(表中的内容);

例:insert into student values(1, 'xiaoming', 99);

从表格中删除信息

格式为:delete from 表名 where 列名 = 条件;

例:delete  from student where name = 'xiaoming';

查询表中的内容

格式为:select 列名 from 表名 where 列名 = 条件;

例:select score from student where name = 'xiaoming';

我们可以用这样的语句查询所有的信息

select * from student;

修改表中的数据

格式为:update 表名 set 列名 = 新内容 where 列名 = 条件;

例:update student set score = 66 where name = 'xiaoming';

从数据库中删除一个表

格式为:drop table 表名;

例:drop table student;


11.别的版本的代码

#include "sqlitedatabase.h"

SqliteDatabase::SqliteDatabase()
{
    qDebug() << "hhh";
//    initPickNameDB();
}

void SqliteDatabase::initPickNameDB()
{
    // 创建并打开数据库
    QSqlDatabase database;
    database = QSqlDatabase::addDatabase("QSQLITE");
//    qDebug() << QApplication::applicationDirPath();

    database.setDatabaseName(QApplication::applicationDirPath() + "/CONFIG/" + "PickNameDB.sqlite3");
    if(!database.open())
    {
        qDebug() << "Error: Failed to connect database." << database.lastError();
    }
    else
    {
        qDebug() << "Succeed to connect database.";
    }

    // 创建表格 先清空一下表
    QSqlQuery sql_query = database.exec("DROP TABLE department");
    sql_query = database.exec("DROP TABLE person");

    if(!sql_query.exec("create table department (Id int primary key not null, "
                       "DeptName vchar(50) not null )"))
    {
        qDebug() << "Error: Fail to create department table." << sql_query.lastError();
    }
    else
    {
        qDebug() << "Department table created!";
    }
    if(!sql_query.exec("create table person (Id int primary key not null , "
                       "DeptID integer not null , "
                       "PerName vchar(50) not null, "
                       "foreign key(DeptID) references department (Id))"))
    {
        qDebug() << "Error: Fail to create person table." << sql_query.lastError();
    }
    // 填充表
//    sql_query.exec("insert into department (id, name) values (1, '办领导')");
//    sql_query.exec("insert into department (id, name) values (2, '综合处')");
//    sql_query.exec("insert into department (id, name) values (3, '政策法规处')");
//    sql_query.exec("insert into department (id, name) values (4, '机构改革处')");
//    sql_query.exec("insert into department (id, name) values (5, '党群政法行政机构编制管理处')");
//    sql_query.exec("insert into department (id, name) values (6, '政府行政机构编制管理处')");
//    sql_query.exec("insert into department (id, name) values (7, '市县行政机构编制管理处')");
//    sql_query.exec("insert into department (id, name) values (8, '事业机构编制管理处')");
//    sql_query.exec("insert into department (id, name) values (9, '事业单位登记管理处')");
//    sql_query.exec("insert into department (id, name) values (10, '机构编制监督检查处')");
//    sql_query.exec("insert into department (id, name) values (11, '人事处')");
//    sql_query.exec("insert into department (id, name) values (12, '机关党委')");
//    sql_query.exec("insert into department (id, name) values (13, '省机构编制电子政务中心')");
//    sql_query.exec("insert into department (id, name) values (14, '省机构编制研究中心')");

    // 批量填充表
    QStringList deptNames;
    deptNames << "办领导" << "综合处" << "政策法规处" << "机构改革处"
              << "党群政法行政机构编制管理处" << "政府行政机构编制管理处"
              << "市县行政机构编制管理处" << "事业机构编制管理处" << "事业单位登记管理处"
              << "机构编制监督检查处" << "人事处" << "机关党委"
              << "省机构编制电子政务中心" << "省机构编制研究中心";

    // 绑定关键字后才能进行操作
    sql_query.prepare("INSERT INTO department (Id, DeptName) "
                      "VALUES (:Id, :DeptName)");
    qint8 i = 0;
    foreach (QString deptName, deptNames)
    {
        sql_query.bindValue(":Id", i + 1);
        sql_query.bindValue(":DeptName", deptName);
        if(!sql_query.exec())
        {
            qDebug() << "Error: Fail." << sql_query.lastError();
        }
        i++;
    }
    // 读取sqlite
    department dept;
    QVector<department> tmpDept; // 数据库缓存
    sql_query.exec("SELECT * FROM ");
}

12.Qt实现Excel表格的读写操作(office,WPS)

我们用QT经常会将表格的数据导入数据库或者将数据库中的数据导出为*.xls/*.xlsx。使用比较多的就是用QAxObject对象进行操作。一般首先会连接数据库:

QAxObject *excel = new QAxObject(this);	//连接Excel控件
excel->setControl("Excel.Application");

但是很多人的电脑上并没有安装office,这样会导致运行失败,如果安装了WPS,我们可以

QAxObject *excel = new QAxObject(this);	//连接Excel控件
excel->setControl("ket.Application");

这说明office和WPS是兼容的,我们只需要修改这一行代码就可以了。

另外,附上详细的代码说明:

void Window::importExcelToDatabase()
{
	QString strFilePathName = QFileDialog::getOpenFileName(this,QStringLiteral("选择Excel文件"),"",tr("Exel file(*.xls *.xlsx)"));
	if(strFilePathName.isNull())
	{
		return ;
	}
	QAxObject *excel = new QAxObject(this);	//连接Excel控件
	if (excel->setControl("Excel.Application"))
	{
 
	}
	else
	{
		excel->setControl("ket.Application");  //连接Excel控件
	}
	excel->setProperty("Visible", false);  //不显示窗体
	QAxObject* workbooks = excel->querySubObject("WorkBooks");  //获取工作簿集合
	workbooks->dynamicCall("Open(const QString&)", strFilePathName); //打开打开已存在的工作簿
	QAxObject* workbook = excel->querySubObject("ActiveWorkBook"); //获取当前工作簿 
	QAxObject* sheets = workbook->querySubObject("Sheets");  //获取工作表集合,Sheets也可换用WorkSheets
	QAxObject* sheet = workbook->querySubObject("WorkSheets(int)", 1);//获取工作表集合的工作表1,即sheet1
	QAxObject* range = sheet->querySubObject("UsedRange"); //获取该sheet的使用范围对象
	QVariant var = range->dynamicCall("Value");
	delete range;
	QVariantList varRows = var.toList();  //得到表格中的所有数据
	if(varRows.isEmpty())
	{
		return;
	}
	const int rowCount = varRows.size();
	QStringList m_userid,m_card_id,m_action;
	for(int i = 1; i < rowCount; ++i)   //
	{
		QVariantList rowData = varRows[i].toList();
		m_userid<<rowData[0].toString();
		m_card_id<<rowData[1].toString();
		m_action<<rowData[2].toString();
	}
}

注意:对Excel文档的读写操作,如果数据量很大,最好使用多线程,否则会导致主界面的假死。)