2010-07-18

Jak zrobić CV w PDF - Zend_Pdf Tutorial

Outline

Netizen Labs W życiu każdego Developera przychodzi moment, kiedy trzeba generować PDF-y. W takich chwilach pomocnym jest Zend PDF. Poniżej obszerny przykład.

Kod

class PdfController extends Zend_Controller_Action {

	public function indexAction() {

            //inicjuję dokument
            $pdf = new Zend_Pdf();

            //kolory
            $color1 = new Zend_Pdf_Color_Html('#111111');
            $color2 = new Zend_Pdf_Color_Html('#666666');
            $color_link = new Zend_Pdf_Color_Html('#0000ff');

            //tworzę stronę
            $pdfPage = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);


            //nagłówek
            $pdfPage->setFillColor($color1); //ustawiam kolor
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arialbd.ttf') , 24); //ustawiam "zagnieżdżoną" czcionkę
            $this->_drawText( $pdfPage, 'Mariusz Adam Górski - RESUME', 100, 60 ); //piszę

            $this->_drawImage( $pdfPage , '/smokunet_res/mariusz.png' , 1380 , 1797 , 50 , 65 , 0.1 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 15);
            $this->_drawText( $pdfPage, 'Programmer / Web Developer / Web Producer', 200, 120 );

            $pdfPage->setFillColor($color2);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/ariali.ttf') , 10);
            $this->_drawText( $pdfPage, 'Ponad 12 lat tworzenia serwisów internetowych.', 225, 170-14 );
            $this->_drawText( $pdfPage, 'Ponad 12 lat ciągłego podnoszenia umiejętności,', 225, 185-14 );
            $this->_drawText( $pdfPage, 'innowacyjności, pasji i satysfakcji z tworzenia', 225, 200-14 );
            $this->_drawText( $pdfPage, 'rzeczy które często zmieniają życie innych.', 225, 215-14 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/webdings.ttf') , 17);
            $this->_drawText( $pdfPage, $this->_unichr(245), 225, 231 ); //wstawiam znaczek

            $pdfPage->setFillColor($color_link);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 8);
            $this->_drawText( $pdfPage, 'magorski@gmail.com', 245, 230 );
            $this->_attachLink(
                $pdfPage, 244, 221, 80, 12,
                'mailto:magorski@gmail.com'
            ); //wstawiam link

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/webdings.ttf') , 17);
            $this->_drawText( $pdfPage, $this->_unichr(187), 345, 231 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 8);
            $this->_drawText( $pdfPage, '+48 695931773', 365, 230 );

