public function addBody($rows, callable $fn = null) {
        // last column will have TRUE for the TCPDF [ln] property
        end($this->columnDefinition);
        $this->columnDefinition[key($this->columnDefinition)]['ln'] = true;

        $auto_pb = $this->pdf->getAutoPageBreak();
        $bmargin = $this->pdf->getMargins()['bottom'];
        $this->pdf->SetAutoPageBreak(false, $this->bottomMargin);
        if ($this->trigger(self::EV_BODY_ADD, [$rows, $fn]) === false) {
            $this->trigger(self::EV_BODY_SKIPPED, [$rows]);
            $this->endBody($auto_pb, $bmargin);
            return $this;
        }
        if ($this->showHeader) {
            $this->addHeader();
        }
        foreach ($rows as $index => $row) {
            $data = $fn ? $fn($this, $row, $index, false) : $row;
            // draw row only if it's an array. It gives the possibility to skip
            // some rows with the user func
            if (is_array($data) || is_object($data)) {
                $this->addRow($data, $index);
            } else {
                $this->trigger(self::EV_ROW_SKIPPED, [$row, $index]);
            }
        }
        $this->trigger(self::EV_BODY_ADDED, [$rows]);
        $this->endBody($auto_pb, $bmargin);
        return $this;
    }
public function addBody($rows, callable $fn = null) {
        // last column will have TRUE for the TCPDF [ln] property
        end($this->columnDefinition);
        $this->columnDefinition[key($this->columnDefinition)]['ln'] = true;

        $auto_pb = $this->pdf->getAutoPageBreak();
        $bmargin = $this->pdf->getMargins()['bottom'];
        $this->pdf->SetAutoPageBreak(false, $this->bottomMargin);
        if ($this->trigger(self::EV_BODY_ADD, [$rows, $fn]) === false) {
            $this->trigger(self::EV_BODY_SKIPPED, [$rows]);
            $this->endBody($auto_pb, $bmargin);
            return $this;
        }
        if ($this->showHeader) {
            $this->addHeader();
        }
        foreach ($rows as $index => $row) {
            $data = $fn ? $fn($this, $row, $index, false) : $row;
            // draw row only if it's an array. It gives the possibility to skip
            // some rows with the user func
            if (is_array($data) || is_object($data)) {
                $this->addRow($data, $index);
            } else {
                $this->trigger(self::EV_ROW_SKIPPED, [$row, $index]);
            }
        }
        $this->trigger(self::EV_BODY_ADDED, [$rows]);
        $this->endBody($auto_pb, $bmargin);
        return $this;
    }
public function addBody ( $ rows , callable $ fn = null ) { // last column will have TRUE for the TCPDF [ln] property end ( $ this -> columnDefinition ) ; $ this -> columnDefinition [ key ( $ this -> columnDefinition ) ] [ 'ln' ] = true ; $ auto_pb = $ this -> pdf -> getAutoPageBreak ( ) ; $ bmargin = $ this -> pdf -> getMargins ( ) [ 'bottom' ] ; $ this -> pdf -> SetAutoPageBreak ( false , $ this -> bottomMargin ) ; if ( $ this -> trigger ( self :: EV_BODY_ADD , [ $ rows , $ fn ] ) === false ) { $ this -> trigger ( self :: EV_BODY_SKIPPED , [ $ rows ] ) ; $ this -> endBody ( $ auto_pb , $ bmargin ) ; return $ this ; } if ( $ this -> showHeader ) { $ this -> addHeader ( ) ; } foreach ( $ rows as $ index => $ row ) { $ data = $ fn ? $ fn ( $ this , $ row , $ index , false ) : $ row ; // draw row only if it's an array. It gives the possibility to skip // some rows with the user func if ( is_array ( $ data ) || is_object ( $ data ) ) { $ this -> addRow ( $ data , $ index ) ; } else { $ this -> trigger ( self :: EV_ROW_SKIPPED , [ $ row , $ index ] ) ; } } $ this -> trigger ( self :: EV_BODY_ADDED , [ $ rows ] ) ; $ this -> endBody ( $ auto_pb , $ bmargin ) ; return $ this ; }
Add content to the table. It launches events at start and end, if we need
to add some custom stuff.

The callable function structure is as follow:
<ul>
<li><i>TcTable</i> <b>$table</b> the TcTable object</li>
<li><i>array|object</i> <b>$row</b> current row</li>
<li><i>int</i> <b>$index</b> current row index</li>
<li><i>bool</i> <b>$widow</b> TRUE if this method is called when
parsing widows (from plugin plugin\Widows)</li>
</ul>
<ul>
<li>Return <i>array</i> formatted data, where keys are the one
configured in the column definition</li>
</ul>

@param array|Traversable $rows the complete set of data
@param callable|null $fn data layout function
@return TcTable
Add content to the table . It launches events at start and end if we need to add some custom stuff .