#include <ActiveQt/qaxobject.h>
- 链接器-输入-附加依赖项:
Qt5AxBased.lib;Qt5AxContainerd.lib;
否则报错如下
1>Qt5AxContainerd.lib(qaxbase.obj) : error LNK2019: 无法解析的外部符号 "bool __cdecl QVariantToVoidStar(class QVariant const &,void *,class QByteArray const &,unsigned int)" (?QVariantToVoidStar@@YA_NAEBVQVariant@@PEAXAEBVQByteArray@@I@Z),该符号在函数 "private: int __cdecl QAxBase::internalProperty(enum QMetaObject::Call,int,void * *)" (?internalProperty@QAxBase@@AEAAHW4Call@QMetaObject@@HPEAPEAX@Z) 中被引用
1>Qt5AxContainerd.lib(qaxbase.obj) : error LNK2019: 无法解析的外部符号 "void __cdecl clearVARIANT(struct tagVARIANT *)" (?clearVARIANT@@YAXPEAUtagVARIANT@@@Z),该符号在函数 "public: class QAxObject * __cdecl QAxBase::querySubObject(char const *,class QList<class QVariant> &)" (?querySubObject@QAxBase@@QEAAPEAVQAxObject@@PEBDAEAV?$QList@VQVariant@@@@@Z) 中被引用
1>Qt5AxContainerd.lib(qaxtypes.obj) : error LNK2001: 无法解析的外部符号 "void __cdecl clearVARIANT(struct tagVARIANT *)" (?clearVARIANT@@YAXPEAUtagVARIANT@@@Z)
1>Qt5AxContainerd.lib(qaxtypes.obj) : error LNK2019: 无法解析的外部符号 "class QColor __cdecl OLEColorToQColor(unsigned int)" (?OLEColorToQColor@@YA?AVQColor@@I@Z),该符号在函数 "class QVariant __cdecl VARIANTToQVariant_container(struct tagVARIANT const &,class QByteArray const &,unsigned int)" (?VARIANTToQVariant_container@@YA?AVQVariant@@AEBUtagVARIANT@@AEBVQByteArray@@I@Z) 中被引用
1>C:\Project\tabtest\x64\Debug\\tabtest.exe : fatal error LNK1120: 3 个无法解析的外部命令
- QAxObject派生自QAxBase,QAxBase通过ActiveX(OLE)操作COM对象(Excel),对象关系如下
- Application-WorkBooks-Sheets
- UsedRange:
property("Row").toInt()
为起始行,property("Column").toInt()
为起始列
- Rows:
property("Count").toInt()
为总行数
- Columns:
property("Count").toInt()
为总列数
- Cells
- 写入到文件
void dlg::slot()
{
QString path = QFileDialog::getSaveFileName(this, tr(u8"另存为"),
tr(u8"C:\\Users\\downdemo\\Desktop\\test"), tr(u8"Excel文件(*.xlsx);"));
if (!path.isEmpty())
{
QAxObject excel("Excel.Application");
excel.setProperty("Visible", false); // 设置为true则会在写入同时显示文件
QAxObject* workbooks = excel.querySubObject("WorkBooks");
// 添加新工作簿
workbooks->dynamicCall("Add");
// 获取活动工作簿
QAxObject * workbook = excel.querySubObject("ActiveWorkBook");
// 获取所有工作表,querySubObject("WorkSheets")也可以
QAxObject* worksheets = workbook->querySubObject("Sheets");
// 获取第一张工作表
QAxObject* sheet1 = worksheets->querySubObject("Item(int)", 1);
// 删除工作表,若该表不存在则报异常
// sheet1->dynamicCall("delete");
// 获取单元格并设置值,注意单元格(1, 1)而非(0, 0)开始
QAxObject* cell = sheet1->querySubObject("Cells(int,int)", 1, 1);
cell->setProperty("Value2", "111");
// 继续设置第一行第二列单元格
QAxObject* cell2 = sheet1->querySubObject("Cells(int,int)", 1, 2);
cell2->setProperty("Value2", "222");
// 设置工作表名称
sheet1->setProperty("Name", tr(u8"table1"));
// 获取工作表数量
// int sheetCount = worksheets->property("Count").toInt();
// 添加新工作表到第一张表之后
QAxObject* last = worksheets->querySubObject("Item(int)", 1);
QAxObject* sheet2 = worksheets->querySubObject("Add(QVariant)", last->asVariant());
last->dynamicCall("Move(QVariant)", sheet2->asVariant());
// 设置新工作表名称
sheet2->setProperty("Name", tr(u8"table2"));
// 添加table3
QAxObject* last2 = worksheets->querySubObject("Item(int)", 2);
QAxObject* sheet3 = worksheets->querySubObject("Add(QVariant)", last2->asVariant());
last2->dynamicCall("Move(QVariant)", sheet3->asVariant());
sheet3->setProperty("Name", tr(u8"table3"));
// 添加table4
QAxObject* last3 = worksheets->querySubObject("Item(int)", 3);
QAxObject* sheet4 = worksheets->querySubObject("Add(QVariant)", last3->asVariant());
last3->dynamicCall("Move(QVariant)", sheet4->asVariant());
sheet4->setProperty("Name", tr(u8"table4"));
// 打开Excel时默认显示第一张工作表
sheet1->querySubObject("Activate");
// 另存为
workbook->dynamicCall("SaveAs(const QString&, int, const QString&, const QString&, bool, bool)",
QDir::toNativeSeparators(path), 56, QString(""), QString(""), false, false);
// 关闭文件
workbook->dynamicCall("Close(Boolean)", false);
// 退出
excel.dynamicCall("Quit(void)");
}
}
生成的EXCEL文件(table2-4内容为空)
void dlg::slot2()
{
QString path = QFileDialog::getOpenFileName(this, tr(u8"打开"),
"C:\\Users\\downdemo\\Desktop\\", tr(u8"Excel文件(*.xlsx);"));
if (!path.isEmpty())
{
QAxObject excel("Excel.Application");
excel.setProperty("Visible", false); // 设置为true则会在写入同时显示文件
// 更改标题栏
excel.setProperty("Caption", "My Excel");
// 获取标题
QVariant titleValue = excel.property("Caption");
QString titleName = titleValue.toString();
qDebug() << titleName; // 打印"My Excel"
QAxObject* workbooks = excel.querySubObject("WorkBooks");
// 打开已有工作簿
workbooks->dynamicCall("Open(const QString&)", path);
// 获取活动工作簿
QAxObject* workbook = excel.querySubObject("ActiveWorkBook");
// 获取所有工作表,querySubObject("WorkSheets")也可以
QAxObject* worksheets = workbook->querySubObject("Sheets");
// 获取第一张工作表
QAxObject* sheet1 = worksheets->querySubObject("Item(int)", 1);
// 删除工作表,若该表不存在则报异常
// sheet1->dynamicCall("delete");
// 获取sheet1名称
QString sheetName = sheet1->property("Name").toString();
// 获取范围以及行列数
QAxObject* usedrange = sheet1->querySubObject("UsedRange");
QAxObject* rows = usedrange->querySubObject("Rows");
QAxObject* columns = usedrange->querySubObject("Columns");
int rowStart = usedrange->property("Row").toInt();
int colStart = usedrange->property("Column").toInt();
int rowCount = rows->property("Count").toInt();
int colCount = columns->property("Count").toInt();
// 打印sheet1的表格内容
for (int i = rowStart; i < rowStart + rowCount; ++i)
{
for (int j = colStart; j < colStart + colCount; ++j)
{
QAxObject* cell = sheet1->querySubObject("Cells(int,int)", i, j);
qDebug() << i << j << cell->property("Value2").toString();
}
}
// 另一种读取范围批量打印的方法
QString Range = "A1:";
Range.append(QChar('A' + colCount - 1)).append(QString::number(rowCount));
QAxObject* data = sheet1->querySubObject("Range(const QString&)", Range);
QVariant dataValue= data->property("Value2");
QVariantList dataList = dataValue.toList();
for (int i = 0; i < rowCount; ++i)
{
QVariantList outList = dataList[i].toList();
for(int j = 0; j < colCount; ++j) qDebug() << i+1 << j+1<< outList[j].toString();
}
// 保存工作簿
workbook->dynamicCall("Save");
// 关闭文件
workbook->dynamicCall("Close(Boolean)", false);
// 退出
excel.dynamicCall("Quit(void)");
}
}
cell->setProperty("RowHeight", 20); // 设置行高
cell->setProperty("ColumnWidth", 30); // 设置列宽
// 默认水平靠左,垂直居中
cell->setProperty("HorizontalAlignment", -4108); // 水平居中,靠左-4131,靠右-4152
cell->setProperty("VerticalAlignment", -4108); // 垂直居中,靠上-4160,靠下-4107
cell->setProperty("WrapText", true); // 超过列宽自动换行
cell->dynamicCall("ClearContents()"); // 清空单元格内容
// 单元格背景色
QAxObject* interior = cell->querySubObject("Interior");
interior->setProperty("Color", QColor(255, 0, 0)); // 单元格背景色(红色)
// 边框色
QAxObject* border = cell->querySubObject("Borders");
border->setProperty("Color", QColor(0, 255, 0)); // 边框色(绿色)
// 字体
QAxObject* font = cell->querySubObject("Font");
font->setProperty("Color", QColor(0, 0, 255)); // 字体色(蓝色)
font->setProperty("Size", 12); // 字体大小
font->setProperty("Name", QStringLiteral("仿宋"));
font->setProperty("Bold", true); // 加粗
font->setProperty("Italic", true); // 斜体
font->setProperty("Underline", true); // 下划线
// 合并单元格
// 合并实际只保留左上角单元格数据,范围内其他单元格数据为空
QString merge; // 假设要合并的范围为A3:G7
merge.append(QChar('A'));
merge.append(QString::number(3));
merge.append(":");
merge.append(QChar('A' + 6));
merge.append(QString::number(7));
QAxObject* mergeRange = sheet1->querySubObject("Range(const QString&)", merge);
mergeRange->setProperty("HorizontalAlignment", -4108); // 靠左-4131,靠右-4152
mergeRange->setProperty("VerticalAlignment", -4108); // 靠上-4160,靠下-4107
mergeRange->setProperty("MergeCells", true); // 合并单元格
// mergeRange->setProperty("MergeCells", false); // 拆分单元格
// 只有行表头的表格
for (int i = 0; i < table1->rowCount(); ++i)
{
QAxObject* cell = sheet1->querySubObject("Cells(int, int)", i + 1, 1);
cell->setProperty("Value2", table1->verticalHeaderItem(i)->text());
}
for (int i = 0; i < table1->rowCount(); ++i)
{
for (int j = 0; j < table1->columnCount(); ++j)
{
QAxObject* cell = sheet1->querySubObject("Cells(int, int)", i + 1, j + 2);
if (table1->item(i, j) != nullptr)
{
cell->setProperty("Value2", table1->item(i, j)->text());
}
}
}
// 只有列表头的表格
for (int j = 0; j < table2->columnCount(); ++j)
{
QAxObject* cell = sheet2->querySubObject("Cells(int, int)", 1, j + 1);
cell->setProperty("Value2", table2->horizontalHeaderItem(j)->text());
}
for (int i = 0; i < table2->rowCount(); ++i)
{
for (int j = 0; j < table2->columnCount(); ++j)
{
QAxObject* cell = sheet2->querySubObject("Cells(int, int)", i + 2, j + 1);
if (table2->item(i, j) != nullptr)
{
cell->setProperty("Value2", table2->item(i, j)->text());
}
}
}
CoCreateInstance failure (尚未调用 CoInitialize)
QAxBase::setControl: requested control Excel.Application could not be instantiated
QAxBase::dynamicCallHelper: Object is not initialized, or initialization failed
#include "qt_windows.h"
// 在操作前加上
HRESULT r = OleInitialize(0);
CoInitialize(0);
if (r != S_OK && r != S_FALSE) {
qWarning("Qt: Could not initialize OLE (error %x)\n", (unsigned int)r);
}
// 结束加上释放代码
OleUninitialize();
- 报错如下则是因为没有安装Excel(必须是Excel,WPS不行),缺少Excel组件服务
CoCreateInstance failure (没有注册类)
QAxBase::setControl: requested control Excel.Application could not be instantiated
QAxBase::dynamicCallHelper: Object is not initialized, or initialization failed
0x00007FF7E57B4EBE 处(位于 tabtest.exe 中)引发的异常: 0xC0000005: 读取位置 0x0000000000000018 时发生访问冲突。
- 如果存在Excel组件,WIN+R运行
dcomcnfg
打开组件服务,查看组件服务-计算机-我的电脑-DCOM配置
,其中可以看到Mircosoft Excel Application
网友评论