表格导出为Excel

  • 注意:演示所用到的软件为Qt5.14.2,编译器为MinGW 64-bit,电脑必须装有office
  • 所用的类为 QAxObject,QAxObject可以实例化为一个空对象,使用它应该封装的COM对象的名称,或者使用一个指向表示现有COM对象的IUnknown的指针。如果COM对象实现了IDispatch接口,则该对象的属性、方法和事件将作为Qt属性、槽和信号可用。基类QAxBase提供了通过IUnknown指针直接访问COM对象的API。
    简而言之,可以通过QAxObject 来读取、修改Excel表格
  • 在.pro中添加 QT += axcontainer
  • 添加头文件
#include <QFileDialog>
#include <QDesktopServices>

话不多说,代码搞起

QTableWidget导出为Excel

void MainWindow::WidgetExcalByHtml(QTableWidget *tableWidget, QString &title)
{QString fileName = QFileDialog::getSaveFileName(tableWidget, "保存",                                           QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "Excel 文件(*.xls *.xlsx)");if(fileName != ""){QAxObject *excel = new QAxObject;if(excel->setControl("Excel.Application")) //连接Excel控件{excel->dynamicCall("SetVisible (bool Visible)","false"); //不显示当前窗体excel->setProperty("DisplayAlerts", false); //不显示任何警告消息,如果为true那么在关闭是会出现类似"文件已修改,是否保存"的提示QAxObject *workBooks = excel->querySubObject("WorkBooks");//获取工作簿集合workBooks->dynamicCall("Add"); //新建一个工作簿QAxObject *workBook = excel->querySubObject("ActiveWorkBook"); //获取当前工作簿QAxObject *workSheet = workBook->querySubObject("Worksheets(int)", 1); //获取第一个工作表(后面的参数代表的是第几张工作表)int colCount = tableWidget->columnCount();int rowCount = tableWidget->rowCount();QAxObject *cell, *col;//标题行cell = workSheet->querySubObject("Cells(int, int)", 1, 1);cell->dynamicCall("SetValue(const QString&)", title);cell->querySubObject("Font")->setProperty("Size", 18);//调整行高workSheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);//合并标题行QString cellTitle;cellTitle.append("A1:");cellTitle.append(QChar(colCount - 1 + 'A'));cellTitle.append(QString::number(1));QAxObject *range = workSheet->querySubObject("Range(const QString&)", cellTitle);range->setProperty("WrapText", true);range->setProperty("MergeCells", true);range->setProperty("HorizontalAlignment", -4108);range->setProperty("VertivcalAlignment", -4108);//列标题for (int i = 0; i < colCount; i++){QString columnName;columnName.append(QChar(i + 'A'));columnName.append(":");columnName.append(QChar(i + 'A'));col = workSheet->querySubObject("Columns(const QString&)", columnName);col->setProperty("ColumnWidth", tableWidget->columnWidth(i)/6);cell = workSheet->querySubObject("Cells(int, int)", 2, i+1);columnName = tableWidget->horizontalHeaderItem(i)->text();cell->dynamicCall("SetValue(const QString&)", columnName);cell->querySubObject("Font")->setProperty("Bold", true);cell->querySubObject("Interior")->setProperty("Color", QColor(191, 191, 191));cell->setProperty("HorizontalAlignment", -4108);cell->setProperty("VertivcalAlignment", -4108);}//处理数据for (int i = 0; i < rowCount; i++){for (int j = 0; j < colCount; j++){workSheet->querySubObject("Cells(int, int)", i + 3, j + 1)->dynamicCall("SetValue(const QString&)", tableWidget->item(i, j)? tableWidget->item(i, j)->text():"");}}//画框线QString l_range;l_range.append("A2:");l_range.append(colCount -1 + 'A');l_range.append(QString::number(tableWidget->rowCount() + 2));range = workSheet->querySubObject("Range(const QString&)", l_range);range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));//调整数据区行高QString rowsName;rowsName.append("2:");rowsName.append(QString::number(tableWidget->rowCount() + 2));range = workSheet->querySubObject("Range(const QString&)", rowsName);range->setProperty("RowHeight", 20);workBook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(fileName)); //保存到fileNameworkBook->dynamicCall("Close()"); //关闭工作簿excel->dynamicCall("Quit()"); //关闭exceldelete  excel;excel = NULL;if ((QMessageBox::question(NULL, tr("完成"), tr("文件已导出,是否现在打开?")), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){QDesktopServices().openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));}}else{QMessageBox::warning(NULL, tr("错误"), tr("未能创建 Excel 对象,请安装 Microsoft Excel。"), QMessageBox::Apply);}}

QTableView导出为Excel

与QTableWidget导出Excel写法一样,只是QTableView获取行列以及获取单元格数据的方式和上面的不同,这个我在上篇博客已经提到,下面代码我在不同的地方设置了粗斜体,方便观看。

void MainWindow::Table2ExcelByHtml(QTableView *tableView, QString &title)
{QString fileName = QFileDialog::getSaveFileName(tableView, "保存",                                                    QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "Excel 文件(*.xls *.xlsx)");if(fileName != ""){QAxObject *excel = new QAxObject;if(excel->setControl("Excel.Application")) //连接Excel控件{excel->dynamicCall("SetVisible (bool Visible)","false"); //不显示窗体excel->setProperty("DisplayAlerts", false); //不显示任何警告消息,如果为true那么在关闭是会出现类似"文件已修改,是否保存"的提示QAxObject *workBooks = excel->querySubObject("WorkBooks");//获取工作簿集合workBooks->dynamicCall("Add"); //新建一个工作簿QAxObject *workBook = excel->querySubObject("ActiveWorkBook"); //获取当前工作簿QAxObject *workSheet = workBook->querySubObject("Worksheets(int)", 1);***int colCount = tableView->model()->columnCount();int rowCount = tableView->model()->rowCount();***QAxObject *cell, *col;//标题行cell = workSheet->querySubObject("Cells(int, int)", 1, 1);cell->dynamicCall("SetValue(const QString&)", title);cell->querySubObject("Font")->setProperty("Size", 18);//调整行高workSheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);//合并标题行QString cellTitle;cellTitle.append("A1:");cellTitle.append(QChar(colCount - 1 + 'A'));cellTitle.append(QString::number(1));QAxObject *range = workSheet->querySubObject("Range(const QString&)", cellTitle);range->setProperty("WrapText", true);range->setProperty("MergeCells", true);range->setProperty("HorizontalAlignment", -4108);range->setProperty("VertivcalAlignment", -4108);//列标题for (int i = 0; i < colCount; i++){QString columnName;columnName.append(QChar(i + 'A'));columnName.append(":");columnName.append(QChar(i + 'A'));col = workSheet->querySubObject("Columns(const QString&)", columnName);col->setProperty("ColumnWidth", tableView->columnWidth(i)/6);cell = workSheet->querySubObject("Cells(int, int)", 2, i+1);***columnName = tableView->model()->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString();***cell->dynamicCall("SetValue(const QString&)", columnName);cell->querySubObject("Font")->setProperty("Bold", true);cell->querySubObject("Interior")->setProperty("Color", QColor(191, 191, 191));cell->setProperty("HorizontalAlignment", -4108);cell->setProperty("VertivcalAlignment", -4108);}//处理数据for (int i = 0; i < rowCount; i++){for (int j = 0; j < colCount; j++){***QModelIndex index = tableView->model()->index(i, j);QString strData = tableView->model()->data(index).toString();workSheet->querySubObject("Cells(int, int)", i + 3, j + 1)->dynamicCall("SetValue(const QString&)", strData);***}}//画框线QString l_range;l_range.append("A2:");l_range.append(colCount -1 + 'A');***l_range.append(QString::number(tableView->model()->rowCount() + 2));***range = workSheet->querySubObject("Range(const QString&)", l_range);range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));//调整数据区行高QString rowsName;rowsName.append("2:");***rowsName.append(QString::number(tableView->model()->rowCount() + 2));***range = workSheet->querySubObject("Range(const QString&)", rowsName);range->setProperty("RowHeight", 20);workBook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(fileName)); //保存到fileNameworkBook->dynamicCall("Close()"); //关闭工作簿excel->dynamicCall("Quit()"); //关闭exceldelete  excel;excel = NULL;if ((QMessageBox::question(NULL, tr("完成"), tr("文件已导出,是否现在打开?")), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){QDesktopServices().openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));}}else{QMessageBox::warning(NULL, tr("错误"), tr("未能创建 Excel 对象,请安装 Microsoft Excel。"), QMessageBox::Apply);}}
}

Excel导出小结

  • 使用方法
    QString fileName = "newExcel";WidgetExcalByHtml(ui->tableWidget, fileName);Table2ExcelByHtml(ui->tableView, fileName);
  • 常用函数
QAxWidget excel("Excel.Application");//将对象的name属性的值设置为value
bool QObject::setProperty(const char *name, const QVariant &value)//调用COM对象的方法函数,以var形式传递参数,并返回该方法返回的值。
//如果方法没有返回值或函数调用失败,此函数将返回无效的QVariant对象。
QVariant QAxBase::dynamicCall(const char *function, QList<QVariant> &vars)1) 显示当前窗口:
excel.setProperty("Visible", true);
2) 更改 Excel 标题栏:
excel.setProperty("Caption", "Invoke Microsoft Excel");
3) 添加新工作簿:
QAxObject * workbooks = excel.querySubObject("WorkBooks");
workbooks->dynamicCall("Add");
4) 打开已存在的工作簿:
workbooks->dynamicCall("Open (const QString&)", QString("c:/test.xls"));
5) 获取活动工作簿:
QAxObject * workbook = excel.querySubObject("ActiveWorkBook");
6) 获取所有的工作表:
QAxObject * worksheets = workbook->querySubObject("WorkSheets");
7) 获取工作表数量:
int intCount = worksheets->property("Count").toInt();
8) 获取第一个工作表:
QAxObject * worksheet = workbook->querySubObject("Worksheets(int)", 1);
9) 获取cell的值:
QAxObject * range = worksheet->querySubObject("Cells(int,int)", 1, 1 );

