Qt 操作Excel

Qt对Excel的数据读/写操作没有现存的类,需要使用QAxObject,下面是从网上下载下来的一个封装好的类,感觉还可以,一般情况下够用,拿来给大家分享。

头文件:

#ifndef EXCELENGINE_H#define EXCELENGINE_H

#include <QObject>#include <QFile>#include <QString>#include <QStringList>#include <QVariant>#include <QAxBase>#include <QAxObject>#include <QTableWidget>#include <QTableView>#include <QTableWidgetItem>#include <QDebug>
typedef unsigned int UINT;/**  *@brief 这是一个便于Qt读写excel封装的类,同时,便于把excel中的数据  *显示到界面上,或者把界面上的数据写入excel中,同GUI进行交互,关系如下:  *Qt tableWidget <--> ExcelEngine <--> xls file.  *  *@note ExcelEngine类只负责读/写数据,不负责解析,做中间层  *@author yaoboyuan [email protected]  *@date 2012-4-12  */
class ExcelEngine : protected QObject{public:    ExcelEngine();    ExcelEngine(QString xlsFile);    ~ExcelEngine();public:    bool Open(UINT nSheet = 1,bool visible = false);          //打开xls文件    bool Open(QString xlsFile,UINT nSheet = 1,bool visible = false);    void Save();                                              //保存xls报表    void Close();                                             //关闭xls报表    bool SaveDataFrTable(QTableWidget* tableWidget);          //保存数据到xls    bool ReadDataToTable(QTableWidget* tableWidget);          //从xls读取数据到ui    QVariant GetCellData(UINT row,UINT column);               //获取指定单元数据    bool     SetCellData(UINT row,UINT column,QVariant data); //修改指定单元数据
    UINT GetRowCount()const;    UINT GetColumnCount()const;
    bool IsOpen();    bool IsValid();
protected:    void Clear();
private:    QAxObject *pExcel;       //指向整个excel应用程序    QAxObject *pWorkbooks;   //指向工作簿集,excel有很多工作簿    QAxObject *pWorkbook;    //指向sXlsFile对应的工作簿    QAxObject *pWorksheet;   //指向工作簿中的某个sheet表单
    QString   sXlsFile;      //xls文件路径    UINT      nCurrSheet;    //当前打开的第几个sheet    bool      bIsVisible;    //excel是否可见    int       nRowCount;     //行数    int       nColumnCount;  //列数
    int       nStartRow;     //开始有数据的行下标值    int       nStartColumn;  //开始有数据的列下标值
    bool      bIsOpen;       //是否已打开    bool      bIsValid;      //是否有效
    bool      bIsANewFile;   //是否是一个新建xls文件,用来区分打开的excel是已存在文件还是有本类新建的    bool      bIsSaveAlready;//防止重复保存};
#endif // EXCELENGINE_H

源文件:#include "excelengine.h"#include "qt_windows.h"

ExcelEngine::ExcelEngine(){    pExcel     = NULL;    pWorkbooks = NULL;    pWorkbook  = NULL;    pWorksheet = NULL;    sXlsFile     = "";    nRowCount    = 0;    nColumnCount = 0;    nStartRow    = 0;    nStartColumn = 0;    bIsOpen     = false;    bIsValid    = false;    bIsANewFile = false;    bIsSaveAlready = false;    HRESULT r = OleInitialize(0);
    if (r != S_OK && r != S_FALSE)    {        qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r);    }}

ExcelEngine::ExcelEngine(QString xlsFile){    pExcel     = NULL;    pWorkbooks = NULL;    pWorkbook  = NULL;    pWorksheet = NULL;    sXlsFile     = xlsFile;    nRowCount    = 0;    nColumnCount = 0;    nStartRow    = 0;    nStartColumn = 0;    bIsOpen     = false;    bIsValid    = false;    bIsANewFile = false;    bIsSaveAlready = false;
    HRESULT r = OleInitialize(0);    if (r != S_OK && r != S_FALSE)    {        qDebug("Qt: Could not initialize OLE (error %x)", (unsigned int)r);    }}
