Qt之excel 操做使用說明

學習背景:

    適合熟悉些qt開發,可是不是深刻了解的開發者學習。具體實現(qt 5.1版本),office2007 Excel作驗證,Win 7(64位),若有講解有誤,歡迎斧正!安全


 

一.簡單介紹

    QAxObject是Qt提供的包裝COM組件的類,經過COM經過COM操做使用QAxObject類,使用此類,須要在pro文件中添加"QT  +=  axcontainer "。服務器

二.與excel com鏈接的方法

  1. #include <ActiveQt/QAxObject>  app

  2. QAxObject *excel = new QAxObject("Excel.Application"); //!創建excel操做對象,並鏈接Excel控件學習

  3. excel->dynamicCall("SetVisible (bool Visible)",  "false"); //!  設置爲不顯示窗體大數據

  4.excel->setProperty("DisplayAlerts", false); //! 不顯示任何警告信息, 如關閉時的是否保存提示ui

  5.excel->dynamicCall("Quit(void)");  //! 關閉excel程序,操做完後記着關閉,因爲是隱藏在後臺進程中,不關閉進程會有不少excel.exe。this

  6.workbook->dynamicCall("Close(Boolean)", false); //! 關閉exce程序先關閉.xls文件spa

三.Excel基本操做

  只介紹簡單的讀寫操做,須要修改單元格格式等操做,請"Excel VBA參考手冊.chm"線程

  3.1  excel文件操做excel

   獲取當前工做簿的集合

  1> QAxObject *workbooks =  excel->querySubObject("Workbooks"); //! 獲取工做簿(excel文件)集合

  新建一個工做簿

  1> workbooks->synamicCall("Add"); //新建一個工做簿

      QAxObject *workbook = excel->querySubObject("ActiveWorkBook"); //! 獲取當前工做簿

  打開一個已有的工做簿

  1>QString filename = "e:/123.xlsx";

  2>QAxObject* workbook = workbooks->querySubObject("Open(const QString&)", filename);

  保存工做簿

  1>workbook->dynamicCall("Save()");   //!保存文件

  2>workbook->dynamicCall("Close(Boolean)", false);  //! 關閉文件 

  3>excel->dynamicCall("Quit()"); //! 關閉excel

  另存爲工做簿

  1>QDir::toNativeSeparators,將路徑中的"/"轉換爲"\",不然沒法保存,"/"只是qt中能夠識別

  2>workbook->dynamiCall("SaveAs(const QString&)",  QDit::toNativeSeparators(filename));

  3>workbook->synamicCall("Close(Boolean)", false); //! 關閉文件

  4>excel->dynamicCall("Quit()"); //! 關閉excel

  3.2 Sheet工做表操做

  獲取全部工做表

  1> QAxObject *worksheets = workbook->querySubObject("Sheets"):

  根據序號獲取某個工做表,序號順序就是excel 打開後下方的排序

  1>QAxObject *worksheet = worksheets->querySubObejct("Item(int)", 1);

  獲取表中的行數列數 

  1>QAxObject* usedrange = worksheet->querySubObject("UsedRange"); //!  sheet 範圍

  2>int intRowStart = usedrange->property("Row").toInt(); //!  起始行數

  3>int intColStart = usedrange->property("Column").toInt(); //!  起始列數 

  4>QAxObject *rows, *columns;

  5>rows = usedrange->querySubObject("Rows"): //! 行 

  6>columns = usedrange->querySubObject("Columns"); //! 列

  7>int intRow = rows->property("Count").toInt(); //! 行數

  8>int intCol = columns->property("Count").toInt();  //!  列數

  3.3 內容操做

  數據內容操做--獲取單元格--基於座標

  1> QAxObject *cell = worksheet->querySubObject("Cells(int, int)", i,  j);

  數據內容操做--獲取單元格--基於行列名稱

  1>QAxObject *cell = worksheet->querySubObject("Range(QVariant, QVariant)", "A1");

  數據內容操做--讀單元格內容

  1> QVariant cell_value = cell->property("Value");

  數據內容操做-- 寫單元格內容

      1> cell->setProperty("Value",  "內容");

