设置 headers 并下载文件后代码无法继续

Code doesn't continue after setting headers and downloading file

我有蛋糕 php 索引函数,它显示了一些订单图表。在此索引视图中,用户可以查看 select 日期,一旦表单提交,select 日期的订单图表就会更新。现在我正在尝试实现另一个功能,将数据导出到 excel,方法是向这两个日期 selects 添加简单的 select 选项。

问题是,当您不想导出 Excel 时,您必须设置 headers,一旦设置 header,代码就不会像我想要的那样连续.

这是我的索引函数

public function index() {
        $orderData = $this->Order->getDashboardOrdersStatisticBetweenData();

        if ($this->request->is('post') || $this->request->is('put')) {
            $dateFrom = $this->request->data['orderSumDates']['date_from'];
            $dateTo = $this->request->data['orderSumDates']['date_to'];
            $orderData = $this->Order->getDashboardOrdersStatisticBetweenData($dateFrom, $dateTo);
            if ($this->request->data['orderSumDates']['export_type'] == 'export_excel') {
                $this->generateExcelFile($orderData, $dateFrom, $dateTo);
                die('Code never gets here, but file is downloaded');
            }
        }

        $this->set('orderStatistic', $orderData);
    } 

这是我生成 excel 文件的函数

protected function generateExcelFile($orderData, $dateFrom, $dateTo) {
        header('Content-type: application/vnd.ms-excel');
        header('Content-Disposition: attachment; filename="OrderReport'.$dateFrom.'-'.$dateTo.'.xlsx"');

        $objPHPExcel = new PHPExcel();
        $objPHPExcel->setActiveSheetIndex(0);
        // Summary of report
        $objPHPExcel->getActiveSheet()->SetCellValue('A5', 'Total number of orders');
        // Some other stuff
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');

        header_remove('Content-type');
        header_remove('Content-Disposition');
    }

所以问题是如果我 select export_excel 选项,$this->generateExcelFile 函数被执行并且 excel 文件被下载,但是其余的代码永远不会发生,例如这个 die('Code never gets here, but file is downloaded'); 我不想被执行。我做了一些测试,如果我注释掉 $this->generateExcelFile 函数的 header() 部分,代码正常连续(die 被执行),但是 excel 文件没有正确生成,所以那些headers 是至关重要的。你能帮我解决我的问题吗?

您可以保存 Excel 文件,然后使用 Cakephp 内置函数将其发送到浏览器。

1 - 在您的 TMP 文件夹

上创建一个文件夹 files
app/tmp/files

2- 将在该文件夹中生成的文件保存在您的函数中,并且 return 文件位置

protected function generateExcelFile($orderData, $dateFrom, $dateTo) {
    //header('Content-type: application/vnd.ms-excel'); // REMOVE THIS LINE
    //header('Content-Disposition: attachment; filename="OrderReport' . $dateFrom . '-' . $dateTo . '.xlsx"'); // REMOVE THIS LINE

    $objPHPExcel = new PHPExcel();
    $objPHPExcel->setActiveSheetIndex(0);
    // Summary of report
    $objPHPExcel->getActiveSheet()->SetCellValue('A5', 'Total number of orders');
    // Some other stuff
    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

    $tmpFile = TMP . "files" . DS . sprintf("excel-file-%s.xlsx", date('Y-m-d-H-i-s')); // The tmp file
    $objWriter->save($tmpFile); // Save on excel file
    return $tmpFile; //send the file location

    //$objWriter->save('php://output'); // REMOVE THIS LINE

    //header_remove('Content-type'); // REMOVE THIS LINE
    //header_remove('Content-Disposition'); // REMOVE THIS LINE
}

3- 根据您的操作,删除此文件后将该文件内容发送到浏览器

public function index() {
    $orderData = $this->Order->getDashboardOrdersStatisticBetweenData();

    if ($this->request->is('post') || $this->request->is('put')) {
        $dateFrom = $this->request->data['orderSumDates']['date_from'];
        $dateTo = $this->request->data['orderSumDates']['date_to'];
        $orderData = $this->Order->getDashboardOrdersStatisticBetweenData($dateFrom, $dateTo);
        if ($this->request->data['orderSumDates']['export_type'] == 'export_excel') {
            $excelFile = $this->generateExcelFile($orderData, $dateFrom, $dateTo);
            //Get the file content
            $content = file_get_contents($excelFile);
            //Delete that file
            unlink($excelFile);
            //Put the content on the response
            $this->response->body($content);
            //Force download (test.xlsx is the file name browser will recieve)
            $this->response->download("test.xlsx");
            //spécify the response type
            $this->response->type("application/vnd.ms-excel");
            //send the response
            return $this->response;
        }
    }

    $this->set('orderStatistic', $orderData);
}