QT使用QAxObject读取Excel教程-全网最全_qt读取excel,阿里P8面试官都说太详细了

2401_84263282 2024-07-11 17:35:02 阅读 77

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)

img

正文

实战项目4实战项目5-封装好的库

头文件 excelmanager.h

实现文件 excelmanager.cpp其他

项目实战6-封装好的库

六、一些小技巧

读取excel中的数据

一、背景

QT中没有操作Excel的官方库,本文章介绍的是Windows系统的ActiveX对象(QAxObject)操作Excel。

当然还有一些开源库可以用来操作Excel,详见:Qt处理Excel的一些库

本文只对QAxObject读取Excel作说明。

二、介绍

首先,我们先来解释一些概念,方面我们去理解Qt操作excel的基本流程。

Qt中,QAxObject对COM对象进行封装,QAObject派生自QAxBase,QAxBase提供了一组API通过IUnknown指针直接访问COM对象。具体结构如下图。

这里写图片描述

我们要操作的Excel也是一个COM对象,因此,可以采用上述方式实现对Excel的操作。

在具体操作之前,我们先了解一下excel的层次结构,如图所示,Application对象–>Workbook对象–>Worksheet对象–>Range对象。

1个excel有一个Application对象,1个Application对象有多个workbook对象组成,这些workbook对象由workbooks对象统一管理,workbook对象下包含若干个worksheet,这些worksheet对象由worksheets对象统一管理,worksheet下面的range对象,对应这worksheet里面的表格单元了。

这里写图片描述

基本操作方法
获取对象

上述对象获取某个子对象一般通过 QAxObjectquerySubObject() 方法,比如:

QAxObject *excel = new QAxObject(“Excel.Application”);

QAxObject *workbooks = excel->;querySubObject(“WorkBooks”);

QAxObject *workbook = workbooks->querySubObject(“Open(QString&)”, path);

QAxObject *sheets = workbook->querySubObject(“Sheets”);

QAxObject *sheet = sheets->querySubObject(“Item(int)”, 1);

QAxObject *range = sheet->querySubObject(“Cells(int,int)”, row, col);

这其中依次得到的对象分别是:

Excel 的 Application 对象。管理 Workbook 对象的 Workbooks 对象。路径为 path 的 Excel 文件对应的 Workbook 对象。管理其中工作表 SheetSheets 对象。第一张工作表对应的 Sheet 对象。其中第 row 行,第 col 列的表格单元的 range 对象。

调用动态方法

还可以通过 dynamicCall() 方法调用一些动作,比如:

workbook->dynamicCall(“SaveAs(const QString &)”, QDir::toNativeSeparators(path));

这是调用另存为 path 路径。

workbook->dynamicCall(“Save()”);

这是调用保存。

range->dynamicCall(“Value”, value);

这时设置单元格的值。

excel->dynamicCall(“SetVisible(bool)”, false);

这是设置打开 Excel 时不可见(也就是后台进行)。

workbooks->dynamicCall(“Add”);

这是新建一个 Excel 文件。

workbooks->dynamicCall(“Close()”);

excel->dynamicCall(“Quit()”);

这是关闭 Excel 应用。

除此之外,还有很多类似的方法。

设置和获取属性

一般通过 setProperty() 方法设置属性,比如:

range->setProperty(“VerticalAlignment”, -4108);

range->setProperty(“HorizontalAlignment”, -4108);

range->setProperty(“WrapText”, true);

range->setProperty(“MergeCells”, true);

range->setProperty(“Bold”, isBold);

分别为设置单元格:

竖直居中。水平居中。文本自动换行。单元格合并。字体加粗。

而如果想获取属性就可以通过 property() 方法,会返回一个 QVariant 对象,可以根据需求通过 toString()toInt() 等方法转为 Qt 的基本类型。

更多相关

除了上面提到的,更多的方法可以直接到微软官网查看文档

三、使用要求

添加模块

在Qt Creator中使用QAxObject需要先在pro中添加:

QT += axcontainer

包含头文件ActiveQt/QAxObject

#include

与excel com连接的方法

QAxObject *excel = new QAxObject(“Excel.Application”); //!建立excel操作对象,并连接Excel控件

excel->dynamicCall(“SetVisible (bool Visible)”, “false”); //! 设置为不显示窗体

