Есть такая библиотека PHPExcel. Качать тут
http://phpexcel.codeplex.com/В принципе там в пакете есть полная документация на английском. Все что, остается сделать, это:
1. Составить правильный SQL запрос к базе (могу помочь отдельно)
2. Создать Файл php-скрипта, в котором сделать выборку из базы с этим SQL запросом (см. п.1) и вывести полученное, используя классы библиотеки PHPExcel.
3. Повесить на сайте ссылку на этот php-скрипт.
Если разобраться, то всей работы на 15 минут.
Можно обернуть все это в Joomla-фреймворк - но так как надо было срочно, временно сделал в обход. Может чуть позже сделаю отдельное Joomla-расширение...
Теперь чуть подробней:
1. Создаете папку у себя на сервере где-нить в public_html/ например public_html/price_xls/
2. В эту папку переписываете папку Classes из архива скачанного по ссылке
http://phpexcel.codeplex.com/ так, чтоб получился такой путь public_html/price_xls/Classes/
3. в public_html/price_xls/ создаете файл, например, price_xls.php
вот пример скрипта:
<?php
set_include_path(get_include_path(). PATH_SEPARATOR .
'Classes/');
//подключаем и создаем класс PHPExcel
require_once 'PHPExcel.php';
$pExcel = new PHPExcel();
$pExcel->setActiveSheetIndex(0);
$aSheet = $pExcel->getActiveSheet();
$aSheet->setTitle('Прайс'); //Это название листа в книге excel
//Описываем стили (для начала можно стили пропустить)
$cellStyleArray = array(
'borders' => array(
'outline' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN,
'color' => array('rgb' => '000000'),
),
),
);
$cellNameStyleArray = array(
'borders' => array(
'outline' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN,
'color' => array('rgb' => '000000'),
),
),
);
$cellPriceStyleArray = array(
'borders' => array(
'outline' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN,
'color' => array('rgb' => '000000'),
),
),
'numberformat' => array(
'code' => PHPExcel_Style_NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1,
),
);
$subcategoryStyleArray = array(
'font' => array(
'bold' => true,
),
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,
),
'borders' => array(
'outline' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN,
'color' => array('rgb' => '000000'),
),
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'color' => array(
'argb' => 'FFDDDDDD',
),
),
);
$categoryStyleArray = array(
'font' => array(
'bold' => true,
'size' => 12,
),
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS,
),
);
//устанавливаем данные
$xlpos = 1; //тут будем считать строки
//тут Вставляем хедер (это то что будет выше выводимых данных и после каждой строки увеличиваем $xlpos на 1)
// соединение с БД
$db = "ntpromco_jdb";
$cn = mysql_connect("localhost", "логин к БД","пароль к БД");
if ( !$cn ) die ("Невозможно подключение к MySQL");
mysql_select_db ( $db ) or die ("Невозможно открыть $db");
//тут пишем свой SQL запрос. ну у меня такой
$query = "SELECT if(vm_cat_xref.`category_parent_id`=0, vm_cat2.`category_name`, vm_cat.`category_name`) as cat, if(vm_cat_xref.`category_parent_id`=0, '', vm_cat2.`category_name`), `jos_vm_product`.`product_sku`, `jos_vm_product`.`product_name`, ROUND(`jos_vm_product_price`.`product_price` * 1.2, 2) as price FROM `jos_vm_product` INNER JOIN `jos_vm_product_price` ON (`jos_vm_product_price`.`product_id`=`jos_vm_product`.`product_id`) INNER JOIN `jos_vm_product_category_xref` as vm_cat_xref2 ON (vm_cat_xref2.`product_id`=`jos_vm_product`.`product_id`) INNER JOIN `jos_vm_category` as vm_cat2 ON (vm_cat2.`category_id`=vm_cat_xref2.`category_id`) INNER JOIN `jos_vm_category_xref` as vm_cat_xref ON (vm_cat_xref.`category_child_id`=vm_cat_xref2.`category_id`) left JOIN `jos_vm_category` as vm_cat ON (vm_cat.`category_id`=vm_cat_xref.`category_parent_id`) WHERE (`jos_vm_product`.`product_in_stock` <> 0 AND `jos_vm_product`.`product_publish` LIKE 'Y') ORDER BY `jos_vm_product`.`product_sku`";
$result = mysql_query ( $query );
$m = mysql_num_rows ( $result );
$n = mysql_num_fields( $result );
$cur_sect="";
$cur_cat="";
$sect_num=0;
$cat_num=0;
// далее идет пример вывода данных. для моей структуры "категория уровня 1 ($cur_sect)-> категория уровня 2 ($cur_cat)-> товар"
for ( $i=0; $i<$m; $i++ )
{
$row = mysql_fetch_array($result);
if ($row[0] != $cur_sect)
{
//Вывод загаловка категории уровня 1
$sect_num++;
$cat_num=0;
$cur_sect=$row[0];
if ($sect_num > 1)
{
}
$aSheet->setCellValueByColumnAndRow(0,$xlpos,$sect_num . ". " . mb_convert_encoding($cur_sect,"UTF-8","CP1251"));
$aSheet->mergeCells('A' . $xlpos . ':' . PHPExcel_Cell::stringFromColumnIndex($n-4). $xlpos);
$aSheet->getStyle('A' . $xlpos . ':' . PHPExcel_Cell::stringFromColumnIndex($n-4). $xlpos)->applyFromArray($categoryStyleArray);
$aSheet->getRowDimension($xlpos)->setRowHeight(25);
$xlpos++;
}
if ($row[1] != $cur_cat && $row[1] != "")
{
//Вывод загаловка категории уровня 2
$cat_num++;
$cur_cat=$row[1];
$aSheet->setCellValueByColumnAndRow(0,$xlpos,$sect_num . "." . $cat_num . ". " . mb_convert_encoding($cur_cat,"UTF-8","CP1251"));
$aSheet->setCellValueByColumnAndRow(1,$xlpos,"грн./т");
//$aSheet->mergeCells('A' . $xlpos . ':' . PHPExcel_Cell::stringFromColumnIndex($n-4). $xlpos);
$aSheet->getStyle('A' . $xlpos . ':' . PHPExcel_Cell::stringFromColumnIndex($n-4). $xlpos)->applyFromArray($subcategoryStyleArray);
$aSheet->getStyle('B' . $xlpos)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
$xlpos++;
}
//Так можно вывести если у вас много столбцов в прайсе
// for ( $j=3; $j<$n; $j++ )
// {
// $aSheet->setCellValueByColumnAndRow($j-3,$xlpos,$row[$j]);
// $aSheet->getStyle(PHPExcel_Cell::stringFromColumnIndex($j-3). $xlpos)->applyFromArray($cellStyleArray);
// }
//у меня столбцов всего 2 поэтому я вывожу так
$aSheet->setCellValueByColumnAndRow(0,$xlpos,mb_convert_encoding($row[3],"UTF-8","CP1251"));
$aSheet->getStyle('A' . $xlpos)->applyFromArray($cellNameStyleArray);
$aSheet->setCellValueByColumnAndRow(1,$xlpos,$row[4]);
$aSheet->getStyle('B' . $xlpos)->applyFromArray($cellPriceStyleArray);
$xlpos++;
}
if ( $m == 0 ) echo "Ничего не можем предложить. Извините";
mysql_close ( $cn );
//устанавливаем ширину
$aSheet->getColumnDimension('A')->setWidth(70);
$aSheet->getColumnDimension('B')->setWidth(20);
//отдаем пользователю в браузер
include("PHPExcel/Writer/Excel5.php"); //тут можно сохранить в Excel2007 - читайте документацию к PHPExcel
$objWriter = new PHPExcel_Writer_Excel5($pExcel);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="ntp-price.xls"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
// Конец листа, отправка обозревателю
?>
там где используется функция mb_convert_encoding, ее можно не использовать, если у вас результаты запроса возвращаются уже в "utf-8", иначе приходится перекодировать как у меня из "CP1251".
4. В нужном месте на сайте выводите ссылку ../public_html/price_xls/price_xls.php
Чтоб сделать ссылку более привычного вида можно внести ее через встроенный в Joomla компонент "Каталог ссылок". Или с помощью sh404SEF создать алиас.
Еще раз повторюсь, так как времени не было, решил не делать это во фреймворке Joomla. Можно на базе этого сделать компонент с более универсальной функциональностью, но это будет уже сложнее, а мне большая функциональность была не нужна.
Так как я не использую фреймворк, то приходится описывать соединение в самом скрипте и где-то прописывать логин и пароль к БД. Тут надо быть осторожным, чтоб его никто не мог прочитать. Или, как сделал я, просто создать отдельную учетную запись для доступа к БД только с привилегиями SELECT и только к этой базе... можно также ограничить доступ на уровне таблиц.
Короче, если есть вопросы, обращайтесь...
P.S. Кстати эта библиотека работает не только с xls, а еще и с кучей других форматов, в т.ч. pdf.