Excel表格数据导入到QT中的表格

个人简单实现的界面,关键代码下面会介绍,如何读取Excel表格数据

  1. 获取Excel表格中的workSheet
    QString filePath = QFileDialog::getOpenFileName(this, QStringLiteral("选择Excel文件"), "",QStringLiteral("Excel file(*.xls *.xlsx)"));if(filePath.isEmpty()) return;excel = new QAxObject(this);excel->setControl("Excel.Application");excel->dynamicCall("SetVisible (bool Visible)", "false");excel->setProperty("DisplayAlerts", false);workbooks = excel->querySubObject("WorkBooks");workbook = workbooks->querySubObject("Open (const QString&)",filePath);worksheets = workbook->querySubObject("WorkSheets");int sheet_count = worksheets->property("Count").toInt();// 获取工作表数目for (int i = 1; i <= sheet_count; i++){work_sheet = workbook->querySubObject("Sheets(int)",i);// Sheets(int)也可换为Worksheets(int)QString work_sheet_name = work_sheet->property("Name").toString(); // 获取工作表名称work_sheet_name = QString("sheet%1:").arg(i) + work_sheet_name;ui->sheetName->addItem(work_sheet_name);  // 这里因为项目需要,我加了个ComboBox来列举所有sheet/*打印出sheet表名QString message = QString("sheet ") + QString::number(i,10) + QString(" name:");qDebug()<<message<<work_sheet_name;*/}
  1. 导入某一个sheet表
    QString str = "";if(sheet_count < 0){if(QMessageBox::warning(this, "提示", "这是一个空表格!", QMessageBox::Yes) == QMessageBox::Yes)return;}str = ui->sheetName->currentText();if(ui->sheetName->count() <= 0){if(QMessageBox::warning(this, "提示", "请重新从文件中导入!", QMessageBox::Yes) == QMessageBox::Yes)return;}int index = str.mid(5, str.indexOf(":") - 5).toInt();qDebug() << "index===" << index;worksheet = workbook->querySubObject("Worksheets(int)", index);usedRange = worksheet->querySubObject("UsedRange");QAxObject *Rows = usedRange->querySubObject("Rows");QAxObject *Columns = usedRange->querySubObject("Columns");int intRows = Rows->property("Count").toInt();int intColumns = Columns->property("Count").toInt();qDebug() << "行:" << intRows << "列:" << intColumns;QVariant var = usedRange->dynamicCall("value");QVariantList varRowContents =var.toList();const int rowCount = varRowContents.size();totalLine = rowCount - 1;qDebug() << "rowCount" << rowCount;QVariantList tmp;//将每一个sheet表格中数据按行存到importData中,这是全局的QList<QList<QVariant>>类型for (int i = 1; i < rowCount; i++) {tmp = varRowContents[i].toList();importData.append(tmp);}
