PHPExcel и авто подбор высоты строки

При работе с библиотекой PHPExcel (для формирования эксэлевских документов "на лету") может возникнуть задача авто определения высоты строки. Другими словами, чтобы большой текст полностью помещался в ячейке с фиксированной шириной, а не урезался до одной строки или выходил за рамки.

Берём библиотеку PHPExcel версии 1.7.9 и начинаем ваять.

Пример "толстой" строки

<?php

require_once 'lib/PHPExcel/PHPExcel.php';

$objPHPExcel = new PHPExcel();

$objPHPExcel->getDefaultStyle()->getFont()->setName("Calibri")->setSize(11);

$row = 1;				// номер испытуемой строки
$col = "A";				// идентификатор испытуемой колонки
$width = 50;			// ширина испытуемой ячейки

// "толстый" текс
$text = "Другими словами, чтобы большой текст полностью помещался в ячейке с фиксированной шириной, а не урезался до одной строки или выходил за рамки.";

$objPHPExcel->setActiveSheetIndex(0);
$ActiveSheet = $objPHPExcel->getActiveSheet();

// задаём текст
$ActiveSheet->setCellValue($col.$row, $text);

// задаём ширину испытуемой ячейке
$ActiveSheet->getColumnDimension($col)->setWidth($width);
			
// отдаём файлом Excel 2007
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=test1.xlsx"); 
header("Content-Transfer-Encoding: binary ");

$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); 
$objWriter->save('php://output');

?>

В итоге получаем

А хотелось бы


Решение для одинарных ячеек.

Загоняется текст в ячейку посредством автоматического подбора высоты строки и установки автоматического разбиения по строчкам текста:

// устанавливаем авто подбор высоты 
$objPHPExcel->getActiveSheet()->getRowDimension($row)->setRowHeight(-1);

// и авто перенос текста
$objPHPExcel->getActiveSheet()->getStyle($col.$row)->getAlignment()->setWrapText(true);

, где $objPHPExcel - объект класса PHPExcel, $row - номер строки, которой необходимо задать авто подбор высоты, $col - идентификатор столбца, например, А или Z.

Получаем в итоге то, что требовалось.


Всегда есть это "НО".

Что если ячейка у нас является объединением нескольких ячеек, а именно объединённых с помощью функции mergeCells()?

Получим следующее

А хотелось бы


Решение для авто подбора высоты строки для объединённых ячеек.

Для этого решения нам необходимо знать общую ширину ячейки, которая была собрана с помощью функции mergeCells. Если предыдущее решение работает только с одинарными ячейками, тогда почему бы нам не создать аналогичную, но уже одинарную ячейку в этой же строке, к примеру, в далёкой-далёкой колонке ZZ и задать ей авто перенос текста и скрыть. Тем самым мы заставим Excel установить высоту для данной строки.

$row = 1;			// номер испытуемой строки
$col1 = "A";			// идентификатор начальной колонки для объединения
$col2 = "B";			// идентификатор конечной колонки для объединения
$far_col = "ZZ";		// идентификатор "далёкой-далёкой" колонки
$width = 50;			// ширина испытуемой ячейки
$default_width = 10;		// ширина ячеек по умолчанию

// "толстый" текст
$text = "Другими словами, чтобы большой текст полностью помещался в ячейке с фиксированной шириной, а не урезался до одной строки или выходил за рамки.";


$ActiveSheet = $objPHPExcel->getActiveSheet();

// задаём текст для дубликата
$ActiveSheet->setCellValue($far_col.$row, $text);

// устанавливаем идентичную ширину дубликату и делаем невидимым
$ActiveSheet->getColumnDimension($far_col)->setWidth($width + $default_width)
					->setVisible(false);

// задаём авто перенос дубликату
$ActiveSheet->getStyle($far_col.$row)->getAlignment()->setWrapText(true);

Получаем в итоге то, что требовалось.



Осуждение статьи :) б

Сергей20.02.2014

А как быть в случае, если надо еще и на печать выводить? Решение «Решение для авто подбора высоты строки для объединённых ячеек.» не подходит,т.к. excel на печать пытается отправить и скрытый столбец.

Васильков Андрей21.02.2014

Действительно, Сергей, это решение не учитывает данный нюанс. Будем искать выход. Может быть у Вас есть какое-то решение, было бы интересно его узнать?

Соколов Михаил11.03.2014

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

естественно случай частны.. но для Arial 10 вполне подходит..
function getheight_t($str, $size_pole, $height_need) {
if (strlen($str)>$size_pole-9) {
$size_h=(((strlen($str))-(strlen($str))%$size_pole)/$size_pole)+1;
} else $size_h=1;
return $size_h*$height_need;
}

Виктор12.03.2014

Есть шаблон (ценник), который занимает несколько строк (например 5 строк), как организовать повтор этого шаблона на лист? Тое-сть мне нужно на лист несколько ценников.
Спасибо.

Васильков Андрей12.03.2014

Виктор, формирование вывода этого ценника вставьте в тело цикла с наращиванием начальной позиции по строкам (если ценники будут располагаться вертикально) или по столбцам (если ценники должны располагаться в ряд).

Соколов Михаил16.03.2014

$start_rows=18;
foreach ($list_item as $item) {
//тело шаблона с использованием $start_rows
$start_rows++;
}

Дмитрий14.10.2014

Забыли написать, для каких версий применимо решение.

Васильков Андрей14.10.2014

Спасибо, Дмитрий, очень верное замечание. Версия библиотеки PHPExcel 1.7.9
Есть вопросы или комментарии?
Как вас зовут?
E-mail (укажите, если хотите чтобы мы ответили на почту)
Комментарий
Введите цифры с картинки:


Ваше имя

Телефон

Удобное время