Пытаюсь сделать экспорт данных в xlsx файл. Сначала сделал экспорт в xls таким образом:
1) Вывожу нужные данные на страницу с помощью echo
2) Выполняю код:
$xls_data = ob_get_clean();
header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=export.xls");
echo $xls_data;
exit();
3) Получаю файл export.xls - то есть всё работает.
Проблема возникла с xlsx. Поискал на разных источниках какие нужно писать заголовки для экспорта xlsx, но всевозможные варианты не работают. Файл скачивается, но открыть его не удаётся (ошибка "Файл повреждён или имеет неверное расширение").
Пробую экспортировать xlsx так:
$xls_data = ob_get_clean();
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=export.xlsx");
header('Content-Transfer-Encoding: binary');
echo $xls_data;
exit();
Подскажите в чём моя ошибка?
P.S. Различные библиотеки для формирования xlsx прошу не предлагать.
Пример моего файла xlsx, открытого в блокноте:
<table border=1 cellspacing=0>
<tr>
<td style="padding:2px 5px; mso-number-format:\@;">№</td>
<td style="padding:2px 5px; mso-number-format:\@;">Заголовок материала</td>
<td style="padding:2px 5px; mso-number-format:\@;">Эксклюзив</td>
<td style="padding:2px 5px; mso-number-format:\@;">Ссылка на материал на сайте</td>
<td style="padding:2px 5px; mso-number-format:\@;">Дата публикации</td>
<td style="padding:2px 5px; mso-number-format:\@;">Время публикации</td>
<td style="padding:2px 5px; mso-number-format:\@;">Создатель материала</td>
<td style="padding:2px 5px; mso-number-format:\@;">Автор материала</td>
<td style="padding:2px 5px; mso-number-format:\@;">Категории</td>
<td style="padding:2px 5px; mso-number-format:\@;">Просмотры</td>
<td style="padding:2px 5px; mso-number-format:\@;">Просмотры 24</td>
<td style="padding:2px 5px; mso-number-format:\@;">Теги</td>
<td style="padding:2px 5px; mso-number-format:\@;">Символы</td>
</tr>
...
</table>
<html>
<head>
<title>Report</title>
</head>
<body>
<?php
$conn = mysqli_connect('localhost', 'root', 'admin', 'sfgcjm') or die('Error connecting to MySQL server.');
$setSql = "SELECT * FROM table_name";
if (!$query = mysqli_query($conn, $setSql) ) {
echo("Error description: " . mysqli_error($conn));
die();
}
$columnHeader = '';
$columnHeader = "Name1" . "\t" . "Name2" . "\t" . "Name3" . "\n";
$setData = '';
while ($rec = mysqli_fetch_row($query)) {
$rowData = '';
foreach ($rec as $value) {
$value = $value . "\t";
$rowData .= $value;
}
$setData .= trim($rowData) . "\n";
}
$result = str_replace( "\r" , "" , $result );
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=Mailing_list_Report.xls");
header("Pragma: no-cache");
header("Expires: 0");
echo ucwords($columnHeader) . "\n" . $setData . "\n";
mysqli_close($conn);
?>
</body>
</html>
Либо так:
<?php
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
}
// Имя загружаемого файла файла.
$filename = "otchet_" . date('Y-m-d') . ".xls";
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.ms-excel");
// Подключение к бд
mysqli_connect ("localhost","root","admin");// Хост юзер и пароль
mysqli_select_db("mailing_list") or die (mysqli_error());// Имя базы данных
//Указать кодировку выводимых данных
mysqli_query('SET character_set_database = cp1251_general_ci');
mysqli_query ("SET NAMES 'cp1251'");
//запрос и вывод данных
$flag = false;
$result = mysqli_query("SELECT * FROM mailing_list ORDER BY Data DESC")
or die('Запрос не выполнен!');
while(false !== ($row = mysqli_fetch_assoc($result))) {
if(!$flag) {
// Вывод заголовков
echo implode("\t", array_keys($row)) . "\r\n";
$flag = true;
}
//Вывод данных столбцов
array_walk($row, 'cleanData');
echo implode("\t", array_values($row)) . "\r\n";
}
exit;
У вас filename в Content-Disposition не с тем расширением. Измените на xslx
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Disposition: attachment; filename=export.xlsx");
Ещё можно попробовать заменить Content-Type на application/octet-stream
UPD 1
В моём последнем проекте при экспорте xslx файла высылаются такие заголовки (из полного списка оставил только значимые):
Content-Type: application/vnd.ms-excel; charset=utf-8
Content-Length: 6743
Cache-Control: public
Content-Disposition: attachment; filename="users.xlsx"
UPD 2
Всё, что было написано выше касалось настоящих xslx файлов (т.е. тех, которые запакованы в zip)
Есть ещё один способ передавать данные в Excel - через HTML-таблицы. Создайте пустой файл test.xls со следующим содержимым:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8" />
</head>
<body>
<table>
<tr>
<td>1</td>
</tr>
</table>
</body>
</html>
Файл откроется в Excel. Здесь важно расширение файла xls и <meta /> внутри html с Content-Type.
Чтобы передать такой файл с сервера я передавал такие заголовки:
Pragma: Public
Content-Type: application/octet-stream
Content-Description: File Transfer
Content-Disposition: attachment; filename="file.xls"
Content-Transfer-Encoding: binary
Попробуйте следующий пример:
$file = "myfile.xlsx" ;
header('Content-Disposition: attachment; filename=' . $file );
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Length: ' . filesize($file));
header('Content-Transfer-Encoding: binary');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: public');
readfile('myfile.xlsx');
Если этот подход не решит вашу проблему то делаем -
Вывод :
Вы не сможете просто создать один без библиотеки. Прочитайте этот PHPExcel Github, который должен указать вам правильноe направлениe.
Существует много разных форматов файлов электронных таблиц, каждый из которых имеет свои собств> BIFF Format >
Used by Microsoft Excel between versions 95 and 2003 File
extension: xls
PHPEXcel Writer: PHPExcel_Writer_Excel5
Mime Type: application/vnd.ms-excel
OfficeOpenXML Format
Used by Microsoft Excel since version 2007
File extension: xlsx
PHPEXcel Writer: PHPExcel_Writer_Excel2007
Mime Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Попробуйте так
$objPHPExcel = new PHPExcel();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=test.xlsx");
//header("Content-Disposition: attachment;filename=test.xls");
header("Content-Transfer-Encoding: binary ");
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->setOffice2003Compatibility(true);
$objWriter->save('php://output');
Продвижение своими сайтами как стратегия роста и независимости