@fixit-ss

Выгрузка данных в EXCEL: PHP и PhpSpreadsheet — почему не срабатывает с первого раза?

Суть такова имеется файл exportmezved.php в котором отображаются списки активных запросов пользователей системы.

<button id="mezved_to_excel" class="btn btn-primary float-right" onclick="location.href='../lib/exporttoexcel/mezvedtoexcel.php'"


При нажатии на данную кнопку в файле mezvedtoexcel.php происходит формирование книги Excel. И тут проблема, при нажатии на нее, браузер не предлагает скачать сформированный файл. При повторном нажатии - все срабатывает идеально.

Вот код файла mezvedtoexcel.php
require '../config.php'; // здесь настройки подключения к базе данных
require 'vendor/autoload.php'; 
 
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
 
//Создаем экземпляр класса электронной таблицы
$spreadsheet = new Spreadsheet();
//Получаем текущий активный лист
$sheet = $spreadsheet->getActiveSheet();
//устанавливаем перенос текста
$spreadsheet->getActiveSheet()->getStyle('A:I')->getAlignment()->setWrapText(true);
//устанавливаем выравнивание текста
$spreadsheet->getActiveSheet()->getStyle('A:I')->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
//Формируем заголовок
$sheet->getStyle('A1')->applyFromArray([
    'font' => [
      'name' => 'Calibri',
      'size' => 14,
      'bold' => true,
    ],
    'alignment' => [
        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
        'vertical' =>  \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
    ]
]); 
$sheet->getRowDimension(1)->setRowHeight(24);
$sheet->setCellValue('A1', 'Выгрузка межвед запросов от '.date('d.m.Y'));
$sheet->mergeCells('A1:I1');
//Записываем шапку
$sheet->setCellValue('A2', '№ п.п.');
$sheet->setCellValue('B2', 'ПКУ');
$sheet->setCellValue('C2', 'ФИО');
$sheet->setCellValue('D2', 'Адрес');
$sheet->setCellValue('E2', 'Дата заявки');
$sheet->setCellValue('F2', 'Вид МСП');
$sheet->setCellValue('G2', 'Специалист');
$sheet->setCellValue('H2', 'Дата запроса');
$sheet->setCellValue('I2', 'Содержание');
 
//формирование данных
$query = "SELECT mezved.*, orders.pku, orders.declarant_f, orders.declarant_n, orders.declarant_o, orders.address, orders.date_order, orders.id_msp, orders.id_user, msp.name AS msp_name, users.name AS user_name
            FROM mezved JOIN orders
                ON mezved.id_order = orders.id
            LEFT JOIN msp
                ON orders.id_msp = msp.id
            LEFT JOIN users
                        ON orders.id_user = users.id
            WHERE mezved.date_mezved_send IS NULL
            ORDER BY date_mezved DESC";
$result = $mysqli->query($query);
if ($result->num_rows > 0) {
    $n = 2;
    while($row = $result->fetch_assoc()){
        $rowNum = $n + 1;
        $sheet->setCellValue('A'.$rowNum, $n-1);
        $sheet->setCellValue('B'.$rowNum, $row['pku']);
        $sheet->setCellValue('C'.$rowNum, $row['declarant_f'].' '.$row['declarant_n'].' '.$row['declarant_o']);
        $sheet->setCellValue('D'.$rowNum, $row['address']);
        $sheet->setCellValue('E'.$rowNum, $row['date_order']);
        $sheet->setCellValue('F'.$rowNum, $row['msp_name']);
        $sheet->setCellValue('G'.$rowNum, $row['user_name']);
        $sheet->setCellValue('H'.$rowNum, $row['date_mezved']);
        $sheet->setCellValue('I'.$rowNum, $row['content_mezved']);
        $n++;
    }
}
//Установка ширины столбцов
$sheet->getColumnDimension('A')->setWidth(6);
$sheet->getColumnDimension('B')->setWidth(13);
$sheet->getColumnDimension('C')->setWidth(24);
$sheet->getColumnDimension('D')->setWidth(41);
$sheet->getColumnDimension('E')->setWidth(11);
$sheet->getColumnDimension('F')->setWidth(22);
$sheet->getColumnDimension('G')->setWidth(17);
$sheet->getColumnDimension('H')->setWidth(11);
$sheet->getColumnDimension('I')->setWidth(44);
//Установка границы ячеек
$rowCnt = $result->num_rows + 2;
$borderStyleArray = [
    'borders' => [
        'allBorders' => [
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            'color' => ['rgb' => '000000'],
        ],
    ],
];
$sheet->getStyle('A2:I'.$rowCnt)->applyFromArray($borderStyleArray);
 
//Установка параметров страницы
$spreadsheet->getActiveSheet()->getPageSetup()
    ->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
$spreadsheet->getActiveSheet()->getPageSetup()->setFitToWidth(1);
$spreadsheet->getActiveSheet()->getPageSetup()->setFitToHeight(0);
$spreadsheet->getActiveSheet()->getPageMargins()->setTop(0.4);
$spreadsheet->getActiveSheet()->getPageMargins()->setRight(0.4);
$spreadsheet->getActiveSheet()->getPageMargins()->setLeft(0.4);
$spreadsheet->getActiveSheet()->getPageMargins()->setBottom(0.4);
 
//здесь идет обновление записей в базе данных - проставляется дата выгрузки запросов, что бы повторно не попадали в выгрузку
$query = "UPDATE `mezved` SET `date_mezved_send` = '".date('Y-m-d')."' WHERE `date_mezved_send` IS NULL";
$result = $mysqli->query($query);
 
//Указываем имя файла
$filename = 'Запросы от '.date('Y-m-d H-i-s').'.xlsx';
 
 
//редирект на сохранение
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'"');
header('Cache-Control: max-age=0');
// Если пользователь работает в IE 9, то может потребоваться следующее
//header('Cache-Control: max-age=1');
 
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');


Сам файл Excel формируется верно, проблема, как я понимаю, где-то в момент отправки команды на сохранение

Почему так происходит, что срабатывает только со второго раза. Причем на следующий день такая же ерунда - только со второго раза (сервер работает в режиме 24/7) не могу понять. Пробовал с разных браузеров, разных компов - проблема везде.
  • Вопрос задан
  • 859 просмотров
Пригласить эксперта
Ответы на вопрос 1
@AlexRsk
Попробуйте вместо вывода в php output сохранить файл, а затем
echo file_get_contents(...);
unlink(...);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы