Ответ Symfony2 PHPWord

Я пытаюсь создать документ docx на Symfony2, используя пакет PHPWord.

В моем контроллере мне удается вернуть файл docx, но он пуст, я думаю, это связано с моим неправильным форматом ответа.

public function indexAction($id)
{
    $PHPWord = new PHPWord();
    $section = $PHPWord->addSection();

    $section->addText(htmlspecialchars(
    '"Learn from yesterday, live for today, hope for tomorrow. '
        . 'The important thing is not to stop questioning." '
        . '(Albert Einstein)'
    ));


  // Saving the document
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord, 'Word2007');

return new Response($objWriter->save('helloWorld.docx'), 200, array('Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'));
}

person Adrien Chapelet    schedule 13.05.2015    source источник
comment
Что возвращает $objWriter-›save('helloWorld.docx')?   -  person John Cartwright    schedule 13.05.2015


Ответы (3)


Большое спасибо за ответ.

Я достигаю с помощью 2-го метода, который, на мой взгляд, лучший. Мне просто нужно вернуть ответ, иначе файл был сгенерирован, но застрял в веб-каталоге. Используя этот ответ, все было в порядке, и появилось приглашение для загрузки с «полным» файлом.

Вот мой код:

$PHPWord = new PHPWord();

$section = $PHPWord->addSection();

$section->addText(htmlspecialchars(
            '"Learn from yesterday, live for today, hope for tomorrow. '
                . 'The important thing is not to stop questioning." '
                . '(Albert Einstein)'
        ));

    // Saving the document
    $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($PHPWord, 'Word2007');     
    $filename="MyAwesomeFile.docx";
    $objWriter->save($filename, 'Word2007', true);

    $path = $this->get('kernel')->getRootDir(). "/../web/" . $filename;
    $content = file_get_contents($path);

    $response = new Response();
    $response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    $response->headers->set('Content-Disposition', 'attachment;filename="'.$filename);
    $response->setContent($content);
    return $response;
person Adrien Chapelet    schedule 15.05.2015

Попробуйте этот класс

<?php

use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use Symfony\Component\HttpFoundation\Response;

class WordResponse extends Response
{
    /**
     * WordResponse constructor.
     * @param string $name The name of the word file
     * @param PhpWord $word
     */
    public function __construct($name, &$word)
    {
        parent::__construct();

        // Set default zip library.
        if( !class_exists('ZipArchive')){
            Settings::setZipClass(Settings::PCLZIP);
        }

        $writer = IOFactory::createWriter($word, 'Word2007');

        //Set headers.
        $this->headers->set("Content-Disposition", 'attachment; filename="' . $name . '"');
        $this->headers->set("Content-Type", 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
        $this->headers->set("Content-Transfer-Encoding", 'binary');
        $this->headers->set("Cache-Control", 'must-revalidate, post-check=0, pre-check=0');
        $this->headers->set("Expires", '0');

        $this->sendHeaders();
        $writer->save('php://output');
    }
}

Затем в вашем контроллере выполните:

return new WordResponse($phpWord, "filename.docx"); 
person CStff    schedule 15.05.2017

PHPWord->save() возвращает истинное значение, поэтому ваш файл не загружается. С вашим return new Response() вы устанавливаете содержание своего ответа на true (результат вашего save вызова), поэтому ваш ответ пуст.

У вас есть 2 (и, возможно, больше, о которых я не подумал) варианты создания и загрузки этого файла.

1. Сохраните файл во временной папке и оттуда на сервер

$filename = sprintf(
    '%s%sDoc-Storage%s%s.%s',
    sys_get_temp_dir(),
    DIRECTORY_SEPARATOR,
    DIRECTORY_SEPARATOR,
    uniqid(),
    'docx'
);

$objWriter->save($filename);

$response = new BinaryFileResponse($filename);

Для получения дополнительной информации о BinaryFileResponse см. документацию.

2. Игнорировать Symfony и обслуживать напрямую через действие PHPWord

$objWriter->save($filename, 'Word2007', true);
exit();

Метод ->save обеспечивает все действия для внутренней загрузки сгенерированного файла (см. код), поэтому все, что вам нужно сделать, это установить формат и третий параметр в значение true, и он будет обрабатывать все заголовки за вас. Конечно, он не будет возвращать ответ Symfony, но вы выйдете, прежде чем доберетесь до этого исключения.

person qooplmao    schedule 13.05.2015