Qt对Excel表格的自动化调用汇总(新建、打开和保存)

2023-11-11

为便于实时采集并保存数据到excel,需要调用QAxObject

首先定义变量excel workbooks workbook worksheets worksheet range 等;

#ifndef EXCEL_H
#define EXCEL_H
//添加头文件
#include <QVariant>
#include <ActiveQt/QAxObject>//Excel
#include <QDebug>//debug输出
#include <QDir>//保存路径

class Excel
{
public:
    Excel();
    void SetTitle1(const QVariant &var,const QVariant &value);
    QVariant getValue(const QVariant &var);
    bool openExcel();
    bool newExcel();
    void exitExcel();
    void autoFit(const QVariant &var);
    bool fileSaveAs(QString path);
    bool readXlsFile(QString path, QList<QStringList> &res);
    void setPath(QString path);
    void convertToColName(int data, QString &res);
    QString to26AlphabetString(int data);
private:
    QString filePath;
    QAxObject *excel;
    QAxObject *workbooks;
    QAxObject *workbook;
    QAxObject *worksheets;
    QAxObject *worksheet;
    QAxObject *range;
    QAxObject *interior;
    QAxObject *cell;
    QAxObject *font;
    int currRow;

};

#endif // EXCEL_H

定义新建文件、打开文件、关闭文件等函数;

注意:异常情况下需要关闭并退出(此时要delete excel 才能退出进程!)

