说实际的操作之前先介绍下excel格式(百度拷过来的),excel有两种格式xls和xlsx
XLS 就是 Microsoft Excel 工作表,是一种非常常用的电子表格格式。xls文件可以使用Microsoft Excel打开,另外微软为那些没有安装Excel的用户开发了专门的查看器Excel Viewer。使用Microsoft Excel可以将XLS格式的表格转换为多种格式:XML表格、XML数据、网页、使用制表符分割的文本文件(*.txt)、使用逗号分隔的文本文件(*.csv)等。
Microsoft Office EXCEL 2007/2010/2013/2016文档的扩展名。xlsx是从Office2007开始使用的,是用新的基于XML的压缩文件格式取代了其目前专有的默认文件格式,在传统的文件名扩展名后面添加了字母x(即:docx取代doc、.xlsx取代xls等等),使其占用空间更小。
为什么要介绍这两种格式其实就涉及到我为什么要使用下面的格式,在之前我曾今搞过一次读写excel不过那个时候没太注意还有这两种区分(那个时候应该迷迷糊糊的就操作的xls),那个时候是直接使用的文件读写来操作(也就是QFile)就可以直接解决了,然后最近要操作的的这个表格的格式是xlsx才发现QFile不好用了,读出来的全是乱码,写进去打开文件看也是看不到任何东西,于是就去网上搜了下,成功之后就整理了下自己的过程:
网上讲了两种方式1.使用ODBC,也就是读写数据的方式,2.使用qt提供的COM套件。这里我使用的第二种,因此只写出第二种。步骤如下:
1.先在.pro文件钟加入QT+= axcontainer
QT+= axcontainer
2.头文件包含
#include <QAxObject>
3.下面上操作代码
QString filename = url_info_file;
QFile f(filename);
if(f.exists())
{
int flag = 0;
QAxObject excel("Excel.Application"); // 连接excel控件
excel.setProperty("Visible", false); // 不显示窗体
QAxObject* workbooks = excel.querySubObject("WorkBooks"); //获取工作簿集合
workbooks->dynamicCall("Open(const QString&)", filename); // 打开文件
QAxObject* workbook = excel.querySubObject("ActiveWorkBook");
//QAxObject* sheets = workbook->querySubObject("Sheets");
QAxObject* sheet = workbook->querySubObject("Sheets(int)", 1);
QAxObject* range = sheet->querySubObject("UsedRange");
QAxObject* rows = range->querySubObject("Rows");
QAxObject* columns = range->querySubObject("Columns");
// 注意行、列中多余的(如:列标题)数据的排除
int rowStart = range->property( "Row" ).toInt();
int columnStart = range->property( "Column" ).toInt();
int nRow = rows->property( "Count" ).toInt();
int nColumn = columns->property( "Count" ).toInt();
// 实测上面获取到的列数会不正确,因此需要自己重新判断
// 打印每行的第2列的元素
for (int i=rowStart; i<=nRow; i++ )
{
QAxObject* cell = range->querySubObject( "Cells(int,int)", i, 2);
QString strValue = cell->property( "Value" ).toString();
if ( strValue != "" )
{
qDebug() << strValue;
}
}
workbook->dynamicCall( "Close(Boolen)", false); // 关闭文件
excel.dynamicCall( "Quit(void)" ); // 退出
}
4.操作过程钟可能会遇到的问题:
(1)文件路径不能使用相对路径,会报下图中的错误
(2)上面的这段代码每次操作excel任务管理器中就会出现一个EXCEL的进程,看到网上说是要加下面代码就不会再出现了
excel->setProperty("DisplayAlerts", true);
,但是我实测然并卵,我测到的现象是将窗体显示出来就不会出现多一个进程的情况了(即如下代码),但是有会有窗体显示出来,如果有哪位大佬找到了真的解决方法麻烦评论留下言
excel.setProperty("Visible", true);