QT-Excel功能操作

简介

1.Qt操作Excel封装了很多功能,接口详细,注释丰富。

代码

1.1.0.0更新到1.0.1,①更新读取单元格样式。②更新列数转换英文字母超过26累加字母

#ifndef EXCELTHREAD_H
#define EXCELTHREAD_H

#define VERSION "Excel Version V-1.0.1"

#include 
#include 
#include 
#include 
#include 
#include 


struct TableCellAttr {
    int fillColor;//填充色/*无色 = -4142,自动 = -4105,黑色 = 1,褐色 = 53,橄榄 = 52,深绿 = 51,深青 = 49,深蓝 = 11,靛蓝 = 55,灰色80 = 56,深红 = 9,橙色 = 46,深黄 = 12,绿色 = 10,青色 = 14,蓝色 = 5,蓝灰 = 47,灰色50 = 16,红色 = 3,浅橙色 = 45,酸橙色 = 43,海绿 = 50,水绿色 = 42,浅蓝 = 41,    紫罗兰 = 13,灰色40 = 48,粉红 = 7,金色 = 44,黄色 = 6,鲜绿 = 4,青绿 = 8,天蓝 = 33,梅红 = 54,灰色25 = 15,玫瑰红 = 38,茶色 = 40,浅黄 = 36,浅绿 = 35,浅青绿 = 34,淡蓝 = 37,淡紫 = 39,白色 = 2*/
    int border;//边框(=1 虚线;=2实线;=-4238 粗实线(一般粗);=4实线(很粗))
    int fontColor;//字体颜色 = fillColor注释
    int fontSize;//字体大小
    QString fontStr;//字体
    bool isItalic;//斜体
    bool isBoldface;//粗体
    bool isUnderline;//下划线
    bool isWrapText;//自动换行
    bool isAutoFitRow; //自适应行高
    int cellFormat;//单元格格式 1文本 2日期 3数字 4货币 5百分比
    TableCellAttr()
        : fillColor(-1)
        , border(-1)
        , fontColor(-1)
        , fontSize(-1)
        , fontStr("")
        , isItalic(false)
        , isBoldface(false)
        , isUnderline(false)
        , isWrapText(false)
        , isAutoFitRow(false)
        , cellFormat(-1)
    {}
};

class ExcelThread : public QObject
{
    Q_OBJECT
public:
    explicit ExcelThread(QObject *parent = nullptr);
    ~ExcelThread();
private slots:
    void init();
public:
    //打开excel
    bool OpenExcel(const QString filePath);

    /*----------工作表----------*/
    //切换工作表
    void switchSheet(const int sheetIndex);
    bool switchSheet(const QString sheetName);
    //获取当前工作表
    int getCurrentSheetIndex();
    QString getCurrentSheetName();
    //获取所有工作表
    QStringList getAllSheetName();
    //增加工作表
    void addSheet(const QString sheetName);
    //删除工作表
    bool delSheet(const QString sheetName);
    void delSheet(const int sheetindex);

    /*--------单元格数据--------*/
    //获取行数列数
    bool getRowAndColumn(int &row, int &column);
    int getRow();
    int getColumn();
    //获取excel所有数据
    bool getExcelAllContent(QList<QStringList>& allData);
    bool getExcelAllContent(QList<QStringList>& allData, QList<QList<TableCellAttr>>& allDataStyle);
    //插入数据
    bool insertFileData(const int row, const int column, const QString data);
    bool insertFileData(const int row, const int column, const QString data,
                        const TableCellAttr tableCellAttr); //row and column >=1
    //一行行插入效率快
    bool insertFileData(const int row, const int column, const QList<QVariant> dataList,
                        const TableCellAttr tableCellAttr = TableCellAttr());
    //清除内容和样式
    bool clearDataAndStyle(const int row, const int column);
    //删除一行
    void delRow(const int row);
    //删除一列
    void delColumn(const int column);
    //单元格合并
    bool cellMerge(const int beginRow, const int beginColumn, const int endRow,
                   const int endColumn, const bool isMergeCells = true);
    //修改单元格行高和行宽
    bool setHighAndWidth(const int row, const int column, const int high,
                         const int width, QAxObject* worksheet);
    //修改列宽
    void setColumnWidth(const int column, int width);
    //修改行高
    void setRowHeight(const int row, int height);

