Пользователь
0,0
рейтинг
21 ноября 2011 в 18:33

Разработка → Самый простой способ генерации xls в PHP

PHP*
Вообще казалось бы вынесенная в заголовок задача не должно быть сложной, да и гугл дает кучу ссылок, в том числе на хабр, однако для того чтобы сделать выгрузку БД с сайта в эксель мне пришлось несколько помучаться.

С модулем Spreadsheet_Excel_Writer я предпочел не связываться, по причине отсутствия необходимых ему модулей php на трех имеющихся у меня в наличии для тестирования серверах, хочется все-таки сделать код перетаскиваемый между серверами легко и просто.
php_write_excel оттолкнул полным отсутствием документации при необходимости сделать работу быстро (хотя в дальнейшем я хочу с этим модулем поразбираться).


В итоге я выбрал самый простейший способ из найденных в интернете — выведение стандартной html таблицы под видом xls-файла. На этом пути лично у меня возникла проблема с кодировкой, эксель упорно не хотел видеть кириллицу в честном Windows-1251. В итоге рабочей оказалась следующая конструкция.

header('Content-Type: text/html; charset=windows-1251');
header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');
header('Content-transfer-encoding: binary');
header('Content-Disposition: attachment; filename=list.xls');
header('Content-Type: application/x-unknown');

echo<<<HTML
<table border="1">
<tr><td>
htmlentities(iconv("utf-8", "windows-1251", $val),ENT_QUOTES, "cp1251"));
</td></tr>
</table>
HTML;


Соответственно iconv нужен в случае если данные в БД пишутся в utf-8, htmlentities переводит в доступный экселю формат. Попытка применить htmlentities к тексту в utf-8 привела к очень большому количеству китайских иероглифов в экселе.

Этот способ позволяет с помощью стандартных же html тэгов задавать жирный и курсивный текст, но пока не удалось понять, можно ли сделать заливку ячеек цветом. Впрочем для генерации простенького .xls файла способ все равно вполне пригоден. Данные потом нормально просматриваются, редактируются и сохраняются в экселе.

