FPDF - 放置前确定MultiCell的高度?

Rog*_*ury 7 php pdf fpdf

基本问题:是否可以在将MultiCell放入文档之前确定其高度?

原因是:我的任务是创建表单的PDF版本.此表单允许文本输入,结果可变长度.一个人我没有输入任何东西,另一个人可能会写几段."那些力量"不希望这些文本在页面之间打破.

目前,在放置每个块之后,我检查页面上的位置,如果我接近结束,我创建一个新页面.

if($this->getY() >= 250) {
    $this->AddPage('P');
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,这是有效的.但是有一些偷偷摸摸的进来,比如249,然后有大量的文字.在放置块之前确定块的高度以确定它是否真正适合页面似乎更有意义.

当然必须有办法做到这一点,但谷歌搜索并没有证明非常有用.

编辑以澄清:在提交表单后生成PDF.不是一个活跃的,可编辑的PDF表单......

Rog*_*ury 7

获得了这个问题的风滚草徽章.:(无论如何,在有机会出现同样问题的情况下,我想我会回答我的所作所为.我怀疑这是最有效的方法,但它完成了工作.

首先,我创建了两个FPDF对象; 一个永远不会得到输出的临时版本,以及最终用户将看到的最终完整pdf.

我在两个对象中得到了当前的Y坐标.然后,我使用Cell()或MultiCell()(对于此形式,通常是两者的组合)将数据块放入临时对象,然后检查新的Y坐标.然后我可以做数学来确定块的高度.注意,如果块在页面中断,数学可以变得有点时髦.请记住将上下边距考虑在内.

现在我知道块的高度,我可以获取目标对象的当前Y坐标,从页面的总高度减去它(减去下边距)以获得我的可用空间.如果块适合,请将其放置,如果不适合,则添加页面并将其放在顶部.

每个块重复一次.

我看到的唯一警告是,如果任何单个块比整个页面长,但是使用这种形式,这种情况永远不会发生.(著名遗言...)


JLu*_*Luc 7

另见https://gist.github.com/johnballantyne/4089627

function GetMultiCellHeight($w, $h, $txt, $border=null, $align='J') {
    // Calculate MultiCell with automatic or explicit line breaks height
    // $border is un-used, but I kept it in the parameters to keep the call
    //   to this function consistent with MultiCell()
    $cw = &$this->CurrentFont['cw'];
    if($w==0)
        $w = $this->w-$this->rMargin-$this->x;
    $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
    $s = str_replace("\r",'',$txt);
    $nb = strlen($s);
    if($nb>0 && $s[$nb-1]=="\n")
        $nb--;
    $sep = -1;
    $i = 0;
    $j = 0;
    $l = 0;
    $ns = 0;
    $height = 0;
    while($i<$nb)
    {
        // Get next character
        $c = $s[$i];
        if($c=="\n")
        {
            // Explicit line break
            if($this->ws>0)
            {
                $this->ws = 0;
                $this->_out('0 Tw');
            }
            //Increase Height
            $height += $h;
            $i++;
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
            continue;
        }
        if($c==' ')
        {
            $sep = $i;
            $ls = $l;
            $ns++;
        }
        $l += $cw[$c];
        if($l>$wmax)
        {
            // Automatic line break
            if($sep==-1)
            {
                if($i==$j)
                    $i++;
                if($this->ws>0)
                {
                    $this->ws = 0;
                    $this->_out('0 Tw');
                }
                //Increase Height
                $height += $h;
            }
            else
            {
                if($align=='J')
                {
                    $this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
                    $this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
                }
                //Increase Height
                $height += $h;
                $i = $sep+1;
            }
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
        }
        else
            $i++;
    }
    // Last chunk
    if($this->ws>0)
    {
        $this->ws = 0;
        $this->_out('0 Tw');
    }
    //Increase Height
    $height += $h;

    return $height;
}
Run Code Online (Sandbox Code Playgroud)