I have a Full HTML text which needs to be converted accordingly to phpword and added finally in word. HTML code is :
$html = '<table style="height:500px;width:600px;"><thead><tr><th>Lor<strong>em</strong></th><th colspan="2"><p>ipsum</p><p>dolr</p></th></tr></thead><tbody><tr><td colspan="2"><table><tbody><tr><td>1</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td></tr></tbody></table></td><td style="height:50px;padding:5px;text-align:center;vertical-align:top;">cell value</td></tr><tr><td>datetime</td><td>touch</td><td>inputtypes</td></tr><tr><td colspan="3">Merged third row</td></tr><tr><td>fourth row 1</td><td>fourth row 2</td><td>fourth row 3</td></tr><tr><td>fifth row 1</td><td>fifth row 2</td><td>fifth row 3</td></tr></tbody></table>';
here is my PHP code
$section = $phpWord->addSection();
processTableToWord($section, $html);
function processTableToWord($section, $table_data) {
$table_style = new \PhpOffice\PhpWord\Style\Table;
$table_style->setBorderColor('aaaaaa');
$table_style->setBorderSize(1);
$table_style->setUnit('auto');
$table_style->setWidth('100px');
$clm_width = countColumns($table_data);
$table = $section->addTable($table_style);
$dom = new \DOMDocument;
$dom->loadHTML($table_data);
$tbody = $dom->getElementsByTagName('tbody')->item(0);
$thead = $dom->getElementsByTagName('thead')->item(0);
$thead_rows = $thead->getElementsByTagName('tr');
foreach ($thead_rows as $thead_row) {
$thead_cells = $thead_row->getElementsByTagName('th');
$table->addRow();
foreach ($thead_cells as $thead_cell) {
$thead_text = $thead_cell->nodeValue;
// dump(htmlspecialchars($thead_text));
$table->addCell($clm_width)->addText($thead_text, ['bold' => true], 'a_table');
}
}
$rows = $tbody->getElementsByTagName('tr');
foreach ($rows as $row) {
$cells = $row->getElementsByTagName('td');
$table->addRow();
foreach ($cells as $cell) {
// dump($dom->saveHTML($cell));
$width = $cell->getAttribute('width');
$height = $cell->getAttribute('height');
$text = $cell->nodeValue;
$style_arrs = [];
if (!empty($cell->getAttribute('style'))) {
$style_arrs = processStyleAttributes($cell->getAttribute('style'));
}
$colspan = $cell->getAttribute('colspan');
if ($colspan > 1) {
if (isset($style_arrs['vertical-align']) && !empty($style_arrs['vertical-align'])) {
$table->addCell($colspan * $clm_width, ['gridSpan' => $colspan, 'valign' => $style_arrs['vertical-align']])->addText($text, [], 'a_table');
}else {
$table->addCell($colspan * $clm_width, ['gridSpan' => $colspan])->addText($text, [], 'a_table');
}
}else {
if (isset($style_arrs['vertical-align']) && !empty($style_arrs['vertical-align'])) {
$table->addCell($clm_width, ['valign' => $style_arrs['vertical-align']])->addText($text, [], 'a_table');
}else {
$table->addCell($clm_width)->addText($text, [], 'a_table');
}
}
}
}
}
I am actually doing the right thing for outer table but when comes to inner Table, Its rendering with outer table and breaking everything. Need someone help in fixing the code.
I got about $cells = $row->getElementsByTagName('td');
Here it is adding second table td's also into main one. So there should be something doing it here. Thank you
I am to achieve by multiple attempts by looping through self function
function processTableToWord($section, $table_data, $nested = FALSE) {
$table_style = new \PhpOffice\PhpWord\Style\Table;
$table_style->setBorderColor('aaaaaa');
$table_style->setBorderSize(1);
$table_style->setUnit('auto');
$clm_width = countColumns($table_data);
$table = $section->addTable($table_style);
$dom = new \DOMDocument;
$dom->loadHTML($table_data);
$tbody = $dom->getElementsByTagName('tbody')->item(0);
$thead = $dom->getElementsByTagName('thead')->item(0);
$thead_rows = !empty($thead) ? $thead->getElementsByTagName('tr') : [];
foreach ($thead_rows as $thead_row) {
$thead_cells = $thead_row->getElementsByTagName('th');
$table->addRow();
foreach ($thead_cells as $thead_cell) {
$thead_text = $thead_cell->nodeValue;
$table->addCell($clm_width)->addText($thead_text, ['bold' => true], 'a_table');
}
}
$rows = $tbody->getElementsByTagName('tr');
foreach ($rows as $row) {
$cells = $row->getElementsByTagName('td');
$table->addRow(1500);
foreach ($cells as $cell) {
$haveNestedTbl = FALSE;
$nested_tbl = '';
$nestedTable = $cell->getElementsByTagName('table')->item(0);
if ($nestedTable) {
$haveNestedTbl = TRUE;
$nested_tbl = $dom->saveHTML($nestedTable);
$cell->removeChild($nestedTable);
}
$width = $cell->hasAttribute('width') ? $cell->getAttribute('width') : '';
$height = $cell->hasAttribute('height') ? $cell->getAttribute('height') : '';
$text = $cell->nodeValue;
$style_arrs = [];
if ($cell->hasAttribute('style')) {
$style_arrs = processStyleAttributes($cell->getAttribute('style'));
}
$colspan = $cell->getAttribute('colspan');
if ($colspan > 1) {
if (isset($style_arrs['vertical-align']) && !empty($style_arrs['vertical-align'])) {
$innerCell = $table->addCell($colspan * $clm_width, ['gridSpan' => $colspan, 'valign' => $style_arrs['vertical-align']]);
$innerCell->addText($text, [], 'a_table');
}else {
$innerCell = $table->addCell($colspan * $clm_width, ['gridSpan' => $colspan]);
$innerCell->addText($text, [], 'a_table');
}
}else {
if (isset($style_arrs['vertical-align']) && !empty($style_arrs['vertical-align'])) {
$innerCell = $table->addCell($clm_width, ['valign' => $style_arrs['vertical-align']]);
$innerCell->addText($text, [], 'a_table');
}else {
$innerCell = $table->addCell($clm_width);
$innerCell->addText($text, [], 'a_table');
}
}
if ($haveNestedTbl) {
processTableToWord($innerCell, $nested_tbl);
}
}
}
}
Here after assigining nested table to a variable, have to delete it from DOM to not further process it in another rows. Here is the screenshot of the output