Как правильно вернуть файл .xls Excel из контроллера UserFrosting и обработать его в Angular 2+? - PullRequest
0 голосов
/ 30 января 2019

У меня проблема с получением файла BLOB-объекта Excel с помощью метода get () Angular 2+ из API UserFrosting.

Вот код для API Userfrosting:

public function apiGetAPExport(Request $request, Response $response, $args)
{
        $objPHPExcel = $this->getAPExcelObject($apfilename); // create the PHPExcel Object.

        //  Redirect output to a client's web browser (Excel5)
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment;filename="'.$apfilename.'.xls"');
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: max-age=0');

        //  If you're serving to IE 9, then the following may be needed
        header('Cache-Control: max-age=1');

        //  If you're serving to IE over SSL, then the following may be needed
        header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
        header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
        header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
        header ('Pragma: public'); // HTTP/1.0
        header('Access-Control-Allow-Origin: *');

        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');

        exit;
    }

Я использую PHP Excel для создания файла Excel.

Вот угловые функции:

btn_createAPfile(){
        const url = this.AppService.fetchHost()+'/api/ap-export';

        let req = this.http.get(url, {responseType: 'blob'})
            .pipe(
                map( // Log the result or error
                    data => {
                        console.log(data);
                        let blob = new Blob([data], { type: "application/vnd.ms-excel"});

                        return blob;
                    },
                    error => console.error("err: ", error)
                )
            );

        req.subscribe(blob => {
            console.log("dbg: ", blob);
            let link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = "apfile.xls";
            link.click();

            this.populateInvoices();

            setTimeout(function () {
                window.URL.revokeObjectURL(url);
            }, 0);
        });
}

Я пытаюсь загрузить файл Excel, используяhttp.get () и после завершения загрузки повторно заполните таблицу счетов-фактур с помощью populateInvoices().Но проблема в том, что я всегда получаю эту ошибку на консоли моего браузера, когда пытаюсь вызвать функцию Angular:

GET http://192.168.33.10/api/ap-export 500 (Internal Server Error)
Access to XMLHttpRequest at 'http://192.168.33.10/api/ap-export' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Uncaught HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}

Я пытался напрямую ввести URL в адресную строку моего браузера, и она работает нормально.

Я знаю, что могу сделать загрузку с windows.open(), но я не могу заполнить ею таблицу.

Пожалуйста, помогите мне, что мне здесь не хватает?

1 Ответ

0 голосов
/ 18 февраля 2019

В сообщении об ошибке указывается, что 192.168.33.10 заблокировал совместное использование ресурсов между источниками.Ваш веб-сервер не позволяет другому серверу или URI получить доступ к API.

Если вы используете Apache, я решил следующие проблемы:

Создайте файл .htaccess в http://192.168.33.10/api/, содержащий

Header set Access-Control-Allow-Origin "*"

убедитесь, что у вас включен мод заголовков (пример linux ниже):

sudo a2enmod headers

У меня также есть заметки, что мне нужно было разрешить переопределения в каталоге, в котором находится api в apache2.conf:

AllowOverride All

Справочная и дополнительная информация: https://enable -cors.org / server_apache.html

...