FPDF 中 MultiCell 的换行问题

发布于 2024-08-04 20:21:38 字数 706 浏览 4 评论 0原文

我正在使用 FPDF 的 Java 端口。我遇到以下错误。

  1. 当我调用 multicell 两次时,每次文本都会打印在新行上。
MultiCell(0, 1, "abcd", currentBorders, Alignment.LEFT, false); //prints on one line
MultiCell(0, 1, "efg", currentBorders, Alignment.LEFT, false); //prints on next line

我希望在调用多单元格后没有换行符。我该怎么做呢?

  1. 如果我执行以下操作,则字符串的某些部分将打印在一行上,而某些部分将打印在下一行上。
MultiCell(getStringWidth(myString), 1, myStringcurrentBorders, Alignment.LEFT, false);
  1. 如果我执行以下操作,则打印 myString 的行后面会有许多空行。如果我使用一个 1 作为第二个参数,它就可以正常工作。
MultiCell(0, myFontSize, "123456", currentBorders, Alignment.LEFT, false);

问题是什么?

I am using the Java port of FPDF. I am encountering the following errors.

  1. When I call multicell two times, every time the text is printed on a new line.
MultiCell(0, 1, "abcd", currentBorders, Alignment.LEFT, false); //prints on one line
MultiCell(0, 1, "efg", currentBorders, Alignment.LEFT, false); //prints on next line

I want there to be no line break after the call to multicell. How can I do it?

  1. If I do the following, then some part of my string gets printed on one line and some on the next.
MultiCell(getStringWidth(myString), 1, myStringcurrentBorders, Alignment.LEFT, false);
  1. If I do the following, then there are many blank lines after the line on which myString is printed. It works correctly if I use one 1 as the second parameter.
MultiCell(0, myFontSize, "123456", currentBorders, Alignment.LEFT, false);

What is the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

又爬满兰若 2024-08-11 20:21:38

我会在写入 MultiCell 之前获取当前的 Y 位置,然后将“光标”移回 MultiCell 之后的 Y 位置一代。像这样:

$current_y = $pdf->GetY();
$current_x = $pdf->GetX();

$cell_width = 50;
MultiCell($cell_width, 1, "abcd", currentBorders, Alignment.LEFT, false);

$pdf->SetXY($current_x + $cell_width, $current_y);

$current_x = $pdf->GetX();
MultiCell($cell_width, 1, "abcd", currentBorders, Alignment.LEFT, false);

类似这样的事。

I would get the current Y position before writing the MultiCell and then move the "cursor" back to that Y position after the MultiCell generation. Like this:

$current_y = $pdf->GetY();
$current_x = $pdf->GetX();

$cell_width = 50;
MultiCell($cell_width, 1, "abcd", currentBorders, Alignment.LEFT, false);

$pdf->SetXY($current_x + $cell_width, $current_y);

$current_x = $pdf->GetX();
MultiCell($cell_width, 1, "abcd", currentBorders, Alignment.LEFT, false);

Something like that.

再浓的妆也掩不了殇 2024-08-11 20:21:38

我创建了一个名为 MultiAlignCell 的新方法。它采用与 MultiCell 相同的参数,但使用从 Cellln 字段一个>。您可以将其添加到扩展的 FPDF 类中。

/**
* MultiCell with alignment as in Cell.
* @param float $w
* @param float $h
* @param string $text
* @param mixed $border
* @param int $ln
* @param string $align
* @param boolean $fill
*/
private function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false)
{
    // Store reset values for (x,y) positions
    $x = $this->GetX() + $w;
    $y = $this->GetY();

    // Make a call to FPDF's MultiCell
    $this->MultiCell($w,$h,$text,$border,$align,$fill);

    // Reset the line position to the right, like in Cell
    if( $ln==0 )
    {
        $this->SetXY($x,$y);
    }
}

I created a new method called MultiAlignCell. It takes the same parameters as MultiCell but with the added ln field from Cell. You can add it to your extended FPDF class.

