Qt之Excel:QAxObject 自定义封装类 ExcelManager

本文介绍如何使用QAxObject改进Excel应用性能,通过ExcelManager类封装常见操作,如工作簿管理、工作表获取和数据写入。讨论了并发问题及解决方案,并展示了如何使用单例模式简化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


​ QAxObject 操作 excel程序,数据读写都很快,唯一的美中不足的是刚开始打开excel程序,则速度会有点慢,如果在GUI中通过按钮的信号槽来启动excel程序,就会觉得有点卡。想用并发去写,结果报一堆错误,没有成功,设想:或许再main函数那里启动,可能不会卡,但是未实践,以后再说。

​ QAxObject 操纵 EXCEL 还是有点烦琐的,显得有点零碎,于是用一个Excel的管理类来封装各个功能模块,方便调用。关于QAxObject 操控 excle 的一些细节,可参考其他文章。

  • 单例–懒汉模式
  • 定义 qExcel 宏,让代码简洁点。

ExcelManager 头文件

#pragma once
#include <QAxObject>
#define qExcel (ExcelManager::Instance())

class ExcelManager
{
public:
    QStringList sheetsNames;
    QAxObject * Application;

    static ExcelManager *Instance();
    ~ExcelManager();    // 构造函数

    void setVisible(bool visible);   // 设置Excel程序是否可见
    void quit();                     // Excel 退出

    void addWorkBook();                // 增加工作簿
    void openWorkBook(QString &fileName);                // 打开工作簿
    void getWorkSheetsName();     // 获取工作表的名称
    void getActiveSheet();

    void appendToActSheet(QVariantList list );

    QAxObject *Rows(int row);
private:
    explicit ExcelManager(QObject *parent = 0);    // 构造函数
    static ExcelManager *self;

    QAxObject * WorkBooks;
    QAxObject * ActiveWorkbook = 0;
    QAxObject * WorkSheets;
    QAxObject * activeSheet=0;
};

ExcelManager 源文件

#include "ExcelManager.h"
#include <QMutex>
#include "DebugTool.h"

ExcelManager* ExcelManager::self = 0;

/**
  * @brief : 原型 static ExcelManager *Instance();,懒汉模式
  * @retval: 返回当前的指针
  */
ExcelManager* ExcelManager::Instance() {
  QMutex mutex;
  if (!self) {
    QMutexLocker locker(&mutex);
    if (!self) {
      self = new ExcelManager;
    }
  }
  return self;
}

ExcelManager::~ExcelManager()
{
}
/**
  * @brief    : 设置Excel程序是否可见, 对于已经显示的Excel 无影响
  * @param : bool visible
  * @retval  :  void
  */
void ExcelManager::setVisible(bool visible = true) {
  Application->setProperty("Visible", visible);
}

/**
  * @brief    :   Excel Application退出,并自动删除Application
  *                   Application->dynamicCall("Quit()");
  * @param :    无
  * @retval:      None
  */
void ExcelManager::quit() {
  QObject::connect(Application, &QObject::destroyed,
                   [] { Dout << "Excel Application is destroyed"; });
  Application->dynamicCall("Quit()");
  Application->deleteLater();
}

/**
  * @brief :      增加新的工作簿
  *                   WorkBooks->dynamicCall("Add");
  * @retval: None
  */
void ExcelManager::addWorkBook() {
  WorkBooks->dynamicCall("Add");
   ActiveWorkbook = Application->querySubObject("ActiveWorkBook");
}

/**
  * @brief :      打开指定的工作簿,并获取
  * @param :   QString& fileName   文件名
  * @retval: None
  */
void ExcelManager::openWorkBook(QString& fileName) {
  WorkBooks->dynamicCall("Open(const QString&)", fileName);
  ActiveWorkbook = Application->querySubObject("ActiveWorkBook");
  qExcel->setVisible (true);
}

// 获取活动工作簿的 所有工作表的名称
/**
  * @brief :      获取活动工作簿的 所有工作表的名称
  * @param :
  * @param :
  * @retval: None
  */
void ExcelManager::getWorkSheetsName() {
  ActiveWorkbook = Application->querySubObject("ActiveWorkBook");
  WorkSheets = ActiveWorkbook->querySubObject("Sheets");
  int Count = WorkSheets->property("Count").toUInt();

  QList<QAxObject*> list;

  for (int i = 1; i <= Count; ++i) {
    auto sheet = WorkSheets->querySubObject("Item(int)", i);
    list << sheet;
  }

  sheetsNames.clear ();

  for (int i = 0; i < Count; ++i) {
    sheetsNames << list.at(i)->property("Name").toString();
  }

  Dout << sheetsNames;
}
// 获取当前活动的工作表
void ExcelManager::getActiveSheet()
{
    activeSheet = Application->querySubObject("ActiveSheet");
}

// 添加数据
void ExcelManager::appendToActSheet(QVariantList list)
{
    if(ActiveWorkbook==0) {
        addWorkBook ();
    }
    getActiveSheet ();
    QAxObject *usedRange = activeSheet->querySubObject("UsedRange");
    QAxObject *rows = usedRange->querySubObject("Rows");

    int  cr = rows->property ("Count").toInt ();
    int sr = usedRange->property ("Row").toInt ();
    Dout <<cr << sr;

    QAxObject *Range = activeSheet->querySubObject ("Cells(int,int)",cr+sr,1);
    Range = Range->querySubObject("Resize(int,int)", list.count() , 4);

    Range->setProperty ("Value", list );       // 可以设置属性的方法写入
    Range->deleteLater ();
    rows->deleteLater ();
    usedRange->deleteLater ();
}

// 获取指定行
QAxObject* ExcelManager::Rows(int row) {
  QAxObject* Row = Application->querySubObject("Rows(int)", row);
  Row->setProperty("Value", row);
  return Row;
}

// 构造函数
ExcelManager::ExcelManager(QObject *parent) {

  Application = new QAxObject("Excel.Application", parent);
  WorkBooks = Application->querySubObject(
      "WorkBooks");  // Application 退出后,WorkBooks会自动销毁
                     //    cout << WorkBooks->parent () << Application;

  // 程序退出,调用excle退出,否则会挂在后台
  QObject::connect(qApp, &QApplication::aboutToQuit, [this] { this->quit(); });
  setVisible(true);  // 默认显示
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值