Qt建立excel與快速寫入的方法

用Qt5寫了個生成excel數據的程序,發現生成數據速度很慢,
經查證,
在單元格不少的時候,按單元格寫入很慢,按範圍批量讀寫速度快不少,excel部分代碼片斷以下,
初學者代碼很差,另外設置頁面和單元格格式有更好具體意見建議者,歡迎留言指導數組

這段代碼生成同一種格式的7頁數據,最終結果以下:
圖片描述app

void mainwindow::produce_excel()    
{
    //獲取桌面路徑,設置爲表格的絕對路徑
    QString excel_file_path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)
                             + "/baodi.xlsx";  
    //把"/baodi.xlsx"中//替換成所在系統分隔符,不然路徑讀取會失敗
    excel_file_path = QDir::toNativeSeparators(excel_file_path);    

    QAxObject *excel = new QAxObject(this);
    excel->setControl("Excel.Application"); //鏈接EXCEL控件
    excel->setProperty("DisplayAlerts", true);  //顯示窗體
    QAxObject *workbooks = excel->querySubObject("WorkBooks");  //  獲取工做薄(EXCEL文件)集合
    workbooks->dynamicCall("Add");  //建立新工做薄
    //workbooks->dynamicCall("Open(const QString&)", excel_file_path);
    QAxObject *workbook = excel->querySubObject("ActiveWorkBook");  //獲取當前工做薄
    workbook->dynamicCall("SaveAs(const QString&, int, const QString&, const QString&, bool,bool)",
                          excel_file_path, 51, QString(""),QString(""),false,false);//51xlsx,56xls

    QAxObject *worksheet = workbook->querySubObject("WorkSheets(int)", 1);
    //根據序號獲取EXCEL下方第int張工做表

