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); // 默认显示
}