Как создать docx и сделать c файл с QAxObject в qt для windows? - PullRequest
2 голосов
/ 15 января 2020

Я хочу использовать QAxObject для создания нового файла docx. Как я могу создать новый файл doc и docx и написать свой текст с QAxObject в qt для windows. Я пробовал этот код, но не смог найти ответ, потому что он открывает существующий файл, но я хочу создать новый и использовать QAxObject.

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()");

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020
#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 голосов
/ 16 января 2020

Уже есть несколько ответов на подобные вопросы в SO, предполагающие использование QAxObject с dynamicCall() для автоматизации MS Office. Это может быть сделано, и это будет работать, но я думаю, что есть лучший и более интересный способ сделать это.

Мое предложение состоит в том, чтобы импортировать библиотеку типов COM, которая поставляется с каждым приложением Office, создавая С ++ объектная модель. Это имеет два преимущества: аналогично подходу взаимодействия, популярному в C# и VB. NET, и даже примеры для этих языков могут использоваться в качестве моделей для наших собственных проектов Qt. И, конечно, вы можете наслаждаться автозаполнением в Qt Creator для классов и имен членов. Я уже упоминал веселье?

Это очень похоже на Пример Qutlook для приложения Outlook, включенного в примеры ActiveQt. Документация ничего не говорит о большем, чем добавление переменной TYPELIBS в файл .pro вашего приложения. Перевод выполняется утилитой dumpcpp.exe , которую можно найти в каталоге Qt bin. Это простой программный проект командной строки, импортирующий объектную модель MS Word:

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 с нуля и сохраняет его в двух форматах:

#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;
}

Как видите, код достаточно читабелен, за счет включения большого куска кода. Вы #include сгенерировали заголовок MSWORD.h, и программа создает новый документ, заполняет его содержимое двумя текстовыми строками и сохраняет этот документ дважды: сначала в современном формате DOCX, а затем в формате, совместимом с DO C. со словом 97/2003.

Полный проект можно найти в этом GitHub репозитории .

...