excel->setProperty(“DisplayAlerts”, false); //! 不显示任何警告信息, 如关闭时的是否保存提示

excel->dynamicCall(“Quit(void)”); //! 关闭excel程序,操作完后记着关闭,由于是隐藏在后台进程中,不关闭进程会有很多excel.exe。

workbook->dynamicCall(“Close(Boolean)”, false); //! 关闭exce程序先关闭.xls文件

Excel基本操作

只介绍简单的读写操作,需要修改单元格格式等操作,请"Excel VBA参考手册.chm"

excel文件操作

获取当前工作簿的集合,这里需要注意,工作簿就是Excel文件。

QAxObject *workbooks = excel->querySubObject(“Workbooks”); //! 获取工作簿(excel文件)集合

新建一个工作簿,新建一个工作簿就是新建一个Excel文件

workbooks->synamicCall(“Add”); //新建一个工作簿

QAxObject *workbook = excel->querySubObject(“ActiveWorkBook”); //! 获取当前工作簿

打开一个已有的工作簿,就是打开一个Excel文件

QString filename = “e:/123.xlsx”;

QAxObject* workbook = workbooks->querySubObject(“Open(const QString&)”, filename);

保存工作簿

workbook->dynamicCall(“Save()”); //!保存文件

workbook->dynamicCall(“Close(Boolean)”, false); //! 关闭文件

excel->dynamicCall(“Quit()”); //! 关闭excel

另存为工作簿

QDir::toNativeSeparators,将路径中的"/“转换为”“,否则无法保存,”/"只是qt中可以识别

workbook->dynamiCall(“SaveAs(const QString&)”, QDit::toNativeSeparators(filename));

workbook->synamicCall(“Close(Boolean)”, false); //! 关闭文件

excel->dynamicCall(“Quit()”); //! 关闭excel

Sheet工作表操作

获取所有工作表

QAxObject *worksheets = workbook->querySubObject(“Sheets”):

根据序号获取某个工作表,序号顺序就是excel 打开后下方的排序

QAxObject *worksheet = worksheets->querySubObejct(“Item(int)”, 1);

获取表中的行数列数

QAxObject* usedrange = worksheet->querySubObject(“UsedRange”); //! sheet 范围

int intRowStart = usedrange->property(“Row”).toInt(); //! 起始行数

int intColStart = usedrange->property(“Column”).toInt(); //! 起始列数

QAxObject *rows, *columns;

rows = usedrange->querySubObject(“Rows”): //! 行

columns = usedrange->querySubObject(“Columns”); //! 列

int intRow = rows->property(“Count”).toInt(); //! 行数

int intCol = columns->property(“Count”).toInt(); //! 列数

内容操作

数据内容操作–获取单元格–基于坐标

QAxObject *cell = worksheet->querySubObject(“Cells(int, int)”, i, j);

数据内容操作–获取单元格–基于行列名称

QAxObject *cell = worksheet->querySubObject(“Range(QVariant, QVariant)”, “A1”);

数据内容操作–读单元格内容

QVariant cell_value = cell->property(“Value”);

数据内容操作-- 写单元格内容

cell->setProperty(“Value”, “内容”);

大数据量读取

读取所有单元格内容-数据量大,只需要进行一次操作即可读取所有内容,避免重复对每个单元格进行QAxObect操作

QVariant var;

QAxObject * usedRange = sheet->querySubObject(“UseRange”); //! 获取用户区域范围

if(NULL == usedRange || usedRange->isNull())

{

return var;

}

var = usedRange->dynamicCall(“Value”); // 读取区域内所有值

delete usedRange;

此时结果以QVariant保存,需要自行转化为QList

QList<QList> excel_list;

auto rows = var.toList();

for(auto row:rows)

{

excel_list.append(row.toList());

}

大数据写入

以QList存储,需要限定范围

QAxObject *user_rang = this->sheet->querySubObject(“Rang(const QString&)”, “A1:D100”);

写入数据

rang->setProperty(“Value”, var);

四、具体使用说明

一般我们使用QAxObject操作Excel分为以下的步骤:

连接控件Excel打开工作簿(新建或打开Excel文件)打开sheet获取行数,列数读和写设置样式保存文件另存为关闭文件