    //操作完成保存
    void writeFinishSave();
private:
    //数据样式修改
    void setCellStyle(const TableCellAttr tableCellAttr, QAxObject* cell);
    TableCellAttr readCellStyle(QAxObject* cell);
    //列数转换英文字母超过26累加字母
    QString numberConvertCellStr(int size);

private:
    QList<QStringList> m_DataList;
    QString m_WriteFile;

    QAxObject* m_Excel; //excel程序
    QAxObject* m_WorkBooks; //excel所有工作薄
    QAxObject* m_WorkBook; //excel文件对象
    QAxObject* m_WorkSheets; //所有模板

    int m_SheetIndex;
};

#endif // EXCELTHREAD_H


#include "excelthread.h"
#include "windows.h"

ExcelThread::ExcelThread( QObject *parent)
    : QObject(parent)
    , m_Excel(nullptr)
    , m_SheetIndex(1)
{
    qDebug() << VERSION;
    init();
}

ExcelThread::~ExcelThread()
{
    qDebug() << "excel quit";
    if (m_Excel == nullptr) {
        return;
    }

    delete m_Excel;
    m_Excel = NULL;
}

void ExcelThread::init()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    m_Excel = new QAxObject("Excel.Application");
    m_Excel->dynamicCall("SetVisible(bool Visible)", false);
    m_Excel->setProperty("DisplayAlert", false);
}

bool ExcelThread::OpenExcel(const QString filePath)
{
    if (!QFileInfo(filePath).exists()) {
        qDebug() << filePath << "file no exists";
        return false;
    }
    m_WorkBooks = m_Excel->querySubObject("WorkBooks");
    m_WorkBook = m_WorkBooks->querySubObject("Open(const QString&)", filePath);

    if (!m_WorkBook)
    {
        qDebug()  << "m_WorkBook Error";
        return false;
    }
    m_WorkSheets = m_WorkBook->querySubObject("Sheets");

    return true;
}

void ExcelThread::switchSheet(const int sheetIndex)
{
    m_SheetIndex = sheetIndex;
    if (sheetIndex <= 0) {
        m_SheetIndex = 1;
    }
}

bool ExcelThread::switchSheet(const QString sheetName)
{
    if (sheetName.isEmpty()) return false;

    QStringList sheetNameList = getAllSheetName();
    int index = sheetNameList.indexOf(sheetName);
    if (index != -1) {
        m_SheetIndex = index + 1;
    }
    return false;
}

int ExcelThread::getCurrentSheetIndex()
{
    return m_SheetIndex;
}

QString ExcelThread::getCurrentSheetName()
{
    QAxObject* sheet =  m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    return sheet->dynamicCall("Name").toString();
}

QStringList ExcelThread::getAllSheetName()
{
    int count = m_WorkSheets->dynamicCall("Count").toInt();

    QStringList sheetNameList;
    for (int i = 1; i <= count; ++i) {
        QAxObject* sheet =  m_WorkSheets->querySubObject("Item(int)", i);
        sheetNameList << sheet->dynamicCall("Name").toString();
    }
    return sheetNameList;
}

void ExcelThread::addSheet(const QString sheetName)
{
    m_WorkSheets->querySubObject("Add()");
    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    workSheet->setProperty("Name", sheetName);
}

bool ExcelThread::delSheet(const QString sheetName)
{
    if (sheetName.isEmpty()) return false;

    QStringList sheetNameList = getAllSheetName();
    int index = sheetNameList.indexOf(sheetName);
    if (index != -1) {
        QAxObject* sheet = m_WorkSheets->querySubObject("Item(int)", index);
        sheet->dynamicCall("delete");
    }
    return false;
}

