TCPDF — поворот текста или ячейки в pdf

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Используется система GLPI, в которой установлен плагин Reports и необходимо было в отчете разместить текст вертикально, то есть развернуть на 90 градусов. В HTML это делается легко с помощью стилей

. . .
<td style="transform: rotate(-90deg);">РЕМОНТ</td>
. . .

Но при конвертации в PDF стиль не применяется и в результате мы получим обычный горизонтальный текст.

Модуль TCPDF и применение метода Rotate

С начала формируется отчет в HTML и отображается на экране, после нажатия на кнопку «Экспорт» отчет конвертируется в PDF. Так вот конвертацией в PDF занимается модуль TCPDF, находящийся по следующему пути

\vendor\tecnickcom\tcpdf\

У данного модуля уже заложена возможность разворачивать текст и ячейки, для этого есть метод Rotate

пример использования

$pdf = new GLPIPDF('L', 'mm', 'A4', true, 'UTF-8', false);
. . .
$pdf->StartTransform();
$pdf->Rotate(-90);
$pdf->Cell(0,0,'This is a sample data',1,1,'L',0,''); // ячейка
// или
$pdf->Text(0,0,'This is a sample data'); // текст
$pdf->StopTransform();
. . .
$pdf->Output('glpi.pdf', 'I');

То есть, перед трансформацией используем метод StartTransform и в конце трансформации метод StopTransform

Настройка и применение тегов tcpdf

Все это хорошо, НО у нас есть уже HTML отчет а не отдельная ячейка, и надо имея готовый код HTML с таблицей, в ячейке развернуть текст.

И опять же разработчики это предусмотрели. Надо в код HTML внедрить теги <tcpdf />

$pdf = new GLPIPDF('L', 'mm', 'A4', true, 'UTF-8', false);
$params = $pdf->serializeTCPDFtagParameters(array(90));
. . .
$output .= "<td style=\"transform: rotate(-90deg);\">";
$output .= "<tcpdf method=\"StartTransform\" /><tcpdf method=\"Rotate\" params=\"$params\" />РЕМОНТ<tcpdf method=\"StopTransform\" />";
$output .= "</td>";
. . .
<pre>

Вроде бы все, но этот код не сработает если не активировать в конфиге модуля константу

\vendor\tecnickcom\tcpdf\config\tcpdf_config.php

define('K_TCPDF_CALLS_IN_HTML', true);

Так же проверьте вывод кода HTML, не удаляются ли теги <tcpdf>. Если при выводе отчета они удаляются то надо внести правки в файл класса вывода отчета, в моем случае это

\plugins\reports\inc\detailsreport.class.php


function execute($options=[]){

. . .

$rowMarkup = $this->renderer->render($rowWrapper, $output_type);

$tidy_config = array(
'output-xhtml' => true,
'show-body-only' => true,
'wrap' => 0,
'new-blocklevel-tags' => 'tcpdf',  // -> разрешаю теги
'lower-literals' => 'false' // ->запрещаю перевод в нижний регистр
);
$tidy = tidy_parse_string($rowMarkup, $tidy_config, 'UTF8');
$tidy->cleanRepair();
$rowMarkup = (string) $tidy;

. . .

}

Ошибки которые еще могут возникнуть

А теперь самое интересное, если вы при генерации отчета создадите класс и определите параметр

$pdf = new GLPIPDF('L', 'mm', 'A4', true, 'UTF-8', false);
$params = $pdf->serializeTCPDFtagParameters(array(90));

то при экспорте в PDF пойдет ошибка

Invalid parameters

и все из-за того что в модуле TCPDF при сериализации параметра используется $this->file_id

protected function getHashForTCPDFtagParams($data) {
  return md5(strlen($data).$this->file_id.$data);
}
public function serializeTCPDFtagParameters($data) {
  $encoded = urlencode(json_encode($data));
  return $this->getHashForTCPDFtagParams($encoded).$encoded;
}

protected function unserializeTCPDFtagParameters($data) {		
  $hash = substr($data, 0, 32);
  $encoded = substr($data, 32);
  if ($hash != $this->getHashForTCPDFtagParams($encoded)) {
    $this->Error('Invalid parameters');
  }
  return json_decode(urldecode($encoded), true);
}

Тоесть вы создали класс $pdf в отчете со своим file_id и потом при экспорте создается опять же класс $pdf (в файле \inc\search.class.php метод showFooter() ) но уже с другим file_id который используется при извлечении параметра unserializeTCPDFtagParameters, и конечно же выдаст ошибку. Тут уже, как вариант, в методе showFooter(), после создания класса $pdf, значение переменной file_id заменить значением переданным с отчета, тогда проверка пройдет удачно, или же заранее определить её значение в классе.

 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *