JavaScript: Еще один вариант загрузки файла по клику на кнопку
Общая идея следующая: по клику на кнопку вызываем AJAX запрос на сервер с определенными параметрами передаваемыми в POST, затем получив в результат запроса файл — формируем в DOM на файл в формате blob, и тут-же её нажимаем. В результате браузер показывает диалоговое окно сохранения файла.
Таким необычным способом мы убиваем несколько зайцев сразу:
- Получаем возможность показать ошибку, если вдруг файл на сервере сформировать не удалось. Это полезно если например файл формируется на сервере «на лету» — например файл XLSX с отчётом
- Мы можем передать серверу какие-то условия для формирования файла в POST запросе
- На странице мы не размещаем заранее данные в тегах <form></form>, как практикуется в подобных решениях
- Пользователю достаточно нажать на кнопку один раз для получения результата.
В результате скрипт формирования файла может выглядеть примерно следующим образом:
На клиенте:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /**  * Формирование отчета  * @param {type} filename - имя файла на сервере для формирования отчета  * @param {type} ext - выходное расширение (например xlsx,csv)  * @returns {Number}  */ function get_report(filename,ext){         $("#global").addClass("loading");             var xhr = new XMLHttpRequest();         xhr.open('POST', '?r=reports/'+filename, true);         xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');         xhr.responseType = 'blob';              xhr.onload = function(e) {             $("#global").removeClass("loading");                 if (this.status == 200) {                 var link=document.createElement('a');                 link.href=window.URL.createObjectURL(this.response);                                 console.log("Расширение:"+ext);                 link.download="report."+ext;                 link.click();             }             else {                 console.log(e);                 ToastMessage("error","Произошла ошибка при формировании файла. Попробуйте позднее или обратитесь к администратору системы.");             }         };              var form_data = new Map();         form_data.period_from = period_from.value;         form_data.period_to = period_to.value;         form_data.area = area_select.value;         form_data.division_check=division_check.checked;         form_data.period_check=period_check.checked;         xhr.send(mapToQueryString(form_data));                                           }; | 
На сервере:
| 1 2 3 4 5 6 7 8 9 10 11 12 |     public function actionGet_report_by_settlers(){                       $request = Yii::$app->request;              $area= $request->post("area");        $dir=Yii::$app->basePath."/web/templates";       $oSpreadsheet = IOFactory::load($dir . "/report_1_1.xlsx");       ...       формируем файл эксель       ...       $oWriter = IOFactory::createWriter($oSpreadsheet, 'Xlsx');       $oWriter->save('php://output');           }; |