Например
По работе надо было отправлять таблицу по почте в письме и во вложении xls-файл с аналогичной таблицей
Открывается нормально в MS office и сносно в Open Office (опен имеет проблемы с кирилицей, но если данные числовые, то гуд).
Писал по работе, но если кому надо, чтобы не использовать полновесные решения, то используйте.
/**
* Создание xls-документов
* @link http://habrahabr.ru/blogs/php/18726/
* @author Nikitian
*/
class XLS{
var $content='';
var $constructflag=false;
var $table=array();
/**
* Начинает созздавать бинарник xls
*/
function __construct() {
$constructflag=true;
$this->xlsBOF();
}
/**
* Заканчивает создавать бинарник xls и выводит его в браузер для сохранения
*/
function __destruct() {
if(is_array($this->table) && sizeof($this->table)>0 && $this->content!='')
$this->write();
}
/**
* Получить сформированный xls
* @return binary
*/
function get(){
$this->xlsEOF();
return$this->content;
}
/**
* Получение массива данных. Пропущенные ячейки заполняются пустыми строками
* @return array
*/
function getTable(){
$table_=array();
$rows=$cols=0;
foreach($this->table as $krow=>$row){
$rows=$krow;
if(is_array($row) && sizeof($row)>0)
foreach($row as $kcol=>$col)
if($cols<$kcol)
$cols=$kcol;
}
for($row=0;$row<=$krow;$row++)
for($col=0;$col<=$cols;$col++)
$table_[$row][$col]=isset($this->table[$row][$col])?$this->table[$row][$col]:'';
return$table_;
}
/**
* Записать ячейку
* @param int $row Строка от 0
* @param int $col Столбец от 0
* @param mixed $data Данные
* @param enum $type Тип данных. string/int. Можно не указывать - будет определён автоматически
* @return bool
*/
function set($row,$col,$data,$type='auto'){
if(!$this->constructflag){
//PHP4...
$this->xlsBOF();
$this->constructflag=true;
}
$data=iconv('cp1251','cp1251//TRANSLIT',$data);
$this->table[$row][$col]=$data;
switch($type){
case'int':{
return$this->xlsWriteNumber($row,$col,$data);
}
break;
case'string':{
return$this->xlsWriteLabel($row,$col,$data);
}
break;
case'auto':
default:{
if(is_int($data)){
return$this->xlsWriteNumber($row,$col,$data);
}
elseif(is_string($data)){
return$this->xlsWriteLabel($row,$col,$data);
}
else{
return$this->xlsWriteLabel($row,$col,serialize($data));
$this->table[$row][$col]=serialize($data);
}
}
break;
}
}
/**
* Вывести xls для сохранения в браузере
* @param string $filename Имя файла для сохранения.default:file.xls
* @return bool
*/
function write($filename=''){
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=".($filename!=''?$filename:'file.xls'));
header("Content-Transfer-Encoding: binary");
echo $this->get();
return true;
}
/**
* Очистка данных, чтобы деструктор не вывел всё в поток
* @return bool
*/
function clear(){
$this->table=array();
$this->content='';
return true;
}
function xlsBOF() {
$this->content.=pack("ssssss", 0x809, 0x8, 0x0, 0x10, 0x0, 0x0);
return;
}
function xlsEOF() {
$this->content.=pack("ss", 0x0A, 0x00);
return;
}
function xlsWriteNumber($Row, $Col, $Value) {
$this->content.=pack("sssss", 0x203, 14, $Row, $Col, 0x0);
$this->content.=pack("d", $Value);
return;
}
function xlsWriteLabel($Row, $Col, $Value ) {
$L = strlen($Value);
$this->content.=pack("ssssss", 0x204, 8 + $L, $Row, $Col, 0x0, $L);
$this->content.=$Value;
return;
}
}
Пример использования
<?php
/*подключаем этот класс*/
include_once('XLS.class.php');
//Создаём таблицу
$table=new XLS;
//Заполняем случайными значениями
for($i=0;$i<10;$i++){
$table->set(mt_rand(0,100),mt_rand(0,100),mt_rand(0,1000));//Заполняем случайные ячейки случайными данными
}
//Теперь мы можем сделать любое из следующих действий:
// 1) В $arr массив который сформировался в итоге - вдруг где пригодится для рисования html-таблицы или ещё чего
$arr=$table->getTable();
// 2) Сохраняем в файл
file_put_contents('cell.xls',$table->get());
// 3) Выводим в поток как файл для скачивания.
$table->write();
die;
Спустя 2 часа, 8 минут, 6 секунд (17.07.2010 - 21:31) KaFe написал(а):
Nikitian покажи простенький пример использования, пожалуйста.
Спустя 12 минут, 16 секунд (17.07.2010 - 21:43) Nikitian написал(а):
KaFe
Добавил в конец первого поста примеры использования
Добавил в конец первого поста примеры использования
Спустя 56 минут, 6 секунд (17.07.2010 - 22:39) KaFe написал(а):
Nikitian OpenOficce3 не хочет читать ваш файл, просто пустой лист. Что касается красовка офиса то возможности нету.
Спустя 1 час, 36 минут, 21 секунда (18.07.2010 - 00:15) Nikitian написал(а):
На работе именно последним ОО проверял - читалось. Можете выложить то, что у вас генерится и не читается?
Есть предположение, что чистый лист из-за того, что пределы по столбцу-колонке до 100, а на экран влезает меньше, вот и не видно, что что-то заполнилось...
Есть предположение, что чистый лист из-за того, что пределы по столбцу-колонке до 100, а на экран влезает меньше, вот и не видно, что что-то заполнилось...
Спустя 1 час, 8 минут, 19 секунд (18.07.2010 - 01:24) KaFe написал(а):
Ес
Цитата |
ть предположение, что чистый лист из-за того, что пределы по столбцу-колонке до 100, а на экран влезает меньше, вот и не видно, что что-то заполнилось... |
Вы думаете, что я на столько туп.....

