最近在學習Qt,想做個讀寫卡工具,卡號來自excel,相當於需要加載excel,這裏記錄一下讀寫excel的過程。
先上代碼:
頭文件代碼如下:
#ifndef EXCELMANAGER_H
#define EXCELMANAGER_H
#include <QObject>
#include <QList>
struct ExcelRow
{
//卡號碼
QString cardNum;
//是否已經使用過了。
bool usedStatus;
};
Q_DECLARE_METATYPE(ExcelRow);
class ExcelManager : public QObject
{
Q_OBJECT
public:
explicit ExcelManager(QObject *parent = nullptr);
public:
QList<ExcelRow> ReadExcel(const QString &filePath);
int RepairExcel(const QString &filePath,QString content,int row);//row 行 column 列
int RepairExcelList(const QString &filePath,QList<QString> contents);
signals:
void signalRefreshProBar(int);
void signalShowProBar(bool);
public slots:
};
#endif // EXCELMANAGER_H
cpp代碼如下:
#include "excelmanager.h"
#include <QFileDialog>
#include <QAxObject>
#include <QVariant>
#include <QList>
#include <QDebug>
#define EXCEL_USED "Used" // 卡號
ExcelManager::ExcelManager(QObject *parent) : QObject(parent)
{
}
int ExcelManager::RepairExcel(const QString &filePath,QString content,int row)//row 行 column 列
{
QAxObject excel("Excel.Application"); //加載Excel驅動
excel.setProperty("Visible", false); //不顯示Excel界面,如果爲true會看到啓動的Excel界面
excel.setProperty("DisplayAlerts", false);//不顯示任何警告信息
QAxObject* pWorkBooks = excel.querySubObject("WorkBooks");
pWorkBooks->dynamicCall("Open (const QString&)", filePath);//打開指定文
QAxObject* pWorkBook = excel.querySubObject("ActiveWorkBook");
QAxObject* pWorkSheets = pWorkBook->querySubObject("Sheets");//獲取工作表
int nSheetCount = pWorkSheets->property("Count").toInt(); //獲取工作表的數目
if(nSheetCount > 0)
{
QAxObject* pWorkSheet = pWorkBook->querySubObject("Sheets(int)", 1);//獲取第一張表
//獲取表中的數據到QVariant中
QAxObject *usedRange=pWorkSheet->querySubObject("UsedRange");
QVariant varData = usedRange->dynamicCall("Value2()");
QVariantList var =varData.toList();
QVariantList tmpTitle=var[1].toList();
int tmpTitleIndex=-1;
for(int i=0;i<tmpTitle.size();i++)
{
if(tmpTitle[i].toString()==EXCEL_USED)
{
tmpTitleIndex=i;
break;
}
}
if(tmpTitleIndex<0)
{
tmpTitleIndex=tmpTitle.size();
pWorkSheet->querySubObject("Cells(int,int)",2,tmpTitleIndex)->setProperty("Value",EXCEL_USED);
}
pWorkSheet->querySubObject("Cells(int,int)",row,tmpTitleIndex+1)->setProperty("Value",content);// 設置單元格值
pWorkBook->dynamicCall("Save()");
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
return 0;
}
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
return -1;
}
int ExcelManager::RepairExcelList(const QString &filePath, QList<QString> contents)
{
QAxObject excel("Excel.Application"); //加載Excel驅動
excel.setProperty("Visible", false); //不顯示Excel界面,如果爲true會看到啓動的Excel界面
excel.setProperty("DisplayAlerts", false);//不顯示任何警告信息
QAxObject* pWorkBooks = excel.querySubObject("WorkBooks");
pWorkBooks->dynamicCall("Open (const QString&)", filePath);//打開指定文
QAxObject* pWorkBook = excel.querySubObject("ActiveWorkBook");
QAxObject* pWorkSheets = pWorkBook->querySubObject("Sheets");//獲取工作表
int nSheetCount = pWorkSheets->property("Count").toInt(); //獲取工作表的數目
if(nSheetCount > 0)
{
QAxObject* pWorkSheet = pWorkBook->querySubObject("Sheets(int)", 1);//獲取第一張表
//獲取表中的數據到QVariant中
QAxObject *usedRange=pWorkSheet->querySubObject("UsedRange");
QVariant varData = usedRange->dynamicCall("Value2()");
QVariantList var =varData.toList();
const int rowCount=var.size();
QVariantList tmp;
QVariantList tmpTitle;
int tmpTitleIndex=-1;
QString tmpStr;
tmpTitle=var[1].toList();
for(int i=0;i<tmpTitle.size();i++)
{
if(tmpTitle[i].toString()==EXCEL_USED)
{
tmpTitleIndex=i;
break;
}
}
if(tmpTitleIndex<0)
{
tmpTitleIndex=tmpTitle.size();
pWorkSheet->querySubObject("Cells(int,int)",2,tmpTitleIndex+1)->setProperty("Value",EXCEL_USED);
}
emit signalShowProBar(true);
for(int i=2;i<rowCount;++i)
{
int per=i*1.0/rowCount*100;
emit signalRefreshProBar(per);
tmp=var[i].toList();
if(tmp.size()>0)
{
tmpStr=tmp[0].toString();
if(contents.contains(tmpStr))
{
//找到一樣內容的欄
pWorkSheet->querySubObject("Cells(int,int)",i+1,tmpTitleIndex+1)->setProperty("Value","1");// 設置單元格值
}
}
}
pWorkBook->dynamicCall("Save()");
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
emit signalShowProBar(false);
return 0;
}
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
return -1;
}
QList<ExcelRow> ExcelManager::ReadExcel(const QString &filePath)
{
QList<ExcelRow> result;
QAxObject excel("Excel.Application"); //加載Excel驅動
excel.setProperty("Visible", false); //不顯示Excel界面,如果爲true會看到啓動的Excel界面
excel.setProperty("DisplayAlerts", false);//不顯示任何警告信息
QAxObject* pWorkBooks = excel.querySubObject("WorkBooks");
pWorkBooks->dynamicCall("Open (const QString&)", filePath);//打開指定文
QAxObject* pWorkBook = excel.querySubObject("ActiveWorkBook");
QAxObject* pWorkSheets = pWorkBook->querySubObject("Sheets");//獲取工作表
int nSheetCount = pWorkSheets->property("Count").toInt(); //獲取工作表的數目
if(nSheetCount > 0)
{
QAxObject* pWorkSheet = pWorkBook->querySubObject("Sheets(int)", 1);//獲取第一張表
//獲取表中的數據到QVariant中
QAxObject *usedRange=pWorkSheet->querySubObject("UsedRange");
QVariant varData = usedRange->dynamicCall("Value2()");
QVariantList var =varData.toList();
const int rowCount=var.size();
QVariantList tmp;
QVariantList tmpTitle;
int tmpTitleIndex=-1;
QString tmpStr;
tmpTitle=var[1].toList();
for(int i=0;i<tmpTitle.size();i++)
{
if(tmpTitle[i].toString()==EXCEL_USED)
{
tmpTitleIndex=i;
break;
}
}
emit signalShowProBar(true);
for(int i=2;i<rowCount;++i)
{
tmp=var[i].toList();
if(tmp.size()>0)
{
int per=i*1.0/rowCount*100;
//qDebug()<<per;
emit signalRefreshProBar(per);
tmpStr=tmp[0].toString();
// qDebug()<<tmpStr;
ExcelRow rowStruct;
rowStruct.cardNum=tmpStr;
QVariant tmpData=tmp[tmpTitleIndex];
rowStruct.usedStatus=(tmpTitleIndex<0)?false:(tmp[tmpTitleIndex].toInt()==1);
result.append(rowStruct);
}
}
pWorkBook->dynamicCall("Save()");
pWorkBooks->dynamicCall("Close(Boolean)",false);
excel.dynamicCall("Quit(void)");
emit signalShowProBar(false);
return result;
}
}
這個地方需要注意的是,關閉excel,如果你電腦上裝了福昕這個pdf軟件的話,最好卸載了,否則你會發現進程並沒有關閉。
關於保存,注意兩個參數的區別,一個是pWorkBook,一個是pWorkBooks,如果都協程pWorkBooks的話,保存不會成功的。
最後出一張界面設計圖:
一張最後效果圖。
就這樣吧。