TYPO3 v11.5 或更高版本 - 获取控制器方法来创建 XLSX,然后发送标头以下载文件

问题描述 投票:0回答:2

我无法让该控制器创建 XLS 并下载它。下面的代码确实创建了 Excel。 Excel 也保存在服务器上,我可以看到该文件具有正确的结构和内容。但是,下载的文件包含当前页面(HTML)代码,而不是我从存储库中提取的内容。

public function exportAction()
{

    // Create a new PHPExcel spreadsheet
    $spreadsheet = new Spreadsheet();

    // Create a worksheet
    $worksheet = $spreadsheet->getActiveSheet();

    // The Excel data logic goes here
    // (..)

    $tempFilePath = GeneralUtility::tempnam('export_', '.xlsx');
    $writer = new Xlsx($spreadsheet);
    $writer->save($tempFilePath);

    $uploadFolder = "fileadmin/";
    $uploadFolderAbsolutePath = GeneralUtility::getFileAbsFileName($uploadFolder);

    $filename = "Upload.xls";
    $destinationPath = $uploadFolderAbsolutePath . "/" . $filename;

    GeneralUtility::upload_copy_move($tempFilePath, $destinationPath);

    unlink($tempFilePath);

    // The file upload.XLS is correct
    // The below does not work as expected.

    if (file_exists($destinationPath)) {
        $response = $this->responseFactory->createResponse();

        $response = $response->withHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        $response = $response->withHeader("Content-Disposition", "attachment; filename=" . basename($filename));

        $response = $response->withHeader("Content-Transfer-Encoding", "binary");

        $stream = new Stream($destinationPath, 'r');
        $response = $response->withBody($stream);

        return $response;

    }

    return $this->htmlResponse();

}
excel controller header typo3 xlsx
2个回答
0
投票

如果放置退出的“解决方法”有帮助,原因可能是在您的插件之后执行了其他操作并覆盖了内容。

然后,您可以调整以下插件,保留您的解决方法,或者通过抛出立即页面解析异常来“正确”解决您的最终操作:https://api.typo3.org/9.5/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_http_1_1_immediate_response_exception.html

当这是“正确”的操作时抛出异常听起来很奇怪,但它是“好的”😅


0
投票

“添加响应接口作为控制器操作的返回有点早。事实是,正常的链被打乱了,您创建的响应不会直接返回并用作真正的请求响应。

在 ContentObjectRendering 和分派到 extbase 生态系统中的某个位置,操作返回的响应对象被“分散”并作为中间的字符串返回。这样,响应头就会丢失。

可以抛出一个特定的异常,获取附加的响应对象,硬跳转到稍后的响应点,超越正常的内容租用者堆栈 - 并允许按原样返回您的构建响应以及所有标头。


use TYPO3\CMS\Core\Http\PropagateResponseException;

public function exportAction()
{

    // Create a new PHPExcel spreadsheet
    $spreadsheet = new Spreadsheet();

    // Create a worksheet
    $worksheet = $spreadsheet->getActiveSheet();

    // The Excel data logic goes here
    // (..)

    $tempFilePath = GeneralUtility::tempnam('export_', '.xlsx');
    $writer = new Xlsx($spreadsheet);
    $writer->save($tempFilePath);

    $uploadFolder = "fileadmin/";
    $uploadFolderAbsolutePath = GeneralUtility::getFileAbsFileName($uploadFolder);

    $filename = "Upload.xls";
    $destinationPath = $uploadFolderAbsolutePath . "/" . $filename;

    GeneralUtility::upload_copy_move($tempFilePath, $destinationPath);

    unlink($tempFilePath);

    // The file upload.XLS is correct
    // The below does not work as expected.

    if (file_exists($destinationPath)) {
        $response = $this->responseFactory->createResponse();

        $response = $response->withHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        $response = $response->withHeader("Content-Disposition", "attachment; filename=" . basename($filename));

        $response = $response->withHeader("Content-Transfer-Encoding", "binary");

        $stream = new Stream($destinationPath, 'r');
        $response = $response->withBody($stream);

        // throw exception to jump over the content render stack
        // and use $response as is for the response.
        throw new PropagateResponseException($response);
    }

    return $this->htmlResponse();

}
© www.soinside.com 2019 - 2024. All rights reserved.