Files
aportil/themes/codebase4.0/grid-pdf-php/gridPdfWrapper.php

481 lines
16 KiB
PHP

<?php
class TCPDFExt extends TCPDF {
public function Footer() {
$cur_y = $this->GetY();
$ormargins = $this->getOriginalMargins();
$this->SetTextColor(0, 0, 0);
//set style for cell border
$line_width = 0.85 / $this->getScaleFactor();
$this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 1, 'color' => array(0, 0, 0)));
//print document barcode
$barcode = $this->getBarcode();
if (!empty($barcode)) {
$this->Ln($line_width);
$barcode_width = round(($this->getPageWidth() - $ormargins['left'] - $ormargins['right'])/3);
$this->write1DBarcode($barcode, 'C128B', $this->GetX(), $cur_y + $line_width, $barcode_width, (($this->getFooterMargin() / 3) - $line_width), 0.3, '', '');
}
if (empty($this->pagegroups)) {
$pagenumtxt = $this->l['w_page'].' '.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
} else {
$pagenumtxt = $this->l['w_page'].' '.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
}
$this->SetY($cur_y);
//Print page number
if ($this->getRTL()) {
$this->SetX($ormargins['right']);
$this->Cell(0, 0, $pagenumtxt, 0, 0, 'L');
} else {
$this->SetX($ormargins['left']);
$this->Cell(0, 0, $pagenumtxt, 0, 0, 'R');
}
}
}
class gridPdfWrapper {
private $imgsPath = './imgs/';
private $noPages = false;
private $currentRow = 0;
private $pageWidth;
private $pageHeight;
private $offsetTop;
private $offsetBottom;
private $offsetLeft;
private $offsetRight;
private $cb;
private $rows;
private $columns;
private $rowsNum;
private $headerHeight;
private $summaryWidth;
private $rowHeader;
private $gridHeight;
private $orientation;
private $headerFontSize;
private $pageFontSize;
private $gridFontSize;
private $bgColor;
private $lineColor;
private $headerTextColor;
private $scaleOneColor;
private $scaleTwoColor;
private $gridTextColor;
private $pageTextColor;
private $profile;
private $dpi;
public function gridPdfWrapper($offsetTop, $offsetRight, $offsetBottom, $offsetLeft, $orientation='P', $fontSize = 8, $dpi = 72, $lang) {
// pdf-component initialization
$this->cb = new TCPDFExt($orientation, 'mm', 'A4', true, 'UTF-8', false);
$this->orientation = $orientation;
// sets minimal offsets
$this->minOffsetTop = $offsetTop;
$this->minOffsetRight = $offsetRight;
$this->minOffsetBottom = $offsetBottom;
$this->minOffsetLeft = $offsetLeft;
// sets offsets
$this->offsetTop = $offsetTop;
$this->offsetRight = $offsetRight;
$this->offsetBottom = $offsetBottom;
$this->offsetLeft = $offsetLeft;
$this->fontSize = $fontSize;
$this->dpi = $dpi;
// calculation page height and width
$this->pageWidth = $this->cb->getPageWidth() - $this->offsetLeft - $this->offsetRight;
$this->pageHeight = $this->cb->getPageHeight() - $this->offsetTop - $this->offsetBottom;
// sets header and footer
$this->cb->setPrintHeader(false);
$this->cb->setPrintFooter(true);
$this->cb->SetMargins($this->offsetLeft, $this->offsetTop, $this->offsetRight);
$this->cb->SetAutoPageBreak(FALSE, $this->offsetBottom);
$this->cb->SetFooterMargin($this->offsetBottom);
$this->cb->setLanguageArray($lang);
// sets output PDF information
$this->cb->SetCreator('DHTMLX LTD');
$this->cb->SetAuthor('DHTMLX LTD');
$this->cb->SetTitle('dhtmlxGrid');
$this->cb->SetSubject('DHTMLX LTD');
$this->cb->SetKeywords('');
// sets font family and size
$this->cb->SetFont('freesans', '', $this->fontSize);
}
// draws grid header
public function headerDraw($headerHeight, $columns, $summaryWidth, $headerTextColor, $bgColor, $lineColor) {
$this->columns = $columns;
$this->bgColor = $this->convertColor($bgColor);
$this->lineColor = $this->convertColor($lineColor);
$this->headerTextColor = $this->convertColor($headerTextColor);
$this->summaryWidth = $summaryWidth;
$this->lineStyle = Array('width' => 0.1, 'cap' => 'round', 'join' => 'round', 'dash' => '0', 'color' => $this->lineColor);
$this->cb->SetLineStyle($this->lineStyle);
$this->cb->SetFillColor($this->bgColor['R'], $this->bgColor['G'], $this->bgColor['B']);
$this->cb->SetTextColor($this->headerTextColor['R'], $this->headerTextColor['G'], $this->headerTextColor['B']);
$this->cb->setX($this->offsetLeft);
$this->cb->setY($this->offsetTop, false);
// circle for every header row
for ($i = 0; $i < count($columns); $i++) {
// circle for every header cell in row
for ($j = 0; $j < count($columns[$i]) - 1; $j++) {
// check if cell is not part of colspan cell
if ($columns[$i][$j]['width'] != 0) {
// check if cell is not part of rowspan cell
if (((isset($columns[$i][$j]['rowspanPos']))&&($columns[$i][$j]['rowspanPos'] == 'top'))||(!isset($columns[$i][$j]['rowspanPos']))) {
// calculation width of cell
$width = $this->pageWidth*$columns[$i][$j]['width']/$columns[0]['width'];
// calculation height: if cell hasn't rowspan its height = rowHeight, else its height = rowspan*rowHeight;
if ($columns[$i][$j]['rowspan'] != '') {
$height = $columns[$i][$j]['rowspan']*$headerHeight;
} else {
$height = $headerHeight;
}
// draws header cell
$this->cb->Cell($width, $height, $columns[$i][$j]['text'], 1, 0, 'C', 1);
} else {
// add width of cell that is part of cell with rowspan
$width = $this->pageWidth*$columns[$i][$j]['width']/$columns[0]['width'];
$this->cb->setX($this->cb->getX() + $width);
}
}
}
// sets new row
$this->cb->setY($this->cb->getY() + $headerHeight);
}
}
// draws grid footer
public function footerDraw($footerHeight, $columns) {
$this->footerColumns = $columns;
$this->footerHeight = $footerHeight;
}
private function footerDrawAfterRows() {
// saving pointer position
$this->lineStyle = Array('width' => 0.1, 'cap' => 'round', 'join' => 'round', 'dash' => '0', 'color' => $this->lineColor);
$this->cb->SetLineStyle($this->lineStyle);
$this->cb->SetFillColor($this->bgColor['R'], $this->bgColor['G'], $this->bgColor['B']);
$yPos = $this->cb->getPageHeight() - $this->offsetBottom - $this->footerHeight*count($this->footerColumns);
if ($this->footerColumns) {
for ($i = 0; $i < count($this->footerColumns); $i++) {
for ($j = 0; $j < count($this->footerColumns[$i]) - 1; $j++) {
if (((isset($this->footerColumns[$i][$j]['rowspanPos']))&&($this->footerColumns[$i][$j]['rowspanPos'] == 'top'))||(!isset($this->footerColumns[$i][$j]['rowspanPos']))) {
// calculation width of cell
$width = $this->pageWidth*$this->footerColumns[$i][$j]['width']/$this->footerColumns[0]['width'];
// calculation height: if cell hasn't rowspan its height = rowHeight, else its height = rowspan*rowHeight;
if ($this->footerColumns[$i][$j]['rowspan'] != '') {
$height = $this->footerColumns[$i][$j]['rowspan']*$this->footerHeight;
} else {
$height = $this->footerHeight;
}
if ($width > 0) {
// draws footer cell
$this->cb->Cell($width, $height, $this->footerColumns[$i][$j]['text'], 1, 0, 'C', 1);
}
} else {
// add width of cell that is part of cell with rowspan
$width = $this->pageWidth*$this->footerColumns[$i][$j]['width']/$this->footerColumns[0]['width'];
$this->cb->setX($this->cb->getX() + $width);
}
}
$this->cb->setY($this->cb->getY() + $this->footerHeight);
}
}
}
// draws grid values
public function gridDraw($rowHeight, $rows, $widths, $startRow, $rowsNum, $scaleOneColor, $scaleTwoColor, $profile) {
$this->rows = $rows;
$this->rowHeight = $rowHeight;
$this->scaleOneColor = $this->convertColor($scaleOneColor);
$this->scaleTwoColor = $this->convertColor($scaleTwoColor);
$this->profile = $profile;
$this->widths = $widths;
// calculate the last row for using in circle
if ($startRow + $rowsNum > count($rows)) {
$limit = count($rows);
} else {
$limit = $startRow + $rowsNum;
}
$printedRowsHeight = 0;
$printedRowsNum = 0;
$last = '0';
$limitY = $this->cb->getPageHeight() - $this->offsetBottom - count($this->footerColumns)*$this->footerHeight;
while (($this->currentRow < count($this->rows))&&($this->cb->getY() + $this->getMaxRowHeight($this->currentRow) <= $limitY)) {
$height = $this->getMaxRowHeight($this->currentRow);
// circle for drawing cells
for ($j = 0; $j < count($this->rows[$this->currentRow]); $j++) {
// to start next cell from new line or not
if ($j == count($rows[$this->currentRow]) - 1) {
$newLn = 1;
} else {
$newLn = 0;
}
// calculation positions and sizes for cell
$width = $this->pageWidth*$this->widths[$j]/$this->summaryWidth;
$xImg = $this->cb->getX();
$yImg = $this->cb->getY();
$value = $this->rows[$this->currentRow][$j]['text'];
if (($this->columns[0][$j]['type'] == 'ch')||($this->columns[0][$j]['type'] == 'ra')||($this->columns[0][$j]['type'] == 'img'))
$value = '';
$bg = $this->convertColor($this->rows[$this->currentRow][$j]['bg']);
$this->cb->SetFillColor($bg['R'], $bg['G'], $bg['B']);
$text = $this->convertColor($this->rows[$this->currentRow][$j]['textColor']);
$this->cb->SetTextColor($text['R'], $text['G'], $text['B']);
$bold = ($this->rows[$this->currentRow][$j]['bold']) ? 'b' : '';
$italic = ($this->rows[$this->currentRow][$j]['italic']) ? 'i' : '';
$this->cb->SetFont('freesans'.$bold.$italic, '', $this->fontSize);
$align = $this->rows[$this->currentRow][$j]['align'];
if ($align == false)
$align = (isset($this->columns[0][$j]['align'])) ? $this->columns[0][$j]['align'] : 'center';
switch ($align) {
case 'left':
$align = 'L';
break;
case 'right':
$align = 'R';
break;
case 'center':
default:
$align = 'C';
break;
}
// draws cell
$this->cb->MultiCell($width, $height, $value, 1, $align, 1, $newLn, '', '', true, 0);
$x = $this->cb->getX();
$y = $this->cb->getY();
// draws image if cell type is checkbox or radio-button
if (($this->columns[0][$j]['type'] == 'ch')||($this->columns[0][$j]['type'] == 'ra')) {
$xImg += $width/2 - 1.5;
$yImg += 1.7;
$img = $this->getImg($this->columns[0][$j]['type'], $this->rows[$this->currentRow][$j]['text'], $this->profile);
$this->cb->Image($img, $xImg, $yImg, 3, 3, 'PNG', '', 'M', false, 96, 'L', false, false, 0, false, false);
// sets next cell position
$this->cb->setX($x);
$this->cb->setY($y, false);
}
// draws image if type of cell is 'img'
if (($this->columns[0][$j]['type'] == 'img')&&((strpos($this->rows[$this->currentRow][$j]['text'], 'http://') === 0)||(file_exists($this->rows[$this->currentRow][$j]['text'])))) {
$imgSize = getimagesize($this->rows[$this->currentRow][$j]['text']);
$widthImg = $imgSize[0]/$this->dpi*25.4;
$heightImg = $imgSize[1]/$this->dpi*25.4;
switch ($align) {
case 'C':
$xImg += ($width - $widthImg)/2;
break;
case 'R':
$xImg += ($width - $widthImg - 0.5);
break;
case 'L':
$xImg += 0.5;
break;
}
$this->cb->Image($this->rows[$this->currentRow][$j]['text'], $xImg, $yImg + 0.5, $widthImg, $heightImg, '', '', 'M', false, $this->dpi, 'L', false, false, 0, false, false);
$this->cb->setX($x);
$this->cb->setY($y, false);
}
}
$printedRowsHeight += $height;
$printedRowsNum++;
$this->currentRow++;
}
$this->footerDrawAfterRows();
return $printedRowsNum;
}
// calculates the maximum height of cell in row
private function getMaxRowHeight($num) {
// the min height is value setted by user
$heightMax = $this->rowHeight;
// circle for every row cell
for ($j = 0; $j < count($this->rows[$num]); $j++) {
// calculation width of cell
$width = $this->pageWidth*$this->widths[$j]/$this->summaryWidth;
// selecting type of data: img or other
if ($this->columns[0][$j]['type'] == 'img') {
// if file exists
if ((strpos($this->rows[$this->currentRow][$j]['text'], 'http://') === 0)||(file_exists($this->rows[$this->currentRow][$j]['text']))) {
$imgSize = getimagesize($this->rows[$num][$j]['text']);
// calculation image size in mm
$height = $imgSize[1]/$this->dpi*25.4;
} else {
// else height will setted as height of row setted by user
$height = $this->rowHeight;
}
} else {
// else gets number of line, that is nedd for printing text with some width
$linesNum = $this->cb->getNumLines($this->rows[$num][$j]['text'],$width);
// calculation cell height
$height = $linesNum*$this->cb->getFontSize() + $this->cb->getFontSize()*0.5*($linesNum + 1);
}
// condition for saving max height
if ($height > $heightMax) {
$heightMax = $height;
}
}
return $heightMax + 1;
}
// sets offsets
public function setPageSize($offsetTop, $offsetRight, $offsetBottom, $offsetLeft) {
$this->offsetTop = $offsetTop + $this->minOffsetTop;
$this->offsetLeft = $offsetLeft;
$this->offsetBottom = $offsetBottom + $this->minOffsetBottom;
$this->offsetRight = $offsetRight;
$this->pageWidth = $this->cb->getPageWidth() - $this->offsetLeft - $this->offsetRight;
$this->pageHeight = $this->cb->getPageHeight() - $this->offsetBottom;
$this->cb->SetMargins($this->offsetLeft, $this->offsetTop, $this->offsetRight);
$this->cb->SetFooterMargin($this->offsetBottom);
}
// outputs PDF in browser
public function pdfOut() {
$this->cb->setFooterMargin($this->minOffsetBottom);
// send PDF-file in browser
$this->cb->Output('grid.pdf', 'I');
}
// forms image name for chackbox or radio-button values
public function getImg($type, $value, $profile) {
$img = '';
if ($type == 'ch') {
$img .= 'Ch';
} else {
$img .= 'Ra';
}
if ($value == '1') {
$img .= 'On';
} else {
$img .= 'Off';
}
if ($profile == 'color') {
$img .= 'Color';
} elseif ($profile == 'gray') {
$img .= 'Gray';
} else {
$img .= 'Bw';
}
$img = $this->imgsPath.$img.'.png';
return $img;
}
// draws header image
public function drawImgHeader($filename) {
$y = $this->minOffsetTop;
$headerWidth = $this->cb->getPageWidth() - $this->offsetLeft - $this->offsetRight;
$headerHeight = $this->offsetTop - $this->minOffsetTop;
$x = $this->offsetLeft;
$this->cb->Image($filename, $x, $y, $headerWidth, $headerHeight, 'PNG', '', 'M', false, 96, 'L', false, false, 0, false, false);
}
// draws footer image
public function drawImgFooter($filename, $footerImgHeight) {
$footerWidth = $this->cb->getPageWidth() - $this->offsetLeft - $this->offsetRight;
$footerHeight = $this->offsetBottom - $this->minOffsetBottom;
$footerHeight = $footerImgHeight;
$x = $this->offsetLeft;
$y = $this->cb->getPageHeight() - $footerHeight - $this->minOffsetBottom;
$this->cb->Image($filename, $x, $y, $footerWidth, $footerHeight, 'PNG', '', 'M', false, 96, 'L', false, false, 0, false, false);
}
// returns absolute page height in mm
public function getPageHeight() {
return $this->cb->getPageHeight();
}
// creates new page
public function addPage() {
$this->cb->setFooterMargin($this->minOffsetBottom);
$this->cb->AddPage();
}
public function setNoPages() {
// echo 'no pages';
$this->cb->setPrintFooter(false);
}
// converts color from "ffffff" to Array('R' => 255, 'G' => 255, 'B' => 255)
private function convertColor($colorHex) {
$colorHex = strtoupper($this->processColorForm($colorHex));
$final = Array();
$final['R'] = hexdec(substr($colorHex, 0, 2));
$final['G'] = hexdec(substr($colorHex, 2, 2));
$final['B'] = hexdec(substr($colorHex, 4, 2));
return $final;
}
private function processColorForm($color) {
if ($color == 'transparent') {
return $color;
}
if (preg_match("/#[0-9A-Fa-f]{6}/", $color)) {
return substr($color, 1);
}
if (preg_match("/[0-9A-Fa-f]{6}/", $color)) {
return $color;
}
$color = trim($color);
$result = preg_match_all("/rgb\s?\(\s?(\d{1,3})\s?,\s?(\d{1,3})\s?,\s?(\d{1,3})\s?\)/", $color, $rgb);
if ($result) {
$color = '';
for ($i = 1; $i <= 3; $i++) {
$comp = dechex($rgb[$i][0]);
if (strlen($comp) == 1) {
$comp = '0'.$comp;
}
$color .= $comp;
}
return $color;
} else {
return 'transparent';
}
}
}
?>