QAxObject对COM对象进行了封装,QAxObject派生自QAxBase,而后者提供了一组API通过
IUnknown(不清楚
IUnknown的同学可以去看看COM对象模型
)指针
直接访问COM对象,我们这里讲的excel也是一个COM对象,因此我们可以通过QAxObject来操作它,为了便于理解,我们首先了解一下excel的对象的主要层次结构:
上图是excel对象的层次结构,1个excel就有1个Application对象,1个Application对象由多个Workbook对象组成,这些Workbook对象由Workbooks对象统一管理,Workbook对象下可以包含若干个Worksheet,这些Worksheet对象也有一个WorkSheets对象来统一管理,接下来是Range对象,这个对象就对应Worksheet里的表格单元了,好了大家应该清楚了Excel的对象的主要层次结构了吧,下面我们来看看QAxObject是怎么来导出excel的: (该部分理论参考别处网络文档,文章结尾表明参考处)
1、要在QT中使用QAxObject,需要在.pro文件中添加语句:CONFIG += qaxcontainer,之后便可以添加头文件:#include
2、这里通过帮助类实现数据导出excel:(通过封装类,方便之后的使用)
.h 文件:
#ifndef
EXCELHELPER_H
#define
EXCELHELPER_H
#include
#include
#include
class
ExcelHelper
{
public:
ExcelHelper();
void
newExcel(
const
QString
&fileName);
void
appendSheet(
const
QString
&sheetName);
void
setCellValue(
int
row,
int
column,
const
QString
&value);
void
saveExcel(
const
QString
&fileName);
void
freeExcel();
QAxObject
*
pApplication;
QAxObject
*
pWorkBooks;
QAxObject
*
pWorkBook;
QAxObject
*
pSheets;
QAxObject
*
pSheet;
};
#endif
//
EXCELHELPER_H
.cpp文件
ExcelHelper
::ExcelHelper()
{
}
//新建Execl文件
void
ExcelHelper
::newExcel(
const
QString
&fileName)
{
pApplication
=
new
QAxObject
();
pApplication
->setControl(
"Excel.Application"
);
//连接Excel控件
pApplication
->dynamicCall(
"SetVisible(bool)"
,
false
);
//false不显示窗体
pApplication
->setProperty(
"DisplayAlerts"
,
false
);
//不显示任何警告信息。
pWorkBooks
=
pApplication
->querySubObject(
"Workbooks"
);
QFile
file(fileName);
if
(file.exists()){
pWorkBook
=
pWorkBooks
->querySubObject(
"Open(const
QString
&)"
,
fileName);
}
else
{
pWorkBooks
->dynamicCall(
"Add"
);
pWorkBook
=
pApplication
->querySubObject(
"ActiveWorkBook"
);
}
//默认有一个sheet
pSheets
=
pWorkBook
->querySubObject(
"Sheets"
);
pSheet
=
pSheets
->querySubObject(
"Item(int)"
,
1
);
}
//增加1个Worksheet,这里要注意:默认有一个sheet,需要的时候再调用这个函数
void
ExcelHelper
::appendSheet(
const
QString
&sheetName)
{
int
cnt
=
1
;
QAxObject
*pLastSheet
=
pSheets
->querySubObject(
"Item(int)"
,
cnt);
pSheets
->querySubObject(
"Add(QVariant)"
,
pLastSheet->asVariant());
pSheet
=
pSheets
->querySubObject(
"Item(int)"
,
cnt);
pLastSheet->dynamicCall(
"Move(QVariant)"
,
pSheet
->asVariant());
pSheet
->setProperty(
"Name"
,
sheetName);
}
//向Excel单元格中写入数据
//PS:这里涉及到 对于数据格式的设置
void
ExcelHelper
::setCellValue(
int
row,
int
column,
const
QString
&value)
{
QAxObject
*pRange
=
pSheet
->querySubObject(
"Cells(int,int)"
,
row,
column);
pRange->dynamicCall(
"Value"
,
value);
//内容居中
pRange->setProperty(
"HorizontalAlignment"
,
-
4108
);
pRange->setProperty(
"VerticalAlignment"
,
-
4108
);
// pRange->setProperty("RowHeight", 50); //设置单元格行高
//
pRange
->setProperty("ColumnWidth",
30);
//设置单元格列宽
//
pRange
->setProperty("HorizontalAlignment",
-4108);
//左对齐(xlLeft):-4131
居中(xlCenter):-4108
右对齐(xlRight):-4152
//
pRange
->setProperty("VerticalAlignment",
-4108);
//上对齐(xlTop)-4160
居中(xlCenter):-4108
下对齐(xlBottom):-4107
//
pRange
->setProperty("WrapText",
true);
//内容过多,自动换行
//
pRange
->dynamicCall("ClearContents()");
//清空单元格内容
//
QAxObject*
interior
=pRange
->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));
//设置单元格字体颜色(红色)
if
(row
==
1
){
//加粗
QAxObject
*font
=
pRange->querySubObject(
"Font"
);
//获取单元格字体
font->setProperty(
"Bold"
,
true
);
//设置单元格字体加粗
}
}
//保存Excel
void
ExcelHelper
::saveExcel(
const
QString
&fileName)
{
pWorkBook
->dynamicCall(
"SaveAs(const
QString
&)"
,
QDir
::toNativeSeparators(fileName));
}
//释放Excel
void
ExcelHelper
::freeExcel()
{
if
(
pApplication
!=
NULL
){
pApplication
->dynamicCall(
"Quit()"
);
delete
pApplication
;
pApplication
=
NULL
;
}
}
主要参考: https://blog.csdn.net/luols/article/details/48781075
https://blog.csdn.net/w_ww_w/article/details/9167573