void ExcelThread::delSheet(const int sheetindex)
{
    QAxObject* sheet = m_WorkSheets->querySubObject("Item(int)", sheetindex);
    sheet->dynamicCall("delete");
}

bool ExcelThread::getRowAndColumn(int &row, int &column)
{
    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);

    QAxObject* usedrange = workSheet->querySubObject("UsedRange");
    if (!usedrange) {
        qDebug() << "usedrange error";
        return false;
    }
    QAxObject *rows, *columns;
    rows = usedrange->querySubObject("Rows");
    columns = usedrange->querySubObject("Columns");

    row = rows->property("Count").toInt();
    column = columns->property("Count").toInt();
    return true;
}

int ExcelThread::getRow()
{
    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);

    QAxObject* usedrange = workSheet->querySubObject("UsedRange");
    if (!usedrange) {
        qDebug() << "usedrange error";
        return false;
    }
    QAxObject *rows;
    rows = usedrange->querySubObject("Rows");

    int row = rows->property("Count").toInt();
    return row;
}

int ExcelThread::getColumn()
{
    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);

    QAxObject* usedrange = workSheet->querySubObject("UsedRange");
    if (!usedrange) {
        qDebug() << "usedrange error";
        return false;
    }
    QAxObject *columns;
    columns = usedrange->querySubObject("Columns");
    int column = columns->property("Count").toInt();
    return column;
}

bool ExcelThread::getExcelAllContent(QList<QStringList> &allData)
{
    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    int row, column;
    if (getRowAndColumn(row, column)) {
        for (int i = 1; i <= row; ++i) {
            QStringList data;
            for (int j = 1; j <= column; ++j) {
                QAxObject* cell = workSheet->querySubObject("Cells(int, int)", i, j);
                data << cell->dynamicCall("Value2()").toString();
            }
            allData << data;
        }
    }
    else {
        return false;
    }
    return true;
}

bool ExcelThread::getExcelAllContent(QList<QStringList> &allData, QList<QList<TableCellAttr> > &allDataStyle)
{
    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);

    int row, column;
    if (getRowAndColumn(row, column)) {
        for (int i = 1; i <= row; ++i) {
            QStringList data;
            QList<TableCellAttr> dataStyle;
            for (int j = 1; j <= column; ++j) {
                QAxObject* cell = workSheet->querySubObject("Cells(int, int)", i, j);
                data << cell->dynamicCall("Value2()").toString();
                dataStyle << readCellStyle(cell);
            }
            allData << data;
            allDataStyle << dataStyle;
        }
    }
    else {
        return false;
    }
    return true;
}

bool ExcelThread::insertFileData(const int row, const int column, const QString data)
{
    int setRow = row;
    int setColumn = column;
    if (setRow == 0) setRow = 1;
    if (setColumn == 0) setColumn = 1;

    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Cells(int, int)", setRow, setColumn);

    cell->dynamicCall("SetValue(conts QVariant&)", data);
    return true;
}

bool ExcelThread::insertFileData(const int row, const int column, const QString data, const TableCellAttr tableCellAttr)
{
    int setRow = row;
    int setColumn = column;
    if (setRow == 0) setRow = 1;
    if (setColumn == 0) setColumn = 1;

    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Cells(int, int)", setRow, setColumn);

    setCellStyle(tableCellAttr, cell);
    cell->dynamicCall("SetValue(conts QVariant&)", data);
    return true;
}

bool ExcelThread::insertFileData(const int row, const int column, const QList<QVariant> dataList, const TableCellAttr tableCellAttr)
{
    int setRow = row;
    int setColumn = column;
    if (setRow == 0) setRow = 1;
    if (setColumn == 0) setColumn = 1;

    QString cellStr;
    cellStr.append(numberConvertCellStr(setColumn));
    cellStr.append(QString::number(setRow));
    cellStr.append(":");
    cellStr.append(numberConvertCellStr(dataList.size() + setColumn - 1));
    cellStr.append(QString::number(setRow));

    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Range(QString)", cellStr);
    setCellStyle(tableCellAttr, cell);
    cell->dynamicCall("SetValue(conts QVariant&)", dataList);
    return true;
}

