Table.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. /**
  3. * This file is part of PHPWord - A pure PHP library for reading and writing
  4. * word processing documents.
  5. *
  6. * PHPWord is free software distributed under the terms of the GNU Lesser
  7. * General Public License version 3 as published by the Free Software Foundation.
  8. *
  9. * For the full copyright and license information, please read the LICENSE
  10. * file that was distributed with this source code. For the full list of
  11. * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
  12. *
  13. * @see https://github.com/PHPOffice/PHPWord
  14. * @copyright 2010-2018 PHPWord contributors
  15. * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
  16. */
  17. namespace PhpOffice\PhpWord\Writer\HTML\Element;
  18. /**
  19. * Table element HTML writer
  20. *
  21. * @since 0.10.0
  22. */
  23. class Table extends AbstractElement
  24. {
  25. /**
  26. * Write table
  27. *
  28. * @return string
  29. */
  30. public function write()
  31. {
  32. if (!$this->element instanceof \PhpOffice\PhpWord\Element\Table) {
  33. return '';
  34. }
  35. $content = '';
  36. $rows = $this->element->getRows();
  37. $rowCount = count($rows);
  38. if ($rowCount > 0) {
  39. $content .= '<table' . self::getTableStyle($this->element->getStyle()) . '>' . PHP_EOL;
  40. for ($i = 0; $i < $rowCount; $i++) {
  41. /** @var $row \PhpOffice\PhpWord\Element\Row Type hint */
  42. $rowStyle = $rows[$i]->getStyle();
  43. // $height = $row->getHeight();
  44. $tblHeader = $rowStyle->isTblHeader();
  45. $content .= '<tr>' . PHP_EOL;
  46. $rowCells = $rows[$i]->getCells();
  47. $rowCellCount = count($rowCells);
  48. for ($j = 0; $j < $rowCellCount; $j++) {
  49. $cellStyle = $rowCells[$j]->getStyle();
  50. $cellBgColor = $cellStyle->getBgColor();
  51. $cellBgColor === 'auto' && $cellBgColor = null; // auto cannot be parsed to hexadecimal number
  52. $cellFgColor = null;
  53. if ($cellBgColor) {
  54. $red = hexdec(substr($cellBgColor, 0, 2));
  55. $green = hexdec(substr($cellBgColor, 2, 2));
  56. $blue = hexdec(substr($cellBgColor, 4, 2));
  57. $cellFgColor = (($red * 0.299 + $green * 0.587 + $blue * 0.114) > 186) ? null : 'ffffff';
  58. }
  59. $cellColSpan = $cellStyle->getGridSpan();
  60. $cellRowSpan = 1;
  61. $cellVMerge = $cellStyle->getVMerge();
  62. // If this is the first cell of the vertical merge, find out how man rows it spans
  63. if ($cellVMerge === 'restart') {
  64. for ($k = $i + 1; $k < $rowCount; $k++) {
  65. $kRowCells = $rows[$k]->getCells();
  66. if (isset($kRowCells[$j])) {
  67. if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
  68. $cellRowSpan++;
  69. } else {
  70. break;
  71. }
  72. } else {
  73. break;
  74. }
  75. }
  76. }
  77. // Ignore cells that are merged vertically with previous rows
  78. if ($cellVMerge !== 'continue') {
  79. $cellTag = $tblHeader ? 'th' : 'td';
  80. $cellColSpanAttr = (is_numeric($cellColSpan) && ($cellColSpan > 1) ? " colspan=\"{$cellColSpan}\"" : '');
  81. $cellRowSpanAttr = ($cellRowSpan > 1 ? " rowspan=\"{$cellRowSpan}\"" : '');
  82. $cellBgColorAttr = (is_null($cellBgColor) ? '' : " bgcolor=\"#{$cellBgColor}\"");
  83. $cellFgColorAttr = (is_null($cellFgColor) ? '' : " color=\"#{$cellFgColor}\"");
  84. $content .= "<{$cellTag}{$cellColSpanAttr}{$cellRowSpanAttr}{$cellBgColorAttr}{$cellFgColorAttr}>" . PHP_EOL;
  85. $writer = new Container($this->parentWriter, $rowCells[$j]);
  86. $content .= $writer->write();
  87. if ($cellRowSpan > 1) {
  88. // There shouldn't be any content in the subsequent merged cells, but lets check anyway
  89. for ($k = $i + 1; $k < $rowCount; $k++) {
  90. $kRowCells = $rows[$k]->getCells();
  91. if (isset($kRowCells[$j])) {
  92. if ($kRowCells[$j]->getStyle()->getVMerge() === 'continue') {
  93. $writer = new Container($this->parentWriter, $kRowCells[$j]);
  94. $content .= $writer->write();
  95. } else {
  96. break;
  97. }
  98. } else {
  99. break;
  100. }
  101. }
  102. }
  103. $content .= "</{$cellTag}>" . PHP_EOL;
  104. }
  105. }
  106. $content .= '</tr>' . PHP_EOL;
  107. }
  108. $content .= '</table>' . PHP_EOL;
  109. }
  110. return $content;
  111. }
  112. /**
  113. * Translates Table style in CSS equivalent
  114. *
  115. * @param string|\PhpOffice\PhpWord\Style\Table|null $tableStyle
  116. * @return string
  117. */
  118. private function getTableStyle($tableStyle = null)
  119. {
  120. if ($tableStyle == null) {
  121. return '';
  122. }
  123. if (is_string($tableStyle)) {
  124. $style = ' class="' . $tableStyle;
  125. } else {
  126. $style = ' style="';
  127. if ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED) {
  128. $style .= 'table-layout: fixed;';
  129. } elseif ($tableStyle->getLayout() == \PhpOffice\PhpWord\Style\Table::LAYOUT_AUTO) {
  130. $style .= 'table-layout: auto;';
  131. }
  132. }
  133. return $style . '"';
  134. }
  135. }