【问题标题】:Symfony2 FOSRESTBundle REST API to return PDFSymfony2 FOSRESTBundle REST API 返回 PDF
【发布时间】:2023-03-19 13:35:02
【问题描述】:

我在里面做了一个 Bundle 和一个 REST 控制器。 “index”方法返回JSON格式的数组,没关系:

MyBundle/Controller/Api/Rest/BaconController.php

class BaconController extends Controller implements ClassResourceInterface
{
    /**
     * @var Request $request
     * @return array
     * @Rest\View
     */
    public function cgetAction(Request $request)
    {
        $mediaType = $request->attributes->get('media_type');
        $format = $request->getFormat($mediaType);
        my_dump($format);

        return array(
             array("id" => 1, "title" => "hello",),
             array("id" => 2, "title" => "there",),
        );
    }
}

MyBundle/Resources/config/api/routing_rest.yml

my_api_rest_bacon:
    type: rest
    resource: "MyBundle:Api/Rest/Bacon"
    name_prefix: api_rest_bacon_
    prefix: /my/bacon

所以,此时 JSON 结果得到完美返回:

mysite.com/app_dev.php/api/my/bacon/bacons.json

返回我的数组。

但现在我需要让我的控制器生成包含数据的 PDF。所以我希望它在我调用时返回 PDF 文档:

mysite.com/app_dev.php/api/my/bacon/bacons.pdf

我找到了一些半手册:RSS view handlerRSS config.ynalCSV issue with answers。并尝试制作类似的东西:

我已将这些行添加到

Symfony/app/config/config.yml

framework:
    [...some old stuff here...]
    request:
        formats:
            pdf: 'application/pdf'

fos_rest:
    body_converter:
        enabled:              true
    format_listener:
        rules:
            # Prototype array
            -
                # URL path info
                path:                 ~
                # URL host name
                host:                 ~
                prefer_extension:     true
                fallback_format:      html
                priorities:           [html,json]
            -
                path:                 ~
                host:                 ~
                prefer_extension:     true
                fallback_format:      pdf
                priorities:           [pdf]
    view:
        # @View or @Template
        view_response_listener: force #true
        formats:
            json: true
            pdf: true
            xls: true
            html: false
        templating_formats:
            pdf: false
            xls: false
        mime_types: {'pdf': ['application/pdf']}
    routing_loader:
        default_format: html
    param_fetcher_listener: true
    body_listener: true
    allowed_methods_listener: true

services:
    my.view_handler.pdf:
        class: Lobster\MyBundle\View\PdfViewHandler
    my.view_handler:
        parent: fos_rest.view_handler.default
        calls:
            - ['registerHandler', [ 'pdf', [@my.view_handler.pdf, 'createResponse'] ] ]

MyBundle/View/PdfViewHandler.php

namespace Lobster\MyBundle\View;

use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class PdfViewHandler
{
    public function createResponse(ViewHandler $handler, View $view, Request $request, $format)
    {
        my_dump('pdf createResponse started');

        $pdf = "some pdf";

        return new Response($pdf, 200, $view->getHeaders());
    }
}

所以现在当我打电话时

mysite.com/app_dev.php/api/my/bacon/bacons.pdf

我看到一个错误 An Exception was thrown while handling: Format html not supported, handler must be implemented 并且我的函数 my_dump 将有关文件格式的信息保存到文本文件中:它是 html,而不是 pdf

pdf createResponse 也不起作用。为什么?

【问题讨论】:

    标签: php symfony fosrestbundle


    【解决方案1】:

    所以我找到了解决方案(我将描述如何启用 2 种输出格式:PDF 和 XLS):

    1) config.yml 中的这一部分不需要:

    framework:
        [...some old stuff here...]
        request:
            formats:
                pdf: 'application/pdf'
    

    2) config.yml 中的 fos_rest.format_listener 部分应如下所示:

    format_listener:
        rules:
            -
                path:                 '^/api/my/bacon.*\.xls$'
                host:                 ~
                prefer_extension:     false
                fallback_format:      json
                priorities:           [xls, json]
            -
                path:                 '^/api/my/bacon.*\.pdf$'
                host:                 ~
                prefer_extension:     false
                fallback_format:      json
                priorities:           [pdf, json]
            -
                path:                 ~
                host:                 ~
                prefer_extension:     true
                fallback_format:      html
                priorities:           [html,json]
    

    3) 需要在config.ymlfos_rest 中添加service 部分

    fos_rest:
    [...]
        service:
            view_handler: my.view_handler
    

    4) config.yml 中的 services 根部分应如下所示

    services:
        my.view_handler.xls:
            class: Lobster\MyBundle\View\XlsViewHandler
        my.view_handler.pdf:
            class: Lobster\MyBundle\View\PdfViewHandler
        my.view_handler:
            parent: fos_rest.view_handler.default
            calls:
                - ['registerHandler', ['xls', [@my.view_handler.xls, 'createResponse'] ] ]
                - ['registerHandler', ['pdf', [@my.view_handler.pdf, 'createResponse'] ] ]
    

    就是这样。现在完美运行

    【讨论】:

    【解决方案2】:

    如果文件有不同的数据内容,那么Controller也可以自己生成文件,在BinaryFileResponse中返回结果。

    • 无需更改任何配置
    • _format 可用于选择所需的文件格式
    • 所有代码都驻留在控制器中(以及一些与特定格式生成相关的服务),因此添加新内容或更改现有内容需要更改少量文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-14
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2014-10-16
      相关资源
      最近更新 更多