void ExcelThread::setCellStyle(const TableCellAttr tableCellAttr, QAxObject *cell)
{
    if (tableCellAttr.fillColor != -1) {
        QAxObject* temp = cell->querySubObject("Interior");
        temp->setProperty("ColorIndex", tableCellAttr.fillColor);
    }
    if (tableCellAttr.border != -1) {
        QAxObject* temp = cell->querySubObject("Borders");
        temp->setProperty("Weight", tableCellAttr.border);
    }
    if (tableCellAttr.fontColor != -1) {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("ColorIndex", tableCellAttr.fontColor);
    }
    if (tableCellAttr.fontSize != -1) {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("Size", tableCellAttr.fontSize);
    }
    if (tableCellAttr.fontStr != "") {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("Name", tableCellAttr.fontStr);
    }
    if (tableCellAttr.isItalic) {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("Italic", tableCellAttr.isItalic);
    }
    if (tableCellAttr.isBoldface) {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("Bold", tableCellAttr.isBoldface);
    }
    if (tableCellAttr.isUnderline) {
        QAxObject* temp = cell->querySubObject("Font");
        temp->setProperty("UnderLine", tableCellAttr.isUnderline);
    }
    if (tableCellAttr.isWrapText) {
        QAxObject* temp = cell;
        temp->setProperty("WrapText", tableCellAttr.isWrapText);
    }
    if (tableCellAttr.isAutoFitRow) {
        QAxObject* temp = cell;
        temp->dynamicCall("AutoFit()");
    }
    if (tableCellAttr.cellFormat != -1) {
        switch (tableCellAttr.cellFormat) {
        case 1:
            cell->setProperty("NumberFormatLocal", "@");
            break;
        case 2:
            cell->setProperty("NumberFormatLocal", "yyyy/mm/dd");
            break;
        case 3:
            cell->setProperty("NumberFormatLocal", "#,##0.00");
            break;
        case 4:
            cell->setProperty("NumberFormatLocal", "#,##0.00");
            break;
        case 5:
            cell->setProperty("NumberFormatLocal", "#0.00%");
            break;
        default:
            cell->setProperty("NumberFormatLocal", "@");
            break;
        }
    }
}

TableCellAttr ExcelThread::readCellStyle(QAxObject *cell)
{
    if (cell->isNull()) return TableCellAttr();

    TableCellAttr tableCellAttr;

    QAxObject* temp = cell->querySubObject("Interior");
    tableCellAttr.fillColor = temp->dynamicCall("ColorIndex").toInt();

    temp = cell->querySubObject("Borders");;
    tableCellAttr.border = temp->dynamicCall("Weight").toInt();

    temp = cell->querySubObject("Font");;
    tableCellAttr.fontColor = temp->dynamicCall("ColorIndex").toInt();

    temp = cell->querySubObject("Font");;
    tableCellAttr.fontSize = temp->dynamicCall("Size").toInt();

    temp = cell->querySubObject("Font");;
    tableCellAttr.fontStr = temp->dynamicCall("Name").toString();

    temp = cell->querySubObject("Font");;
    tableCellAttr.isItalic = temp->dynamicCall("Italic").toBool();

    temp = cell->querySubObject("Font");;
    tableCellAttr.isBoldface = temp->dynamicCall("Bold").toBool();

    temp = cell->querySubObject("Font");;
    tableCellAttr.isUnderline = temp->dynamicCall("UnderLine").toBool();

    tableCellAttr.isWrapText = cell->dynamicCall("WrapText").toBool();

    tableCellAttr.isAutoFitRow = cell->dynamicCall("AutoFit()").toBool();

    QString cellFormat = cell->dynamicCall("NumberFormatLocal").toString();

    if (cellFormat.contains("yyyy")) {
        tableCellAttr.cellFormat = 2;
    }
    else if (cellFormat.contains("0.00_")) {
        tableCellAttr.cellFormat = 3;
    }
    else if (cellFormat.contains("??#")) {
        tableCellAttr.cellFormat = 4;
    }
    else if (cellFormat.contains("0.00%")) {
        tableCellAttr.cellFormat = 5;
    }
    else {
        tableCellAttr.cellFormat = 1;
    }

    return tableCellAttr;
}

