Russian Qt Forum

Qt => ActiveX => Тема начата: Yegor от Сентябрь 26, 2012, 20:40



Название: Медленный вывод данных в MsWord
Отправлено: Yegor от Сентябрь 26, 2012, 20:40
Здравствуйте!

Вывожу данные из своей программы в документ Ms Word программно, используя COM.
Почему-то это делается слишком медленно.

Вот привожу кусок кода:

Код:
    //Enter into WORD, create new document.
    QAxObject* pWordApplication=new QAxObject("Word.Application"); // Создаю интерфейс к MSWord
    QAxObject* pWordDocuments = pWordApplication->querySubObject( "Documents()" ); // Получаю интерфейсы к его подобъекту "коллекция открытых документов":
    pWordDocuments->querySubObject( "Add()" ); // Создаю новый документ
    pWordApplication->setProperty("Visible", true); // Делаем Word видимым

    // отключение грамматики
    QAxObject* pGrammatic = pWordApplication->querySubObject("Options()");
    pGrammatic->setProperty("CheckSpellingAsYouType(bool)", false); // отключение грамматики

    //Get active document.
    QAxObject* pActiveDocument = pWordApplication->querySubObject("ActiveDocument()");

    //Set landscape orientation.
    QAxObject *pPageSetup = pActiveDocument->querySubObject("PageSetup");
    pPageSetup->setProperty("Orientation", "wdOrientLandscape");

    //Inserting automatically pages numerations.
    pActiveDocument->querySubObject("Sections(Index)", 1)
            ->querySubObject("Footers(WdHeaderFooterIndex)", "wdHeaderFooterPrimary")
            ->querySubObject("PageNumbers")
            ->dynamicCall("Add(PageNumberAlignment,FirstPage)", "wdAlignPageNumberCenter", TRUE);

    //Get selection.
    QAxObject *pSelection = pWordApplication->querySubObject("ActiveDocument")->querySubObject("ActiveWindow")->querySubObject("Selection");

    // создание таблицы
    QAxObject* pTables = pActiveDocument->querySubObject("Tables()");
    QAxObject* pNewTable = pTables->querySubObject("Add(Range, NumRows, NumColumns, DefaultTableBehavior, AutoFitBehavior)", pSelection->property("Range"), 1, 5, 1, 1);
    //5 columns.

    //Resize table width to whole page width.
    pNewTable->setProperty("PreferredWidthType", "wdPreferredWidthPercent");
    pNewTable->setProperty("PreferredWidth", 100);

    //Align table to center.
    pNewTable->querySubObject("Rows()")->setProperty("Alignment", "wdAlignRowCenter");

    //Iterate found records.
    QAxObject *pCell=NULL, *pCellRange=NULL;
int cur_row = 0;
    while(cur_row < 100)
    {
        //Inserting new row for each new data.
        pSelection->dynamicCall("InsertRowsBelow()");

        //Column-0.
        pCell = pCurRow->querySubObject("Cells(Index)", 1); //Warning! Arg of col num is 1-based.
        pCellRange = pCell->querySubObject("Range()");
        pCellRange->dynamicCall("InsertAfter(Text)","My 1 cell");

        //Column-1.
        pCell = pCurRow->querySubObject("Cells(Index)", 2);
        pCellRange = pCell->querySubObject("Range()");
         pCellRange->dynamicCall("InsertAfter(Text)","My 2 cell");

        //Column-2.
        pCell = pCurRow->querySubObject("Cells(Index)", 3);
        pCellRange = pCell->querySubObject("Range()");
        pCellRange->dynamicCall("InsertAfter(Text)","My 3 cell");

//Column-3.
        pCell = pCurRow->querySubObject("Cells(Index)", 4);
        pCellRange = pCell->querySubObject("Range()");
        pCellRange->dynamicCall("InsertAfter(Text)","My 4 cell");

        //Column-4. State.Begin.
        pCell = pCurRow->querySubObject("Cells(Index)", 5);
        pCellRange = pCell->querySubObject("Range()");
pCellRange->dynamicCall("InsertAfter(Text)","My 5 cell");

        //Update cur row index.
        cur_row++;
    }
    //Iterate found records.End.

В коде происходит следующее:
 - Открывается MS Word
 - Добавляется новый документ
 - отключается грамматика
 - расположение страницы делается альбомная
 - Добавляется автоматическая нумерация страниц.
 - Создается таблица
 - Ширина таблицы делается на всю страницу
 - Таблица выравнивается по центру по горизонтали
 - Заполняется таблица текстом

На каждую страницу документа уходит много времени.
Подскажите, пожалуйста, как это ускорить. Может как то переделать код?


Название: Re: Медленный вывод данных в MsWord
Отправлено: ssoft от Сентябрь 27, 2012, 07:05
Если я точно помню (давно дело было), если скрыть интерфейс Word, то дело быстрее пойдет, только как его скрыть я уже не помню.
Еще можно предложить подготовить заранее шаблон документа с откомпилированными макросами внутри и вызывать их вместо по-командного вызова из своей программы. Сто пудняк быстрее будет.


Название: Re: Медленный вывод данных в MsWord
Отправлено: xokc от Сентябрь 27, 2012, 07:27
Ну ты бы сам отпрофайлил все свои шаги - и стало бы понятно, что именно оптимизировать надо.
Если основные тормоза приходятся не на заполнение таблицы - следуй совету ssoft: создавай заранее нужный документ с пустой таблицей, а из своего приложения только её заполняй.
Иначе - или просто смириться с тормозами, или если совсем не вариант ждать - пробовать, например:
1. вставлять таблицу через буфер обмена
2. разобраться с форматом docx и формировать документ без участия word
3. использовать Excel вместо Word  и т.п.