使用QAxObject讀excel

// .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
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章