Надеюсь этот пост кому-нибудь поможет в решении аналогичной задачи.
Глеб Игумнов @CrazySage
карма
6,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (40)

  • +4
    Такой способ используют старые версии phpMyAdmin. Функционал такого решения крайне ограничен, но решение практично к примеру при очень больших объемах информации. Но именно для сохранения больших объемов я недавно этот класс добавлял в новую версию phpMyAdmin на сервере клиента. Но многие клиенты не распознают его как документ Excel и ругаются на это, хоть и отображают корректно.

    Использую в работе библиотеку PHPExcel. Достаточно гибкая и удобная. Ее единственная проблема — переполнение памяти при создании документа большого объема, даже когда выбираешь кэш на диске. Пока этот баг, к сожалению, не пофиксили.
    • 0
      У меня данные очень простые, поэтому выгоднее накидать примитивное решение, чем ставить библиотеку. Тем более, что с расширениями для PHP возникли какие-то проблемы, когда я эту библиотеку пытался поставить (чего-то не хватило, не помню чего именно), а разбираться с хостером было очень лениво.
    • 0
      Функционал такого решения крайне ограничен, но решение практично к примеру при очень больших объемах информации.


      Эксель, конечно, не воспроизводит, но через th можно делать статичные заголовки которые не будут скроллиться.

      И можно использовать примитивные формулы вроде «подсчитать все значения из столбца».
    • 0
      к сожалению библиотека еще и течет если писать в цикле в разные XLS файлы. Решал через костыль в виде запуска внешнего РНР скрипта для генерации одного файла.

      Тем не менее библиотека очень хороша
  • 0
    Spreadsheet_Excel_Writer хорош, но скудность документации и наличие пролем с кирилицей, даже при принудительном указании $worksheet0->setInputEncoding('UTF-8');. Плюс — вышеозначенный set неработает одновременно с setVersion.
    • 0
      Кириллица и умлауты вроде отображаются при setVersion(8), но правда не в названии листа. Ошибок памяти у этой библиотеки не возникает, а документации достаточно для создания стандартных документов. К сожалению пришлось от нее отказаться, т.к. версия 8 не открывается на некоторых устройствах, к примеру iPhone/iPad (а у главного заказчика это рабочий инструмент), а в других версиях не отображается UTF, как вы правильно написали.
      • 0
        Ненадо путать теплое с мягким — дока есть, но ее мало. Я помню долго сидел и развлекался с setVersion/setInputEncoding, в итоге остановился на последнем. Даже им в багрепорт отписывал, правда безответно.
        • 0
          да, с кодировками у них лажа полная, согласен. Доки я брал тут: pear.php.net/package/Spreadsheet_Excel_Writer/docs
          вроде, основной функционал там расписан, но по сравнению с тем же PHPExcel функций не так много. Но как я писал, от нее пришлось отказаться
  • +7
    А CSV не?
    • 0
      а многостраничные документы? а формулы как формулы, а не как текст?
      • 0
        А как ты формулы в HTML выведешь?
        • 0
          эээ, а как часто в ГЕНЕРИРУЕМОМ xls-файле нужны формулы?
          • +8
            Ну значит достаточно и csv в итоге, не?
  • +1
    phpexcel.codeplex.com/ смотрели?
    • 0
      Смотрел, на хостинге заказчика ему не хватало компонент, а экселевский файл надо было слишком простой генерировать, чтобы ради этого заморачиваться.
  • +2
    Зачем велосипед?
    Использую class Excel_XML
    Генериует валидный Excel 2003 XML файл (открывается Excel 2003+). Пусть и больше размером, зато стандартный.
    • 0
      На него не натыкался, поизучаю.
    • –1
      Ожидал увидеть этот комментарий. В данном конкретном примере поддерживаю.
      Формат для экселя родной и главное строгий, парсит он его на много быстрее, особенно заметно на больших выгрузках.
      Но не очень удобно, когда требуются опциональные колонки.
  • 0
    А <head><meta http-equiv="content-type" content="text/html; charset=windows-1251"></head> от кодировки не помогает?
    • 0
      Честно говоря не помню, я это полгода назад уже писал. Вроде пробовал и не помогло.
  • +1
    А зачем тут P3P заголовок?
    • –4
      Тупо скопировал пример, в котором объяснялось как php генерировать скачиваемый файл, а дальше как обычно, подобный мусор из кода убирается либо когда уже ни хрена не понятно, либо если он вредит работе :)
      Я лентяй, да.
  • 0
    А чем потом такие файлы разбирать на php? =)
    Да таким, что-бы и нормальные файлы xls(xlsx) тоже разбирались?..
    • 0
      Разбирать у меня задачи не было)
      Вроде такой файл, если его открыть в экселе, а потом сохранить, превращается в честный xml, но надо проверить
      • 0
        К сожалению на php пересохранить файл экселем крайне сложно.
        • 0
          Вообще, если набор тэгов, которые будут в таблице, нам известен, то разобрать ее проблем не вижу. Или даже просто разбирать табличные тэги, а все что внутри гнать чистым текстом, без парсинга.
  • +4
    Вы по сути заставляете Excel открыть html-страницу, переименовую в xls, а не создаете файл формата Excel. Цель топика «сгенерировать xls посредством php» не достигнута, зато изобретен очередной костыль.
    • 0
      Открыв этот файл в экселе мы можем с ним полноценно работать в плане форматирования, формул и т.д., в чем проблема? Да, с точки зрения внутреннего формата это будет не полноценный xls (до первого сохранения), но тут уже вечный вопрос про шашечки или ехать. Если оно выглядит как xls и работает как xls, то вот не пофиг что там внутри?
      • 0
        файл, открывающийся excel-ем — не есть xls документ. Просто умный интерпретатор экселя разгадывает предоставленный ему ребус.
        • 0
          Переименуем csv файл в xls — не откроется с ходу, потребует импорт. Я не спорю, у меня задачи простые, но на небольших объемах простых данных во всех внешних проявлениях файл идентичен xls.
          Заказчик тоже человек простой, ему нужен файл, который открывается как xls, обрабатывается как xls и сохраняется как xls, а внутреннее устройство ему пофигу :)
          • 0
            Зачем переименовывать csv в xls? O_o
            csv откроется в экселе безо всяких вопросов — молча и правильно.
            Если данные простые, как уже было указано, то зачем пытаться преобразовать их в формат, который предусматривает более сложное представление? тем более что тут даже не преобразование в формат, а просто подсовывание данных под его видом.
            Используйте CSV — это отличный способ передать данные в эксель. А дальше, как вы сами говорили, клиент будет делать с ними что угодно в нем.
            • 0
              В csv как минимум шрифты нельзя сделать жирный\курсив и т.д., с объединенными колонками тоже не представляю как сделать
              Переименованный csv я просто привел в пример, что умный интерпретатор экселя не все представляющее таблицу без вопросов распознает
  • 0
    Есть еще один пример — habrahabr.ru/blogs/php/18726/
    • 0
      Его я так и не смог заставить работать с UTF-8 корректно.
      • 0
        xlsWriteLabel(1,0,iconv(...)); пробовали?
        Дабы не захламлять код, можно сделать что-то вроде:

        function i($arg) {
        return iconv("utf-8","windows-1251", $arg);
        }


        И использовать

        xlsWriteLabel(1,0,i("Text"))

        Либо же просто подправить функцию xlsWriteLabel.
  • 0
    У нас используется
    header("Content-Type: application/vnd.ms-excel");

    И да, это не генерация xls, а способ открыть таблички из отчетов в экселе, чего во многих случаях достаточно:)
  • +2
    Почему то все, все без исключения, когда пытаются продружить «что то и Excel», пытаются использовать всё, всё что угодно — CSV, «HTML под видом XLS», даже библиотеки, которые генерируют «чистый XLS». Но все забывают про простой, удобный, не сильно сложнее чем CSV формат SYLK ( http://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK) ). Это как RTF только для Excel.
    • 0
      Чтобы про что-то забыть, надо про что-то знать, спасибо за информацию.
  • 0
    Самый простой способ избежать проблем с кодировкой xls в Excel:
    — создать новый документ в Excel содержащий символы кириллицы
    — сохранить его как .html
    — открыть *.html — там будет самый верный мануал

    Не верите? Переименуйте в .xls и откройте в Excel.
  • 0
    А как же быть с большими прайсами с разворачивающейся/сворачивающейся структурой?

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