/**
* MultiCell with alignment as in Cell.
* @param float $w
* @param float $h
* @param string $text
* @param mixed $border
* @param int $ln
* @param string $align
* @param boolean $fill
*/
private function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false)
{
    // Store reset values for (x,y) positions
    $x = $this->GetX() + $w;
    $y = $this->GetY();

    // Make a call to FPDF's MultiCell
    $this->MultiCell($w,$h,$text,$border,$align,$fill);

    // Reset the line position to the right, like in Cell
    if( $ln==0 )
    {
        $this->SetXY($x,$y);
    }
}
鹤仙姿 2024-08-11 20:21:38

我修改了MultiCell方法,它的工作原理与上面的答案相同,您可以像Cell方法一样使用该方法。

function MultiCell($w, $h, $txt, $border=0, $ln=0, $align='J', $fill=false)
{
    // Custom Tomaz Ahlin
    if($ln == 0) {
        $current_y = $this->GetY();
        $current_x = $this->GetX();
    }

    // Output text with automatic or explicit line breaks
    $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--;
    $b = 0;
    if($border)
    {
        if($border==1)
        {
            $border = 'LTRB';
            $b = 'LRT';
            $b2 = 'LR';
        }
        else
        {
            $b2 = '';
            if(strpos($border,'L')!==false)
                $b2 .= 'L';
            if(strpos($border,'R')!==false)
                $b2 .= 'R';
            $b = (strpos($border,'T')!==false) ? $b2.'T' : $b2;
        }
    }
    $sep = -1;
    $i = 0;
    $j = 0;
    $l = 0;
    $ns = 0;
    $nl = 1;
    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');
            }
            $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
            $i++;
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
            $nl++;
            if($border && $nl==2)
                $b = $b2;
            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');
                }
                $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
            }
            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));
                }
                $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
                $i = $sep+1;
            }
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
            $nl++;
            if($border && $nl==2)
                $b = $b2;
        }
        else
            $i++;
    }
    // Last chunk
    if($this->ws>0)
    {
        $this->ws = 0;
        $this->_out('0 Tw');
    }
    if($border && strpos($border,'B')!==false)
        $b .= 'B';
    $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
    $this->x = $this->lMargin;

    // Custom Tomaz Ahlin
    if($ln == 0) {
        $this->SetXY($current_x + $w, $current_y);
    }
}

I have modified the MultiCell method, it works as the above answer, and you can use the method in the same way as the Cell method.

function MultiCell($w, $h, $txt, $border=0, $ln=0, $align='J', $fill=false)
{
    // Custom Tomaz Ahlin
    if($ln == 0) {
        $current_y = $this->GetY();
        $current_x = $this->GetX();
    }

    // Output text with automatic or explicit line breaks
    $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--;
    $b = 0;
    if($border)
    {
        if($border==1)
        {
            $border = 'LTRB';
            $b = 'LRT';
            $b2 = 'LR';
        }
        else
        {
            $b2 = '';
            if(strpos($border,'L')!==false)
                $b2 .= 'L';
            if(strpos($border,'R')!==false)
                $b2 .= 'R';
            $b = (strpos($border,'T')!==false) ? $b2.'T' : $b2;
        }
    }
    $sep = -1;
    $i = 0;
    $j = 0;
    $l = 0;
    $ns = 0;
    $nl = 1;
    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');
            }
            $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
            $i++;
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
            $nl++;
            if($border && $nl==2)
                $b = $b2;
            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');
                }
                $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
            }
            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));
                }
                $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
                $i = $sep+1;
            }
            $sep = -1;
            $j = $i;
            $l = 0;
            $ns = 0;
            $nl++;
            if($border && $nl==2)
                $b = $b2;
        }
        else
            $i++;
    }
    // Last chunk
    if($this->ws>0)
    {
        $this->ws = 0;
        $this->_out('0 Tw');
    }
    if($border && strpos($border,'B')!==false)
        $b .= 'B';
    $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
    $this->x = $this->lMargin;

    // Custom Tomaz Ahlin
    if($ln == 0) {
        $this->SetXY($current_x + $w, $current_y);
    }
}
再浓的妆也掩不了殇 2024-08-11 20:21:38

