首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在qt for windows中用QAxObject创建docx和doc文件?

如何在qt for windows中用QAxObject创建docx和doc文件?
EN

Stack Overflow用户
提问于 2020-01-15 16:49:38
回答 2查看 1.4K关注 0票数 2

我想使用QAxObject创建一个新的docx文件。如何在windows的qt中创建新的docdocx文件并使用QAxObject编写文本。我尝试了这段代码,但我找不到我的答案,因为它打开了现有的文件,但我想创建一个新的文件并使用QAxObject

代码语言:javascript
复制
QString     outFile("C:/test.docx");
QString     inFile1("C:/test1.docx");
QString     inFile2("C:/test2.docx");
QAxObject   axObject("Word.Application");
QAxObject   *documents = axObject.querySubObject("Documents");
QAxObject   *document = documents->querySubObject("Open(const QString&, bool)", inFile1, true);
QAxObject   *selection = axObject.querySubObject("Selection");

selection->dynamicCall("EndKey(QVariant&)", 6); // WdUnits::wdStory=6
selection->dynamicCall("InsertBreak(QVariant&)", 7); // WdBreakType::wdPageBreak=7
selection->dynamicCall("InsertFile(QString&)", inFile2);

document->dynamicCall("SaveAs(const QString&)", outFile);
document->dynamicCall("Close()");
axObject.dynamicCall("Quit()");
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-17 19:33:37

代码语言:javascript
复制
#if defined(Q_OS_WIN)
    else if (mod == "DOCX" || mod == "DOC") {
        QTemporaryDir tempDir;
        QString text_filename;
        QString     outFile;
        QString     allMessage;
        else if (mod == "DOCX") {
            if(tempDir.isValid()){
                const QString tempFile = tempDir.path() + "/docxTemplate.docx";
                if(QFile::copy(":/docxTemplate.docx",tempFile)){
                    text_filename = tempFile;
                } else {
                    qDebug()<< "cannot locate docxTemplate.docx";
                }
            }
            else {
                qDebug()<< "cannot access filesystem";
            }
            QString     outFile(pathDirectory+"/"+filename+".docx");
        }
        else if (mod == "DOC") {
            if(tempDir.isValid()){
                const QString tempFile = tempDir.path() + "/docTemplate.doc";
                if(QFile::copy(":/docTemplate.doc",tempFile)){
                    text_filename = tempFile;
                } else {
                    qDebug()<< "cannot locate docTemplate.doc";
                }
            }
            else {
                qDebug()<< "cannot access filesystem";
            }
            QString     outFile(pathDirectory+"/"+filename+".doc");
        }
        QString     inFile(text_filename);
        QAxObject   axObject("Word.Application");
        QAxObject   *documents = axObject.querySubObject("Documents");
        QAxObject   *document = documents->querySubObject("Open(const QString&, bool)", inFile, true);
        document->dynamicCall("SaveAs(const QString&)", outFile);
        document->dynamicCall("Close()");
        axObject.dynamicCall("Quit()");

        QAxObject   axObjectNew("Word.Application");
        QAxObject   *documentsNew = axObjectNew.querySubObject("Documents");
        QAxObject   *documentNew = documentsNew->querySubObject("Open(const QString&, bool)", outFile, true);
        QAxObject   *selection = axObjectNew.querySubObject("Selection");
        selection->dynamicCall("TypeText(QString)",allMessage);
        documentNew->dynamicCall("Close()");
        axObjectNew.dynamicCall("Quit()");
    }
#endif
票数 0
EN

Stack Overflow用户

发布于 2020-01-16 07:28:01

已经有一些类似于此问题的answers,因此建议将QAxObjectdynamicCall()结合使用以实现MS Office自动化。这是可以做到的,也会奏效,但我认为有一种更好、更有趣的方法。

我的建议是导入每个Office应用程序附带的COM类型库,生成一个C++对象模型。这有两个优点:类似于C#和VB.NET中流行的互操作方法,甚至这些语言的示例也可以用作我们自己的Qt项目的模型。当然,您可以在Qt Creator中自动完成类和成员名称。我已经提过好玩了吗?

这与ActiveQt示例中包含的Outlook应用程序的Qutlook Example非常相似。除了将TYPELIBS变量添加到应用程序的.pro文件中之外,documentation并没有提供更多的信息。转换由可以在Qt目录中找到的dumpcpp.exe utility执行。这是一个导入MS Word对象模型的简单命令行程序项目:

代码语言:javascript
复制
QT += widgets axcontainer
CONFIG += c++11 cmdline

DUMPCPP=$$absolute_path("dumpcpp.exe", $$dirname(QMAKE_QMAKE))
TYPELIBS = $$system($$DUMPCPP -getfile {00020905-0000-0000-C000-000000000046})

isEmpty(TYPELIBS) {
    message("Microsoft Word type library not found!")
    REQUIRES += MSWord
} else {
    SOURCES  = main.cpp
}

若要发现其他类型库的GUID,可以使用oleview.exe实用工具。

QMake创建一个源文件MSWORD.cpp和一个头MSWORD.h,您可以将它们包含在您自己的类中,以访问生成的对象模型。此示例从头开始生成Word文档,并将其保存为两种格式:

代码语言:javascript
复制
#include <QApplication>
#include <QStandardPaths>
#include <QDir>
#include "MSWORD.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Word::Application word;
    if (!word.isNull()) {
        word.SetVisible(false);

        Word::Documents* docs = word.Documents();
        Word::Document* newDoc = docs->Add();
        Word::Paragraph* p = newDoc->Content()->Paragraphs()->Add();
        p->Range()->SetText("Hello Word Document from Qt!");
        p->Range()->InsertParagraphAfter();
        p->Range()->SetText("That's it!");

        QDir outDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));

        QVariant fileName = outDir.absoluteFilePath("wordaut.docx");
        QVariant format = Word::wdFormatXMLDocument;
        newDoc->SaveAs2(fileName, format);

        QVariant fileName2 = outDir.absoluteFilePath("wordaut2.doc");
        QVariant format2 = Word::wdFormatDocument;
        newDoc->SaveAs2(fileName2, format2);

        newDoc->Close();
        word.Quit();
    }

    return 0;
}

正如您所看到的,代码的可读性非常好,代价是包含了大量代码。您对生成的头文件MSWORD.h执行#include操作,程序将创建一个新文档,用两行文本填充其内容,然后将该文档保存两次:第一次是以现代DOCX格式,然后是以与Word 97/2003兼容的DOC格式保存。

完整的项目可以在这个GitHub repository中找到。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59747787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档