說實際的操作之前先介紹下excel格式(百度拷過來的),excel有兩種格式xls和xlsx
XLS 就是 Microsoft Excel 工作表,是一種非常常用的電子表格格式。xls文件可以使用Microsoft Excel打開,另外微軟爲那些沒有安裝Excel的用戶開發了專門的查看器Excel Viewer。使用Microsoft Excel可以將XLS格式的表格轉換爲多種格式:XML表格、XML數據、網頁、使用製表符分割的文本文件(*.txt)、使用逗號分隔的文本文件(*.csv)等。
Microsoft Office EXCEL 2007/2010/2013/2016文檔的擴展名。xlsx是從Office2007開始使用的,是用新的基於XML的壓縮文件格式取代了其目前專有的默認文件格式,在傳統的文件名擴展名後面添加了字母x(即:docx取代doc、.xlsx取代xls等等),使其佔用空間更小。
爲什麼要介紹這兩種格式其實就涉及到我爲什麼要使用下面的格式,在之前我曾今搞過一次讀寫excel不過那個時候沒太注意還有這兩種區分(那個時候應該迷迷糊糊的就操作的xls),那個時候是直接使用的文件讀寫來操作(也就是QFile)就可以直接解決了,然後最近要操作的的這個表格的格式是xlsx才發現QFile不好用了,讀出來的全是亂碼,寫進去打開文件看也是看不到任何東西,於是就去網上搜了下,成功之後就整理了下自己的過程:
網上講了兩種方式1.使用ODBC,也就是讀寫數據的方式,2.使用qt提供的COM套件。這裏我使用的第二種,因此只寫出第二種。步驟如下:
1.先在.pro文件鐘加入QT+= axcontainer
QT+= axcontainer
2.頭文件包含
#include <QAxObject>
3.下面上操作代碼
QString filename = url_info_file;
QFile f(filename);
if(f.exists())
{
int flag = 0;
QAxObject excel("Excel.Application"); // 連接excel控件
excel.setProperty("Visible", false); // 不顯示窗體
QAxObject* workbooks = excel.querySubObject("WorkBooks"); //獲取工作簿集合
workbooks->dynamicCall("Open(const QString&)", filename); // 打開文件
QAxObject* workbook = excel.querySubObject("ActiveWorkBook");
//QAxObject* sheets = workbook->querySubObject("Sheets");
QAxObject* sheet = workbook->querySubObject("Sheets(int)", 1);
QAxObject* range = sheet->querySubObject("UsedRange");
QAxObject* rows = range->querySubObject("Rows");
QAxObject* columns = range->querySubObject("Columns");
// 注意行、列中多餘的(如:列標題)數據的排除
int rowStart = range->property( "Row" ).toInt();
int columnStart = range->property( "Column" ).toInt();
int nRow = rows->property( "Count" ).toInt();
int nColumn = columns->property( "Count" ).toInt();
// 實測上面獲取到的列數會不正確,因此需要自己重新判斷
// 打印每行的第2列的元素
for (int i=rowStart; i<=nRow; i++ )
{
QAxObject* cell = range->querySubObject( "Cells(int,int)", i, 2);
QString strValue = cell->property( "Value" ).toString();
if ( strValue != "" )
{
qDebug() << strValue;
}
}
workbook->dynamicCall( "Close(Boolen)", false); // 關閉文件
excel.dynamicCall( "Quit(void)" ); // 退出
}
4.操作過程鍾可能會遇到的問題:
(1)文件路徑不能使用相對路徑,會報下圖中的錯誤
(2)上面的這段代碼每次操作excel任務管理器中就會出現一個EXCEL的進程,看到網上說是要加下面代碼就不會再出現了
excel->setProperty("DisplayAlerts", true);
,但是我實測然並卵,我測到的現象是將窗體顯示出來就不會出現多一個進程的情況了(即如下代碼),但是有會有窗體顯示出來,如果有哪位大佬找到了真的解決方法麻煩評論留下言
excel.setProperty("Visible", true);