• 17696阅读
  • 9回复

Qt读写Excel文件 [复制链接]

上一主题 下一主题
离线alex_lue
 
只看楼主 倒序阅读 楼主  发表于: 2010-12-15
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
各位论坛的朋友,我想实现用Qt编写的GUI读写Excel文件,已经在网上和论坛上查了几个例子,但似乎都是说只有商业版才能使用QAxObject来控制Excel。我已经自己实验了一段简单的代码,虽然已经include了QAxObject,Creator编译确实提示诸如:“undefined reference to 'QAxObject::QAxObject(QString const &, QObject*)' ”。想问问论坛里的朋友们,是否有好的方法可以用非商业版来读写Excel文件,我用的是Qt 4.6和Qt Creator 2.0,windows XP系统。十分感谢!
离线dbzhang800

只看该作者 1楼 发表于: 2010-12-15
1. 你看的说法太老。或者你搜索的太少。在Qt4.5.2 时,ActiveQt 已经在LPGL下可用

2. 链接错误,认真看Qt自带的Manual和例子,看看pro文件是怎么写。因为答案简单,我就不说了。
离线alex_lue
只看该作者 2楼 发表于: 2010-12-15
多谢这位朋友的提示,看来我还是没好好看手册,我再看一下,如果不行再问你吧。Sanx!
离线alex_lue
只看该作者 3楼 发表于: 2010-12-15
回 1楼(dbzhang800) 的帖子
是不是在.pro文件里加上CONFIG  += qaxcontainer就行,还需要加Typelibs吗?
Qt的Manual里只有outlook的例子,TYPELIBS = $$system(dumpcpp -getfile {00062FFF-0000-0000-C000-000000000046}),excel是用哪个代码?我是指getfile括号后面的那些数字,多谢!
离线alex_lue
只看该作者 4楼 发表于: 2010-12-15
已找到Excel的数字,生成Excel.h和Excel.cpp,但编译时得到300多错误,大部分是use of enum 'MSOCalloutType' without previous declaration,请问是什么原因?
离线alex_lue
只看该作者 5楼 发表于: 2010-12-16
顶顶,多谢各位帮忙!
离线alex_lue
只看该作者 6楼 发表于: 2010-12-16
问题还没解决,希望论坛的朋友们帮帮。
离线XChinux