Вот например, файл прекрепил
Спустя 57 минут, 57 секунд (18.07.2010 - 02:22) Nikitian написал(а):
Однако что у вас виднеется в ячейке O13?
Спустя 8 часов, 37 минут, 39 секунд (18.07.2010 - 10:59) Michael написал(а):
В Excel проверил. Все ОК. Только небольшой восклицательный знак возле ячеек - "число отформатировано как текст".
Спустя 24 минуты, 39 секунд (18.07.2010 - 11:24) KaFe написал(а):
Nikitian Пусто пусто.
Спустя 41 минута, 25 секунд (18.07.2010 - 12:05) Reflex написал(а):
KaFe
<?php
include_once('XLS.class.php');
$table = new XLS;
for($x = 0; $x < 100; $x++)
for($y = 0; $y < 100; $y++)
$table->set($x, $y, mt_rand(0,1000));
file_put_contents('its_work.xls', $table->get());
Спустя 10 минут, 5 секунд (18.07.2010 - 12:15) Nikitian написал(а):
Цитата (Michael @ 18.07.2010 - 07:59) |
Только небольшой восклицательный знак возле ячеек - "число отформатировано как текст". |
Это потому, что автоматическое распознание типа данных опознало число как число и записало его как число. Если не ошибаюсь, то для рассчётов можно использовать данные, только если они представлены в числовом виде, хотя могу и ошибаться.
Как смогу - скачаю ОО, проверю так ли в нём всё плохо. К сожалению сайт ОО лежит в данный момент

Спустя 18 минут, 5 секунд (18.07.2010 - 12:33) KaFe написал(а):
Reflex ничего не изменилось. Просто наверно OO 3 не хочет распознать этот файл
Спустя 22 часа, 1 минута, 52 секунды (19.07.2010 - 10:35) Nikitian написал(а):
KaFe
Ваш файл действительно не читается ОО3. Во вложении скрипт, сгенерированный файл и скриншот его читаемости в ОО3.
К сожалению не нашёл как выкладывать более 1 файла, поэтому в архиве всё.
Ваш файл действительно не читается ОО3. Во вложении скрипт, сгенерированный файл и скриншот его читаемости в ОО3.
К сожалению не нашёл как выкладывать более 1 файла, поэтому в архиве всё.
Спустя 1 месяц, 22 дня, 5 часов, 43 минуты, 16 секунд (11.09.2010 - 16:19) Michael написал(а):
Спасибо. Уже применил в деле.
Но write в деструкторе мне конечно пришлось поискать, чтобы убрать и заработало как мне надо.
Но write в деструкторе мне конечно пришлось поискать, чтобы убрать и заработало как мне надо.