我无法让该控制器创建 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();
}
如果放置退出的“解决方法”有帮助,原因可能是在您的插件之后执行了其他操作并覆盖了内容。
然后,您可以调整以下插件,保留您的解决方法,或者通过抛出立即页面解析异常来“正确”解决您的最终操作: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
当这是“正确”的操作时抛出异常听起来很奇怪,但它是“好的”😅
“添加响应接口作为控制器操作的返回有点早。事实是,正常的链被打乱了,您创建的响应不会直接返回并用作真正的请求响应。
在 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();
}