I want to download a Drupal page to a Word document in an Event Subscriber. The code I'm starting with will download a document which msword will open. Here's the original code:
protected function setResponseContentToWordDocument(ResponseEvent $event) {
// Get response.
$response = $event->getResponse();
// Get response's HTML.
$html = $this->getResponseHtml($response);
// Update headers.
$response->headers->set('Content-Length', strlen($html));
$response->headers->set('Content-Type', 'application/msword');
$response->headers->set('Content-Disposition', 'attachment; filename=' . MskString::filename('word_doc.doc'));
// Set content to html.
$response->setContent($html);
}
But the response html includes everything, which is too much. I would like to try the phpoffice/phpword library which I've used in the past in controllers.
The problem is the file is silently downloading to the /tmp directory, and not downloading in the browser. Here's the code:
protected function setResponseContentToWordDocument(ResponseEvent $event) {
global $base_url;
$filename = 'my_file';
// Create a new Word document.
$php_word = new PhpWord();
// Add styles.
...
$section = $php_word->addSection();
$node = \Drupal::routeMatch()->getParameter('node');
$html = $node->body->value;
Html::addHtml($section, $html, FALSE, FALSE);
// Save the document as OOXML file.
$writer = IOFactory::createWriter($php_word, 'Word2007');
// Create a temporary file in the system.
$temp_file = \Drupal::service('file_system')->getTempDirectory() . '/' . $filename . '.docx';
// Write in the temporary filepath.
$writer->save($temp_file);
// Send the temporary file as response (as an attachment).
$response = new BinaryFileResponse($temp_file);
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$filename . '.docx'
);
$response->deleteFileAfterSend(TRUE);
return $response;
}
The above code downloads my_file.docx to the /tmp directory. If change return $response;
to $response->setContent($temp_file);
, a LogicException: The content cannot be set on a BinaryFileResponse instance.
error is thrown. How can I download the word file in the Event Subscriber like in the Controller?
$event->setResponse($response);
instead of the return