Forum


Replies: 4   Views: 213
Return a docx as a stream
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by khalid-s  · 01-02-2024 - 22:29

Hi, I am currently struggling with returning a docx as a stream in a symfony app.

Here is what i got 

 

#[Route('/', name: 'app_app')]
public function index(): StreamedResponse
{
    $doc = new CreateDocx();
    CreateDocx::$streamMode = true;
    CreateDocx::$returnDocxStructure = true;

    $doc->addText('This is a test');
    $doc->embedHTML('<p style="font-size: 30px;">New paragraph</p>');

    return new StreamedResponse(function () use ($doc) {
        $stream = fopen('php://output', 'wb');
        stream_copy_to_stream($doc, $stream);
    });
}

 

Of course this cannot work since the $doc in my stream_copy_to_stream is not a resource. How can i transform it as a resource.

 

Posted by khalid-s  · 01-02-2024 - 22:43

Also can you correct the way i am trying to retrieve the document from the API:

 

public function index(HttpClientInterface $http): Response
{
    $response = $http->request(Request::METHOD_GET, 'https://dev.doc.ey');

    $doc = new DOCXStructureFromStream;
    $doc->generateDOCXStructure($response->getContent());

    dd($doc);

    return $this->render('app/index.html.twig', [
        'controller_name' => 'AppController',
    ]);
}

 

Thanks in advance

Posted by admin  · 02-02-2024 - 06:47

Hello,

To generate a DOCX as a stream you need to enable the streamMode option (https://www.phpdocx.com/api-documentation/performance/zip-stream-docx-with-PHP). For example:

$docx = new CreateDocx();

CreateDocx::$streamMode = true;

$docx->addText($'Text mode.');

$docx->createDocx('output');

In this streamMode, when you call createDocx, the DOCX is generated as a stream, so after calling this method (createDocx) you can do anything you need with this stream.

If you enable $returnDocxStructure you are working with in-memory DOCX documents, not streams. An in-memory DOCX document is not a stream but an object that you can serialize or reuse instead of generating the file. On https://www.phpdocx.com/documentation/cookbook/in-memory-docx-documents you can read more information about working with in-memory DOCX documents

About using generateDOCXStructure, this method generates a DOCXStructure (this is an in-memory DOCX document) from a DOCX stream. This DOCXStructure is an in-memory DOCX document that can be used as template with CreateDocxFromTemplate and with other phpdocx methods.
Using phpdocx you can work with DOCX documents from the filesystem, as in-memory DOCX documents (https://www.phpdocx.com/documentation/cookbook/in-memory-docx-documents) or as streams (https://www.phpdocx.com/api-documentation/performance/zip-stream-docx-with-PHP).

We recommend you check the examples/Performance folder included in the Premium package that illustrate using generateDOCXStructure, parseDocx, returnDocxStructure and zipStream.

On https://www.phpdocx.com/en/forum/default/topic/2091 you can read a topic with the same stream question and how the user implemented it.

Regards.

Posted by khalid-s  · 02-02-2024 - 10:40

Hey again,

I appologize in advance but i've been looking at all the examples and the other related topics from the forum but i still dont understand how to stream a docx from an api and retrieve it from another app. Would it be possible to have an actual fully working example ideally with symfony.

here is what i got so far:

 

The API endpoint

use Phpdocx\Create\CreateDocx;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;

class AppController extends AbstractController
{
    #[Route('/', name: 'app_app')]
    public function index(): StreamedResponse
    {
        $doc = new CreateDocx();
        CreateDocx::$streamMode = true;

        $doc->addText('This is a test');
        $doc->embedHTML('<p style="font-size: 30px;">New paragraph</p>');

        return new StreamedResponse(function () use ($doc) {
            $doc->createDocx('output1');
        });
    }
}

 

and the front.

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class AppController extends AbstractController
{
    #[Route('/', name: 'app_home')]
    public function index(HttpClientInterface $http): Response
    {
        $response = $http->request(Request::METHOD_GET, 'https://dev.doc.ey');
        $doc = $response->getContent();

        dd($doc);

        return $this->render('app/index.html.twig', [
            'controller_name' => 'AppController',
        ]);
    }
}

Posted by admin  · 02-02-2024 - 11:16

Hello,

Sorry, but we don't have a whole sample using a stream with Symfony. phpdocx can be used with any PHP project, CMS, framework... the stream is generated as a generic stream.

We recommend you check the Symfony documentation about working with streams available on:

https://dev.to/rubenrubiob/serve-a-file-stream-in-symfony-3ei3

https://symfony.com/doc/current/components/http_foundation.html#serving-files

and also test step by step your code: if the DOCX stream is generated and returned correctly, if the stream is being captured correctly (and then if you can save as a fs or stream it).

We have moved your request to the development team to write a new cookbook page about working with streams using the StreamedResponse clas available in some frameworks.

Regards.