Fpdf 多小区问题

Fpdf 多小区问题,fpdf,Fpdf,我们如何以相同高度显示fpdf多小区,其内容量不同这是一个很好的问题。 我通过检查您所在行中将被多单元化的每个数据单元来解决这个问题,并确定所有这些单元的最大高度。这发生在创建行中的第一个单元格之前,并且在实际渲染行时,它将成为行的新高度 以下是仅针对一个单元实现此目标的一些步骤,但您需要针对每个多单元执行此操作: 这假设数据的$row具有名为description的字符串属性 首先,获取单元格内容并设置单元格的列宽。 $description=$row['description'];//多单元

我们如何以相同高度显示fpdf多小区,其内容量不同

这是一个很好的问题。

我通过检查您所在行中将被多单元化的每个数据单元来解决这个问题,并确定所有这些单元的最大高度。这发生在创建行中的第一个单元格之前,并且在实际渲染行时,它将成为行的新高度

以下是仅针对一个单元实现此目标的一些步骤,但您需要针对每个多单元执行此操作:

这假设数据的
$row
具有名为
description
的字符串属性

  • 首先,获取单元格内容并设置单元格的列宽。

    $description=$row['description'];//多单元(多行)内容。
    $column_width=50;
    
  • 使用
    FPDF
    中的
    GetStringWidth()
    函数获取
    描述
    字符串的宽度:

    $total\u string\u width=$pdf->GetStringWidth($description);
    
  • 确定此单元格的行数:

    $number\u of_line=$total\u string\u width/($column\u width-1);
    $number_of_line=ceil($number_of_line);//把它围起来。
    
    我从
    $column\u width
    中减去1作为一种单元格填充。它产生了更好的结果

  • 确定生成的多行单元格的高度:

    $line_height=5;//不管你的线有多高。
    $height\u of_cell=$number\u of_line*$line\u height;
    $height_of_cell=ceil($height_of_cell);//把它围起来。
    
  • 对任何其他多小区重复此方法,将
    $row\u height
    设置为\u小区的最大
    $height\u

  • 最后,使用
    $row\u height
    渲染行的高度。


  • 我也遇到了同样的问题,当我必须将高度设置为三行时,即使我的内容是半行或一行半,我通过检查字符串中元素的数量是否少于一行中可能的字母的数量来解决这个问题,它是60。如果字母数不小于或等于一行,则为两行空行调用ln(),如果单词数不小于或等于两行字母,则为一行调用ln()。 我的代码在这里:

    $line_width = 60; // Line width (approx) in mm
    if($pdf->GetStringWidth($msg1) < $line_width) 
    {
        $pdf->MultiCell(75, 8, $msg1,' ', 'L');
        $pdf->ln(3);
        $pdf->ln(3.1);
    }
    else{
        $pdf->MultiCell(76, 4, $msg1,' ', 'L');
        $pdf->ln(3.1);
    }
    
    $line_width=60;//线条宽度(约)单位:mm
    如果($pdf->GetStringWidth($msg1)<$line\u width)
    {
    $pdf->MultiCell(75,8,$msg1,,'L');
    $pdf->ln(3);
    $pdf->ln(3.1);
    }
    否则{
    $pdf->MultiCell(76,4,$msg1,,'L');
    $pdf->ln(3.1);
    }
    
    好的,我已经完成了递归版本。希望这对事业有更大的帮助! 考虑这些变量:

    $columnLabels:每列的标签,因此您将在每列后面存储数据) $alturasFilas:存储每行最大高度的数组

    //Calculate max height for each column for each row and store the value in      //////an array
            $height_of_cell = 0;
            $alturasFilas = array();
    
            foreach ( $data as $dataRow ) {
                for ( $i=0; $i<count($columnLabels); $i++ ) {
                    $variable = $dataRow[$i];
                    $total_string_width = $pdf->GetStringWidth($variable);
                    $number_of_lines = $total_string_width / ($columnSizeWidth[$i] - 1);
                    $number_of_lines = ceil( $number_of_lines );  // Redondeo.
    
                    $line_height = 8;  // Altura de fuente.
                    $height_of_cellAux = $number_of_lines * $line_height; 
                    $height_of_cellAux = ceil( $height_of_cellAux ); 
    
                    if($height_of_cellAux > $height_of_cell){
                        $height_of_cell = $height_of_cellAux;
                        }
    
                }
                array_push($alturasFilas, $height_of_cell);
                $height_of_cell = 0;
            }
            //--END-- 
    
    //计算每行每列的最大高度,并将值存储在数组中
    $height_of_cell=0;
    $alturasFilas=array();
    foreach($dataRow形式的数据){
    对于($i=0;$iGetStringWidth($variable));
    $number_of_line=$total_string_width/($columnSizeWidth[$i]-1);
    $number\u of_line=ceil($number\u of_line);//Redondeo。
    $line_height=8;//富恩特阿尔图拉酒店。
    $height_of_cellAux=$number_of_line*$line_height;
    $height\u of_cellAux=ceil($height\u of_cellAux);
    if($height\u of_cellAux>$height\u of_cell){
    $height\u of_cell=$height\u of_cellAux;
    }
    }
    阵列推送($alturasFilas,$height_of_cell);
    $height_of_cell=0;
    }
    //--结束--
    

    享受吧!

    首先,获得Multicell的高度不是问题。(致@Matias,@Josh Pinter)

    我修改了@Balram Singh的答案,将此代码用于两行以上的代码。 我添加了新行(\n)以锁定Multicell的高度。 像

    $cell\u width=92;//多小区宽度(单位:mm)
    $max\u line\u number=4;//如您所愿,多小区的最大行号
    $string_width=$pdf->GetStringWidth($data);
    $line\u number=ceil($string\u width/$cell\u width);
    
    对于($i=0;$i我的方法非常简单。您已经需要重写fpdf类中的header()和footer()。 所以我刚刚添加了一个函数
    MultiCellLines($w,$h,$txt,$border=0,$align='J',$fill=false)
    。 这是原始MultiCell的一个非常简单的副本。但它不会输出任何内容,只返回行数

    将线与线的高度相乘,您就安全了;) 下载我的代码是

    只要把它重新命名为“.php”或任何你喜欢的名字。玩得开心。它肯定能工作


    Mac

    我的个人解决方案,根据预设框减小字体大小和行距:

    // set box size and default font size
    $textWidth  = 100;
    $textHeight = 100;
    $fontsize   = 12;
    
    // if you get text from html div (using jquery and ajax) you must replace every <br> in a new line
    $desc    = utf8_decode(str_replace('<br>',chr(10),strip_tags($_POST['textarea'],'<br>')));
    
    // count newline set in $desc variable
    $countnl = substr_count($desc, "\n");
    
    // Create a loop to reduce the font according to the contents
    while($pdf->GetStringWidth($desc) > ($textWidth * (($textHeight-$fontsize*0.5*$countnl) / ($fontsize*0.5)))){
      $fontsize--;
      $pdf->SetFont('Arial','', $fontsize);
    }
    
    // print multicell and set line spacing
    $pdf->MultiCell($textWidth, ($fontsize*0.5), "$desc", 0, 'L');
    
    //设置框大小和默认字体大小
    $textWidth=100;
    $textHeight=100;
    $fontsize=12;
    //如果从HTMLdiv(使用jquery和ajax)获取文本,则必须在新行中替换每个
    $desc=utf8_解码(str_替换(“
    ”,chr(10),strip_标签($_POST['textarea'],“
    ”)); //计数$desc变量中的换行符集 $countnl=子计数($desc,“\n”); //创建一个循环,根据内容减少字体 而($pdf->GetStringWidth($desc)>($textWidth*($textHeight-$fontsize*0.5*$countnl)/($fontsize*0.5))){ $fontsize--; $pdf->SetFont('Arial','',$fontsize); } //打印多单元格并设置行距 $pdf->MultiCell($textWidth,($fontsize*0.5),“$desc”,0,'L');

    仅此而已!

    更好的解决方案是使用您自己的换行功能,因为FPDF不会剪切单词,因此您不必依赖多小区换行

    我编写了一个方法,如果FPDF的getStringWidth更大,则检查文本的每个子字符串
    // set box size and default font size
    $textWidth  = 100;
    $textHeight = 100;
    $fontsize   = 12;
    
    // if you get text from html div (using jquery and ajax) you must replace every <br> in a new line
    $desc    = utf8_decode(str_replace('<br>',chr(10),strip_tags($_POST['textarea'],'<br>')));
    
    // count newline set in $desc variable
    $countnl = substr_count($desc, "\n");
    
    // Create a loop to reduce the font according to the contents
    while($pdf->GetStringWidth($desc) > ($textWidth * (($textHeight-$fontsize*0.5*$countnl) / ($fontsize*0.5)))){
      $fontsize--;
      $pdf->SetFont('Arial','', $fontsize);
    }
    
    // print multicell and set line spacing
    $pdf->MultiCell($textWidth, ($fontsize*0.5), "$desc", 0, 'L');
    
    public function wordWrapMultiCell($text, $cellWidth = 80) {
        $explode = explode("\n", $text);
    
        array_walk($explode, 'trim');
    
        $lines = [];
        foreach($explode as $split) {
            $sub = $split;
            $char = 1;
    
            while($char <= strlen($sub)) {
                $substr = substr($sub, 0, $char);
    
                if($this->pdf->getStringWidth($substr) >= $cellWidth - 1) { // -1 for better getStringWidth calculating
                    $pos = strrpos($substr, " ");
    
                    $lines[] = substr($sub, 0, ($pos !== FALSE ? $pos : $char)).($pos === FALSE ? '-' : '');
    
                    if($pos !== FALSE) { //if $pos returns FALSE, substr has no whitespace, so split word on current position
                        $char = $pos + 1;
                        $len = $char;
                    }
    
                    $sub = ltrim(substr($sub, $char));
                    $char = 0;
                }
    
                $char++;
            }
    
            if(!empty($sub)) {
                $lines[] = $sub;
            }
        }
    
        return $lines;
    }
    
    join("\r\n", $lines);
    
    $lineHeight = count($lines) * $multiCellLineHeight;