/*
    //按單元格寫入,數據多時,速度很慢,真的很慢,十分不推薦,已經註釋掉了,按範圍寫入在後面
    QAxObject *usedRange = worksheet->querySubObject("UsedRange"); //sheet範圍
    int Row = usedRange->property("Row").toInt();// 得到起始行數
    int Col = usedRange->property("Column").toInt();//得到起始列數

    QAxObject *cell = worksheet->querySubObject("Cells(int,int)", Row, Col);
    const int ROW_NUM {30};
    const int COL_NUM {3};
    const int HIGHT {26};
    const int WIDE {10};
    long t = 0;//用於選擇時間time
    for(auto d:day)
    {
        //輸入表頭
        //auto t = time.begin();
        cell->setProperty("Value", d);
        cell->setProperty("RowHeight", HIGHT+9);//設置行高
        //cell->setProperty("ColumnWidth", WIDE-4);  //設置單元格列寬
        //cell->setProperty("HorizontalAlignment", -4108); 
        //左對齊(xlLeft):-4131  居中(xlCenter):-4108  右對齊(xlRight):-4152

        cell = worksheet->querySubObject("Cells(int,int)", ++Row, Col);
        cell->setProperty("Value", sn);
        cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE-4);  //設置單元格列寬
        cell->setProperty("HorizontalAlignment", -4108); 

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        cell->setProperty("Value", time[t++%6]);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        //cell->setProperty("Value", sn);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        cell->setProperty("Value", sn);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE-4);  //設置單元格列寬
        cell->setProperty("HorizontalAlignment", -4108); 

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        cell->setProperty("Value", time[t++%6]);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬
        cell->setProperty("HorizontalAlignment", -4108);

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        //cell->setProperty("Value", sn);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        cell->setProperty("Value", sn);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE-4);  //設置單元格列寬
        cell->setProperty("HorizontalAlignment", -4108); 

        cell = worksheet->querySubObject("Cells(int,int)", Row, ++Col);
        cell->setProperty("Value", time[t++%6]);
        //cell->setProperty("RowHeight", HIGHT);
        cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬
        cell->setProperty("HorizontalAlignment", -4108); 

        Col = usedRange->property("Column").toInt();//得到起始列數
        cell = worksheet->querySubObject("Cells(int,int)", ++Row, Col);
        //輸入數據
        for(int i=0; i<ROW_NUM; i++)
        {
            for(int j=0; j<COL_NUM; j++)
            {
                cell = worksheet->querySubObject("Cells(int,int)", Row, Col++);
                cell->setProperty("Value", i+1);
                cell->setProperty("RowHeight", HIGHT);
                //cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬
                cell->setProperty("HorizontalAlignment", -4108); 

                cell = worksheet->querySubObject("Cells(int,int)", Row, Col++);
                cell->setProperty("Value", rand());
                //cell->setProperty("RowHeight", HIGHT);
               // cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬
                cell->setProperty("HorizontalAlignment", -4108); 

                cell = worksheet->querySubObject("Cells(int,int)", Row, Col++);
                cell->setProperty("Value", right_model(model));
                //cell->setProperty("RowHeight", HIGHT);
                //cell->setProperty("ColumnWidth", WIDE);  //設置單元格列寬
                cell->setProperty("HorizontalAlignment", -4108); 

            }
            Col = usedRange->property("Column").toInt();//得到起始列數
            cell = worksheet->querySubObject("Cells(int,int)", ++Row, Col);
        }



    }
*/


    //按範圍寫入,由於不用重複調用QAxObject,比按單元格寫入的方式速度提高巨大
    const int HIGHT{26};
    const int ROW_NUM {224};
    const int COL_NUM {3};
    unsigned int d = 0;
    unsigned int t = 0;

    //以二維數組的形式存儲預寫入數據
    QList<QList<QVariant>>datas;
    for(int i=0;i<ROW_NUM;i++)
    {

        QList<QVariant> rows;
        switch (i%32)//肯定是第幾行
        {
            case 0 :
                rows.append(day[d++]);
                for(int k=0;k<COL_NUM*3-1;k++)
                {

                    //該方法必須輸入整個矩形區域,空的地方不輸入最後寫入結果會異常
                    rows.append("");

                }
            break; //  肯定是第幾篇報文
            case 1 :
                for(int k=0;k<COL_NUM;k++)
                {

                    rows.append(sn);
                    rows.append(time[t++%6]);
                    rows.append("");

                }
            break;


            default:
                for(int k=0;k<COL_NUM;k++)
                {
                    rows.append(i%32?  i%32-1 : 30);
                    rows.append(rand());
                    rows.append(right_model(model));
                }
            break;
        }
        datas.append(rows);

    }

    /*
     *QVariant封裝絕大多數Qt提供的數據類型,只要放入和取出類型對應便可,
     * 至關於一個廣泛的類型聯合,
     * canConvert能夠查詢是否能轉換當前類型,轉換類型以toT()命名
     * 如下爲類型list<list<qvariant>>到qvariant的轉換過程
     
     * 待寫入區域內,每行存爲一個QList<QVariant>,         
     * tjgcQList<QVariant> row1,row2,row3;
     
     * 將QList<QVariant> 轉換爲QVariant類型,
     * QVariant r1(row1),r2(row2),r3(row3);
     
     * 整個寫入區域看成一個QList<QVariant>,存入上述QVariant類型r1,r2,r3
     * 獲得QList<QVariant> r
     
     * 整個寫入區域從QList<QVariant>轉換爲QVariant類型
     * QVariant v(r); *
    */


    //二維數組轉一維
    QList<QVariant> vars;

    for(auto v:datas)
    {
        vars.append(QVariant(v));
    }
    //一維數組轉變量
    QVariant var = QVariant(vars);


    QAxObject *user_range = worksheet->querySubObject("Range(const QString&)", "A1:I224");//指定範圍
    user_range->setProperty("Value", var);//調用一次QAxObject便可完成寫入
    user_range->setProperty("RowHeight", HIGHT);//設置行高
    user_range->setProperty("HorizontalAlignment", -4108); 
    //左對齊(xlLeft):-4131  居中(xlCenter):-4108  右對齊(xlRight):-4152



    workbook->dynamicCall("Save()");    //保存文件
    workbook->dynamicCall("Close(Boolean)", false);
    excel->dynamicCall("Quit(void)");  //EXE結束前須要關閉EXCEL
    delete excel;

    //wait->close();
    //delete wait;
    QMessageBox::information(this,tr("注意"),QStringLiteral("報底已保存在桌面"),QMessageBox::Ok);



}
相關文章
相關標籤/搜索