duandui5648 2017-02-24 08:20
浏览 49
已采纳

设置标头和下载文件后代码不会继续

I have cake php index function which shows some graphs of orders. On this index view user is able to select dates from, to and once form is submitted the graphs of orders for selected date gets updated. Now i'm trying to implement another functionality, exporting data to excel, by adding simple select option to those two date selects.

The problem is that when you wan't to export Excel, you have to set headers and once you set header, code doesn't continuo as i want.

So here is my index function

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);
    } 

And this is my generate excel file function

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');
    }

So the problem is if i select export_excel option, $this->generateExcelFile function gets executed and excel file is downloaded, but then rest of the code never happens, like for example this die('Code never gets here, but file is downloaded'); which i wan't to be executed. I have done some testing and if i comment out header() part of $this->generateExcelFile function, the code continuous normally (die gets executed), but excel file is not properly generate, so those headers are crucial. Can you please help me over come my problems.

  • 写回答

1条回答 默认 最新

  • dongying6179 2017-02-24 10:04
    关注

    You could save that Excel file, then send it to the browser using Cakephp built in functions.

    1 - Create a folder files on your TMP folder

    app/tmp/files
    

    2- Save the file generated on that folder on your function, and return the file location

    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- On your action, send that file content to the browser after deleting this file

    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);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?