QString ExcelThread::numberConvertCellStr(int size)
{
    QString str;
    if (size > 26 && size <= 255) {
        int number1 = 0;
        while (size % 26 != 0) {
            size--;
            number1++;
        }
        int number2 = size / 26;// 整数求商
        str.append(QChar(number2 - 1 + 'A'));
        str.append(QChar((number1 - 1) + 'A'));
        return str;
    }
    else {
        return QString(QChar(size -1 + 'A'));
    }
}

bool ExcelThread::clearDataAndStyle(const int row, const int column)
{
    int setRow = row;
    int setColumn = column;
    if (setRow == 0) setRow = 1;
    if (setColumn == 0) setColumn = 1;

    QAxObject *workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Cells(int, int)", setRow, setColumn);
    cell->querySubObject("ClearContents");
    return true;
}

void ExcelThread::delRow(const int row)
{
    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Rows(int)", row);
    cell->querySubObject("Delete");
}

void ExcelThread::delColumn(const int column)
{
    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Columns(int)", column);
    cell->querySubObject("Delete");
}

bool ExcelThread::cellMerge(const int beginRow, const int beginColumn, const int endRow, const int endColumn, const bool isMergeCells)
{
    int setBeginRow = beginRow;
    int setBeginColumn = beginColumn;
    if (setBeginRow == 0) setBeginRow = 1;
    if (setBeginColumn == 0) setBeginColumn = 1;

    int setEndRow = endRow;
    int setEndColumn = endColumn;
    if (setEndRow == 0) setEndRow = 1;
    if (setEndColumn == 0) setEndColumn = 1;

    QString cellStr;
    cellStr.append(numberConvertCellStr(setBeginColumn));
    cellStr.append(QString::number(setBeginRow));
    cellStr.append(":");
    cellStr.append(numberConvertCellStr(setEndColumn));
    cellStr.append(QString::number(setEndRow));


    qDebug() << cellStr;
    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Range(QString)", cellStr);
    cell->setProperty("VerticalAlignment", -4108);
    cell->setProperty("MergeCells", isMergeCells);

    return true;
}

bool ExcelThread::setHighAndWidth(const int row, const int column, const int high, const int width, QAxObject *worksheet)
{

}

void ExcelThread::setColumnWidth(const int column, int width)
{
    QString cellStr;
    cellStr.append(numberConvertCellStr(column));
    cellStr.append(":");
    cellStr.append(numberConvertCellStr(column));

    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Range(QString)", cellStr);
    cell->setProperty("ColumnWidth", width);
}

void ExcelThread::setRowHeight(const int row, int height)
{
    QString cellStr;
    cellStr.append('A');
    cellStr.append(QString::number(row));

    QAxObject* workSheet = m_WorkSheets->querySubObject("Item(int)", m_SheetIndex);
    QAxObject* cell = workSheet->querySubObject("Range(QString)", cellStr);
    QAxObject* temp = cell->querySubObject("Rows");
    temp->setProperty("RowHeight", height);
}

void ExcelThread::writeFinishSave()
{
    m_WorkBook->dynamicCall("Save()");
    m_Excel->dynamicCall("Quit(void)", false);

    delete m_WorkSheets;
    delete m_WorkBook;
    delete m_WorkBooks;

    m_WorkSheets = NULL;
    m_WorkBook = NULL;
    m_WorkBooks = NULL;
}


调用方式


1.ExcelThread excelWrite;//建议全局,init比较慢
2.OpenExcel; //每次操作都打开
3.insertFileData; //插入数据
4.writeFinishSave();操作完成一定要保存,会清空所有open的WorkBook

你可能感兴趣的:(Qt-功能分享,qt,开发语言)