Вчера столкнулся с задачей экспортировать данные в Excel файл. Поиски в интернете привели меня к библиотеке PHPExcel. Когда я прочитал документацию, посмотрел примеры и почитал отзывы, я остановился именно на этой библиотеке. С помощью PHPExcel можно форматировать таблицы(устанавливать выравнивание, менять текст и его цвет, менять границы таблиц и их цвет), вставлять изображения, рисовать диаграммы и многое другое.
Сейчас я покажу вам на примере экспорта контента как экспортировать данные в Excel.
Первым делом скачиваем саму библиотеку PHPExcel. Распаковываем архив, идем в папку "Classes" и копируем ее содержимое. Далее идем в sites/all/libraries нашего сайта, создаем там каталог PHPExcel и вставляем в нее то, что мы копировали.
Следующим шагом будет установка и включение модуля Libraries API.
Теперь переходим к созданию нашего модуля. Я назову модуль "phpexcel_example", следовательно создаем в sites/all/modules нашего сайта папку "phpexcel_example". В ней создаем "phpexcel_example.info". Содержимое этого файла:
name = PHPExcel Example
description = Allows export nodes to *.xls file
core = 7.x
package = phpexcel
dependencies[] = libraries
Здесь мы указали зависимость нашего модуля от Libraries API:
dependencies[] = libraries
Далее создаем файл "phpexcel_example.module" и создаем страницу на которой будет форма с выбором типа материала:
<?php
/**
* Implements hook_menu().
*/
function phpexcel_example_menu() {
$items = array();
$items['admin/config/content/phpexcel-example'] = array(
'title' => 'PHPExcel Example',
'description' => 'Export nodes to *.xls file.',
'page callback' => 'drupal_get_form',
'page arguments' => array('phpexcel_example_admin_form'),
'access arguments' => array('administer nodes'),
'file' => 'phpexcel_example.admin.inc',
);
return $items;
}
Страницу создали, теперь необходимо создать функцию, которая будет формировать нашу таблицу. Так как в hook_menu() я написал следующую строчку:
'file' => 'phpexcel_example.admin.inc',
То функция будет находится в файле "phpexcel_example.admin.inc". Создаем этот файл и пишем нашу функцию:
<?php
/**
* @file
* Admin menu callbacks for phpexcel_example.module.
*/
/**
* Administrative settings form.
*/
function phpexcel_example_admin_form($form, $form_state) {
// Получаем путь к библиотеке.
$path = libraries_get_path('PHPExcel');
// Если отсутствуют файлы библиотеки, то выводим текст с ошибкой.
if (!file_exists($path . '/PHPExcel.php') || !is_dir($path . '/PHPExcel')) {
$form['empty'] = array(
'#markup' => t('PHPExcel library not found.'),
);
return $form;
}
$form['phpexcel_example'] = array(
'#type' => 'fieldset',
'#title' => t('Node types'),
);
$form['phpexcel_example']['phpexcel_example_node_type'] = array(
'#type' => 'select',
'#title' => t('Select node type'),
'#options' => node_type_get_names(),
);
$form['action'] = array(
'#type' => 'actions',
);
$form['action']['submit'] = array(
'#type' => 'submit',
'#value' => t('Export'),
);
return $form;
}
Теперь необходимо написать сабмит функцию:
/**
* Submit callback for phpexcel_example_admin_form().
*/
function phpexcel_example_admin_form_submit($form, $form_state) {
$type = $form_state['values']['phpexcel_example_node_type'];
// Загружаем из базы ноды выбранного типа.
$nodes = _phpexcel_example_load_nodes($type);
// Если удалось получить из базы ноды, то экспортируем их.
if (!empty($nodes)) {
phpexcel_example_export($nodes);
}
}
Как видно из кода, на сабмите у нас выполняется 2 функции _phpexcel_example_load_nodes() и phpexcel_example_export(). Эти функции мы добавим в файл "phpexcel_example.module". Функция _phpexcel_example_load_nodes() загружает ноды переданного типа:
/**
* @param $type
* @return array
*/
function _phpexcel_example_load_nodes($type) {
$query = db_select('node', 'n')
->fields('n', array('nid', 'vid', 'type', 'language', 'title', 'uid', 'status', 'created', 'changed'))
->condition('n.type', $type);
$result = $query->execute();
$nodes = array();
foreach ($result as $record) {
$nodes[] = (array) $record;
}
return $nodes;
}
Функция phpexcel_example_export() формирует Excel файл, сохраняет его на сервере и открывает диалог для скачивания созданного файла:
/**
* @param $nodes
*/
function phpexcel_example_export($nodes) {
global $user;
// Пытаемся создать директорию, в которую будем сохранять файл, если
// неудачно, то выводим соответствующее сообщение.
$directory = 'public://nodes_export';
if (!file_prepare_directory($directory, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) {
drupal_set_message(t('Failed to create %directory.', array('%directory' => $directory)), 'error');
return FALSE;
}
$path = libraries_get_path('PHPExcel');
require_once DRUPAL_ROOT . '/' . $path . '/PHPExcel.php';
// Начинаем создавать excel файл.
$PHPExcel = new PHPExcel();
// Устанавливаем информацию об файле.
$PHPExcel->getProperties()
->setCreator($user->name)
->setLastModifiedBy($user->name)
->setTitle('Office 2003 XLS Document')
->setSubject('Office 2003 XLS Document')
->setDescription('Document for Office 2003 XLS, generated using PHP classes.')
->setKeywords('office 2003 openxml php')
->setCategory('Nodes export result file');
$rows = array();
// Формируем первую строку таблицы, одно значение массива соответствует
// одному столбику.
$i = 0;
$columnCount = 'A';
foreach ($nodes['0'] as $key => $value) {
$rows['0'][] = $key;
if (++$i != count($nodes['0'])) {
$columnCount++;
}
}
// Формируем содержимое таблицы, одна нода является одной строкой
// таблицы.
$rowCount = 1;
foreach ($nodes as $node) {
$rows[] = array(
$node['nid'],
$node['vid'],
$node['type'],
$node['language'],
$node['title'],
$node['uid'],
$node['status'],
$node['created'],
$node['changed'],
);
$rowCount++;
}
// Записываем в файл данные из ранее подготовленного массива.
$PHPExcel->getActiveSheet()->fromArray($rows);
// Устанавливаем авто ширину каждой колонки.
for($i = 'A'; $i !== $columnCount; $i++) {
$PHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
}
// Формируем массив с форматированием для таблицы.
$styleArray = array(
'borders' => array(
'allborders' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN,
),
),
);
// Устанавливаем форматирование для таблицы из ранее созданного массива,
// в данном случае границы таблицы.
$PHPExcel->getActiveSheet()->getStyle('A1:' . $columnCount . $rowCount)->applyFromArray($styleArray);
// Устанавливаем вертикальное выравнивание по верхнему краю, горизонтальное - по
// левому и перенос слов.
$PHPExcel->getActiveSheet()->getStyle('A1:' . $columnCount . $rowCount)->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP)->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT)->setWrapText(TRUE);
// Изеняем название активного листа в excel файле.
$PHPExcel->getActiveSheet()->setTitle('PHPExcel Example');
// Делаем активным первый лист, для того, чтобы при открытии файла был
// открыт первый лист.
$PHPExcel->setActiveSheetIndex(0);
// Формируем имя файла.
$filename = 'phpexcel_example_' . date('d_m_Y', REQUEST_TIME) . '.xls';
// Формируем полный буть для будущего сохранения файла.
$path = file_create_filename($filename, 'public://nodes_export');
// Создаем excel файл.
$objWriter = PHPExcel_IOFactory::createWriter($PHPExcel, 'Excel5');
// Сохраняем excel файл.
$objWriter->save($path);
// Создаем объект файла для сохранение его в базу.
$file = new stdClass();
$file->fid = NULL;
$file->uri = $path;
$file->filename = drupal_basename($path);
$file->filemime = file_get_mimetype($path);
$file->uid = $user->uid;
// По умолчанию, файл будет удален через 6 часов по крону, если
// необходимо, чтобы файл был сохранен на сервере, то необходимо
// раскоментировать строку.
// $file->status = FILE_STATUS_PERMANENT;
// Сохраняем файл базу.
file_save($file);
// Формируем заголовки, для того, чтобы сразу же скачать созданный файл.
$http_headers = array(
'Content-Type' => 'application/vnd.ms-excel',
'Content-Disposition' => 'attachment; filename="' . drupal_basename($path) . '"',
'Content-Length' => filesize($path),
);
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
$http_headers['Cache-Control'] = 'must-revalidate, post-check=0, pre-check=0';
$http_headers['Pragma'] = 'public';
}
else {
$http_headers['Pragma'] = 'no-cache';
}
// Открываем диалог для скачивания файла.
file_transfer($path, $http_headers);
}
Теперь включаем наш модуль, идем на страницу "admin/config/content/phpexcel-example", выбираем необходимый тип материала и жмем кнопку Export.
P.S. Данный модуль создан только в качестве наглядного примера экспорта данных в Excel файл.