将嵌套表格添加到Word文档中,使用phpword库和DOM对象。

huangapple go评论56阅读模式
英文:

Add nested table into word by phpword library and DOM object

问题

我有一个完整的HTML文本,需要相应地转换为phpword,并最终添加到Word中。

HTML代码是:

$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>';

这是我的PHP代码

```php
$section = $phpWord->addSection();
processTableToWord($section, $html);

function processTableToWord($section, $table_data) {
  //... (此处省略了代码的一部分)
}

这是输出的结果:
将嵌套表格添加到Word文档中,使用phpword库和DOM对象。

我实际上对外部表格做得不错,但当涉及到内部表格时,它与外部表格一起渲染并破坏了一切。需要有人帮忙修复代码。

我看到了$cells = $row->getElementsByTagName('td');这里也将第二个表格的td添加到了主表格中。所以应该在这里进行一些处理。谢谢

英文:

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');
        }
      }
    }
  }
}

Here is the output for this:
将嵌套表格添加到Word文档中,使用phpword库和DOM对象。

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

答案1

得分: 0

我通过循环多次尝试来实现自身函数

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);
      }
    }
  }
}

这里将嵌套表分配给一个变量后,必须从 DOM 中删除它,以便在其他行中不再处理它。这是输出的截图。

英文:

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
将嵌套表格添加到Word文档中,使用phpword库和DOM对象。

huangapple
  • 本文由 发表于 2023年3月10日 00:06:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定