[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Генерация простых xls-таблиц
Nikitian
Класс сделан как обёртка к отсюда. Плюсом добавилось получение данных в виде двумерного массива для использования где-либо.
Например
По работе надо было отправлять таблицу по почте в письме и во вложении 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, а на экран влезает меньше, вот и не видно, что что-то заполнилось...

Спустя 1 час, 8 минут, 19 секунд (18.07.2010 - 01:24) KaFe написал(а):
Ес
Цитата
ть предположение, что чистый лист из-за того, что пределы по столбцу-колонке до 100, а на экран влезает меньше, вот и не видно, что что-то заполнилось...

Вы думаете, что я на столько туп..... wink.gif

Вот например, файл прекрепил

Спустя 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)
Только небольшой восклицательный знак возле ячеек - "число отформатировано как текст".

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

Как смогу - скачаю ОО, проверю так ли в нём всё плохо. К сожалению сайт ОО лежит в данный момент sad.gif А на работе свежий кальк отображал кроме кирилицы всё, но раз есть замечания буду искать проблему.

Спустя 18 минут, 5 секунд (18.07.2010 - 12:33) KaFe написал(а):
Reflex ничего не изменилось. Просто наверно OO 3 не хочет распознать этот файл

Спустя 22 часа, 1 минута, 52 секунды (19.07.2010 - 10:35) Nikitian написал(а):
KaFe
Ваш файл действительно не читается ОО3. Во вложении скрипт, сгенерированный файл и скриншот его читаемости в ОО3.

К сожалению не нашёл как выкладывать более 1 файла, поэтому в архиве всё.

Спустя 1 месяц, 22 дня, 5 часов, 43 минуты, 16 секунд (11.09.2010 - 16:19) Michael написал(а):
Спасибо. Уже применил в деле.
Но write в деструкторе мне конечно пришлось поискать, чтобы убрать и заработало как мне надо.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.