На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Serafim, fatalist
  
    > php, COM, Word
      Приветствую!

      Возможно раздел не тот, но более подходящего не нашел.

      Есть необходимость создать вордовский документ из веб-приложения на php. Пользователь тыкает на кнопку и на сервере формируется документ.
      Как это происходит: создается COM-объект и с помощью методов из VBA формируется документ.
      Вот немного кода, но ни о чем не говорит, мне кажется.
      ExpandedWrap disabled
        try
        {
          $word_handle = new COM('word.application') or die('Unable to instanciate Word');
         
          $word_handle->Visible = false;
          $doc=$word_handle->Documents->Add($tpl);  //$tpl - шаблон для документа
         
          //работа по формированию содержания
         
         
          $doc->SaveAs(str_replace('/','\\',$temppath.$filename));
          $doc->Close();
          $word_handle->Quit();
         
          echo '<a class="link-act" href="./temp/'.$hash.$filename.'">Документ</a>';
        }
        catch (Exception $e)
        {
          $doc->Close(0);
          $word_handle->Quit(0);
          echo 'Ошибка! Код ошибки: ', $e->getCode(), '. Обратитесь к администратору системы или в службу техподдержки';
        }


      Проблема: у некоторых пользователей, документ не формируется, а процесс зависает... Никаких ошибок в лог не попадает, исключений не выходит...
      Кажущаяся причина проблемы: сервер новый, офис там новый(в смысле свежеустановленный), при первом запуске у каждого пользователя просит ввести имя и инициалы, ждет ввода и поэтому висит.
      Причина оказалась неверной, потому что для некоторых пользователей все равно не заработало даже после ввода инициалов и имени.

      Авторизация производится с помощью Active Directory. Для пользователей, входящих в группу локальных админов все работает, для простых пользователей нет. Вывод: косяк в правах пользователей. НО для аналогичного формирования документа Excel все прекрасно работает. Выдача аналогичных прав на запуск ворда пользователям не помогло, видимо, надо еще что-то....

      ЧТО????
      Сообщение отредактировано: Дмитрий Сергеевич -
        Цитата Дмитрий Сергеевич @
        Как это происходит: создается COM-объект и с помощью методов из VBA формируется документ.

        А не пробовали просто открыть Word и прогнать те же методы VBA на прямую?
          Цитата Дмитрий Сергеевич @
          Есть необходимость создать вордовский документ из веб-приложения на php

          <?php
          $word = new COM("word.application");

          $word->Visible = 0;
          $word->Documents->Add();
          $word->Selection->PageSetup->LeftMargin = '2"';
          $word->Selection->PageSetup->RightMargin = '2"';

          //Setup the font
          $word->Selection->Font->Name = 'Verdana';
          $word->Selection->Font->Size = 8;

          //Write some text
          $word->Selection->TypeText("This is a test document");
          //Save the document as DOC file
          $word->Documents[1]->SaveAs("c:\\docs\\test1.doc");

          //quit and release COM resources
          $word->quit();
          $word->Release();
          $word = null;

          ?>
            Для CrewHS
            Создавать документ я умею, не раз решал эту задачу. Проблема в том, для некоторых пользователей данный код не работает. Возможно для запуска ворда удаленно через COM пользователям надо выдать еще какие-то права(потому что, например, для пользователей с админскими правами все работает)?

            Для fatalist
            Собственно, сначала я проверял работоспособность кода на VBA, а потом уже переносил на работу через COM

            Немного изменил код в первом посте, чтоб было понятно откуда берется переменная $doc и как именно создается документ(добавил 2 строчки после создания COM-объекта)
            Сообщение отредактировано: Дмитрий Сергеевич -
              Посмотрел eventlog виндовый на сервере, при запуске там вылезала ошибка DCOM, что нельзя локально запускать Windows Installer. Видимо при первом запуске для нового пользователя ворд еще что-то хочет установить.
              Переставил Ворд, чтоб при установке ни для однго компонента не было выбрано "Устанавливать при первом запуске", а только "Запускать с моего компьютера" и "Не доступно".
              Зависания прекратились, ошибки в эвентлогах тоже не появляются, но падает исключение "Недостаточно памяти"

              exception 'com_exception' with message 'Source: Microsoft Word Description: There is insufficient memory. Save the document now. ' на строке создания документа с шаблоном.

              При этом у пользователей с правами админа по прежнему все работает... :wall:
              Сообщение отредактировано: Дмитрий Сергеевич -
                Цитата Дмитрий Сергеевич @
                При этом у пользователей с правами админа по прежнему все работает...

                Ограничение на использование памяти у обычных пользователей?
                Может шаблон попроще сделать? Убрать личние классы... Что там еще память хавает?..

                Добавлено
                Там используются какие-нибудь MicrosoftEquation или т.п.?
                  Документ настолько сложен, что его невозможно формировать без офиса вообще, а по религиозным соображениям невозможно применение RTF?
                    Цитата fatalist @
                    Может шаблон попроще сделать?

                    Документ - одна страница A4. Грубо говоря, есть некий бланк, его надо заполнить, например, билет на самолет, который заполняется данными из базы... В документе просто создано N закладок (штук 20) и я их заполняю

                    Про религию - Excel-то работает...
                    В общем вопрос, конечно, решен, работоспособность достигнута. Вдоволь нагуглившись по поповоду ошибки "Description: There is insufficient memory. Save the document now", сделал в настройках DCOM для Microsoft Word Document запуск от имени польователя с админскими правами.

                    Но, черт побери, хочется знать, что это за ... было?
                    Сообщение отредактировано: Дмитрий Сергеевич -
                      Цитата Дмитрий Сергеевич @
                      Про религию - Excel-то работает...

                      Ты на эксель не равняйся, эксель работает вообще по другому и совсем не глючит в отличие от ворда ;)
                      [offtop]
                      Мне иногда кажется, что эксель вообще не мелкософтовцы делали, уж очень хороший получился :rolleyes:
                      [/offtop]

                      А Вордовский документ иногда памяти хавает немеренно, пусть даже и одна страница... :yes:
                        Цитата Дмитрий Сергеевич @
                        Про религию - Excel-то работает...
                        Да речь вообще не об этом - для простых документов (а есть подозрение, что речь именно о таком документе) задача решается гораздо проще, без использования офиса и COM, примитивнейшим кодом порядка 10 строк.
                          Цитата SiMM @
                          Да речь вообще не об этом - для простых документов (а есть подозрение, что речь именно о таком документе) задача решается гораздо проще, без использования офиса и COM, примитивнейшим кодом порядка 10 строк.

                          Буду признателен за альтернативные идеи реализации формирования документа... Возможно документ действительно простой. Это заполнение некоего бланка, пусть будет билет на самолет(поезд и т.п.)
                            Делаем Word'ом рыбу в RTF, затем пользуемся простым кодом.
                            ExpandedWrap disabled
                              <?php
                              $doc = file_get_contents('Документ.rtf');
                              $data = array('label1'=>'Метка1','label2'=>'Метка2');
                              $doc = preg_replace('#\\\\{(.*?)\\\\}#se','isset($data["$1"]) ? tortf($data["$1"]) : "$0"',$doc);
                              file_put_contents('Документ2.doc',$doc);
                              function tortf($str) {
                                $s = '';
                                for ($i = 0; $i < strlen($str); $i++)
                                  $s .= (ord($str[$i]) > 127) ? sprintf("\\'%02x",ord($str[$i])) : $str[$i];
                                return $s;
                              }
                              ?>


                            Добавлено
                            В принципе preg_replace может быть заменён str_replace, только массив замен тогда придётся предварительно подготовить.
                            Сообщение отредактировано: SiMM -

                            Прикреплённый файлПрикреплённый файл________.zip (1.44 Кбайт, скачиваний: 169)
                              Цитата SiMM @
                              $doc = preg_replace('#\\\\{(.*?)\\\\}#se','isset($data["$1"]) ? tortf($data["$1"]) : "$0"',$doc);


                              а что за переменные $1 и $0?
                                Содержат совпадения подмасок.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0389 ]   [ 14 queries used ]   [ Generated: 19.05.24, 12:31 GMT ]