【问题标题】:Download CSV from shopware 6 administration从 shopware 6 管理下载 CSV
【发布时间】:2022-11-26 15:12:32
【问题描述】:

我想从 Shopware 6 管理员实现 CSV 导出。我有一个按钮,想要打开一个新窗口并获取一个 CSV 文件。

我实现了一个控制器:

/**
 * @Route(
 *     "/api/winkelwagen/export/csv/{id}",
 *     methods={"GET"},
 *     defaults={"auth_required"=true, "_routeScope"={"api"}}
 * )
 */
public function export(string $id, Context $context, Request $request): Response
{
    /** @var PromotionEntity $promo */
    $response->setContent('csv file');

    return $response;
}

但是要调用这个控制器,你需要登录,这是完全合理的。

我在管理中的按钮当前打开一个新窗口并打开页面:

window.open('http://www.fabian-blechschmidt.de', '_blank');

这当然不适用于 api url,因为您需要进行身份验证。

所以我的问题是:如何实现此身份验证并在后端获取 CSV 文件? :-)

也许我的方法完全被打破了——很高兴得到一个更好的主意!

【问题讨论】:

    标签: shopware6 shopware6-api


    【解决方案1】:

    为了扩展 dneustadt 的答案,下面的代码 sn-p 实际上还通过将数据加载到数据 url 并虚拟单击它来将 csv 下载为文件。

    const initContainer = Shopware.Application.getContainer('init');
    initContainer.httpClient.get(
        `winkelwagen/export/csv/${id}`,
        {
            headers: {
                Accept: 'application/vnd.api+json',
                Authorization: `Bearer ${Shopware.Service('loginService').getToken()}`,
                'Content-Type': 'application/json',
            },
        },
    ).then((response) => {
        if (response.data) {
            const filename = response.headers['content-disposition'].split('filename=')[1];
            const link = document.createElement('a');
            link.href = URL.createObjectURL(response.data);
            link.download = filename;
            link.dispatchEvent(new MouseEvent('click'));
            link.parentNode.removeChild(link);
        }
    });
    

    【讨论】:

      【解决方案2】:

      您可以使用内置的 http 客户端并设置承载令牌以进行身份​​验证:

      const initContainer = Shopware.Application.getContainer('init');
      initContainer.httpClient.get(
          `winkelwagen/export/csv/${id}`,
          {
              headers: {
                  Accept: 'application/vnd.api+json',
                  Authorization: `Bearer ${Shopware.Service('loginService').getToken()}`,
                  'Content-Type': 'application/json',
              },
          },
      );
      

      根据您的需要更改标头。

      【讨论】:

        【解决方案3】:

        诺伊施塔特是一个很好的开始! 但是 Runs Laenens 的答案是金子!

        但我认为由于我不返回 JSON 而是返回 CSV 文件这一事实,我需要更改一些内容。

        • 出于某种原因,文件名包含 " 作为前缀和后缀 - 我们将其删除。
        • response.data 既不是文件也不是 Blob,URL.createObjectURL 需要它 - 没问题,我们只做一个。
        • 并且链接似乎没有附加到文档,所以我们确保没有抛出错误
             if (response.data) {
                let filename = response.headers['content-disposition'].split('filename=')[1];
                filename = filename.substring(1, filename.length - 1);
                const link = document.createElement('a');
                link.href = URL.createObjectURL(new Blob([response.data], {type: response.headers['content-type']}));
                link.download = filename;
                link.dispatchEvent(new MouseEvent('click'));
                try {
                    link.parentNode.removeChild(link);
                } catch (e) {
                    // do nothing
                }
            }
        

        【讨论】:

          【解决方案4】:

          我不建议即时创建与 s 数据对象的链接。我相信这会导致大量下载出现问题(但我只是假设)。

          我建议像核心一样做它并使用访问令牌。

          看这里https://github.com/shopware/platform/blob/469a7fc7c7a60eea6ae0863f54cb489bc0cbf31c/src/Administration/Resources/app/administration/src/core/service/api/import-export.api.service.js#L82

          【讨论】:

            猜你喜欢
            • 2022-11-04
            • 2022-12-17
            • 2022-08-11
            • 1970-01-01
            • 1970-01-01
            • 2019-09-10
            • 2023-04-06
            • 2023-01-31
            • 2021-01-12
            相关资源
            最近更新 更多