#include "excel.h"
#include <QFileInfo>
void Excel::SetTitle1(const QVariant &var,const QVariant &value)
{
    if(worksheet == nullptr)
    {
        qDebug()<<"查询 worksheet 失败!";
        return;
    }
    range=worksheet->querySubObject("Range(const QString&)",var);
    if(range == nullptr)
    {
        qDebug()<<"查询 range 失败!";
        return;
    }
    //range->setProperty("MergeCells",true);
    range->setProperty("NumberFormatLocal", "@");
    range->setProperty("Value",value);
    range->setProperty("HorizontalAlignment",-4108);    
}
void Excel::autoFit(const QVariant &var)
{
    if(worksheet == nullptr)
    {
        qDebug()<<"查询 worksheet 失败!";
        return;
    }
    range=worksheet->querySubObject("Range(const QString&)",var);
    if(range == nullptr)
    {
        qDebug()<<"查询 range 失败!";
        return;
    }
    QAxObject * cells = range->querySubObject("Columns");
    cells->dynamicCall("AutoFit");
    delete cells;
}
QVariant Excel::getValue(const QVariant &var)
{
    if(worksheet == nullptr)
    {
        qDebug()<<"查询 worksheet 失败!";
        return "";
    }
    range=worksheet->querySubObject("Range(const QString&)",var);
    return range->property("Value");
}
bool Excel::newExcel()
{
    excel = new QAxObject("Excel.Application");
    if (!excel)
    {
       qDebug()<<"创建Excel失败!";
       return false;
    }
    excel->dynamicCall("SetVisible(bool Visible)", false);       //是否可视化excel
    excel->dynamicCall("SetUserControl(bool UserControl)", false);             //是否用户可操作
    //excel->setProperty("DisplayAlerts", true);                //是否弹出警告窗口

    workbooks = excel->querySubObject("WorkBooks");             //获取工作簿集合
    if(workbooks == nullptr)
    {
        qDebug()<<"查询 workbooks 失败!";
        exitExcel();
        return false;
    }
    workbooks->dynamicCall("Add");                              //新建一个工作簿
    workbook = excel->querySubObject("ActiveWorkBook");         //获取当前工作簿
    if(workbook == nullptr)
    {
        qDebug()<<"查询 ActiveWorkBook 失败!";
        exitExcel();
        return false;
    }
    worksheets = workbook->querySubObject("Sheets");            //获取工作表格集合
    if(worksheets == nullptr)
    {
        qDebug()<<"查询 worksheets 失败!";
        exitExcel();
        return false;
    }
    worksheet  = worksheets->querySubObject("Item(int)", 1);    //获取当前工作表格1,即sheet1
    if(worksheet == nullptr)
    {
        qDebug()<<"查询 worksheet 失败!";
        exitExcel();
        return false;
    }
    worksheet->setProperty("Name","数据");                  //修改sheet名称
    return true;
}
bool Excel::openExcel()
{
    excel = new QAxObject("Excel.Application");
    if (!excel)
    {
       qDebug()<<"打开Excel失败!";
       return false;
    }
    excel->dynamicCall("SetVisible(bool Visible)", false);       //是否可视化excel
    excel->dynamicCall("SetUserControl(bool UserControl)", false);             //是否用户可操作
    workbooks = excel->querySubObject("WorkBooks");             //获取工作簿集合
    if(workbooks == nullptr)
    {
        qDebug()<<"查询 workbooks 失败!";
        exitExcel();
        return false;
    }
    workbooks->dynamicCall("Open(const QString&)", filePath);
    //excel->setProperty("DisplayAlerts", true);                //是否弹出警告窗口
    workbook = excel->querySubObject("ActiveWorkBook");         //获取当前工作簿
    if(workbook == nullptr)
    {
        qDebug()<<"查询 workbook 失败!";
        exitExcel();
        return false;
    }
    worksheets = workbook->querySubObject("Sheets");            //获取工作表格集合
    if(worksheets == nullptr)
    {
        qDebug()<<"查询 worksheets 失败!";
        exitExcel();
        return false;
    }
    worksheet = workbook->querySubObject("Worksheets(int)", 1);
    if(worksheet == nullptr)
    {
        qDebug()<<"查询 worksheet 失败!";
        exitExcel();
        return false;
    }
    return true;
}
void Excel::exitExcel()
{
    if(excel != nullptr && workbooks != nullptr)
        workbooks->dynamicCall("Close()");
    excel->dynamicCall("Quit()");//退出
    delete excel;
}
void Excel::setPath(QString path)
{
    filePath = path;
}
bool Excel::fileSaveAs(QString path)
{
    if(!openExcel())
        return false;
    workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(path));
    exitExcel();
    return true;
}
bool Excel::readXlsFile(QString path, QList<QStringList > &res)
{
    res.clear();
    if(!openExcel())
        return false;
    if(worksheet->property("Name").toString() != "数据")
    {
        qDebug()<<"sheet name 不等于 数据!";
        exitExcel();
        return false;
    }
    //快速读取数据
    QString checkRange = "A1:A7";
    QAxObject *Data = worksheet->querySubObject("Range(QString)", checkRange);
    QVariant DataQVariant = Data->property("Value");
    QVariantList DataList = DataQVariant.toList();
    QStringList list = {"任务单号","检验人员","检验日期","从机数量","模块数量","从机地址","相应数量"};
    for(int i = 0; i < DataList.size(); i++)
    {
        QStringList t = DataList[i].toStringList();
        if(t[0] != list[i])
        {
            exitExcel();
            return false;
        }
    }
    int moduleNum = getValue("B5:B5").toInt();
    if(moduleNum <= 0)
    {
        qDebug() << "模块数量 " << moduleNum << endl;
        exitExcel();
        return false;
    }

    QAxObject * usedrange = worksheet->querySubObject("UsedRange");//获取该sheet的使用范围对象
    if(usedrange == nullptr)
    {
        qDebug()<<"readXlsFile 查询 usedrange 失败!";
        exitExcel();
        return false;
    }
    QAxObject * rows = usedrange->querySubObject("Rows");
    QAxObject * columns = usedrange->querySubObject("Columns");
    int intRows = rows->property("Count").toInt();
    int intCols = columns->property("Count").toInt();
    qDebug() << "读取 " + filePath +" 行数:"<< intRows;
    qDebug() << " xls列数:"<<intCols;
    if(intRows <= 8)
    {
        exitExcel();
        return false;//只有8行 无数据
    }
    // 批量载入数据
    QString rangStr;
    convertToColName(moduleNum+1,rangStr);
    QString Range = "A8:" + rangStr + QString::number(intRows);
    QAxObject *allEnvData = worksheet->querySubObject("Range(QString)", Range);
    QVariant allEnvDataQVariant = allEnvData->property("Value");
    QVariantList allEnvDataList = allEnvDataQVariant.toList();
    for(int i=0; i < allEnvDataList.size(); i++)
    {
        QStringList allEnvDataList_i =  allEnvDataList[i].toStringList() ;
        //qDebug()<< allEnvDataList_i << endl;
        res.push_back(allEnvDataList_i);
    }
    exitExcel();
    return true;
}
void Excel::convertToColName(int data, QString &res)
{
    Q_ASSERT(data>0 && data<65535);
    int tempData = data / 26;
    if(tempData > 0)
    {
        int mode = data % 26;
        convertToColName(mode,res);
        convertToColName(tempData,res);
    }
    else
    {
        res=(to26AlphabetString(data)+res);
    }
}
QString Excel::to26AlphabetString(int data)
{
    QChar ch = data + 0x40;//A对应0x41
    return QString(ch);
}

