Qt编写xls和xlsx文件

使用Qt开发小工具时,有时会涉及到Excel文件读写操作,就我自己的经历总结了三种方法。

  1. 使用XmlDocument 写xls

Qt定义了xml文件读写接口QDomDocument,也可以通过这个接口写Excel表格,但仅限于xls文件。

bool MainWindow::TestQDomDocument()

{

    QString selectedFile = QFileDialog::getSaveFileName(this,QStringLiteral("保存"), "./data/"QStringLiteral("XLS file (*.xls)"));

    if (selectedFile.isEmpty() == true)

        return false;

 

    if (selectedFile.endsWith(".xls") == false)

        selectedFile += ".xls";

 

    QFile file(selectedFile);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))

    {

        QMessageBox::warning(thisQStringLiteral("错误"), QStringLiteral("创建文件出错!"));

        return false;

    }

 

    QApplication::setOverrideCursor(Qt::WaitCursor);

    QDomDocument domDoc;

 

    QDomProcessingInstruction instruction = domDoc.createProcessingInstruction("xml","version=\'1.0\'");

    domDoc.appendChild(instruction);

    instruction = domDoc.createProcessingInstruction("mso-application","progid=\'Excel.Sheet\'");

    domDoc.appendChild(instruction);

 

    QDomElement rootEle = domDoc.createElement("Workbook");

    rootEle.setAttribute("xmlns","urn:schemas-microsoft-com:office:spreadsheet");

    rootEle.setAttribute("xmlns:ss","urn:schemas-microsoft-com:office:spreadsheet");

    domDoc.appendChild(rootEle);

 

    QDomElement workSheetEle = domDoc.createElement("Worksheet");

    workSheetEle.setAttribute("ss:Name","Sheet1");

    rootEle.appendChild(workSheetEle);

 

    QDomElement tableEle = domDoc.createElement("Table");

    workSheetEle.appendChild(tableEle);

 

    //按行写数据

    QStringList header;

    header << QStringLiteral("名称") << QStringLiteral("类型")<< QStringLiteral("子类型")<<QStringLiteral("数量");

 

    QList<QStringList> allTables;

    allTables.push_back(header);

 

    for(int i=0; i<m_pointList.size(); i++)//QList<PointInfo >

    {

        QStringList itemlist = m_pointList[i].toList();

        allTables.push_back(itemlist);

//        QStringList toList()

//        {

//            return QStringList() << name << type << subtype << num;//结构体转为QStringList

//        }

    }

 

    int count = allTables.size();

    for(int i=0; i<count; i++)

    {

        qApp->processEvents();

 

        QStringList item = allTables[i];

 

        QDomElement rowEle = domDoc.createElement("Row");        //添加标题

        for(int j=0; j<item.count(); j++)

        {

            QDomElement cellEle = domDoc.createElement("Cell");

            QDomElement dataEle = domDoc.createElement("Data");

 

            QString strValue = item.at(j);

            dataEle.setAttribute("ss:Type""String");

 

            QDomText domText = domDoc.createTextNode(strValue);

            dataEle.appendChild(domText);

            cellEle.appendChild(dataEle);

            rowEle.appendChild(cellEle);

        }

        tableEle.appendChild(rowEle);

    }

 

    QTextStream outStream(&file);

    outStream.setCodec(QTextCodec::codecForName("UTF-8"));

    domDoc.save(outStream, 4QDomNode::EncodingFromTextStream);

    file.close();

    QApplication::restoreOverrideCursor();

 

    QMessageBox::information(thisQStringLiteral("提示"), QStringLiteral("保存文件成功!"));

    return true;

}


  1. 使用QtXlsx写xlsx

QtXlsx并不是Qt5本身提供的库,需要下载源码编译才能使用,下载和编译部分我是参考链接:使用QtXlsx来读写excel文件,拜谢!

实际上源码部分已经给出了很多demo,大家找到examples目录可以看到具体内容,包括各种图片,文字,字体设置等等操作都有对应的小demo。

bool MainWindow::TestQXlsx()

