Подтвердить что ты не робот

Многосекундная проблема fpdf

как мы отображаем многосекунд fpdf на равных высотах, имеющих различное количество контента

4b9b3361

Ответ 1

Отличный вопрос.

Я решил это, пройдя каждую ячейку данных в вашей строке, которая будет многострочной и определит наибольшую высоту всех этих ячеек. Это происходит до того, как вы создадите первую ячейку в строке, и она станет новой высотой вашей строки, когда вы действительно собираетесь ее отображать.

Вот несколько шагов для достижения этой цели только для одной ячейки, но вам нужно сделать это для каждой многоядерной книги:

Это предполагает $row данных с атрибутом String под названием description.

  • Сначала введите содержимое ячейки и установите ширину столбца для ячейки.

    $description = $row['desciption'];           // MultiCell (multi-line) content.
    
    $column_width = 50;
    
  • Получить ширину строки description с помощью функции GetStringWidth() в FPDF:

    $total_string_width = $pdf->GetStringWidth($description);
    
  • Определите количество строк, которые эта ячейка будет:

    $number_of_lines = $total_string_width / ($column_width - 1);
    
    $number_of_lines = ceil( $number_of_lines );  // Round it up.
    

    Я вычитал 1 из $column_width как своего рода заполнение ячеек. Это принесло лучшие результаты.

  • Определить высоту результирующей многострочной ячейки:

    $line_height = 5;                             // Whatever your line height is.
    
    $height_of_cell = $number_of_lines * $line_height; 
    
    $height_of_cell = ceil( $height_of_cell );    // Round it up.
    
  • Повторите эту методологию для любых других ячеек MultiCell, установив $row_height в самый большой $height_of_cell.

  • Наконец, сделайте свою строку, используя $row_height для вашей высоты строки.

  • Dance.

Ответ 2

У меня также возникала такая же проблема, когда мне приходилось устанавливать высоту, равную трем строкам, даже если у меня есть половина или 1 и половина строки, я решил это, проверив, нет ли в строке ни одного элемента меньше, чем никаких возможных букв в строке это 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);
}

Ответ 3

Хорошо, я сделал рекурсивную версию. Надеюсь, это поможет еще больше делу! Учитывайте эти переменные:

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

Наслаждайтесь!

Ответ 4

Во-первых, это не вопрос, чтобы получить высоту Multicell. (к @Matias, @Josh Pinter)

Я изменил ответ @Balram Singh, чтобы использовать этот код для более чем двух строк. и я добавил новые строки (\n), чтобы заблокировать высоту Multicell. как..

$cell_width = 92; // Multicell width in mm
$max_line_number = 4; // Maximum line number of Multicell as your wish
$string_width = $pdf->GetStringWidth($data);
$line_number = ceil($string_width / $cell_width);
for($i=0; $i<$max_line_number-$line_number; $i++){
    $data.="\n ";
}

Конечно, вам нужно назначить SetFont() перед использованием GetStringWidth().

Ответ 5

Мой подход был довольно прост. Вам уже нужно переопределить заголовок() и нижний колонтитул() в классе fpdf. Поэтому я просто добавил функцию MultiCellLines($w, $h, $txt, $border=0, $align='J', $fill=false). Это очень простая копия оригинального MultiCell. Но он ничего не выводит, просто верните количество строк.

Умножьте строки с высотой линии, и вы в безопасности;) Загрузить для моего кода здесь.

Просто переименуйте его обратно в ".php" или как угодно. Повеселись. Он работает определенно.

Mac

Ответ 6

Мое личное решение уменьшить размер шрифта и расстояние между строками в соответствии с предустановленным полем:

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

Что все!

Ответ 7

Лучшим решением будет использование вашей собственной функции переноса слов, поскольку FPDF не будет вырезать слова, поэтому вам не придется полагаться на разрыв строки MultiCell.

Я написал метод, который проверяет каждую подстроку текста, если getStringWidth из FPDF больше ширины столбца и соответственно разбивается. Это здорово, если вы больше заботитесь о хорошем формате PDF, чем о производительности.

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

Возвращает массив текстовых строк, которые вы можете объединить с помощью команды implode/join:

join("\r\n", $lines);

И для чего он использовался в первую очередь, получите высоту строки:

$lineHeight = count($lines) * $multiCellLineHeight;

Это работает только для строк с символом пробела, без белых интервалов, таких как вкладки. Затем вы можете заменить strpos на функцию regexp.

Ответ 8

Вы можете попробовать использовать ROW & FancyRow. Пожалуйста, обратитесь ниже ссылки

Я не знаю, почему добавили отрицательные моменты в этом посте, Row более гибок, когда вы пишете в коде. Ряд содержит многоклеточный.