// .h
class ExcelHelper : public QObject
{
Q_OBJECT
public:
explicit ExcelHelper(QObject *parent = 0);
~ExcelHelper();
bool newExcel(const QString &fileName);
QVariantList ReadExcel(const QString &fileName);
private:
QAxObject *ExcelApplication = Q_NULLPTR;
QAxObject *WorkBooks = Q_NULLPTR;
QAxObject *WorkBook = Q_NULLPTR;
QAxObject *Sheets = Q_NULLPTR;
QAxObject *Sheet = Q_NULLPTR;
};
//.cpp
ExcelHelper::~ExcelHelper()
{
if(ExcelApplication != Q_NULLPTR)
{
ExcelApplication->deleteLater();
ExcelApplication = Q_NULLPTR;
}
}
bool ExcelHelper::newExcel(const QString &fileName)
{
ExcelApplication = new QAxObject("Excel.Application");
if (ExcelApplication->isNull())
{
if (ExcelApplication != Q_NULLPTR) //網絡中很多使用excel==Q_NULLPTR判斷,是錯誤的
{
ExcelApplication->dynamicCall("Quit()");
delete ExcelApplication;
ExcelApplication = Q_NULLPTR;
}
QMessageBox::critical(0, "錯誤信息", "沒有找到EXCEL應用程序");
return false;
}
ExcelApplication->dynamicCall("SetVisible(bool)", false);//false不顯示窗體
ExcelApplication->setProperty("DisplayAlerts", false);//不顯示任何警告信息。
WorkBooks = ExcelApplication->querySubObject("Workbooks");
if(WorkBooks == Q_NULLPTR)
{
QMessageBox::critical(0, "錯誤信息", "取得Excel的Workbooks失敗");
return false;
}
QFile file(fileName);
if (file.exists())
{
WorkBook = WorkBooks->querySubObject("Open(const QString &)", fileName);
}
else
{
WorkBooks->dynamicCall("Add");
WorkBook = ExcelApplication->querySubObject("ActiveWorkBook");
}
if(WorkBook == Q_NULLPTR)
{
QMessageBox::critical(0, "錯誤信息", "打開Excel的Workbook失敗");
return false;
}
//默認有一個sheet
Sheets = WorkBook->querySubObject("Sheets");
if(Sheets == Q_NULLPTR)
{
QMessageBox::critical(0, "錯誤信息", "打開Excel的Sheets失敗");
return false;
}
Sheet = Sheets->querySubObject("Item(int)", 1);
if(Sheet == Q_NULLPTR)
{
QMessageBox::critical(0, "錯誤信息", "打開Excel的Sheet失敗");
return false;
}
return true;
}
QVariantList ExcelHelper::ReadExcel(const QString &fileName)
{
QVariantList allDataList;
if(!newExcel(fileName))
return allDataList;
QAxObject * range = Sheet->querySubObject("UsedRange");
if(range == Q_NULLPTR)
{
WLog(LOG_ERR,"range == Q_NULLPTR,save excel[%s] err",fileName.toLocal8Bit().data());
}
if(range != Q_NULLPTR)
{
// 直接用dynamicCall調用Value()函數獲取全部數據,取出來的數據相當於QList<QList<QVariant>>類型
QVariant var = range->dynamicCall("Value");
allDataList = var.toList();
/* 有博客用以下的方法讀取全部數據,試了行列數都讀出來了,到最後調property("Value")時
返回來的QList是空的,一直都沒有數據。
見:
Qt使用QAxObject快速批量讀取Excel內容
https://blog.csdn.net/sandeepin/article/details/71246494
*/
/*QAxObject * cols = range->querySubObject("Columns");
QAxObject * rows = range->querySubObject("Rows");
int colCnt = 0, rowCnt = 0;
if(cols != Q_NULLPTR)
{
colCnt = cols->property("Count").toInt();
}
if(rows != Q_NULLPTR)
{
rowCnt = rows->property("Count").toInt();
}
WLog(LOG_DEBUG,"excel行數:%d,列數:%d",colCnt,rowCnt);
QString name;
int first = colCnt/26;
while(first>0)
{
name += QString("%1").arg(QChar('A'+first-1));
first /= 26;
}
int second = colCnt%26;
name += QString("%1").arg(QChar('A'+second-1));
QString rangeStr = QString("A1:%1%2").arg(name).arg(rowCnt);
QAxObject *allData = range->querySubObject("Range(QString)", rangeStr);//調了沒起作用
//QAxObject *allData = Sheet->querySubObject("Range(QString)", rangeStr);//調了沒起作用
allDataList = allData->property("Value").toList(); //返回值列表爲空 */
}
return allDataList;
}
// 調用
void ReadExcel(const QString &filename)
{
ExcelHelper helper;
QVariantList ls = helper.ReadExcel(filename);
if(ls.isEmpty())
{
return;
}
// 將獲得的數據轉爲QList<QList<QVariant>>
QList<QList<QVariant>> dataLs;
for(int row=0; row<ls.size(); row++)
{
QVariantList vls = ls.at(row).toList();
dataLs.push_back(vls);
}
// 對數據進行處理
}
/ *
參考 Windows Qt5下用QAxObject快速讀寫Excel指南https://blog.csdn.net/qqwangfan/article/details/106808342
*/