下面我们就具体的说明一下怎么完成上面的操作。

1:连接控件Excel

2: 打开工作簿(新建或打开Excel文件)

3: 打开sheet

4: 获取行数,列数

5: 读和写

6:设置样式

7: 保存文件

8:另存为

9:关闭文件

1:连接控件Excel

QAxObject excel(“Excel.Application”);//连接Excel控件

excel.setProperty(“Visible”, false);// 不显示窗体

excel->setProperty(“DisplayAlerts”, false); // 不显示任何警告信息。如果为true, 那么关闭时会出现类似"文件已修改,是否保存"的提示

2: 打开工作簿(新建或打开Excel文件)

QAxObject* workbooks = excel->querySubObject(“WorkBooks”); // 获取工作簿集合

2.1新建

workbooks->dynamicCall(“Add”); // 新建一个工作簿

QAxObject* workbook = excel->querySubObject(“ActiveWorkBook”); // 获取当前工作簿

2.2打开

QAxObject* workbook = workbooks->querySubObject(“Open(const QString&)”, (“C:/Users/lixc/Desktop/tt2.xlsx”));//Excel文件地址

3: 打开sheet

QAxObject* worksheet = workbook->querySubObject(“WorkSheets(int)”, 1); // 获取工作表集合的工作表1, 即sheet1

4: 获取行数,列数

QAxObject* usedrange = worksheet->querySubObject(“UsedRange”); // sheet范围

int intRowStart = usedrange->property(“Row”).toInt(); // 起始行数 为1

int intColStart = usedrange->property(“Column”).toInt(); // 起始列数 为1

QAxObject *rows, *columns;

rows = usedrange->querySubObject(“Rows”); // 行

columns = usedrange->querySubObject(“Columns”); // 列

int intRow = rows->property(“Count”).toInt(); // 行数

int intCol = columns->property(“Count”).toInt(); // 列数

qDebug()<<“intRowStart:”<<intRowStart<<“\t intColStart”<<intColStart;

qDebug()<<“intRow”<<intRow<<“\t intCol”<<intCol;

5: 读和写

5.1读取单元格方式1

for(int i=intRowStart;i<intRow+intRowStart;i++)

{

for(int j=intColStart;j<intCol+intColStart;j++)

{

QAxObject* cell = worksheet->querySubObject(“Cells(int, int)”, i, j); //获单元格值

qDebug() << i << j << cell->dynamicCall(“Value2()”).toString();

}

}

5.2读取单元格方式2

QString X = “A2”; //设置要操作的单元格,A1

QAxObject* cellX = worksheet->querySubObject(“Range(QVariant, QVariant)”, X); //获取单元格

qDebug() << cellX->dynamicCall(“Value2()”).toString();

5.3写单元格方式1

cellX->dynamicCall(“SetValue(conts QVariant&)”, 100); // 设置单元格的值

5.4写单元格方式2

QAxObject *cell_5_6 = worksheet->querySubObject(“Cells(int,int)”, 5, 6);

cell_5_6->setProperty(“Value2”, “Java”);

6:设置样式(未测试)

//获得单元格对象

QAxObject* cell = worksheet->querySubObject(“Cells(int, int)”, i, j);

6.1设置单元格内容的显示setProperty()

cell->setProperty(“Value”, “Java C++ C# PHP Perl Python Delphi Ruby”); //设置单元格值

cell->setProperty(“RowHeight”, 50); //设置单元格行高

cell->setProperty(“ColumnWidth”, 30); //设置单元格列宽

cell->setProperty(“HorizontalAlignment”, -4108); //左对齐(xlLeft):-4131 居中(xlCenter):-4108 右对齐(xlRight):-4152

cell->setProperty(“VerticalAlignment”, -4108); //上对齐(xlTop)-4160 居中(xlCenter):-4108 下对齐(xlBottom):-4107

cell->setProperty(“WrapText”, true); //内容过多,自动换行

cell->dynamicCall(“ClearContents()”); //清空单元格内容

6.2设置单元格的样式 QAxObject* interior = cell->querySubObject(“Interior”);

QAxObject* interior = cell->querySubObject(“Interior”);

interior->setProperty(“Color”, QColor(0, 255, 0)); //设置单元格背景色(绿色)

QAxObject* border = cell->querySubObject(“Borders”);

border->setProperty(“Color”, QColor(0, 0, 255)); //设置单元格边框色(蓝色)

QAxObject *font = cell->querySubObject(“Font”); //获取单元格字体

font->setProperty(“Name”, QStringLiteral(“华文彩云”)); //设置单元格字体

font->setProperty(“Bold”, true); //设置单元格字体加粗

font->setProperty(“Size”, 20); //设置单元格字体大小

font->setProperty(“Italic”, true); //设置单元格字体斜体

font->setProperty(“Underline”, 2); //设置单元格下划线

font->setProperty(“Color”, QColor(255, 0, 0)); //设置单元格字体颜色(红色)

6.3合并拆分单元格

QString merge_cell;

merge_cell.append(QChar(3 - 1 + ‘A’)); //初始列

merge_cell.append(QString::number(5)); //初始行

merge_cell.append(“:”);

merge_cell.append(QChar(5 - 1 + ‘A’)); //终止列

merge_cell.append(QString::number(8)); //终止行

QAxObject *merge_range = work_sheet->querySubObject(“Range(const QString&)”, merge_cell);

//merge_range 可以设置单元格属性

merge_range->setProperty(“MergeCells”, true); //合并单元格

//merge_range->setProperty(“MergeCells”, false); //拆分单元格

7: 保存文件

7.1保存当前文件(根据已经打开的工作簿,如果工作簿是新建的文件保存默认存储于Document文件夹中)

workbook->dynamicCall(“Save()”); //保存文件

7.2指定目录存储

QString fileName = QFileDialog::getSaveFileName(NULL, QStringLiteral(“保存文件”), QStringLiteral(“excel名称”), QStringLiteral(“EXCEL(*.xlsx)”));

//QString fileName=QStringLiteral(“C:/Users/lixc/Desktop/excel名称.xlsx”);

workbook->dynamicCall(“SaveAs(const QString&)”, QDir::toNativeSeparators(fileName)); //保存到filepath

// 注意一定要用QDir::toNativeSeparators, 将路径中的"/“转换为”", 不然一定保存不了

9:关闭文件

workbook->dynamicCall(“Close (Boolean)”, false); //关闭文件

excel.dynamicCall(“Quit(void)”); //退出

如果excel存在于堆上,注意手动释放

delete excel;

注意:调试过程中出现异常:需要打开任务管理器,结束Excle进程

//获得单元格对象

QAxObject* cell = worksheet->querySubObject(“Cells(int, int)”, i, j);

五、项目实战

在了解了大致的使用步骤后,我们可以通过实际项目来综合运用了。

实战项目1

项目代码如下:

//#include <QtGui/QApplication>

#include

#include “mainwindow.h”

#include

#include

#include

#include

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

// QTextCodec::setCodecForCStrings(QTextCodec::codecForName(“GB18030”));

// QTextCodec::setCodecForLocale(QTextCodec::codecForName(“GB18030”));

// QTextCodec::setCodecForTr(QTextCodec::codecForName(“GB18030”));

QAxWidget excel(“Excel.Application”);

excel.setProperty(“Visible”, true);

QAxObject * workbooks = excel.querySubObject(“WorkBooks”);

if (!workbooks) return 1; //错误返回,用 if(!excel)则不行

workbooks->dynamicCall(“Open (const QString&)”, QString(“E:\wenjian\cs\code\QT\testExcel2\test.xlsx”));

QAxObject * workbook = excel.querySubObject(“ActiveWorkBook”); //5) 获取活动工作簿:

QAxObject * worksheets = workbook->querySubObject(“WorkSheets”); //获取所有的工作表:

int intCount = worksheets->property(“Count”).toInt(); //获取工作表数量:

qDebug() << “工作表数量” << intCount;

for (int i = 1; i <= intCount; i++)

{

int intVal;

QAxObject * worksheet = workbook->querySubObject(“Worksheets(int)”, i); //获取第i个工作表:

qDebug() << i << worksheet->property(“Name”).toString();

QAxObject * range = worksheet->querySubObject(“Cells(1,1)”); //获取cell的值:

intVal = range->property(“Value”).toInt();

range->setProperty(“Value”, QVariant(intVal+1));

QAxObject * range2 = worksheet->querySubObject(“Range(C1)”);

intVal = range2->property(“Value”).toInt();

range2->setProperty(“Value”, QVariant(intVal+1));

}

QAxObject * worksheet = workbook->querySubObject(“Worksheets(int)”, 1);

QAxObject * usedrange = worksheet->querySubObject(“UsedRange”);

QAxObject * rows = usedrange->querySubObject(“Rows”);

QAxObject * columns = usedrange->querySubObject(“Columns”);

int intRowStart = usedrange->property(“Row”).toInt();

int intColStart = usedrange->property(“Column”).toInt();

int intCols = columns->property(“Count”).toInt();

int intRows = rows->property(“Count”).toInt();

qDebug() << “表格行数” << intRows;

qDebug() << “表格列数” << intCols;

// for (int i = intRowStart; i < intRowStart + intRows; i++)

// {

// for (int j = intColStart; j <= intColStart + intCols; j++)

// {

// QAxObject * range = worksheet->querySubObject(“Cells(int,int)”, i, j );

// qDebug() << i << j << range->dynamicCall(“Value2()”).toString(); //property(“Value”);不行

// }

// }

for (int i = intRowStart; i < intRows; i++)

{

for (int j = intColStart; j < intCols; j++)

{

QAxObject * range = worksheet->querySubObject(“Cells(int,int)”, i, j );

qDebug() << i << j << range->dynamicCall(“Value2()”).toString(); //property(“Value”);不行

}

}

excel.setProperty(“DisplayAlerts”, 0);

//qDebug(“here?”);

workbook->dynamicCall(“SaveAs (const QString&)”, QString(“E:\wenjian\cs\code\QT\testExcel2\temp.xls”));//这里只能用相对路径!!!用绝对路径就报下面的错误。

excel.setProperty(“DisplayAlerts”, 1);

workbook->dynamicCall(“Close (Boolean)”, false);

excel.dynamicCall(“Quit (void)”);

MainWindow w;

w.show();

return a.exec();

}