//    qDebug() << importData;//导入结束解释释放指针excel->dynamicCall("Quit(void)");worksheet = NULL;usedRange = NULL;excel = NULL;workbook = NULL;workbooks = NULL;

至此,Excel表格中的数据都已经存到QList<QList>中了,根据自己的需求,一个个取出来写入QTableWidget和QTableView表格中,具体怎么插入,可以参照上篇博客的插入方法,细节方面如果有问题可以留言或者发我邮箱
18856496324@163.com

3.一次性导入所有sheet表

if(sheet_count < 0){if(QMessageBox::warning(this, "提示", "这是一个空表格!", QMessageBox::Yes) == QMessageBox::Yes)return;}if(ui->sheetName->count() <= 0){if(QMessageBox::warning(this, "提示", "请重新从文件中导入!", QMessageBox::Yes) == QMessageBox::Yes)return;}//将所有sheet表数据存到importData中,这是全局的QList<QList<QVariant>>类型for (int i = 1; i <= sheet_count; i++){worksheet = workbook->querySubObject("Worksheets(int)", i);usedRange = worksheet->querySubObject("UsedRange");QVariant var = usedRange->dynamicCall("value");QVariantList varRowContents =var.toList();const int rowCount = varRowContents.size();//这一步比较关键,如果每个sheet表前几行都是你不想要的数据,可以每次去除掉那几行,然后所有sheet表行数累加,或者先修改Excel表格,将不需要的行都删除,保留自己的数据行,可以写成totalLine += rowCount;还有一点需要注意,对于某些行列合并的地方,此方法不能准确读取其正确行列位置,可能导致数据顺序出现差错totalLine += (rowCount - 1); qDebug() <<"all impport line::" << totalLine;QVariantList tmp;//这里j代表从第几行开始将数据全部导入,个人因为项目中表格只需要从第3行开始获取数据,所有定的是3for (int j = 3; j < rowCount; j++) {tmp = varRowContents[j].toList();importData.append(tmp);}worksheet = NULL;usedRange = NULL;}ui->sheetName->clear();excel->dynamicCall("Quit(void)");excel = NULL;workbook = NULL;workbooks = NULL;

