Экспорт в csv с добавлением html в файл

Вопрос или проблема

Я пытаюсь экспортировать результаты в файл csv, используя следующий код. Экспорт, кажется, работает, но когда я открываю файл, он содержит HTML-код страницы. Буду признателен за любую помощь.

ob_start();
global $wpdb;
$domain = $_SERVER['SERVER_NAME'];
$table = $wpdb->prefix . "qi_project_requests";
$filename = "export.csv";
$sql = $wpdb->get_results("select * from $table");

$header_row = array(
    'Дата отправки',
    'Имя запрашивающего'
);

$data_rows = array();

foreach ($sql as $data) {
    $row = array(
        $data->date,
        $data->rname
    );
    $data_rows[] = $row;
}

$fh = @fopen( 'php://output', 'w' ); 
fprintf( $fh, chr(0xEF) . chr(0xBB) . chr(0xBF) ); 
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' ); 
header( 'Content-Description: File Transfer' ); 
header( 'Content-type: text/csv' ); 
header( "Content-Disposition: attachment; filename=$filename" ); 
header( 'Expires: 0' ); 
header( 'Pragma: public' ); 
fputcsv( $fh, $header_row ); 
foreach ( $data_rows as $data_row ) { 
    fputcsv( $fh, $data_row ); 
} 
fclose( $fh ); 

ob_end_flush(); 

die(); 

У меня есть похожий процесс, чтобы вывести все адреса электронной почты из базы данных в downloadable txt файл. Это выглядит так:

$xoutput =  show_subscriber_list();
$xfile = fopen('xsubscriber.txt' , "w") or die("Невозможно открыть файл!");;
fwrite($xfile,$xoutput);
fclose($xfile);

$filename="xsubscriber.txt"; // конечно, найдите точное имя файла....        
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false); // требуется для некоторых браузеров 
header('Content-Type: application/pdf');

header('Content-Disposition: attachment; filename="'. basename($filename) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filename));

readfile($filename);

exit;

Функция show_subscriber_list выполняет SQL-запрос данных, получая все данные в цикле по строкам, возвращаемым запросом. Эта функция возвращает эти данные в виде строки, которая используется в качестве содержимого $filename (как в return $text_data;).

$filename хранится в текущей папке. Затем это $filename используется в заголовках, что позволяет получить файл в виде диалога загрузки/открытия.

Важно ‘построить’ содержимое файла перед тем, как вы сделаете заголовки. Вы могли бы так же легко ‘построить’ данные в строку, а затем сделать заголовки.

Добавлено

Вот функция, которая возвращает содержимое базы данных в виде текста. Вызывается с

    $data = mysqli_query($conn, $sql);
    $output = display_data($data); // текстовый вывод, используемый в вышеуказанной функции

    function display_data($data) {
        $output = "";
        foreach($data as $row) {
            $output .= $row["email"] . PHP_EOL ;
        }


    return $output;
}

И обратите внимание, как упоминалось в комментарии от OP, что вам нужно установить правильный Content-Type, необходимый для содержимого вашего файла; у меня он установлен как PDF.

Проблема в том, что вы используете функции ob_start() и ob_end_flush(), которые используются для буферизации вывода вашего скрипта. Эти функции следует удалить из вашего кода, поскольку они могут вызывать включение HTML-кода страницы в экспортируемый CSV-файл.

Ответ или решение

Исходя из вашего вопроса, вы пытаетесь экспортировать данные из базы данных в файл CSV, однако сталкиваетесь с тем, что в результирующем файле появляется HTML-код. Данная проблема чаще всего возникает из-за неправильно настроенной обработки вывода. В этой статье мы рассмотрим, как правильно организовать экспорт данных без HTML-кода, а также приведем исправленный пример вашего кода.

  1. Проблема с буферизацией вывода: Использование функций ob_start() и ob_end_flush() может привести к тому, что буферизованный вывод (включая HTML-код) будет включаться в ваш CSV-файл. Рекомендуется избегать этих функций в вашем случае.

  2. Правильная настройка заголовков: Убедитесь, что заголовки HTTP установлены корректно перед отправкой содержимого CSV-файла. Это включает в себя установку типа содержимого и имени файла.

Вот исправленный код для вашего экспорта данных:

// Не используем буферизацию вывода
global $wpdb;

// Настройка базы данных и переменных
$domain = $_SERVER['SERVER_NAME'];
$table = $wpdb->prefix . "qi_project_requests";
$filename = "export.csv";

// Получение данных из базы
$sql = $wpdb->get_results("SELECT * FROM $table");

// Заголовки колонок для CSV
$header_row = array(
    'Date Submitted',
    'Requestor Name'
);

// Массив данных
$data_rows = array();

foreach ($sql as $data) {
    $row = array(
        $data->date,
        $data->rname
    );
    $data_rows[] = $row;
}

// Настройка заголовков для скачивания файла
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=\"$filename\"");
header('Pragma: no-cache');
header('Expires: 0');

// Открытие потока для записи CSV
$output = fopen('php://output', 'w');

// Запись заголовка
fputcsv($output, $header_row);

// Запись данных
foreach ($data_rows as $data_row) {
    fputcsv($output, $data_row);
}

// Закрытие потока
fclose($output);

// Завершение скрипта
exit();

Объяснение изменений:

  • Удалены функции буферизации вывода: Устранение ob_start() и ob_end_flush() предотвратит вывод ненужного HTML.
  • Настройка заголовков для скачивания: Устанавливаются необходимые заголовки, чтобы браузер мог правильно интерпретировать файл как CSV.
  • Использование php://output: Это стандартный способ вывода данных, который подходит для этой задачи.

Следуя приведенным рекомендациям, вы получите корректно формируемый CSV-файл, содержащий только нужные данные, без нежелательного HTML-кода. Это обеспечит удобство пользователей и решит проблему с экспортом данных.

В случае дополнительных вопросов или необходимости внесения изменений в логику (например, добавление дополнительных полей), не стесняйтесь задавать их.

Оцените материал
Добавить комментарий

Капча загружается...