test.xlsx中内容如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VWR6lCEv-1677385787835)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20230226101051423.png)]

执行代码会打印如下信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZMXaMuYv-1677385787836)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20230226101140437.png)]

说明代码把Excel表格中的内容读取并打印出来了。

实战项目2

具体的操作流程如下:

QAxWidget excel(“Excel.Application”);

显示当前窗口:

excel.setProperty(“Visible”, true);更改 Excel 标题栏:

excel.setProperty(“Caption”, “Invoke Microsoft Excel”);添加新工作簿:

QAxObject * workbooks = excel.querySubObject(“WorkBooks”);

workbooks->dynamicCall(“Add”);打开已存在的工作簿:

workbooks->dynamicCall(“Open (const QString&)”, QString(“c:/test.xls”));获取活动工作簿:

QAxObject * workbook = excel.querySubObject(“ActiveWorkBook”);获取所有的工作表:

QAxObject * worksheets = workbook->querySubObject(“WorkSheets”);获取工作表数量:

int intCount = worksheets->property(“Count”).toInt();获取第一个工作表:

QAxObject * worksheet = workbook->querySubObject(“Worksheets(int)”, 1);获取cell的值:

QAxObject * range = worksheet->querySubObject(“Cells(int,int)”, 1, 1 );

项目代码如下:

#include

#include

#include

//#include

#include “mainwindow.h”

#include

int main(int argc, char **argv)

