Qt下Excel报表制作
Excel的对象层次
1个excel就有1个Application对象,1个Application对象由多个Workbook对象组成,这些Workbook 对象由Workbooks对象统一管理,Workbook对象下可以包含若干个Worksheet,这些Worksheet对象也有一个 WorkSheets对象来统一管理,接下来是Range对象,这个对象对应Worksheet里的表格单元.
封装类实现
class ExcelEngine : public QObject { public: explicit ExcelEngine(QObject *parent = 0);//打开工作表集合 ~ExcelEngine(); public: QAxObject * getWorkBooks(); QAxObject * getWorkBook(); QAxObject * getWorkSheets(); QAxObject * getWorkSheet(); public: /**************************************************************************/ /* 工作表 */ /**************************************************************************/ bool selectSheet(const QString& sheetName); //sheetIndex 起始于 1 //选择工作表 bool selectSheet(int sheetIndex); void deleteSheet(const QString& sheetName); void deleteSheet(int sheetIndex); void insertSheet(QString sheetName); int getSheetsCount(); //在 selectSheet() 之后才可调用 QString getSheetName(); QString getSheetName(int sheetIndex); /**************************************************************************/ /* 单元格 */ /**************************************************************************/ void setCellString(int row, int column, const QString& value); //cell 例如 "A7" void setCellString(const QString& cell, const QString& value); //range 例如 "A5:C7" void mergeCells(const QString& range); void mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn); QVariant getCellValue(int row, int column); void clearCell(int row, int column); void clearCell(const QString& cell); /**************************************************************************/ /* 布局格式 */ /**************************************************************************/ void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn); void setColumnWidth(int column, int width); void setRowHeight(int row, int height); void setCellTextCenter(int row, int column); void setCellTextCenter(const QString& cell); void setCellTextWrap(int row, int column, bool isWrap); void setCellTextWrap(const QString& cell, bool isWrap); void setAutoFitRow(int row); void mergeSerialSameCellsInAColumn(int column, int topRow); int getUsedRowsCount(); void setCellFontBold(int row, int column, bool isBold); void setCellFontBold(const QString& cell, bool isBold); void setCellFontSize(int row, int column, int size); void setCellFontSize(const QString& cell, int size); /**************************************************************************/ /* 文件 */ /**************************************************************************/ bool open(const QString &filename, bool bVisable); void save(); void close(); bool isOpen(){return m_bOpened;} private: QAxObject * excel = nullptr; QAxObject * workBooks = nullptr; QAxObject * workBook = nullptr; QAxObject * sheets = nullptr; QAxObject * sheet = nullptr; bool m_bOpened = false;
ExcelEngine::ExcelEngine(QObject *parent) : QObject (parent) { } ExcelEngine::~ExcelEngine() { close(); } void ExcelEngine::close() { excel->dynamicCall("Quit()"); delete sheet; delete sheets; delete workBook; delete workBooks; delete excel; excel = nullptr; workBooks = nullptr; workBook = nullptr; sheets = nullptr; sheet = nullptr; } QAxObject *ExcelEngine::getWorkBooks() { return workBooks; } QAxObject *ExcelEngine::getWorkBook() { return workBook; } QAxObject *ExcelEngine::getWorkSheets() { return sheets; } QAxObject *ExcelEngine::getWorkSheet() { return sheet; } bool ExcelEngine::selectSheet(const QString& sheetName) { sheet = sheets->querySubObject("Item(const QString&)", sheetName); if(!sheet){ return false; } return true; } void ExcelEngine::deleteSheet(const QString& sheetName) { QAxObject * a = sheets->querySubObject("Item(const QString&)", sheetName); if(!a){ qDebug()<<QString("there is no sheetName %1").arg(sheetName); return; } a->dynamicCall("delete"); } void ExcelEngine::deleteSheet(int sheetIndex) { QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex); if(!a){ qDebug()<<QString("there is no index %1").arg(sheetIndex); return; } a->dynamicCall("delete"); } bool ExcelEngine::selectSheet(int sheetIndex) { if(sheetIndex > (getSheetsCount() + 1)){ return false; } sheet = sheets->querySubObject("Item(int)", sheetIndex); return true; } void ExcelEngine::setCellString(int row, int column, const QString& value) { QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column); range->dynamicCall("SetValue(const QString&)", value); } void ExcelEngine::setCellFontBold(int row, int column, bool isBold) { QString cell; cell.append(QChar(column - 1 + 'A')); cell.append(QString::number(row)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range = range->querySubObject("Font"); range->setProperty("Bold", isBold); } void ExcelEngine::setCellFontSize(int row, int column, int size) { QString cell; cell.append(QChar(column - 1 + 'A')); cell.append(QString::number(row)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range = range->querySubObject("Font"); range->setProperty("Size", size); } void ExcelEngine::mergeCells(const QString& cell) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("VerticalAlignment", -4108);//xlCenter range->setProperty("WrapText", true); range->setProperty("MergeCells", true); } void ExcelEngine::mergeCells(int topLeftRow, int topLeftColumn, int bottomRightRow, int bottomRightColumn) { QString cell; cell.append(QChar(topLeftColumn - 1 + 'A')); cell.append(QString::number(topLeftRow)); cell.append(":"); cell.append(QChar(bottomRightColumn - 1 + 'A')); cell.append(QString::number(bottomRightRow)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("VerticalAlignment", -4108);//xlCenter range->setProperty("WrapText", true); range->setProperty("MergeCells", true); } QVariant ExcelEngine::getCellValue(int row, int column) { QVariant data; QAxObject *range = sheet->querySubObject("Cells(int,int)", row, column); // return range->property("value"); if ( range ) { data = range->dynamicCall("Value2()"); } return data; } void ExcelEngine::save() { workBook->dynamicCall("Save()"); } int ExcelEngine::getSheetsCount() { return sheets->property("Count").toInt(); } QString ExcelEngine::getSheetName() { return sheet->property("Name").toString(); } QString ExcelEngine::getSheetName(int sheetIndex) { if(sheetIndex > (getSheetsCount() + 1)){ return ""; } QAxObject * a = sheets->querySubObject("Item(int)", sheetIndex); return a->property("Name").toString(); } void ExcelEngine::getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn) { QAxObject *usedRange = sheet->querySubObject("UsedRange"); *topLeftRow = usedRange->property("Row").toInt(); *topLeftColumn = usedRange->property("Column").toInt(); QAxObject *rows = usedRange->querySubObject("Rows"); *bottomRightRow = *topLeftRow + rows->property("Count").toInt() - 1; QAxObject *columns = usedRange->querySubObject("Columns"); *bottomRightColumn = *topLeftColumn + columns->property("Count").toInt() - 1; } void ExcelEngine::setColumnWidth(int column, int width) { QString columnName; columnName.append(QChar(column - 1 + 'A')); columnName.append(":"); columnName.append(QChar(column - 1 + 'A')); QAxObject * col = sheet->querySubObject("Columns(const QString&)", columnName); col->setProperty("ColumnWidth", width); } void ExcelEngine::setCellTextCenter(int row, int column) { QString cell; cell.append(QChar(column - 1 + 'A')); cell.append(QString::number(row)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("HorizontalAlignment", -4108);//xlCenter } void ExcelEngine::setCellTextWrap(int row, int column, bool isWrap) { QString cell; cell.append(QChar(column - 1 + 'A')); cell.append(QString::number(row)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("WrapText", isWrap); } void ExcelEngine::setAutoFitRow(int row) { QString rowsName; rowsName.append(QString::number(row)); rowsName.append(":"); rowsName.append(QString::number(row)); QAxObject * rows = sheet->querySubObject("Rows(const QString &)", rowsName); rows->dynamicCall("AutoFit()"); } void ExcelEngine::insertSheet(QString sheetName) { sheets->querySubObject("Add()"); QAxObject * a = sheets->querySubObject("Item(int)", 1); int count = getSheetsCount(); for(int i = 0; i < count; i++){ if(sheetName == getSheetName(i+1)){ return; } } a->setProperty("Name", sheetName); } void ExcelEngine::mergeSerialSameCellsInAColumn(int column, int topRow) { int a,b,c,rowsCount; getUsedRange(&a, &b, &rowsCount, &c); int aMergeStart = topRow, aMergeEnd = topRow + 1; QString value; while(aMergeEnd <= rowsCount) { value = getCellValue(aMergeStart, column).toString(); while(value == getCellValue(aMergeEnd, column).toString()) { clearCell(aMergeEnd, column); aMergeEnd++; } aMergeEnd--; mergeCells(aMergeStart, column, aMergeEnd, column); aMergeStart = aMergeEnd + 1; aMergeEnd = aMergeStart + 1; } } void ExcelEngine::clearCell(int row, int column) { QString cell; cell.append(QChar(column - 1 + 'A')); cell.append(QString::number(row)); QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->dynamicCall("ClearContents()"); } void ExcelEngine::clearCell(const QString& cell) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->dynamicCall("ClearContents()"); } int ExcelEngine::getUsedRowsCount() { QAxObject *usedRange = sheet->querySubObject("UsedRange"); int topRow = usedRange->property("Row").toInt(); QAxObject *rows = usedRange->querySubObject("Rows"); int bottomRow = topRow + rows->property("Count").toInt() - 1; return bottomRow; } void ExcelEngine::setCellString(const QString& cell, const QString& value) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->dynamicCall("SetValue(const QString&)", value); } void ExcelEngine::setCellFontSize(const QString &cell, int size) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range = range->querySubObject("Font"); range->setProperty("Size", size); } bool ExcelEngine::open(const QString &filename, bool bVisable) { QFile file(filename); if (!file.exists()){ qDebug()<<"file is not exists"; return false; } excel = new QAxObject(); bool bFlag = excel->setControl("excel.Application");//初始化COM对象,新建一个excel应用程序 if(!bFlag) { bFlag = excel->setControl("kwps.Application");//尝试用wps打开 qDebug()<<"wps"; if(!bFlag) return false; } //是否可视化excel excel->dynamicCall("SetVisible(bool Visible)", false); //是否弹出警告窗口 excel->setProperty("DisplayAlerts", false); //获取工作簿集合 workBooks = excel->querySubObject("WorkBooks"); if(!workBooks){ qDebug()<<"workBooks init failed"; return false; } //打开一个工作簿 workBooks->dynamicCall("Open(const QString&)", filename); //获取当前工作簿 workBook = excel->querySubObject("ActiveWorkBook"); if(!workBook){ qDebug()<<"workBook init failed"; return false; } //获取工作表格集合 sheets = workBook->querySubObject("Sheets"); if(!sheets){ qDebug()<<"sheets init failed"; return false; } m_bOpened = true; return true; } void ExcelEngine::setCellTextCenter(const QString &cell) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("HorizontalAlignment", -4108);//xlCenter } void ExcelEngine::setCellFontBold(const QString &cell, bool isBold) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range = range->querySubObject("Font"); range->setProperty("Bold", isBold); } void ExcelEngine::setCellTextWrap(const QString &cell, bool isWrap) { QAxObject *range = sheet->querySubObject("Range(const QString&)", cell); range->setProperty("WrapText", isWrap); } void ExcelEngine::setRowHeight(int row, int height) { QString rowsName; rowsName.append(QString::number(row)); rowsName.append(":"); rowsName.append(QString::number(row)); QAxObject * r = sheet->querySubObject("Rows(const QString &)", rowsName); r->setProperty("RowHeight", height); }
测试:
//打开文件,取得工作簿 ExcelEngine excel; if(!excel.open(QStringLiteral("C:/Users/DELL/Desktop/test/xl.xls"), false)){ qDebug()<<"xls open failed"; } //=======工作表操作======= //+-工作表 excel.insertSheet("abc"); excel.deleteSheet(1); // 取得工作表名称 qDebug()<<"SheetName 1"<<excel.getSheetName(1); //取得工作表数量 qDebug()<<excel.getSheetsCount(); //=========数据操作============= //+-数据 if(excel.selectSheet(1)) excel.setCellString(1, 1, "addString"); // excel.clearCell(1,1); //读值 if(excel.selectSheet(1)) qDebug()<<excel.getCellValue(1,1).toString(); //取得工作表已使用范围 if(excel.selectSheet(1)){ int topLeftRow, topLeftColumn, bottomRightRow, bottomRightColumn; excel.getUsedRange(&topLeftRow, &topLeftColumn, &bottomRightRow, &bottomRightColumn); qDebug()<<topLeftRow<<","<<topLeftColumn<<","<<bottomRightRow<<","<<bottomRightColumn; } //=======布局样式============ //合并单元格 if(excel.selectSheet(1)){ excel.mergeCells("G1:H2"); excel.mergeCells(4, 7, 5 ,8); excel.save(); } //设置列宽 if(excel.selectSheet(1)){ excel.setColumnWidth(1, 20); excel.save(); } //设置粗体 excel.selectSheet(1); excel.setCellFontBold(2, 2, true); excel.setCellFontBold("A2", true); excel.save(); //设置文字大小 //excel.selectSheet(1); //excel.setCellFontSize("B3", 20); //excel.setCellFontSize(1, 2, 20); //excel.save(); //设置单元格文字居中 //excel.selectSheet(2); //excel.setCellTextCenter(1, 2); //excel.setCellTextCenter("A2"); //excel.save(); //设置单元格文字自动折行 //excel.selectSheet(1); //excel.setCellTextWrap(2,2,true); //excel.setCellTextWrap("A2", true); //excel.save(); //设置一行自适应行高 //excel.selectSheet(1); //excel.setAutoFitRow(2); //excel.save(); //合并一列中相同连续的单元格 //excel.selectSheet(1); //excel.mergeSerialSameCellsInColumn(1, 2); //excel.save(); //获取一张工作表已用行数 //excel.selectSheet(1); //qDebug()<<excel.getUsedRowsCount(); //设置行高 //excel.selectSheet(1); // excel.setRowHeight(2, 30); excel.save(); excel.close();

浙公网安备 33010602011771号