Заметки
XLSX скачивается с ошибкой: перед архивом попал HTML
Если XLSX сохраняется на сервере нормально, а скачанная через браузер копия не открывается, сравните начало файлов. <!DOCTYPE html> перед содержимым выгрузки — признак того, что обработчик успел вывести страницу сайта.
В коробке частая причина — подключение /bitrix/header.php в файле экспорта. Обработчику нужен служебный пролог prolog_before.php, без визуального шаблона. После подготовки документа ответ должен содержать только файл.
Фрагмент завершения обработчика: $ob_writer — уже созданный PhpSpreadsheet\Writer\Xlsx. Доступ к выгружаемым данным проверен до этого места.
$APPLICATION->RestartBuffer();
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="report.xlsx"');
$ob_writer->save('php://output');
exit; Очистка буфера не отменяет байты, которые уже ушли клиенту. Поэтому уберите ранний вывод в самом обработчике и подключаемых файлах: echo, HTML, BOM и вывод PHP-предупреждений.
После save не подключайте footer.php или header.php. Если этот же URL должен показывать форму, разделите выдачу страницы и скачивание файла на отдельные ветки.
Документация: Вывод PhpSpreadsheet в браузер; Жизненный цикл запроса.