{

QApplication a(argc, argv);

QAxObject excel(“Excel.Application”);

excel.setProperty(“Visible”, false);

QAxObject * workbooks = excel.querySubObject(“WorkBooks”);

workbooks->dynamicCall(“Open (const QString&)”, QString(“E:\wenjian\cs\code\QT\testExcel3\test.xlsx”));

QAxObject * workbook = excel.querySubObject(“ActiveWorkBook”);

QAxObject * worksheets = workbook->querySubObject(“WorkSheets”);

int intCount = worksheets->property(“Count”).toInt();

QAxObject * worksheet = workbook->querySubObject(“Worksheets(int)”, 1);

QAxObject * usedrange = worksheet->querySubObject(“UsedRange”);

QAxObject * rows = usedrange->querySubObject(“Rows”);

QAxObject * columns = usedrange->querySubObject(“Columns”);

int intRowStart = usedrange->property(“Row”).toInt();

int intColStart = usedrange->property(“Column”).toInt();

int intCols = columns->property(“Count”).toInt();

int intRows = rows->property(“Count”).toInt();

qDebug() << “开始行数” << intRowStart;

qDebug() << “开始列数” << intColStart;

qDebug() << “总行数” << intRows;

qDebug() << “总列数” << intCols;

for (int i = intRowStart; i < intRowStart + intRows; i++)

{

for (int j = intColStart; j < intColStart + intCols; j++)

{

QAxObject * range = worksheet->querySubObject(“Cells(int,int)”, i, j );

qDebug() << i << j << range->property(“Value”);

}

}

excel.setProperty(“DisplayAlerts”, 0);

workbook->dynamicCall(“SaveAs (const QString&)”, QDir::toNativeSeparators(“E:\wenjian\cs\code\QT\testExcel3\temp.xlsx”));

excel.setProperty(“DisplayAlerts”, 1);

workbook->dynamicCall(“Close (Boolean)”, false);

excel.dynamicCall(“Quit (void)”);

return a.exec();

}

被操作的Excel文件和实战项目1中的一致。

执行代码打印信息如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OIat4Y1r-1677385787836)(C:\Users\10521\AppData\Roaming\Typora\typora-user-images\image-20230226102643579.png)]

实战项目3

代码如下:

// 参考内容: https://blog.csdn.net/qq319923400/article/details/80149367

// https://www.cnblogs.com/lifexy/p/10743316.html

// https://www.cnblogs.com/lifexy/p/10743352.html

#include “widget.h”

#include

#include // .pro需要添加: QT += axcontainer

#include

#include

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

Widget w;

QAxObject excel(“Excel.Application”); // 关联excel

excel.setProperty(“Visible”, true); // 运行程序时要不要通过excel打开当前编辑的表格

excel.setProperty(“DisplayAlerts”, false); // excel关闭时是否询问要不要保存

//excel.setProperty(“Caption”, “Qt Excel”); // 类似于文件类型吧,感觉这个名称意义不大

QAxObject* workbooks = excel.querySubObject(“WorkBooks”);

workbooks->dynamicCall(“Add”); // 增加一个excel表格,写两遍会打开两个不同的excel表格

QAxObject* workbook = excel.querySubObject(“ActiveWorkBook”);

QAxObject* worksheet = workbook->querySubObject(“WorkSheets(QString)”, “Sheet1”); // 通过sheet名获取sheet1

// QAxObject* worksheet = workbook->querySubObject(“WorkSheets(int)”, “1”); // 通过编号获取sheet1, 结果和上面一样

worksheet->setProperty(“Name”, “Shadow3D_1”); // 修改sheet名

// 行列相关查询

QAxObject* usedrange = worksheet->querySubObject(“UsedRange”);

int intRowStart = usedrange->property(“Row”).toInt();

int intColStart = usedrange->property(“Column”).toInt();

// 注意: 这里的行和列都是从1开始计数的

qDebug() << "intRowStart: " << intRowStart << "\tintColStart: " << intColStart;

// 查看已经使用的最大行数和最大列数

int intRow = usedrange->querySubObject(“Rows”)->property(“Count”).toInt();

int intCol = usedrange->querySubObject(“Columns”)->property(“Count”).toInt();

qDebug() << "Rows: " << intRow << "\tColumns: " << intCol;

// 写单元格

for(int i = 1; i < 10; i++)

for(int j = 1; j < 10; j++)

worksheet->querySubObject(“Cells(int, int)”, i, j)->setProperty(“Value2”, i+j);

// 查看已经使用的最大行数和最大列数

usedrange = worksheet->querySubObject(“UsedRange”); // 当重新修改sheet后,必须重新获取UsedRange值才能得到最新的行数和列数。

QAxObject* rows = usedrange->querySubObject(“Rows”);

QAxObject* columns = usedrange->querySubObject(“Columns”);

qDebug() << rows << columns; // 不知道这个rows和columns的值表示什么意义,每次运行都不一样。。。

intRow = rows->property(“Count”).toInt();

intCol = columns->property(“Count”).toInt();

