Qt tableWidget import/export Excel table

First add the following code in the .pro file:

CONFIG += \
    qaxcontainer #excel

Next is the Excel code: cpp file:

#include "excelengine.h"
#include "qt_windows.h"

QExcelEngine::QExcelEngine()
{
    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);
    }
}

QExcelEngine::QExcelEngine(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);
    }
}

QExcelEngine::~QExcelEngine()
{
    if ( bIsOpen )
    {
        // Before destructing, save the data first, then close the workbook
        Close();
    }
    OleUninitialize ();
}

/**
  *@brief Open the excel report specified by sXlsFile
  *@return true : Open successfully
  * false: open failed
  */
bool QExcelEngine::Open(int nSheet, bool visible)
{
    if ( bIsOpen )
    {
        Close();
    }

    nCurrSheet = nSheet;
    bIsVisible = visible;

    if ( NULL == pExcel )
    {
        pExcel = new QAxObject("Excel.Application"); //Connect the Excel control
        if ( pExcel )
        {
            bIsValid = true;
        }
        else
        {
            bIsValid = false;
            bIsOpen = false;
            return bIsOpen;
        }

        pExcel->dynamicCall("SetVisible(bool)", bIsVisible); //bIsVisible whether to display the form
        pExcel->setProperty("DisplayAlerts", false); //Do not display any warnings
        pWorkbooks = pExcel->querySubObject("WorkBooks"); //Get the workbook
    }

    if ( !bIsValid )
    {
        bIsOpen = false;
        return bIsOpen;
    }

    if ( sXlsFile.isEmpty() )
    {
        bIsOpen = false;
        return bIsOpen;
    }

    //If the file pointed to does not exist, you need to create a new one
    QFile f(sXlsFile);
    if (!f.exists())
    {
        bIsANewFile = true;
    }
    else
    {
        bIsANewFile = false;
    }

    if (! bIsANewFile)
    {
        pWorkbook = pWorkbooks->querySubObject("Open(QString, QVariant)", sXlsFile, QVariant(0)); //Open the workbook corresponding to xls
    }
    else
    {
        pWorkbooks->dynamicCall("Add"); //Add a new workbook
        pWorkbook = pExcel->querySubObject("ActiveWorkBook"); //Create a new xls
    }

    pWorksheet = pWorkbook->querySubObject("WorkSheets(int)", nCurrSheet);//Open the first sheet

    //So far it has been opened, start to get the corresponding properties
    QAxObject *usedrange = pWorksheet->querySubObject("UsedRange");//Get the used range object of the sheet
    QAxObject *rows = usedrange->querySubObject("Rows");
    QAxObject *columns = usedrange->querySubObject("Columns");

    //Because excel can fill in data from any row and column, not necessarily from 0,0, so you need to get the first row and column subscript
    nStartRow = usedrange->property("Row").toInt(); //The starting position of the first row
    nStartColumn = usedrange->property("Column").toInt(); //The starting position of the first column

    nRowCount = rows->property("Count").toInt(); //Get the number of rows
    nColumnCount = columns->property("Count").toInt(); //Get the number of columns

    bIsOpen  = true;
    return bIsOpen;
}

/**
  * @brief Open() overloaded function
  */
bool QExcelEngine::Open(QString xlsFile, int nSheet, bool visible)
{
    sXlsFile = xlsFile;
    nCurrSheet = nSheet;
    bIsVisible = visible;

    return Open(nCurrSheet,bIsVisible);
}

/**
  *@brief save table data and write data to file
  */
void QExcelEngine::Save()
{
    if ( pWorkbook )
    {
        if (bIsSaveAlready)
        {
            return ;
        }

        if (! bIsANewFile)
        {
            pWorkbook->dynamicCall("Save()");
        }
        else /*If the document is newly created, use the save as COM interface*/
        {
//            pWorkbook->dynamicCall("SaveAs (const QString&,int,const QString&,const QString&,bool,bool)",
//                      sXlsFile,56,QString(""),QString(""),false,false);
            pWorkbook->dynamicCall("SaveAs(const QString&)", sXlsFile);
        }

        bIsSaveAlready = true;
    }
}

