Самый простой способ генерации xls в 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 файла способ все равно вполне пригоден. Данные потом нормально просматриваются, редактируются и сохраняются в экселе.

    Надеюсь этот пост кому-нибудь поможет в решении аналогичной задачи.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 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
                                      А как же быть с большими прайсами с разворачивающейся/сворачивающейся структурой?

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