就我而言,我没有创建任何方法,我只是设置了 X 和 Y,然后在行的末尾重置。它也能完美工作。

        $pdf->SetFont('times', 'B', 10);
        $x = $pdf->GetX();
        $y = $pdf->GetY();
        $pdf->MultiCell($etiquetas_largura, $etiquetas_altura, $campos[$linha]['B1COD'], 0, 'L', 0, 0, $x, $y, true, 0, false, true, 0);
        $y = $y + 5;
        $pdf->SetFont('times', '', 10);
        $pdf->MultiCell($etiquetas_largura, $etiquetas_altura, $campos[$linha]['B1DESC'], 0, 'L', 0, 0, $x, $y, true, 0, false, true, 0);
        // resete x y
        $pdf->SetXY($x + $etiquetas_largura, $y - 5);

in my case I didn't create any method, I just set X and Y and then at the end of the line I reset. It works perfectly too.

        $pdf->SetFont('times', 'B', 10);
        $x = $pdf->GetX();
        $y = $pdf->GetY();
        $pdf->MultiCell($etiquetas_largura, $etiquetas_altura, $campos[$linha]['B1COD'], 0, 'L', 0, 0, $x, $y, true, 0, false, true, 0);
        $y = $y + 5;
        $pdf->SetFont('times', '', 10);
        $pdf->MultiCell($etiquetas_largura, $etiquetas_altura, $campos[$linha]['B1DESC'], 0, 'L', 0, 0, $x, $y, true, 0, false, true, 0);
        // resete x y
        $pdf->SetXY($x + $etiquetas_largura, $y - 5);
画骨成沙 2024-08-11 20:21:38

@Muhammad Abdul Rahim 和@tomazahlin 提供了很好的方法。他们只解决了单个单元格中的换行问题。它们的主题单元格的高度与同一行中的其他单元格的高度不匹配。如果处理动态表,使用 GetY() 会变得很复杂。我发现的最简单的解决方案是识别可能具有溢出文本的列并将其用作参考。

$l=strlen($string_of_reference_cell);
$h = ceil($l/$cell_width*1.5)*preferred_normal_height;//1.5 is a loading for allowance`depending on font size.

$pdf->cell(20,$h,$string,1,0);
$pdf->MultiAlignCell(50,5,$string_of_reference_cell,1,0);// 5 is the preferred normal height
$pdf->Cell(23,$h,$string,1,1);

生成pdf时,如果MultiAlignCell的字符串长于单元格宽度,则会产生换行。所得高度是两倍 (5 x 2 = 10)。 10 的高度被指定为 $h。因此,其他单元格也采用 $h 的高度,并且整行获得统一的高度。

@Muhammad Abdul Rahim and @tomazahlin have have provided good methods. The problem they only sort out the line break problem in a single cell. They don't match the height of the subject cell with other cells in the same row. Using GetY() gets complicated if you are dealing with dynamic tables. The simplest solution I have found is identifying the column likely to have overflowing text and using it as a reference.

$l=strlen($string_of_reference_cell);
$h = ceil($l/$cell_width*1.5)*preferred_normal_height;//1.5 is a loading for allowance`depending on font size.

$pdf->cell(20,$h,$string,1,0);
$pdf->MultiAlignCell(50,5,$string_of_reference_cell,1,0);// 5 is the preferred normal height
$pdf->Cell(23,$h,$string,1,1);

When the pdf is generated, if the string of MultiAlignCell is longer than the cell width, a line break is generated. The resulting height is twice(5 x 2 = 10). The height of ten is asigned to $h. Hence the other cells take the height of $h as well and the entire row gets a uniform height.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文