只看该作者 7楼 发表于: 2011-01-06
读EXCEL的例子,代码片段。写就不说了,写我是直接输出成Office 2003 XML格式的,后缀保存成.xls,简单快速。


    QAxObject *excel = NULL;
    QAxObject *workbooks = NULL;
    QAxObject *workbook = NULL;
    QAxObject *sheets = NULL;
    QAxObject *sheet = NULL;
    QAxObject *range = NULL;
    QAxObject *cell = NULL;

    excel = new QAxObject("Excel.Application");
    if (!excel)
    {
        QMessageBox::critical(this, "错误信息", "EXCEL对象丢失");
        QFile::remove(fileName);
        return;
    }
    excel->dynamicCall("SetVisible(bool)", false);
    workbooks = excel->querySubObject("Workbooks");
    if (!workbooks)
    {
        delete excel;
        excel = new QAxObject("ET.Application");
        if (!excel)
        {
            QMessageBox::critical(this, "错误信息", "EXCEL对象丢失");
            QFile::remove(fileName);
            return;
        }
        excel->dynamicCall("SetVisible(bool)", false);
        workbooks = excel->querySubObject("Workbooks");

        if (!workbooks)
        {
            QMessageBox::critical(this, "错误信息", "Workbooks对象丢失");
            delete excel;
            QFile::remove(fileName);
            return;
        }
    }
    workbook = workbooks->querySubObject("Open(QString, QVariant)", fileName, 0);
    if (!workbook)
    {
        QMessageBox::critical(this, "错误信息", "workbook对象丢失");
        excel->dynamicCall("Quit()");
        delete workbooks;
        delete excel;
        QFile::remove(fileName);
        return;
    }
    sheets = workbook->querySubObject("Sheets");
    if (!sheets)
    {
        QMessageBox::critical(this, "错误信息", "sheets对象丢失");
        excel->dynamicCall("Quit()");
        delete workbook;
        delete workbooks;
        delete excel;
        QFile::remove(fileName);
        return;
    }
    int iSheetCnt = sheets->dynamicCall("Count()").toInt();
    if (iSheetCnt < 1)
    {
        QMessageBox::critical(this, "错误信息", "找不到工作表");
        excel->dynamicCall("Quit()");
        delete sheets;
        delete workbook;
        delete workbooks;
        delete excel;
        QFile::remove(fileName);
        return;
    }
    // 读工作表名
    QStringList slNames;
    for (int i = 1; i <= iSheetCnt; i++)
    {
        sheet = sheets->querySubObject("Item(int)", i);
        slNames << sheet->dynamicCall("Name").toString();
        delete sheet;
    }
    BankToolSetReadRuleExDialog dlg(this);
    dlg.setRule(slNames, identity);
    if (dlg.exec() == QDialog::Rejected)
    {
        excel->dynamicCall("Quit()");
        delete sheets;
        delete workbook;
        delete workbooks;
        delete excel;
        QFile::remove(fileName);
        return;
    }
    RuleConfig rule = dlg.rule();

    emit showStatusText(QString("正在读取文件内容......(%1)").arg(fileName));
    QApplication::processEvents();

    QList<QMap<QString, QString> > *data = &_data;
    data->clear();
    QMap<QString, QString> map;

    QStandardItem *item;
    QList<QStandardItem *> items;
    _model.removeRows(0, _model.rowCount());
    QDate dDate;
    QString strV, strV2;
    QString strDate;

    QString strError;
    for (int i = 0; i < rule.workSheets.size(); i++)
    {
        sheet = sheets->querySubObject("Item(int)", rule.workSheets);
        if (!sheet)
        {
            strError += "读取工作表" + slNames[rule.workSheets - 1]
                + "失败;";
            continue;
        }
        sheet->dynamicCall("Select()");
        int iRow = rule.startRow;
        while (true)
        {
            map.clear();

            // 读取日期//{{{
            range = sheet->querySubObject("Cells(int, int)", iRow, rule.dateCol);
            dDate = range->dynamicCall("Value()").toDate();
            strDate = range->dynamicCall("Value()").toString().trimmed();
            delete range;

            if (!dDate.isValid())
            {
                if (strDate.size() == 8)
                {
                    dDate = QDate::fromString(strDate, "yyyyMMdd");
                    if (!dDate.isValid())
                    {
                        break;
                    }
                }
                else if (strDate.size() == 10)
                {
                    if (strDate.indexOf("/") > -1)
                    {
                        dDate = QDate::fromString(strDate, "yyyy/MM/dd");
                        if (!dDate.isValid())
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            if (dDate < dateEditStart->date() || dDate > dateEditEnd->date())
            {
                iRow++;
                continue;
            }
            if (dDate.toString("yyyy") != _strYear)
            {
                iRow++;
                continue;
            }

            map["date"] = dDate.toString("yyyy-MM-dd");

            item = new QStandardItem(map["date"]);
            item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
            items.push_back(item);
            //}}}

            // 读取凭证号//{{{
            if (rule.usedCNID)
            {
                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.CNIDCol);
                strV = range->dynamicCall("Value()").toString().trimmed();
                delete range;
                if (strV == "0")
                {
                    strV = "";
                }
                else
                {
                    if (rule.CNIDPos < 0)
                    {
                        strV = strV.mid(strV.length() + rule.CNIDPos,
                                rule.CNIDLen);
                    }
                    else
                    {
                        strV = strV.mid(rule.CNIDPos, rule.CNIDLen);
                    }
                }
                map["cn_id"] = strV; //凭证号

                item = new QStandardItem(strV);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);
            }
            else
            {
                item = new QStandardItem("");
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);
            }
            //}}}


            // 读取交易金额//{{{
            if (rule.moneyByCol)
            {
                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.moneyJieCol);
                strV = range->dynamicCall("Value()").toString().trimmed();
                strV = QString::number(
                        strV.replace(",", "").toDouble(), 'f', 2);
                delete range;
                map["debitmoney"] = strV; //借方

                if (strV == "0.00")
                {
                    strV = "";
                }
                item = new QStandardItem(strV);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);

                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.moneyDaiCol);
                strV = range->dynamicCall("Value()").toString().trimmed();
                strV = QString::number(
                        strV.replace(",", "").toDouble(), 'f', 2);
                delete range;
                map["lendermoney"] = strV; //贷方

                if (strV == "0.00")
                {
                    strV = "";
                }
                item = new QStandardItem(strV);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);

                strV = map["debitmoney"].toDouble() < 0.01 ? "贷" : "借";
                map["bdc"] = strV;

                item = new QStandardItem(strV);
                item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                items.insert(2, item);
            }
            else // moneybyType
            {
                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.moneyTypeCol);
                strV = range->dynamicCall("Value()").toString().trimmed();
                delete range;

                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.moneyCol);
                strV2 = range->dynamicCall("Value()").toString().trimmed();
                delete range;
                strV2 = QString::number(strV2.replace(",", "").toDouble(), 'f', 2);

                if (strV == rule.jieLabel)
                {
                    // 贷
                    map["lendermoney"] = "";
                    // 借
                    map["debitmoney"]  = strV2;
                }
                else
                {
                    // 贷
                    map["lendermoney"] = strV2;
                    // 借
                    map["debitmoney"] = "";
                }

                item = new QStandardItem(map["debitmoney"]);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);

                item = new QStandardItem(map["lendermoney"]);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);

                item = new QStandardItem(strV == rule.jieLabel ? "借" : "贷");
                item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                items.insert(2, item);
            }//}}}


            // 读取结算方式//{{{
            if (rule.usedJSFS)
            {
                range = sheet->querySubObject("Cells(int, int)", iRow,
                        rule.JSFSCol);
                strV = range->dynamicCall("Value()").toString().trimmed();
                delete range;
                map["csettle"] = strV; //凭证号

                item = new QStandardItem(strV);
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);
            }
            else
            {
                map["csettle"] = "";
                item = new QStandardItem("");
                item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
                items.push_back(item);
            }
            //}}}


            _model.appendRow(items);
            items.clear();

            data->append(map);
            iRow++;
        }
        delete sheet;
    }

    excel->dynamicCall("Quit()");
    delete sheets;
    delete workbook;
    delete workbooks;
    delete excel;
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 8楼 发表于: 2011-01-06
上文中的Excel.Application是使用Ms Office的。ET.Application是使用金山WPS的接口。
两者的接口大同小异,我嫌装Office麻烦且不好用,所以装的WPS。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线downstairs

只看该作者 9楼 发表于: 2011-05-22
..拜读
喜爱编程的猫头鹰
快速回复
限100 字节
 
上一个 下一个