这是设置打开 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 <QAxObject>
与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<QVariant>> 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 =