读写数据类型时QVariant(其他数据类型也可转成QVariant,例如QVariantList)不断包装。

且只能按照行进行打包!

range->setProperty("NumberFormatLocal", "@");

设置显示原始数据格式!

Qt版本为5.13

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt对Excel表格的自动化调用汇总(新建、打开和保存) 的相关文章

  • 使用 ioctl 在 C++ 中以编程方式添加路由

    我编写了简单的 C 函数 添加了新路线 void addRoute int fd socket PF INET SOCK DGRAM IPPROTO IP struct rtentry route memset route 0 sizeof
  • 更新Linux中的包含路径

    我的 my path to file 文件夹中有几个头文件 我知道如何将这些文件包含在新的 C 程序中 但每次我都需要在包含它之前输入头文件的完整路径 我可以在linux中设置一些路径变量 以便它自动查找头文件吗 您可以创建一个 makef
  • 针对初学者的 QT 商业许可证与非商业许可证 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 QT 许可似乎非常反学习 因为据我所知 用它开发的任何东西都只能是商业的当且仅当 its entire开发是在使用商业许可证的情况下完成的
  • Bash:将字符串添加到文件末尾而不换行

    如何将字符串添加到文件末尾而不换行 例如 如果我使用 gt gt 它将添加到文件末尾并换行 cat list txt yourText1 root host 37 echo yourText2 gt gt list txt root hos
  • Docker忽略limits.conf(试图解决“打开文件太多”错误)

    我正在运行一个 Web 服务器 该服务器正在处理数千个并发 Web 套接字连接 为了实现这一点 在 Debian linux 我的基本镜像是 google debian wheezy 在 GCE 上运行 上 打开文件的默认数量设置为 100
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • “git add”返回“致命:外部存储库”错误

    我刚刚进入 git 的奇妙世界 我必须提交我对程序所做的一系列更改 位于名为的目录中 var www myapp 我创建了一个新目录 home mylogin gitclone 从这个目录中 我做了一个git clone针对公共回购 我能够
  • 如何并行执行4个shell脚本,我不能使用GNU并行?

    我有4个shell脚本dog sh bird sh cow sh和fox sh 每个文件使用 xargs 并行执行 4 个 wget 来派生一个单独的进程 现在我希望这些脚本本身能够并行执行 由于某些我不知道的可移植性原因 我无法使用 GN
  • 连接到 QNetworkReply::error 信号

    我正在使用 Qt5 的新连接语法 QNetworkReply 有一个名为error http qt project org doc qt 5 0 qtnetwork qnetworkreply html error 2还有一个函数叫做err
  • 嵌入清单文件以要求具有 mingw32 的管理员执行级别

    我正在 ubuntu 下使用 i586 mingw32msvc 交叉编译应用程序 我很难理解如何嵌入清单文件以要求 mingw32 具有管理员执行级别 对于我的例子 我使用了这个hello c int main return 0 这个资源文
  • 在汇编中使用 printf 会导致管道传输时输出为空,但可以在终端上使用

    无输出 https stackoverflow com questions 54507957 printf call from assembly do not print to stdout即使在终端上 当输出不包含换行符时也有相同的原因
  • 无法运行 Qt 应用程序:找不到版本“Qt_5”

    我运行 Ubuntu 16 04 LTS 我的问题是我无法运行可以编译的 Qt5 应用程序 这是我尝试运行它时得到的结果 home user Desktop sconfig dist Release GNU Linux SCongif us
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li
  • 在内核代码中查找函数的最佳方法[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我开始浏览内核代码 遇到的一件事是如何跟踪函数调用 结构定义等 有没有一种好的方法可以快速跳转到函数定义并退出 我尝试过 Source N
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • Q风格所有权

    在 Qt 应用程序中使用样式时 我遇到了一个有趣的问题QStyle所有权 QStyle继承自QObject 通常接受QObject parent作为构造函数参数来管理其子级的生命周期 但QStyle的构造函数没有此构造函数参数 第一个问题
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 通过 Visual Studio 2017 使用远程调试时 Linux 控制台输出在哪里?

    我的Visual Studio 2017 VS2017 成功连接Linux系统 代码如下 include
  • 在 Qt 中自动调整标签文本大小 - 奇怪的行为

    在 Qt 中 我有一个复合小部件 它由排列在 QBoxLayouts 内的多个 QLabels 组成 当小部件调整大小时 我希望标签文本缩放以填充标签区域 并且我已经在 resizeEvent 中实现了文本大小的调整 这可行 但似乎发生了某

随机推荐

  • php如何无水印解析快手,快手短视频无水印解析过程及代码

    重要 本文最后更新于2020 08 22 08 26 13 某些文章具有时效性 若有错误或已失效 请在下方留言或联系代码狗 抖音快手作为目前最大的两大视频平台 使用量是非常大的 看到某些好看的视频想要保存下来但是又有水印改怎么办呢 狗哥已经
  • Python3_MySQL数据库连接 - PyMySQL 驱动

    数据库连接 连接数据库前 请先确认以下事项 您已经创建了数据库 TESTDB 在TESTDB数据库中您已经创建了表 EMPLOYEE EMPLOYEE表字段为 FIRST NAME LAST NAME AGE SEX 和 INCOME 连接
  • 解决 github clone慢

    转载来源 方法1 代理 通常发现在github clone 代码的时候 开了小飞机也很慢 记得输入下面的命令 git config global https proxy sock5 localhost 1080 这样在操作 git 命令时才
  • Sql Server期末复习

    基础概念 数据库管理系统 是位于用户与操作系统之间的一层数据管理软件 数据库系统 由数据库 数据库管理系统 应用程序和数据库管理员组成 即 DBS DB DBMS 应用程序 DBA 数据库系统的三层模式结构 外模式 模式 内模式 模式 也成
  • 非线性控制理论、反馈线性化、系统的逆、逆系统、微分同胚

    反馈线性化方法是非线性系统控制的一个重要研究方向 在状态反馈下 可 以将一个非线性系统完全变换为一个线性系统 在此情况下 线性系统和非线性 系统的控制问题己不再有本质上的差别 状态反馈具有的这种潜力 使得反馈线 性化方法在产生的同时 也就开
  • 温室气体数据记录软件

    温室气体数据记录软件用于记录温室气体分析仪 冷阱系统 阀箱以及采样单元数据的获取及记录 其软件界面如下 在软件操作几面上部是工具栏 可以实现软件的各种操作 工具栏的排布如下所示 最左侧为 连接 工具 用于整体连接所有设备 包括分析仪 冷阱
  • MySQL数分:窗口函数

    什么是窗口函数 窗口函数在和当前行相关的一组表行上执行计算 这相当于一个可以由聚合函数完成的计算类型 但不同于常规的聚合函数 使用的窗口函数不会导致行被分组到一个单一的输出行 行保留其独立的身份 在后台 窗口函数能够访问的不止查询结果的当前
  • html怎么控制文字的行数,HTML – 最大.文字行数;这种方法可靠吗?

    我需要限制一些文本 以便它永远不会超过2行 这是我到目前为止 Here is some long text it just keeps on going and going and going Hello how are you I m f
  • 系统更新服务器 win7,win7 64位 sp1 update故障。进行系统更新则始终保持 “正在检查更新”且 - Microsoft Community...

    大家好 如题 win7 64位机子 一旦进行系统更新则 1始终保持Windows update 正在检查更新 并无限读条 2svchost exe netsvcs 则消耗1 2个g内存 且出现较多硬页错误 gt 70 而造成系统无法使用 已
  • 前端实现水波图动态效果

    来自 https blog csdn net sheng li article details 84347987 侵删
  • 地摊经济大火之后,如何从零开始摆摊创业?

    地摊经济大火之后 如何从零开始摆摊创业 分享一份新人摆摊手册 https gitmind cn app doc c29513265
  • Sqlmap的使用方法

    sqlmap是一个非常强大的sql注入检测与辅助工具 但是由于没有图形界面 基本上用起来比较麻烦 我们要了解这些语句 如下 检查注入点 sqlmap u http ooxx com tw star photo php artist id 1
  • C51——IO口配置

    I O口配置 STC89C51RC RD 系列单片机所有I O口均 新增P4口 有3种工作类型 准双向口 弱上拉 标准8051输出模式 仅为输入 高阻 或开漏输出功能 STC89C51RC RD 系列单片机的P1 P2 P3 P4 上电复位
  • 使用pandas将numpy中的数组数据保存为csv文件的方法

    如果想保存numpy中的数组元素到一个文件中 在这方面 pandas工具的使用就会让工作方便很多 下面通过一个简单的小例子来演示一下 首先 创建numpy中的数组 import numpy as np import pandas as pd
  • 面向商用活体检测平台的鲁棒性评估

    摘要 活体检测技术已经成为日常生活中的重要应用 手机刷脸解锁 刷脸支付 远程身份验证等场景都会用到这一技术 但如果攻击者利用虚假视频生成技术生成逼真的换脸视频来攻击上述场景的活体检测系统 将会对这些场景的安全性产生巨大的威胁 针对这个问题使
  • 【Oracle】导入/导出DMP文件

    一 导入dmp文件 1 打开cmd 输入sqlplus 录入账户密码 2 exit 3 输入指令 C Users Administrator gt imp hsa nt person hsa nt person 127 0 0 1 orcl
  • 使用腾讯云盲水印服务进行图片水印添加和提取的一个Python Demo

    目录 前言 起因 可略过 代码 addWatermark py extractWatermark py 运行效果 加水印 提取水印 最后 前言 首先 本文写于 2021 5 17 也许在未来的某个时间点 腾讯云盲水印服务的 Python S
  • 5.时间序列分析

    一 定义 时间序列分析 Time Series Analysis 是指将原来的数据分解为四部分来看 长期趋势 secular trend T 季节趋势 seasonal variation S 循环变动 cyclical variation
  • 西门子博图指令(计数器操作)

    计数器操作 综述 加计数 介绍 程序 程序演示 减计数 介绍 程序 程序演示 加减计数 介绍 程序 程序演示 源程序 综述 主要介绍博图V15中计数器功能块指令的相关操作 仿真PLC为1200系列 1 加计数 介绍 接口参数 声明 数据类型
  • Qt对Excel表格的自动化调用汇总(新建、打开和保存)

    为便于实时采集并保存数据到excel 需要调用QAxObject 首先定义变量excel workbooks workbook worksheets worksheet range 等 ifndef EXCEL H define EXCEL