用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); }