{

    QString selectedFile = QFileDialog::getSaveFileName(this,QStringLiteral("保存"), "./data/"QStringLiteral("XLSX file (*.xlsx)"));

    if (selectedFile.isEmpty() == true)

        return false;

 

    if (selectedFile.endsWith(".xlsx") == false)

        selectedFile += ".xlsx";

 

    QXlsx::Document xlsx(selectedFile);

 

    QStringList header;

    header << QStringLiteral("名称") << QStringLiteral("类型")<< QStringLiteral("子类型")<<QStringLiteral("数量");

 

    QList<QStringList> allTables;

    allTables.push_back(header);

 

    for(int i=0; i<m_pointList.size(); i++)

    {

        QStringList itemlist = m_pointList[i].toList();

        allTables.push_back(itemlist);

    }

 

    int rowCount = allTables.size();

    for (int row =0; row<rowCount; ++row)

    {

        QStringList item = allTables[row];

 

        int colCount = item.size();

        for (int col=0; col<colCount; ++col)

        {

            if(col == 3 && row > 0)

            {

                QString numstr = item[col];

                double num = numstr.toDouble();

                xlsx.write(row+1, col+1, num);

            }

            else

                xlsx.write(row+1, col+1, item[col]);

        }

    }

    xlsx.save();

 

    QMessageBox::information(thisQStringLiteral("提示"), QStringLiteral("保存文件成功!"));

    QDesktopServices::openUrl(QUrl::fromLocalFile(selectedFile));

    return true;

}


  1. 使用QAxObject直接操作Excel

这部分内容也是我从网上找到的使用较多的方法,顺便列出来。我自己本身没有使用这个方法,但据说在windows上读写Excel文件是很快的(qt5 使用qtxlsx 读写excel ;快速读取数据量很大的Excel文件),大家可以根据自己的情况尝试下。(ps.代码部分参考博文地址没有单独保存,如果博主看到可以联系我。)

bool MainWindow::TestQAxObject(QString path)

{

    QAxObject *excel = NULL;    //本例中,excel设定为Excel文件的操作对象

    QAxObject *workbooks = NULL;

    QAxObject *workbook = NULL;  //Excel操作对象

    excel = new QAxObject("Excel.Application");

    excel->dynamicCall("SetVisible(bool)"true); //true 表示操作文件时可见,false表示为不可见

    workbooks = excel->querySubObject("WorkBooks");

 

    //————————————————按文件路径打开文件————————————————————

    workbook = workbooks->querySubObject("Open(QString&)", path);

    // 获取打开的excel文件中所有的工作sheet

    QAxObject * worksheets = workbook->querySubObject("WorkSheets");

 

    //—————————————————Excel文件中表的个数:——————————————————

    int iWorkSheet = worksheets->property("Count").toInt();

    qDebug() << QString("Excel文件中表的个数: %1").arg(QString::number(iWorkSheet));

 

    // ————————————————获取第n个工作表 querySubObject("Item(int)", n);——————————

    QAxObject * worksheet = worksheets->querySubObject("Item(int)"1);//本例获取第一个,最后参数填1

 

    //—————————获取该sheet的数据范围(可以理解为有数据的矩形区域)————

    QAxObject * usedrange = worksheet->querySubObject("UsedRange");

 

    //———————————————————获取行数———————————————

    QAxObject * rows = usedrange->querySubObject("Rows");

    int iRows = rows->property("Count").toInt();

    qDebug() << QString("行数为: %1").arg(QString::number(iRows));

 

    //————————————获取列数—————————

    QAxObject * columns = usedrange->querySubObject("Columns");

    int iColumns = columns->property("Count").toInt();

    qDebug() << QString("列数为: %1").arg(QString::number(iColumns));

 

    //————————数据的起始行———

    int iStartRow = rows->property("Row").toInt();

    qDebug() << QString("起始行为: %1").arg(QString::number(iStartRow));

 

    //————————数据的起始列————————————

    int iColumn = columns->property("Column").toInt();

    qDebug() << QString("起始列为: %1").arg(QString::number(iColumn));

 

    //——————————————读出数据—————————————

    //获取第i行第j列的数据

    //假如是第6行,第6列 对应表中F列6行,即F6

    QAxObject *range1 = worksheet->querySubObject("Range(QString)""F6");

    QString strRow6Col6 = "";

    strRow6Col6 = range1->property("Value").toString();

    qDebug() << "第6行,第6列的数据为:" + strRow6Col6;

 

    //列的转换函数如下地址,第6列转为F列,第29列转为AC列

 

    //—————————————写入数据—————————————

    //获取F6的位置

    QAxObject *range2 = worksheet->querySubObject("Range(QString)""F6");

    //写入数据, 第6行,第6列

    range2->setProperty("Value""中共十九大");

    QString newStr = "";

    newStr = range2->property("Value").toString();

    qDebug() << "写入数据后,第6行,第6列的数据为:" + newStr;

 

    //!!!!!!!一定要记得close,不然系统进程里会出现n个EXCEL.EXE进程

    workbook->dynamicCall("Close()");

    excel->dynamicCall("Quit()");

    if (excel)

    {

        delete excel;

        excel = NULL;

    }

 

    return true;

}

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值