/**
  *@brief save the data before closing, then close the current Excel COM object and free the memory
  */
void QExcelEngine::Close()
{
    // save data before closing
//    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 save the data in tableWidget to excel
  *@param tableWidget : Pointer to tablewidget in GUI
  *@return save success or not true : success
  * false: failed
  */
bool QExcelEngine::SaveDataFrTable(QTableWidget *tableWidget)
{
    if ( NULL == tableWidget )
    {
        return false;
    }
    if ( !bIsOpen )
    {
        return false;
    }

    int tableR = tableWidget->rowCount();
    int tableC = tableWidget->columnCount();

    //Get the header and write the first row
    for (int i=0; i<tableC; i++)
    {
        if ( tableWidget->horizontalHeaderItem(i) != NULL )
        {
            this->SetCellData(1, i+1, tableWidget->horizontalHeaderItem(i)->text());
        }
    }

    //write data
    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());
            }
        }
    }

    //keep
    Save();

    return true;
}

/**
  *@brief Import data into tableWidget from the specified xls file
  *@param tableWidget : execute the tablewidget pointer to be imported into
  *@return import success or not true : success
  * false: failed
  */
bool QExcelEngine::ReadDataToTable(QTableWidget *tableWidget)
{
    if ( NULL == tableWidget )
    {
        return false;
    }

    // first clear the contents of the 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;

    //Get the first row of data in excel as the header
    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();
        }
    }

    //recreate the header
    tableWidget->setColumnCount(nColumnCount);
    tableWidget->setHorizontalHeaderLabels(headerList);

    //insert new data
    for (int i = nStartRow + 1, r = 0; i < rowcnt; i++, r++ )  //行
    {
        tableWidget->insertRow(r); //Insert a new row
        for (int j = nStartColumn, c = 0; j < columncnt; j++, c++ )  //列
        {
            QAxObject * cell = pWorksheet->querySubObject("Cells(int,int)", i, j );//Get the cell

            //Add child item data in r new line
            if ( cell )
            {
                tableWidget->setItem(r,c,new QTableWidgetItem(cell->dynamicCall("Value2()").toString()));
                tableWidget->item(r, c)->setTextAlignment(Qt::AlignCenter);
            }
        }
    }

    return true;
}

/**
  *@brief Get the data of the specified cell
  *@param row : the row number of the cell
  *@param column : the column number of the cell
  *@return [row,column] The data corresponding to the cell
  */
QVariant QExcelEngine::GetCellData(int row, int column)
{
    QVariant data;

    QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//Get the cell object
    if ( cell )
    {
        data = cell->dynamicCall("Value2()");
    }

    return data;
}

/**
  *@brief Modify the data of the specified cell
  *@param row : the row number of the cell
  *@param column : the column number specified by the cell
  *@param data : The new data the cell is to be modified to
  *@return whether the modification is successful true : success
  * false: failed
  */
bool QExcelEngine::SetCellData(int row, int column, QVariant data)
{
    bool on = false;

    QAxObject *cell = pWorksheet->querySubObject("Cells(int,int)",row,column);//Get the cell object
    if ( cell )
    {
        QString strData = data.toString(); //Excel can only insert strings and integers, and floating-point cannot be inserted
        cell->dynamicCall("SetValue(const QVariant&)",strData); //Modify the data of the cell
        op = true;
    }
    else
    {
        op = false;
    }

    return op;
}

/**
 * @brief clears the entire Excel sheet
 */
void QExcelEngine::ClearAllData(QString strData)
{
    for (int i=0; i<nStartRow+nRowCount; i++)
    {
        for (int j=0; j<nStartColumn+nColumnCount; j++)
        {
            this->SetCellData(i, j, strData);
        }
    }

    //keep
    Save();
}

/**
  *@brief clear data other than report
  */
void QExcelEngine::Clear()
{
    sXlsFile     = "";
    nRowCount    = 0;
    nColumnCount = 0;
    nStartRow    = 0;
    nStartColumn = 0;
}

