赞
踩
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 <QObject> #include <QAxObject> #include <QFileDialog> #include <QDebug> #include <QThread> #include <QCloseEvent> 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。