            $pdfPage->setLineColor(Zend_Pdf_Color_Html::color('#cccccc'));
            $pdfPage->setLineWidth(1);
            $this->_drawLine( $pdfPage, 40, 255, $pdfPage->getWidth()-40, 255 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 15);
            $this->_drawText( $pdfPage, 'Umiejętności', 40, 280 );
            $pdfPage->setFillColor($color2);
            $this->_drawText( $pdfPage, '[ w skrócie ]', 140, 280 );


            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $this->_drawText( $pdfPage, 'PROGRAMOWANIE', 50, 320 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $this->_drawText( $pdfPage, 'PHP, SQL, JavaScript, AJAX,', 50, 340 );
            $this->_drawText( $pdfPage, 'HTML, XHTML, DHTML, CSS,', 50, 355 );
            $this->_drawText( $pdfPage, 'XML, PASCAL, Linux BASH', 50, 370 );
            $this->_drawText( $pdfPage, 'UML, OOP', 50, 385 );

            $this->_drawLine( $pdfPage, 204, 312, 204, 415 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $this->_drawText( $pdfPage, 'NARZĘDZIA',220, 320 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $this->_drawText( $pdfPage, 'Zend Framework, Smarty,', 220, 340 );
            $this->_drawText( $pdfPage, 'jQuery, Prototype,', 220, 355 );
            $this->_drawText( $pdfPage, 'script.aculo.us, YUI, Typo3,', 220, 370 );
            $this->_drawText( $pdfPage, 'MySQL, Firebird/InterBase,', 220, 385 );
            $this->_drawText( $pdfPage, 'PostgreSQL, Linux, Memcache,', 220, 400 );
            $this->_drawText( $pdfPage, 'UML, SVN, CVS', 220, 415 );

            $this->_drawLine( $pdfPage, 374, 312, 374, 415 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $this->_drawText( $pdfPage, 'POZOSTAŁE', 390, 320 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $this->_drawText( $pdfPage, 'Facebook API ( Graph API,', 390, 340 );
            $this->_drawText( $pdfPage, 'JavaScript SDK, PHP SDK, FQL,', 390, 355 );
            $this->_drawText( $pdfPage, 'FBML ), Twitter API, GaduGadu API,', 390, 370 );
            $this->_drawText( $pdfPage, 'Cloud Computing, WebServices,', 390, 385 );
            $this->_drawText( $pdfPage, 'SEO, SEM, Google Maps,', 390, 400 );
            $this->_drawText( $pdfPage, 'Yahoo Maps, i wiele innych...', 390, 415 );

            $this->_drawLine( $pdfPage, 40, 430, $pdfPage->getWidth()-40, 430 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 15);
            $this->_drawText( $pdfPage, 'Doświadczenie', 40, 455 );
            $pdfPage->setFillColor($color2);
            $this->_drawText( $pdfPage, '[ to najistotniejsze ]', 155, 455 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 12);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'Senior Programmer', 50, 495 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 10);
            $this->_drawText( $pdfPage, 'Netizens, Katowice', 50, 515 );
            $pdfPage->setFillColor($color_link);
            $this->_drawText( $pdfPage, 'www.netizens.pl', 50, 530 );
            $this->_attachLink(
                $pdfPage, 49, 521, 75, 12,
                'http://www.netizens.pl'
            );
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'od 2007-11 do teraz', 50, 545 );
            $this->_drawText( $pdfPage, '( dotychczas '.$this->_yearMonthDifference('2007-11-01',date('Y-m-d')).' )', 50, 560 );

            $this->_drawImage( $pdfPage , '/smokunet_res/netizens_logo_big.png' , 3217 , 618 , 200 , 495 , 0.05 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $this->_drawText( $pdfPage, 'Projektowanie i tworzenie serwisów', 390, 495 );
            $this->_drawText( $pdfPage, 'internetowych oraz ich integrowanie', 390, 505+2 );
            $this->_drawText( $pdfPage, 'z wszelakimi API i usługami.', 390, 515+4 );
            $this->_drawText( $pdfPage, 'Projektowanie baz danych.', 390, 525+6 );
            $this->_drawText( $pdfPage, 'Programowanie głównie w PHP', 390, 535+8 );
            $this->_drawText( $pdfPage, '(Zend Framework) oraz JavaScript', 390, 545+10 );
            $this->_drawText( $pdfPage, '( jQuery , Prototype ).', 390, 555+12 );


            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 12);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'PHP Programmer', 50, 600 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 10);
            $this->_drawText( $pdfPage, 'MaDoNet, Katowice', 50, 620 );
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'od 2006-01 do 2007-10', 50, 635 );
            $this->_drawText( $pdfPage, '( '.$this->_yearMonthDifference('2006-01-01','2007-10-31').' )', 50, 650 );

            $this->_drawImage( $pdfPage , '/smokunet_res/madonet_logo.png' , 154 , 27 , 200 , 600 , 1 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $this->_drawText( $pdfPage, 'Tworzenie serwisów internetowych.', 390, 600 );
            $this->_drawText( $pdfPage, 'Projektowanie baz danych.', 390, 610+2 );
            $this->_drawText( $pdfPage, 'Programowanie w PHP, (My)SQL,', 390, 620+4 );
            $this->_drawText( $pdfPage, '(X)HTML, CSS, JavaScript.', 390, 630+6 );


            $this->_drawLine( $pdfPage, 40, $pdfPage->getHeight()-100, $pdfPage->getWidth()-40, $pdfPage->getHeight()-100 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/ariali.ttf') , 7);
            $pdfPage->setFillColor($color2);
            $this->_drawText( $pdfPage, 'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych w mojej ofercie pracy dla potrzeb niezbędnych do realizacji procesu rekrutacji', 55, $pdfPage->getHeight()-50-40 );
            $this->_drawText( $pdfPage, '(zgodnie z Ustawą z dnia 29.08.1997 roku o Ochronie Danych Osobowych; tekst jednolity: Dz. U. z 2002r. Nr 101, poz. 926 ze zm.).', 80, $pdfPage->getHeight()-40-40 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/ariali.ttf') , 12);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'Strona 1 z 2', 250, $pdfPage->getHeight()-40 );

            $pdf->pages[] = $pdfPage;

            //tworzę drugą stronę
            $pdfPage = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);

            $pdfPage->setLineColor(Zend_Pdf_Color_Html::color('#cccccc'));
            $pdfPage->setLineWidth(1);
            $this->_drawLine( $pdfPage, 40, 40, $pdfPage->getWidth()-40, 40 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 15);
            $this->_drawText( $pdfPage, 'Inne informacje', 40, 65 );
            $pdfPage->setFillColor($color2);
            $this->_drawText( $pdfPage, '[ nie wszystkie są istotne ;) ]', 150, 65 );

            $pdfPage->setFillColor($color1);
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);

            $this->_drawText( $pdfPage, 'uczestniczyłem w produkcji około 100 serwisów internetowych', 50, 100 );

            $this->_drawText( $pdfPage, 'stworzyłem i od ponad '. $this->_yearMonthDifference('2003-10-01',date('Y-m-d'),false) .' administruję nieoficjalnym serwisem internetowym studentów', 50, 130 );
            $this->_drawText( $pdfPage, 'Górnośląskiej Wyższej Szkoły Handlowej', 50, 145 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $pdfPage->setFillColor($color_link);
            $this->_drawText( $pdfPage, 'http://gwsh.one.pl/', 260, 145 );
            $this->_attachLink(
                $pdfPage, 258, 136, 79, 12,
                'http://gwsh.one.pl/'
            );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $pdfPage->setFillColor($color1);

            $this->_drawText( $pdfPage, '11 lat administrowałem lokalną siecią komputerową (45 komputerów)', 50, 175 );

            $this->_drawText( $pdfPage, 'napisałem kiedys w BASH-u (Linux) i Pascalu system statystyk dla routera internetowego', 50, 205 );

            $this->_drawText( $pdfPage, 'mimo, że tworzę serwisy internetowe od 1999 roku to pierwsze udokumentowane ślady mojej', 50, 235 );
            $this->_drawText( $pdfPage, 'internetowej działalności pochodzą z początku 2003 roku:', 50, 250 );
            $this->_drawText( $pdfPage, 'mlask.one.pl z 21.02.2003 -', 55, 265 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $pdfPage->setFillColor($color_link);
            $this->_drawText( $pdfPage, 'http://web.archive.org/web/20030221145630/http://mlask.one.pl/', 200, 265 );
            $this->_attachLink(
                $pdfPage, 198, 256, 263, 12,
                'http://web.archive.org/web/20030221145630/http://mlask.one.pl/'
            );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'legendy.one.pl z 13.07.2003 -', 55, 280 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $pdfPage->setFillColor($color_link);
            $this->_drawText( $pdfPage, 'http://web.archive.org/web/20030713175647/http://legendy.one.pl/', 210, 280 );
            $this->_attachLink(
                $pdfPage, 208, 271, 269, 12,
                'http://web.archive.org/web/20030713175647/http://legendy.one.pl/'
            );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'fotografie.one.pl z 24.07.2003 -', 55, 295 );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 9);
            $pdfPage->setFillColor($color_link);
            $this->_drawText( $pdfPage, 'http://web.archive.org/web/20030724133127/http://fotografie.one.pl/', 220, 295 );
            $this->_attachLink(
                $pdfPage, 218, 286, 276, 12,
                'http://web.archive.org/web/20030724133127/http://fotografie.one.pl/'
            );
            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/arial.ttf') , 11);
            $pdfPage->setFillColor($color1);

            $this->_drawText( $pdfPage, 'mam prawo jazdy', 50, 325 );

            $this->_drawText( $pdfPage, 'rozmawiam, czytam i piszę po angielsku', 50, 355 );

            $this->_drawText( $pdfPage, 'uwielbiam guinness-a !!!', 50, 385 );


            $this->_drawLine( $pdfPage, 40, $pdfPage->getHeight()-100, $pdfPage->getWidth()-40, $pdfPage->getHeight()-100 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/ariali.ttf') , 7);
            $pdfPage->setFillColor($color2);
            $this->_drawText( $pdfPage, 'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych w mojej ofercie pracy dla potrzeb niezbędnych do realizacji procesu rekrutacji', 55, $pdfPage->getHeight()-50-40 );
            $this->_drawText( $pdfPage, '(zgodnie z Ustawą z dnia 29.08.1997 roku o Ochronie Danych Osobowych; tekst jednolity: Dz. U. z 2002r. Nr 101, poz. 926 ze zm.).', 80, $pdfPage->getHeight()-40-40 );

            $pdfPage->setFont( Zend_Pdf_Font::fontWithPath('/library/fonts/ariali.ttf') , 12);
            $pdfPage->setFillColor($color1);
            $this->_drawText( $pdfPage, 'Strona 2 z 2', 250, $pdfPage->getHeight()-40 );

            $pdf->pages[] = $pdfPage;

            //metadane dokumentu
            $pdf->properties['Title'] = 'Mariusz Adam Górski - RESUME';
            $pdf->properties['Author'] = 'Mariusz Adam Górski ';
            $pdf->properties['Subject'] = 'Ponad ' . $this->_yearMonthDifference('1998-05-01',date('Y-m-d'),false). ' tworzenia serwisów internetowych. Ponad ' . $this->_yearMonthDifference('1998-05-01',date('Y-m-d'),false) . ' ciągłego podnoszenia umiejętności, innowacyjności, pasji i satysfakcji z tworzenia rzeczy które często zmieniają życie innych.';
            $pdf->properties['Keywords'] = 'PHP, SQL, JavaScript, AJAX, HTML, XHTML, DHTML, CSS, XML, PASCAL, Linux BASH, UML, OOP, Zend Framework, Smarty,  jQuery, Prototype, script.aculo.us, YUI, Typo3, MySQL, Firebird/InterBase, PostgreSQL, Linux, Memcache, UML, SVN, CVS, Facebook API ( Graph API, JavaScript SDK , PHP SDK , FQL , FBML ), Twitter API, GaduGadu API, Cloud Computing , WebServices , SEO, SEM , Google Maps, Yahoo Maps';
            $pdf->properties['Creator'] = 'http://smoku.net/';
            $pdf->properties['Producer'] = 'http://smoku.net/pdf';
            $pdf->properties['CreationDate'] = date("D:YYYYMMDDHHmmSSOHH'mm'",mktime(10,50,00,7,1,2010));
            $pdf->properties['ModDate'] = date("D:YYYYMMDDHHmmSSOHH'mm'",mktime(10,50,00,7,1,2010));
            $pdf->properties['Trapped'] = TRUE;

            //wysyłam całość do użytkownika
            header('Content-type: application/pdf');
            header('Content-Disposition: attachment; filename="mariusz-adam-gorski_resume_pl.pdf"');
            die($pdf->render());
	}

        /**
         * Zwraca znak zakodowany w utf-8
         *
         * @param integer $u
         * @return string
         */
	private function _unichr($u) {
		return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
	}

        /**
         * lekko przerobiona funkcja. W orginale Zend_Pdf wyznacza współrzędne od lewego dolnego rogu, w mojej wersji od lewego górnego rogu.
         *
         * @param oject $pdfPage
         * @param string $text
         * @param integer $offsetX
         * @param integer $offsetY
         */
	private function _drawText( &$pdfPage, $text='', $offsetX=0, $offsetY=0){
		$pdfPage->drawText( $text , $offsetX , $pdfPage->getHeight() - $offsetY , 'UTF-8' );
	}

        /**
         * lekko przerobiona funkcja. W orginale Zend_Pdf wyznacza współrzędne od lewego dolnego rogu, w mojej wersji od lewego górnego rogu.
         *
         * @param object $pdfPage
         * @param integer $x1
         * @param integer $y1
         * @param integer $x2
         * @param integer $y2
         */
        private function _drawLine( &$pdfPage, $x1, $y1, $x2, $y2){
            $pdfPage->drawLine( $x1, $pdfPage->getHeight() - $y1, $x2, $pdfPage->getHeight() - $y2 );
        }

        /**
         * moja funkcja tworzące link
         *
         * @param object $pdfPage
         * @param integer $offsetX
         * @param integer $offsetY
         * @param integer $w
         * @param integer $h
         * @param string $uri
         */
        private function _attachLink( &$pdfPage, $offsetX=0, $offsetY=0 , $w , $h , $uri ){
            $pdfPage->attachAnnotation(
                Zend_Pdf_Annotation_Link::create(
                    $offsetX,
                    $pdfPage->getHeight() - $offsetY,
                    $offsetX+$w,
                    $pdfPage->getHeight() - $offsetY - $h,
                    Zend_Pdf_Action_URI::create( $uri )
                )
            );
        }

        /**
         * lekko przerobiona funkcja wstawiająca obrazek. W orginale Zend_Pdf wyznacza współrzędne od lewego dolnego rogu, w mojej wersji od lewego górnego rogu.
         *
         * @param integer $pdfPage
         * @param string $imageWithPath
         * @param integer $w
         * @param integer $h
         * @param integer $offsetX
         * @param integer $offsetY
         * @param integer $ratio
         */
	private function _drawImage( &$pdfPage, $imageWithPath, $w=1, $h=1, $offsetX=0, $offsetY=0, $ratio=1 ){
		$pdfPage->drawImage(
			Zend_Pdf_Image::imageWithPath($imageWithPath),
			$offsetX,
			$pdfPage->getHeight() - $h*$ratio - $offsetY,
			$w*$ratio + $offsetX,
			$pdfPage->getHeight() - $offsetY
		);
	}

        /**
         * oblicza różnicę pomiędzy datami w latach i (opcjonalnie) miesiącach
         *
         * @param integer $start_date
         * @param integer $end_date
         * @param boolean $showMonths
         * @return string
         */
	private function _yearMonthDifference($start_date, $end_date, $showMonths=true)
	{
		$start_date = strtotime($start_date);
		$end_date = strtotime($end_date);
		// 31556926 seconds in year
		$years = floor(($end_date - $start_date) / 31556926);
		// takes remaning seconds to find months  2629743.83 seconds each month
		if($showMonths){
			$months = floor((($end_date - $start_date) % 31556926) / 2629743.83);
		}

		if($years > 0){
			switch($years){
				case 1:
					$years_display =$years.' rok'; break;
				case 2:
				case 3:
				case 4:
					$years_display =$years.' lata'; break;
				default:
					$years_display =$years.' lat'; break;
			}
		}
		if($showMonths){
			if($months > 0){
				switch($months){
					case 1:
						$months_display = 'i '.$months.' miesiąc'; break;
					case 2:
					case 3:
					case 4:
						$months_display = 'i '.$months.' miesiące'; break;
					default:
						$months_display = 'i '.$months.' miesięcy'; break;
				}
			}
		}

		return trim($years_display.' '.$months_display);
	}
}

Wynik

Wynik można znaleźć pod adresem:
http://smoku.net/mariusz-adam-gorski/pdf