qDebug() << "Rows: " << intRow << "\tColumns: " << intCol;

// 读单元格

QAxObject* cell = worksheet->querySubObject(“Cells(int, int)”, 5, 5); // 获取单元格对象

QString cellStr = cell->dynamicCall(“Value2()”).toString();

qDebug() << "cell: " << cellStr; // “10”

qDebug() << "cell: " << cellStr.toUtf8().data(); // 10 ( QString 类型转换为 QByteArray,再转换成Char* )

// 单元格格式

cell = worksheet->querySubObject(“Cells(int, int)”, 11, 11);

cell->setProperty(“Value”, “bool setProperty(const char *name, const QVariant &value”);

cell->setProperty(“RowHeight”, 50);

cell->setProperty(“ColumnWidth”, 30);

cell->setProperty(“HorizontalAlignment”, -4108); // left:-4131 center:-4108 right:-4152

cell->setProperty(“VerticalAlignment”, -4108); // left:-4161 center:-4108 right:-4107

cell->setProperty(“WrapText”, true); // 单元格内容多时自动换行

// cell>dynamicCall(“ClearContents()”); // 清空单元格内容

// 设置颜色,字体

cell = worksheet->querySubObject(“Cells(int, int)”, 12, 12); // 获取单元格对象

cell->setProperty(“Value”, “Text”);

QAxObject* interior = cell->querySubObject(“Interior”);

interior->setProperty(“Color”, QColor(0, 255, 0)); // 背景颜色: Green

QAxObject* border = cell->querySubObject(“Borders”);

border->setProperty(“Color”, QColor(0, 0, 255)); // 边框颜色: Blue

QAxObject* font = cell->querySubObject(“Font”);

font->setProperty(“Name”, QStringLiteral(“华文彩云”));

font->setProperty(“Bold”, true);

font->setProperty(“Size”, 20);

font->setProperty(“Italic”, true);

font->setProperty(“Underline”, 3); // 下划线:2 双下划线:3

font->setProperty(“Color”, QColor(255, 0, 0)); // 字体颜色: Red

// 合并拆分单元格

QString merge_cell;

merge_cell.append(QChar(‘A’+20)); // 从第(20+1)列开始,因为’A’表示第一列

merge_cell.append(QString::number(15)); // 从第15行开始

merge_cell.append(“:”);

merge_cell.append(QChar(‘A’+21)); // 到(21+1)列结束

merge_cell.append(QString::number(16)); // 到第16列结束

QAxObject* merge_range = worksheet->querySubObject(“Range(const QString&)”, merge_cell);

merge_range->setProperty(“MergeCells”, true); // 合并单元格

// merge_range->setProperty(“MergeCells”, false); // 拆分单元格

// 文件保存

QString fileName = QFileDialog::getSaveFileName(NULL, QStringLiteral(“Save File As”), QStringLiteral(“Shadow3D”), QStringLiteral(“EXCEL(*.xlsx | *.xls)”));

workbook->dynamicCall(“SaveAs(conse QString&)”, QDir::toNativeSeparators(fileName));

// 关闭文件

workbook->dynamicCall(“Close(Boolean)”, false);

// 退出excel

excel.dynamicCall(“Quit(void)”);

// delete excel; // 如果excel是通过new方式建立在堆上,要记得释放。

w.show();

return a.exec();

}

实战项目4

widget.h

#ifndef WIDGET_H

#define WIDGET_H

#include

#include <ActiveQt/QAxObject>

QT_BEGIN_NAMESPACE

namespace Ui { class Widget; }

QT_END_NAMESPACE

class Widget : public QWidget

{

Q_OBJECT

public:

Widget(QWidget *parent = nullptr);

~Widget();

void OpenExcel();

void AddNewExcel();

void SaveAndClose();

int GetRowsCount();

QString GetCell(int row, int column);

QString GetCell(QString numer);

void SetCell(int row, int column, QString value);

void SetCell(QString number, QString value);

void SetCellColor(int row, int column, QColor color);

private:

Ui::Widget *ui;

QAxObject *m_pExcel;

QAxObject *m_pWorkBooks;

QAxObject *m_pWorkBook;

QAxObject *m_pWorkSheets;

QAxObject *m_pWorkSheet;

};

#endif // WIDGET_H

widget.cpp