4.其餘(沒有實踐操做)

  4.1  大數據量讀取

    讀取全部單元格內容-數據量大,只須要進行一次操做便可讀取全部內容,避免重複對每一個單元格進行QAxObect操做

  1. QVariant var;

  2. QAxObject * usedRange = sheet->querySubObject("UseRange"); //! 獲取用戶區域範圍

  3. if(NULL == usedRange || usedRange->isNull()){

    return  var;

  }

  4. var = usedRange->dynamicCall("Value"); // 讀取區域內全部值

  5.delete usedRange;

  此時結果以QVariant保存,須要自行轉化爲QList<QList<QVariant>>

  QList<QList<QVariant>> excel_list;

  auto rows = var.toList();

  for(auto row:rows{

  •     excel_list.append(row.toList());
  •     
  •         }
  •   4.2 大數據寫入

  以QList<QList<QVariant>>存儲,須要限定範圍

  1>QAxObject *user_rang = this->sheet->querySubObject("Rang(const QString&)", "A1:D100");

   寫入數據

  1> rang->setProperty("Value", var); 

  4.3 簡單的範例

 1 //  HRESULT r = OleInitialize(0);
 2    // if(r != S_OK && r != S_FALSE)
 3    // {
 4         //qWaring("Qt:初始化Ole 失敗(error %x)", (unsigned int)r);
 5     //}
 6     QString filename = "e:/123.xlsx"; //具體路徑
 7     QFile  file(filename);
 8     bool isExit = file.exists();
 9     if(!isExit)
10         return false;
11     qDebug()<<"isExit"<<isExit;
12     qDebug()<<filename;
13     QAxObject *excel = new QAxObject("Excel.Application");
14     excel->dynamicCall("SetVisible(bool Visble)", "false");
15     excel->setProperty("DisplayAlerts", false);
16     QAxObject *workbooks = excel->querySubObject("WorkBooks");
17     QAxObject *workbook = workbooks->querySubObject("Open(const QString&)", filename);
18     QAxObject *worksheets = workbook->querySubObject("Sheets");
19     QAxObject *worksheet = worksheets->querySubObject("Item(int)", 1);
20 
21     //寫入到指定位置
22     QAxObject *workrang = worksheet->querySubObject("Cells(int, int)", 5, 1);
23     //不能這麼存
24     workrang->dynamicCall("SetValue(const QString&)", QString("1ssssssfffssssssssssssssssssssssssssssss10987654321"));
25 
26 
27     //讀取出來並打印
28     QAxObject *workrang1 = worksheet->querySubObject("Cells(int,int)", 3, 5);
29 
30     QVariant var = workrang1->dynamicCall("Value");
31     qDebug()<<var;
32     qDebug()<<var.toDouble();
33 
34     //另存保存
35     //workbook->dynamicCall("SaveAs(const QString&)",
36              //             QDir::toNativeSeparators(filename));
37 
38     workbook->dynamicCall("Save()", true);
39     //關閉文件
40     workbook->dynamicCall("Close(Boolean)", true);
41     excel->dynamicCall("Quit()");
42     delete excel;
43     excel = NULL;
44    // OleUninitialize();

  4.4 關於權限配置

  1):在服務器上安裝office的Excel軟件.

  2):在"開始"->"運行"中輸入dcomcnfg.exe啓動"組件服務" ,win7 64 能夠經過在運行裏面輸入 comexp.msc -32 來打開32位的組件服務,在裏就能看到excel組件了

  3):依次雙擊"組件服務"->"計算機"->"個人電腦"->"DCOM配置"

  4):在"DCOM配置"中找到"Microsoft Excel 應用程序",在它上面點擊右鍵,而後點擊"屬性",彈出"Microsoft Excel 應用程序屬性"對話框

  5):點擊"標識"標籤,選擇"交互式用戶

  6):點擊"安全"標籤,在"啓動和激活權限"上點擊"自定義",而後點擊對應的"編輯"按鈕,在彈出的"安全性"對話框中填加一個"NETWORK SERVICE"用戶

  (注意要選擇本計算機名),並給它賦予"本地啓動"和"本地激活"權限.

  7):依然是"安全"標籤,在"訪問權限"上點擊"自定義",而後點擊"編輯",在彈出的"安全性"對話框中也填加一個"NETWORK SERVICE"用戶,而後賦予"本地訪問"權限.

  8).若是交互式用戶設置後出現錯誤8000401a,可取消交互式用戶,指定爲administratr,可暫時解決此問題。進一步的解決方式還有待探討

  9).採用第8點的設置後,打開Excel可能會出現「沒法使用對象引用或連接」,而且不能進行單元格粘貼。緣由不明,取消設置後便可消失。

  4.5 關於在分線程中調用QAXObject

    請首先初始化COM

    代碼:

1 HRESULT r = OleInitialize(0);
2 if(r != S_OK && r != S_FALSE)
3 {
4         qWaring("Qt:初始化Ole 失敗(error %x)", (unsigned int)r);
5     }
6 OleUninitialize();

 

                                                                                       2018-08-06 00:22:30

相關文章
相關標籤/搜索