481 lines
16 KiB
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';
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
?>
|