至此,Excel表格中的数据都已经存到QList<QList>中了,根据自己的需求,一个个取出来写入QTableWidget和QTableView表格中,具体怎么插入,可以参照上篇博客的插入方法,细节方面如果有问题可以留言或者发我邮箱
18856496324@163.com

Excel导入小结

  1. 代码注意事项:代码中 excel,workbook,workbooks , worksheet ,usedRange定义的都是全局指针对象,很多函数中调用了。使用完这些对象后要严格按照标准 delete、置NULL。
  2. Excel表格注意事项:对于上面代码所示功能,只能导入特定的表格数据,表格不要合并,表格中数据过长设置成换行,不要延长到其他单元格,会影响读取正确性
  3. 用QList<QList>类型读取到的数据格式如下:
(QVariant(Invalid), QVariant(QString, "顶丝"), QVariant(QString, "M5*4mm(100只)"), QVariant(Invalid), QVariant(QString, "个"), QVariant(double, 0), QVariant(double, 0), QVariant(Invalid))

具体可查看官方文档熟悉QVariant和QList容器

小NULL的修行之旅

本文也是借鉴各方资源,在自己做项目后的一些总结,写得有点粗糙,希望大家不吝赐教
借鉴链接:可参考

QT常用表格导出为Excel以及Excel导入表格相关推荐

  1. html表格导出到wps,wps excel导入html表格数据格式-网页表格复制到excel(wps)变得非常混乱...

    WPS表格怎么导入XML数据? 您好!从网页中选中区域复制,然后粘贴到WPS表,再稍理即可使用. 更多WPS办公软件教程,请访问:http://bbs.wps.cn或者http://e.weibo.c ...

  2. MySQL表如何导入图片_excel怎么把图片导入表格

    我们在制作excel表格的时候,可以相对插一些图片进去,让整个excel表格显得更丰富一点,对于新手来说还是有一定难度,怎么办?下面是学习啦小编整理的excel把图片放进去的方法,欢迎大家来到学习啦学 ...

  3. Qt 表格导出数据为 excel html csv

    Qt 表格导出数据为 excel html csv 示例 使用WPS导出出错问题 参考: 从QTableView中导出数据到excel(一) qt QTableWidget&&QTab ...

  4. Qt编写数据导出到Excel及Pdf和打印数据

    一.前言 用Qt开发已经九年了,期间用Qt做过不少的项目,在各种项目中有个功能很常用,尤其是涉及到数据记录存储的项目,那就是需要对查询的数据进行导出到Excel,或者导出到Pdf文件,或者直接打印查询 ...

  5. Oracle表里的照片怎么导出来,如何导出oracle数据库中某张表到excel_oracle数据库表格导出到excel...

    如何将oracle数据库表字段导成excel表格 这个你只要用ADO连oracle并获取记录集,根据你用的编程语言打开EXCEL,然后操作EXCEL对象的工作表就可以了.以VB为例: 1.在工程中引用 ...

  6. 前端复杂表格导出excel,一键导出 Antd Table 看这篇就够了(附源码)

    前端导出 excel 的需求很多,但市面上好用的库并不多,讲明白复杂使用场景的文章更少. 本文将以文字 + demo 源码的形式,力求讲清楚满足 99% 使用场景的终极 excel 导出方案. 如果项 ...

  7. Excel导入导出之easypoi工具之模板复杂表格导出

    工作中难免会遇到一些复杂的表格导出需求,这样普通的Excel表格难免会无法满足我们的需要,easypoi就提供了模板导出的功能,以方便我们导出更加复杂的Excel表格,这篇文章就为大家介绍一下模板导出 ...

  8. vue数组转Excel表格导出

    vue数组转Excel表格导出 安装依赖 npm i xlsx vue组件 <template><div><el-button type="success&qu ...

  9. html页面表格导出到excel总结

    转载:http://www.cnblogs.com/liuguanghai/archive/2012/12/31/2840262.html <table id="tableExcel& ...