/**
  *@brief to determine whether excel has been opened
  *@return true : opened
  * false: not open
  */
bool QExcelEngine::IsOpen()
{
    return bIsOpen;
}

/**
  *@brief Determine whether the excel COM object is successfully called and whether excel is available
  *@return true : available
  * false: not available
  */
bool QExcelEngine::IsValid()
{
    return bIsValid;
}

/**
  *@brief Get the number of rows in excel
  */
int QExcelEngine::GetRowCount() const
{
    return nRowCount;
}

/**
  *@brief Get the number of columns in excel
  */
int QExcelEngine::GetColumnCount() const
{
    return nColumnCount;
}

.h file:

#include <QFile>
#include <QMessageBox>
#include <QString>
#include <QDebug>
#include <QTableWidget>
#include <QAxObject>

class QExcelEngine
{
public:
    QExcelEngine();
    QExcelEngine(QString xlsFile);
    ~QExcelEngine();

public:
    bool Open(int nSheet, bool visible);
    bool Open(QString xlsFile, int nSheet, bool visible);
    void Save();
    void Close();
    bool SaveDataFrTable(QTableWidget *tableWidget);
    bool ReadDataToTable(QTableWidget *tableWidget);
    QVariant GetCellData(int row, int column);
    bool SetCellData(int row, int column, QVariant data);
    void ClearAllData(QString strData);
    void Clear();
    bool IsOpen();
    bool IsValid();
    int GetRowCount() const;
    int GetColumnCount() const;

private:
    QAxObject *pExcel;
    QAxObject *pWorkbooks;
    QAxObject *pWorkbook;
    QAxObject *pWorksheet;

    QString sXlsFile;

    int nRowCount;
    int nColumnCount;
    int nStartRow;
    int nStartColumn;
    int nCurrSheet;

    bool bIsVisible;
    bool bIsOpen;
    bool bIsValid;
    bool bIsANewFile;
    bool bIsSaveAlready;
};

The next step is to call, first import from the Excel table to tableWeight, here I click the button to achieve, the code is as follows:

void QEnteringWidget::slotExcelInto()
{
    QMessageBox::StandardButton rb = QMessageBox::information(this, "warning", "Importing data from an excel file will overwrite all previous content,\nAre you sure about importing?",
                             QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);

    if(rb == QMessageBox::Yes)
    {
        //Import the table from Excel to TableWidget
        excelEngine = new QExcelEngine;

        m_fileName = QFileDialog::getOpenFileName(this, tr("select file"), "../datafile/", tr("*.xls *.xlsx"));
        if(m_fileName.isEmpty())
            return;

        loadingWidget.show();
        bool b = excelEngine->Open(m_fileName, 1, false); //flase is to not display the form
        if(b == false)
        {
            QMessageBox::information(this, "excel prompt", "file failed to open");
            return;
        }
        excelEngine->ReadDataToTable(tableWidget);
        excelEngine->Close();
        loadingWidget.close();
    }
}

Call tableweight to import into the Excel table, the code is as follows:

void QDemandWidget::slotIntoExcel()
{
    excelEngine = new QExcelEngine;

    filename = QFileDialog::getSaveFileName(this, tr("Save as..."), "../datafile", tr("EXCEL files (*.xls *.xlsx);;HTML-Files (*.txt);;"));
    if(filename.isEmpty())
        return;

    loadingWidget.show();
    bool b = excelEngine->Open(filename, 1, false); //flase is to not display the form
    if(b == false)
    {
        QMessageBox::information(this, "excel prompt", "file failed to open");
        return;
    }

    //Clear everything before the table
    excelEngine->ClearAllData(" ");
    excelEngine->Close();

    //Open the database and save the data
//    excelEngine->Open(filename, 1, false);
//    excelEngine->SaveDataFrTable(tableWidget);
//    excelEngine->Close();
    loadingWidget.close();

    QMessageBox::information(this, "excel prompt", "import successful");
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325653164&siteId=291194637