PageRenderTime 77ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/v1.6.2/Classes/PHPExcel/Writer/PDF.php

#
PHP | 469 lines | 271 code | 58 blank | 140 comment | 51 complexity | 08a9e947a6b735a34bab0b63c409c9ae MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.0, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2008 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Writer
  23. * @copyright Copyright (c) 2006 - 2008 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. /** PHPExcel_IWriter */
  28. require_once 'PHPExcel/Writer/IWriter.php';
  29. /** PHPExcel_Cell */
  30. require_once 'PHPExcel/Cell.php';
  31. /** PHPExcel_RichText */
  32. require_once 'PHPExcel/RichText.php';
  33. /** PHPExcel_Shared_Drawing */
  34. require_once 'PHPExcel/Shared/Drawing.php';
  35. /** PHPExcel_HashTable */
  36. require_once 'PHPExcel/HashTable.php';
  37. /** PHPExcel_Shared_PDF */
  38. require_once 'PHPExcel/Shared/PDF.php';
  39. /**
  40. * PHPExcel_Writer_PDF
  41. *
  42. * @category PHPExcel
  43. * @package PHPExcel_Writer
  44. * @copyright Copyright (c) 2006 - 2008 PHPExcel (http://www.codeplex.com/PHPExcel)
  45. */
  46. class PHPExcel_Writer_PDF implements PHPExcel_Writer_IWriter {
  47. /**
  48. * PHPExcel object
  49. *
  50. * @var PHPExcel
  51. */
  52. private $_phpExcel;
  53. /**
  54. * Sheet index to write
  55. *
  56. * @var int
  57. */
  58. private $_sheetIndex;
  59. /**
  60. * Pre-calculate formulas
  61. *
  62. * @var boolean
  63. */
  64. private $_preCalculateFormulas = true;
  65. /**
  66. * Temporary storage directory
  67. *
  68. * @var string
  69. */
  70. private $_tempDir = '';
  71. /**
  72. * Create a new PHPExcel_Writer_PDF
  73. *
  74. * @param PHPExcel $phpExcel PHPExcel object
  75. */
  76. public function __construct(PHPExcel $phpExcel) {
  77. $this->_phpExcel = $phpExcel;
  78. $this->_sheetIndex = 0;
  79. $this->_tempDir = sys_get_temp_dir();
  80. }
  81. /**
  82. * Save PHPExcel to file
  83. *
  84. * @param string $pFileName
  85. * @throws Exception
  86. */
  87. public function save($pFilename = null) {
  88. // Open file
  89. $fileHandle = fopen($pFilename, 'w');
  90. if ($fileHandle === false) {
  91. throw new Exception("Could not open file $pFilename for writing.");
  92. }
  93. // Fetch sheets
  94. $sheets = array();
  95. if (is_null($this->_sheetIndex)) {
  96. $sheets = $this->_phpExcel->getAllSheets();
  97. } else {
  98. $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex);
  99. }
  100. // PDF paper size
  101. $paperSize = 'A4';
  102. // Create PDF
  103. $pdf = new FPDF('P', 'pt', $paperSize);
  104. // Loop all sheets
  105. foreach ($sheets as $sheet) {
  106. // PDF orientation
  107. $orientation = 'P';
  108. if ($sheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) {
  109. $orientation = 'L';
  110. }
  111. // Start sheet
  112. $pdf->SetAutoPageBreak(true);
  113. $pdf->SetFont('Arial', '', 10);
  114. $pdf->AddPage($orientation);
  115. // Get worksheet dimension
  116. $dimension = explode(':', $sheet->calculateWorksheetDimension());
  117. $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]);
  118. $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1;
  119. $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]);
  120. $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1;
  121. // Calculate column widths
  122. $sheet->calculateColumnWidths();
  123. // Loop trough cells
  124. for ($row = $dimension[0][1]; $row <= $dimension[1][1]; $row++) {
  125. // Line height
  126. $lineHeight = 0;
  127. // Calulate line height
  128. for ($column = $dimension[0][0]; $column <= $dimension[1][0]; $column++) {
  129. $rowDimension = $sheet->getRowDimension($row);
  130. $cellHeight = PHPExcel_Shared_Drawing::pixelsToPoints(
  131. PHPExcel_Shared_Drawing::cellDimensionToPixels($rowDimension->getRowHeight())
  132. );
  133. if ($cellHeight < 0) {
  134. $cellHeight = $sheet->getStyleByColumnAndRow($column, $row)->getFont()->getSize();
  135. }
  136. if ($cellHeight > $lineHeight) {
  137. $lineHeight = $cellHeight;
  138. }
  139. }
  140. // Output values
  141. for ($column = $dimension[0][0]; $column <= $dimension[1][0]; $column++) {
  142. // Start with defaults...
  143. $pdf->SetFont('Arial', '', 10);
  144. $pdf->SetTextColor(0, 0, 0);
  145. $pdf->SetDrawColor(100, 100, 100);
  146. $pdf->SetFillColor(255, 255, 255);
  147. // Coordinates
  148. $startX = $pdf->GetX();
  149. $startY = $pdf->GetY();
  150. // Cell exists?
  151. $cellData = '';
  152. if ($sheet->cellExistsByColumnAndRow($column, $row)) {
  153. if ($sheet->getCellByColumnAndRow($column, $row)->getValue() instanceof PHPExcel_RichText) {
  154. $cellData = $sheet->getCellByColumnAndRow($column, $row)->getValue()->getPlainText();
  155. } else {
  156. if ($this->_preCalculateFormulas) {
  157. $cellData = PHPExcel_Style_NumberFormat::ToFormattedString(
  158. $sheet->getCellByColumnAndRow($column, $row)->getCalculatedValue(),
  159. $sheet->getstyle( $sheet->getCellByColumnAndRow($column, $row)->getCoordinate() )->getNumberFormat()->getFormatCode()
  160. );
  161. } else {
  162. $cellData = PHPExcel_Style_NumberFormat::ToFormattedString(
  163. $sheet->getCellByColumnAndRow($column, $row)->getValue(),
  164. $sheet->getstyle( $sheet->getCellByColumnAndRow($column, $row)->getCoordinate() )->getNumberFormat()->getFormatCode()
  165. );
  166. }
  167. }
  168. }
  169. // Style information
  170. $style = $sheet->getStyleByColumnAndRow($column, $row);
  171. // Cell width
  172. $columnDimension = $sheet->getColumnDimensionByColumn($column);
  173. if ($columnDimension->getWidth() == -1) {
  174. $columnDimension->setAutoSize(true);
  175. $sheet->calculateColumnWidths();
  176. }
  177. $cellWidth = PHPExcel_Shared_Drawing::pixelsToPoints(
  178. PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth())
  179. );
  180. // Cell height
  181. $rowDimension = $sheet->getRowDimension($row);
  182. $cellHeight = PHPExcel_Shared_Drawing::pixelsToPoints(
  183. PHPExcel_Shared_Drawing::cellDimensionToPixels($rowDimension->getRowHeight())
  184. );
  185. if ($cellHeight < 0) {
  186. $cellHeight = $style->getFont()->getSize();
  187. }
  188. // Column span? Rowspan?
  189. foreach ($sheet->getMergeCells() as $cells) {
  190. if ($sheet->getCellByColumnAndRow($column, $row)->isInRange($cells)) {
  191. list($first, ) = PHPExcel_Cell::splitRange($cells);
  192. if ($first == $sheet->getCellByColumnAndRow($column, $row)->getCoordinate()) {
  193. list($colSpan, $rowSpan) = PHPExcel_Cell::rangeDimension($cells);
  194. $cellWidth = $cellWidth * $colSpan;
  195. //$cellHeight = $cellHeight * $rowSpan;
  196. }
  197. break;
  198. }
  199. }
  200. // Cell height OK?
  201. if ($cellHeight < $lineHeight) {
  202. $cellHeight = $lineHeight;
  203. }
  204. // Font formatting
  205. $fontStyle = '';
  206. if ($style->getFont()->getBold()) {
  207. $fontStyle .= 'B';
  208. }
  209. if ($style->getFont()->getItalic()) {
  210. $fontStyle .= 'I';
  211. }
  212. if ($style->getFont()->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) {
  213. $fontStyle .= 'U';
  214. }
  215. $pdf->SetFont('Arial', $fontStyle, $style->getFont()->getSize());
  216. // Text alignment
  217. $alignment = 'L';
  218. switch ($style->getAlignment()->getHorizontal()) {
  219. case PHPExcel_Style_Alignment::HORIZONTAL_CENTER:
  220. $alignment = 'C'; break;
  221. case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT:
  222. $alignment = 'R'; break;
  223. case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY:
  224. $alignment = 'J'; break;
  225. case PHPExcel_Style_Alignment::HORIZONTAL_LEFT:
  226. case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL:
  227. default:
  228. $alignment = 'L'; break;
  229. }
  230. // Text color
  231. $pdf->SetTextColor(
  232. hexdec(substr($style->getFont()->getColor()->getRGB(), 0, 2)),
  233. hexdec(substr($style->getFont()->getColor()->getRGB(), 2, 2)),
  234. hexdec(substr($style->getFont()->getColor()->getRGB(), 4, 2))
  235. );
  236. // Fill color
  237. if ($style->getFill()->getFillType() != PHPExcel_Style_Fill::FILL_NONE) {
  238. $pdf->SetFillColor(
  239. hexdec(substr($style->getFill()->getStartColor()->getRGB(), 0, 2)),
  240. hexdec(substr($style->getFill()->getStartColor()->getRGB(), 2, 2)),
  241. hexdec(substr($style->getFill()->getStartColor()->getRGB(), 4, 2))
  242. );
  243. }
  244. // Border color
  245. $borders = '';
  246. if ($style->getBorders()->getLeft()->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {
  247. $borders .= 'L';
  248. $pdf->SetDrawColor(
  249. hexdec(substr($style->getBorders()->getLeft()->getColor()->getRGB(), 0, 2)),
  250. hexdec(substr($style->getBorders()->getLeft()->getColor()->getRGB(), 2, 2)),
  251. hexdec(substr($style->getBorders()->getLeft()->getColor()->getRGB(), 4, 2))
  252. );
  253. }
  254. if ($style->getBorders()->getRight()->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {
  255. $borders .= 'R';
  256. $pdf->SetDrawColor(
  257. hexdec(substr($style->getBorders()->getRight()->getColor()->getRGB(), 0, 2)),
  258. hexdec(substr($style->getBorders()->getRight()->getColor()->getRGB(), 2, 2)),
  259. hexdec(substr($style->getBorders()->getRight()->getColor()->getRGB(), 4, 2))
  260. );
  261. }
  262. if ($style->getBorders()->getTop()->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {
  263. $borders .= 'T';
  264. $pdf->SetDrawColor(
  265. hexdec(substr($style->getBorders()->getTop()->getColor()->getRGB(), 0, 2)),
  266. hexdec(substr($style->getBorders()->getTop()->getColor()->getRGB(), 2, 2)),
  267. hexdec(substr($style->getBorders()->getTop()->getColor()->getRGB(), 4, 2))
  268. );
  269. }
  270. if ($style->getBorders()->getBottom()->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {
  271. $borders .= 'B';
  272. $pdf->SetDrawColor(
  273. hexdec(substr($style->getBorders()->getBottom()->getColor()->getRGB(), 0, 2)),
  274. hexdec(substr($style->getBorders()->getBottom()->getColor()->getRGB(), 2, 2)),
  275. hexdec(substr($style->getBorders()->getBottom()->getColor()->getRGB(), 4, 2))
  276. );
  277. }
  278. if ($borders == '') {
  279. $borders = 0;
  280. }
  281. if ($sheet->getShowGridlines()) {
  282. $borders = 'LTRB';
  283. }
  284. // Image?
  285. $iterator = $sheet->getDrawingCollection()->getIterator();
  286. while ($iterator->valid()) {
  287. if ($iterator->current()->getCoordinates() == PHPExcel_Cell::stringFromColumnIndex($column) . ($row + 1)) {
  288. try {
  289. $pdf->Image(
  290. $iterator->current()->getPath(),
  291. $pdf->GetX(),
  292. $pdf->GetY(),
  293. $iterator->current()->getWidth(),
  294. $iterator->current()->getHeight(),
  295. '',
  296. $this->_tempDir
  297. );
  298. } catch (Exception $ex) { }
  299. }
  300. $iterator->next();
  301. }
  302. // Print cell
  303. $pdf->MultiCell(
  304. $cellWidth,
  305. $cellHeight,
  306. $cellData,
  307. $borders,
  308. $alignment,
  309. ($style->getFill()->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? 0 : 1)
  310. );
  311. // Coordinates
  312. $endX = $pdf->GetX();
  313. $endY = $pdf->GetY();
  314. // Revert to original Y location
  315. if ($endY > $startY) {
  316. $pdf->SetY($startY);
  317. if ($lineHeight < $lineHeight + ($endY - $startY)) {
  318. $lineHeight = $lineHeight + ($endY - $startY);
  319. }
  320. $pdf->SetX($startX + $cellWidth);
  321. }
  322. // Hyperlink?
  323. if ($sheet->getCellByColumnAndRow($column, $row)->hasHyperlink()) {
  324. if (!$sheet->getCellByColumnAndRow($column, $row)->getHyperlink()->isInternal()) {
  325. $pdf->Link(
  326. $startX,
  327. $startY,
  328. $endX - $startX,
  329. $endY - $startY,
  330. $sheet->getCellByColumnAndRow($column, $row)->getHyperlink()->getUrl()
  331. );
  332. }
  333. }
  334. }
  335. // Garbage collect!
  336. $sheet->garbageCollect();
  337. // Next line...
  338. $pdf->Ln($lineHeight);
  339. }
  340. }
  341. // Document info
  342. $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle());
  343. $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator());
  344. $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject());
  345. $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords());
  346. $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator());
  347. // Write to file
  348. fwrite($fileHandle, $pdf->output($pFilename, 'S'));
  349. // Close file
  350. fclose($fileHandle);
  351. }
  352. /**
  353. * Get sheet index
  354. *
  355. * @return int
  356. */
  357. public function getSheetIndex() {
  358. return $this->_sheetIndex;
  359. }
  360. /**
  361. * Set sheet index
  362. *
  363. * @param int $pValue Sheet index
  364. */
  365. public function setSheetIndex($pValue = 0) {
  366. $this->_sheetIndex = $pValue;
  367. }
  368. /**
  369. * Write all sheets (resets sheetIndex to NULL)
  370. */
  371. public function writeAllSheets() {
  372. $this->_sheetIndex = null;
  373. }
  374. /**
  375. * Get Pre-Calculate Formulas
  376. *
  377. * @return boolean
  378. */
  379. public function getPreCalculateFormulas() {
  380. return $this->_preCalculateFormulas;
  381. }
  382. /**
  383. * Set Pre-Calculate Formulas
  384. *
  385. * @param boolean $pValue Pre-Calculate Formulas?
  386. */
  387. public function setPreCalculateFormulas($pValue = true) {
  388. $this->_preCalculateFormulas = $pValue;
  389. }
  390. /**
  391. * Get temporary storage directory
  392. *
  393. * @return string
  394. */
  395. public function getTempDir() {
  396. return $this->_tempDir;
  397. }
  398. /**
  399. * Set temporary storage directory
  400. *
  401. * @param string $pValue Temporary storage directory
  402. * @throws Exception Exception when directory does not exist
  403. */
  404. public function setTempDir($pValue = '') {
  405. if (is_dir($pValue)) {
  406. $this->_tempDir = $pValue;
  407. } else {
  408. throw new Exception("Directory does not exist: $pValue");
  409. }
  410. }
  411. }