最新文章

  1. 融合视频目标检测与单目标、多目标跟踪,港中文开源一体化视频感知平台 MMTracking...
  2. 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 一 | Activity 进程相关源码 )
  3. web前端入门学习 css(5)(浮动)(ps切图)(css属性书写顺序)(学成在线网站案例)
  4. 移植U-Boot思路和实践 | 基于RK3399
  5. php主题怎么增加导航页,教你如何给wordpress主题添加导航栏
  6. magento 1.9 用户无法登录 magento 1.9 customer can not login
  7. 零基础带你学习MySQL—MySQL常用的数据类型(列类型)(五)
  8. 通过身份证号码进行归属地的查询、出生日期,以及判断性别(升级版)
  9. forge是用java装吗_我的世界forge怎么安装 forge使用方法
  10. MySQL数据库管理命令和远程管理问题
  11. 海康威视 + 搭配内网穿透,搭建远程视频监控教程
  12. consul报错:consul at least one health check on one instance is failing
  13. 《面向对象程序设计(Java)》第四周学习总结
  14. c程序设计语言布莱恩克尼汉,《C程序设计语言(第2版新版)典藏版》 —1.5.4 单词计数...
  15. SQLServer日期函数及查询当日昨日本周本月本季度本年数据
  16. 使用 RIBs 重构 Uber 司机端
  17. 淘宝API接口大纲,引领企业信息化
  18. Jenkins安装、配置、构建、脚本、配置邮箱、上传fir
  19. html css 扑克牌桌面,CSS Card:纯css制作扑克牌_html/css_WEB-ITnose
  20. 海浪相关术语波高、浪高等

热门文章

  1. jdk支持arm_毕昇JDK,重现了 “活字印刷术” 的传奇
  2. 基于官方开源Wine7.22完美使用通达信、微信软件
  3. 互评Beta版本-SkyHunter
  4. CTFshow MISC 杂项签到~misc4
  5. 神武3手游哪个跨平台服务器最多人,神武3手游跨平台-羽扇纶巾开服时间表_神武3手游新区开服预告_第一手游网手游开服表...
  6. python的request返回400_400badrequest解决方法
  7. 如何做好迭代回顾 2/4
  8. 全局唯一id生成器----Vesta
  9. 横看成岭侧成峰,远近高低各不同
  10. 分类5:机器学习处理帕尔默企鹅数据