ExcelEngine::~ExcelEngine(){    if ( bIsOpen )    {        //析构前,先保存数据,然后关闭workbook        Close();    }    OleUninitialize();}
/**  *@brief 打开sXlsFile指定的excel报表  *@return true : 打开成功  *        false: 打开失败  */
bool ExcelEngine::Open(UINT nSheet, bool visible){    if(bIsOpen)    {        Close();    }    nCurrSheet = nSheet;    bIsVisible = visible;
    if(NULL == pExcel)    {        pExcel = new QAxObject("Excel.Application");        if(pExcel)        {            bIsValid = true;        }        else        {            bIsValid = false;            bIsOpen  = false;            return bIsOpen;        }        pExcel->dynamicCall("SetVisible(bool)", bIsVisible);    }
    if(!bIsValid)    {        bIsOpen = false;        return bIsOpen;    }

    if(sXlsFile.isEmpty())    {        bIsOpen = false;        return bIsOpen;    }
    /*如果指向的文件不存在,则需要新建一个*/    QFile f(sXlsFile);    if(!f.exists())    {        bIsANewFile = true;    }    else    {        bIsANewFile = false;    }

    if(!bIsANewFile)    {        pWorkbooks = pExcel->querySubObject("WorkBooks"); //获取工作簿        pWorkbook  = pWorkbooks->querySubObject("Open(QString, QVariant)",sXlsFile,QVariant(0)); //打开xls对应的工作簿    }    else    {        pWorkbooks = pExcel->querySubObject("WorkBooks");      //获取工作簿        pWorkbooks->dynamicCall("Add");                        //添加一个新的工作薄        pWorkbook  = pExcel->querySubObject("ActiveWorkBook"); //新建一个xls    }    pWorksheet = pWorkbook->querySubObject("WorkSheets(int)", nCurrSheet);//打开第一个sheet
    //至此已打开,开始获取相应属性    QAxObject *usedrange = pWorksheet->querySubObject("UsedRange");       //获取该sheet的使用范围对象    QAxObject *rows      = usedrange->querySubObject("Rows");    QAxObject *columns   = usedrange->querySubObject("Columns");

    //因为excel可以从任意行列填数据而不一定是从0,0开始,因此要获取首行列下标    nStartRow    = usedrange->property("Row").toInt();    //第一行的起始位置    nStartColumn = usedrange->property("Column").toInt(); //第一列的起始位置    nRowCount    = rows->property("Count").toInt();       //获取行数    nColumnCount = columns->property("Count").toInt();    //获取列数
    bIsOpen  = true;    return bIsOpen;}
/**  *@brief Open()的重载函数  */bool ExcelEngine::Open(QString xlsFile, UINT nSheet, bool visible){    sXlsFile   = xlsFile;    nCurrSheet = nSheet;    bIsVisible = visible;    return Open(nCurrSheet,bIsVisible);}

/**  *@brief 保存表格数据,把数据写入文件  */
void ExcelEngine::Save(){    if(pWorkbook)    {        if(bIsSaveAlready)        {            return ;        }
        if(!bIsANewFile)        {            pWorkbook->dynamicCall("Save()");        }        else /*如果该文档是新建出来的,则使用另存为COM接口*/        {            pWorkbook->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)",                                   sXlsFile,56,QString(""),QString(""),false,false);        }        bIsSaveAlready = true;    }}
/**  *@brief 关闭前先保存数据,然后关闭当前Excel COM对象,并释放内存  */
void ExcelEngine::Close(){    Save();//关闭前先保存数据    if(pExcel && pWorkbook)    {        pWorkbook->dynamicCall("Close(bool)", true);        pExcel->dynamicCall("Quit()");        delete pExcel;        pExcel = NULL;
        bIsOpen        = false;        bIsValid       = false;        bIsANewFile    = false;        bIsSaveAlready = true;    }}

/**  *@brief 把tableWidget中的数据保存到excel中  *@param tableWidget : 指向GUI中的tablewidget指针  *@return 保存成功与否 true : 成功  *                   false: 失败  */bool ExcelEngine::SaveDataFrTable(QTableWidget *tableWidget){    if(NULL == tableWidget)    {        return false;    }
    if(!bIsOpen)    {        return false;    }
    int tableR = tableWidget->rowCount();    int tableC = tableWidget->columnCount();

    //获取表头写做第一行    for(int i=0;i<tableC;i++)    {        if(tableWidget->horizontalHeaderItem(i) != NULL)        {            this->SetCellData(1,i+1,tableWidget->horizontalHeaderItem(i)->text());        }    }
    //写数据    for(int i=0;i<tableR;i++)    {        for(int j=0;j<tableC;j++)        {            if(tableWidget->item(i,j) != NULL)            {                this->SetCellData(i+2,j+1,tableWidget->item(i,j)->text());            }        }    }
    //保存    Save();    return true;}
/**  *@brief 从指定的xls文件中把数据导入到tableWidget中  *@param tableWidget : 执行要导入到的tablewidget指针  *@return 导入成功与否 true : 成功  *                   false: 失败  */bool ExcelEngine::ReadDataToTable(QTableWidget *tableWidget){    if(NULL == tableWidget)    {        return false;    }

    //先把table的内容清空    int tableColumn = tableWidget->columnCount();    tableWidget->clear();    for(int n=0;n<tableColumn;n++)    {        tableWidget->removeColumn(0);    }
    int rowcnt    = nStartRow + nRowCount;    int columncnt = nStartColumn + nColumnCount;

    //获取excel中的第一行数据作为表头    QStringList headerList;    for(int n = nStartColumn;n<columncnt;n++)    {        QAxObject* cell = pWorksheet->querySubObject("Cells(int,int)",nStartRow, n);        if(cell)        {            headerList<<cell->dynamicCall("Value2()").toString();        }    }

    //重新创建表头    tableWidget->setColumnCount(nColumnCount);    tableWidget->setHorizontalHeaderLabels(headerList);

    //插入新数据    for(int i=nStartRow+1,r=0;i<rowcnt;i++,r++)//行    {        tableWidget->insertRow(r); //插入新行        for(int j=nStartColumn,c=0;j<columncnt;j++,c++)//列        {            QAxObject * cell = pWorksheet->querySubObject("Cells(int,int)",i,j);//获取单元格

        //在r新行中添加子项数据            if(cell)            {                tableWidget->setItem(r,c,new QTableWidgetItem(cell->dynamicCall("Value2()").toString()));            }        }    }

    return true;}
/**  *@brief 获取指定单元格的数据  *@param row : 单元格的行号  *@param column : 单元格的列号  *@return [row,column]单元格对应的数据  */
QVariant ExcelEngine::GetCellData(UINT row, UINT column){    QVariant data;    QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//获取单元格对象
    if(cell)    {        data = cell->dynamicCall("Value2()");    }    return data;}
/**  *@brief 修改指定单元格的数据  *@param row : 单元格的行号  *@param column : 单元格指定的列号  *@param data : 单元格要修改为的新数据  *@return 修改是否成功 true : 成功  *                   false: 失败  */
bool ExcelEngine::SetCellData(UINT row,UINT column,QVariant data){    bool op = false;    QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//获取单元格对象
    if ( cell )    {        QString strData = data.toString(); //excel 居然只能插入字符串和整型,浮点型无法插入        cell->dynamicCall("SetValue(const QVariant&)",strData); //修改单元格的数据        op = true;    }    else    {        op = false;    }

    return op;}
/**  *@brief 清空除报表之外的数据  */
void ExcelEngine::Clear(){    sXlsFile     = "";    nRowCount    = 0;    nColumnCount = 0;    nStartRow    = 0;    nStartColumn = 0;}
/**  *@brief 判断excel是否已被打开  *@return true : 已打开  *        false: 未打开  */bool ExcelEngine::IsOpen(){    return bIsOpen;}
/**  *@brief 判断excel COM对象是否调用成功,excel是否可用  *@return true : 可用  *        false: 不可用  */bool ExcelEngine::IsValid(){    return bIsValid;}

/**  *@brief 获取excel的行数  */UINT ExcelEngine::GetRowCount()const{    return nRowCount;}
/**  *@brief 获取excel的列数  */
UINT ExcelEngine::GetColumnCount()const{    return nColumnCount;}

简单使用:

/*
ExcelEngine excel(QObject::tr("c:\\Test.xls")); //创建
excel.Open(); //打开

int num = 0;
for (int i=1; i<=10; i++)
{
for (int j=1; j<=10; j++)
{
excel.SetCellData(i,j,++num); //修改指定单元数据
}
}

QVarient data = excel.GetCellData(1,1); //访问指定单元格数据
excel.GetCellData(2,2);
excel.GetCellData(3,3);
excel.Save(); //保存
excel.Close();
*/

//导入数据到tablewidget中
/*
ExcelEngine excel(QObject::tr("c:\\Import.xls"));
excel.Open();
excel.ReadDataToTable(ui->tableWidget); //导入到widget中
excel.Close();
*/

//把tablewidget中的数据导出到excel中
/*
ExcelEngine excel(QObject::tr("c:\\Export.xls"));
excel.Open();
excel.SaveDataFrTable(ui->tableWidget); //导出报表
excel.Close();
*/

时间: 2024-10-05 04:58:49

Qt 操作Excel的相关文章

Qt操作excel

QAxWidget excel("Excel.Application");1) 显示当前窗口:excel.setProperty("Visible", true);2) 更改 Excel 标题栏:excel.setProperty("Caption", "Invoke Microsoft Excel");3) 添加新工作簿:QAxObject * workbooks = excel.querySubObject("W

QT 操作excel 类封装

1 # pro file 2 [plain] view plaincopy 3 CONFIG += qaxcontainer 4 5 QT += core 6 7 QT -= gui 8 9 TARGET = QExcel 10 CONFIG += console 11 CONFIG -= app_bundle 12 13 TEMPLATE = app 14 15 16 SOURCES += main.cpp \ 17 qexcel.cpp 18 19 HEADERS += \ 20 qexce

qt 操作excel表格

自己编写的一个Qt C++类,用于操作excel表格,在Qt中操作excel需在.pro中增加CONFIG+=qaxcontainer配置. 1.打开Excel:objExcel = new QAxObject("Excel.Application"): <?xml:namespace prefix = o /> 2.创建工作表:workSheet->dynamicCall("Add"); 3.打开工作表:workExcel->dynamic

QT操作Excel(通过QAxObject使用了OLE,前提是本地安装了Excel)

新建QT GUI项目,在选择选项中勾选ActiveQT Container. #include <qaxobject.h> QAxObject *obj = new QAxObject("Excel.Application"); obj->setProperty("Visible", true); obj->setProperty("Caption", "Hello world"); QAxObject

Qt之操作Excel

Visual Basic for Applications(VBA)是一种Visual Basic的一种宏语言,主要能用来扩展Windows的应用程式功能,特别是Microsoft Office软件.也可说是一种应用程式视觉化的Basic Script.1994年发行的Excel 5.0版本中,即具备了VBA的宏功能. 在VBA的参考手册中就可以看到具体函数.属性的用法,Qt操作Excel主要通过 QAxObject + Excel VBA来实现! 关于Qt对Excel的操作,网上的资料挺多的,

Qt QAxObject操作excel文件过程总结(转):

正好同事问道Qt下操作excel. 转自:http://blog.csdn.net/a156392343/article/details/48092515 配制方面: 1.确保Excel软件在本地服务器注册成功,没注册成功的可以通过 在运行中"E:\program Files\Microsoft Office\Office12\EXCEL.EXE" /regserver 手动注册,注意路径要用自己的excel路径. 2.确保组件配制正确,运行命令:dcomcnfg,查看DCOM配置下是

POI操作Excel

Excel简介 一个excel文件就是一个工作簿workbook,一个工作簿中可以创建多张工作表sheet,而一个工作表中包含多个单元格Cell,这些单元格都是由列(Column)行(Row)组成,列用大写英文字母表示,从A开始到Z共26列,然后再从AA到AZ又26列,再从BA到BZ再26列以此类推.行则使用数字表示,例如:A3 表示第三行第一列,E5表示第五行第五列. POI工具包 JAVA中操作Excel的有两种比较主流的工具包: JXL 和 POI .jxl 只能操作Excel 95, 9

java 操作 Excel,java导出excel

WritableWorkbook out = null; try { response.getServletResponse().reset(); ((HttpServletResponse) response.getServletResponse()).setHeader("Content-Disposition", "attachment;filename=export.xls"); response.getServletResponse().setConten

python操作excel

python操作exce的方式: 使用win32com 使用xlrd(读excel).xlwt(写excel) 1.使用win32com方式 代码: # coding=utf-8 from win32com.client import Dispatch import pywintypes ''' 查看excel最大行数和列数 打开一个空白新建EXCEL表格,按CTRL+下箭头,可以查看到最大行数:按CTRL+右箭头, 可以查看到最大列标(若想显示列数,可在最右一列的某单元格中输入=column(