#include “widget.h”

#include “ui_widget.h”

#include

#include

Widget::Widget(QWidget *parent)

QWidget(parent)

, ui(new Ui::Widget)

, m_pExcel(nullptr)

, m_pWorkBooks(nullptr)

, m_pWorkBook(nullptr)

, m_pWorkSheets(nullptr)

, m_pWorkSheet(nullptr)

{

ui->setupUi(this);

// 连接excel 控件

m_pExcel = new QAxObject(“Excel.Application”);

// m_pExcel->setControl(“Excel.Applicatio”);

// 设置操作excel时不打开excel窗体

m_pExcel->dynamicCall(“SetVisible(bool Visible)”,false);

// 设置不显示任何警告信息

m_pExcel->setProperty(“DisplayAlert”,false);

}

// 打开已有的excel

void Widget::OpenExcel()

{

QString strExcelPath = “C:\Users\Qcx\Desktop\test.xlsx”;

// 获取当前工作簿

m_pWorkBooks = m_pExcel->querySubObject(“WorkBooks”);

// 打开指定工作簿

m_pWorkBook = m_pWorkBooks->querySubObject(“Open(const QString&)”,strExcelPath);

if(m_pWorkBook)

{

qDebug()<<“Open Excel Success!”;

}

// 获取sheets

m_pWorkSheets = m_pWorkBook->querySubObject(“Sheets”);

// 获取某个sheet

m_pWorkSheet = m_pWorkSheets->querySubObject(“Item(int)”,1);

}

// 创建新的Excel

void Widget::AddNewExcel()

{

// 获取当前工作簿

m_pWorkBooks = m_pExcel->querySubObject(“WorkBooks”);

m_pWorkBooks->dynamicCall(“Add”);

m_pWorkBook = m_pExcel->querySubObject(“ActiveWorkBook”);

m_pWorkSheets = m_pWorkBook->querySubObject(“Sheets”);

m_pWorkSheet = m_pWorkSheets->querySubObject(“Item(int)”,1);

}

// 保存并关闭Excel

void Widget::SaveAndClose()

{

QString strSavePath = “C:\Users\Qcx\Desktop\temp.xlsx”;

// 保存文件,一定要将路径中的’/‘转为’\',前者只能被Qt识别

m_pWorkBook->dynamicCall(“SaveAs(const QString&)”, QDir::toNativeSeparators(strSavePath));

// 关闭文件

m_pWorkBook->dynamicCall(“Close()”);

// 关闭excel

m_pExcel->dynamicCall(“Quit()”);

delete m_pExcel;

m_pExcel = nullptr;

}

// 获取行数

int Widget::GetRowsCount()

{

int iRows = 0;

QAxObject *pRows = m_pWorkSheet->querySubObject(“Rows”);

iRows = pRows->property(“Count”).toInt();

return iRows;

}

// 获取单元格内容,行号+列号

QString Widget::GetCell(int row, int column)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(int, int)”, row, column);

return pCell->property(“Value”).toString();

}

// 获取单元格内容,单元格标号如: A1,C5

QString Widget::GetCell(QString number)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(QString)”, number);

return pCell->property(“Value”).toString();

}

// 设置单元格内容,行号+列号

void Widget::SetCell(int row, int column, QString value)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(int, int)”, row, column);

pCell->setProperty(“Value”, value);

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)

img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

nullptr;

}

// 获取行数

int Widget::GetRowsCount()

{

int iRows = 0;

QAxObject *pRows = m_pWorkSheet->;querySubObject(“Rows”);

iRows = pRows->property(“Count”).toInt();

return iRows;

}

// 获取单元格内容,行号+列号

QString Widget::GetCell(int row, int column)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(int, int)”, row, column);

return pCell->property(“Value”).toString();

}

// 获取单元格内容,单元格标号如: A1,C5

QString Widget::GetCell(QString number)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(QString)”, number);

return pCell->property(“Value”).toString();

}

// 设置单元格内容,行号+列号

void Widget::SetCell(int row, int column, QString value)

{

QAxObject *pCell = m_pWorkSheet->querySubObject(“Range(int, int)”, row, column);

pCell->setProperty(“Value”, value);

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)

[外链图片转存中…(img-OKZIkK3O-1713156247433)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。