Выровненный текст с WriteHTML FPDF

Проблема: я пытаюсь сделать PDF с FPDF, как эта часть документа ниже (мне нужен PDF с HTML-тегами и оправданным текстом):

Название: Lorem Ipsum Dolor Sit Amet, Заклинатель Адептисинг Элит. Duis Molestie Turpis Vitae Blandit Tristique. Nulla pellentesque et enim non pulvinar. Integer Gravida Ullamcorper Tortor в Дигниссим. Fusce gravida faucibus ultricies. Морби пульвинар нибх нек магна тинсидунт дигнисим. Cras faucibus condimentum pharetra.

Название: Lorem Ipsum Dolor Sit Amet, Заклинатель Адептисинг Элит. Duis Molestie Turpis Vitae Blandit Tristique. Nulla pellentesque et enim non pulvinar. Integer Gravida Ullamcorper Tortor в Дигниссим. Fusce gravida faucibus ultricies. Морби пульвинар нибх нек магна тинсидунт дигнисим. Cras faucibus condimentum pharetra.....

Я могу использовать теги "B", "P", "BR"... или выровнять выравнивание, но не две вещи.

с этими двумя сценариями, FPDF Script41 и FPDF Script42, HTML-теги работают нормально, но я не могу поставить align = justify. с этим скриптом http://fpdf.de/downloads/addons/8/ я не могу использовать теги HTML, потому что он использует "Cell" и "MultiCell".

3 ответа

Решение

У меня была такая же проблема, и я искал решение, когда натолкнулся на ваш вопрос. Теперь, когда я это решил, у вас тоже может быть решение:)

Проблема в том, что Write() вызывает Cell(), а Cell() не поддерживает $align='J'.

Я нашел это решение fpdf addon, который добавляет Justify в функцию Cell(). Я сравнил этот код с моей функцией Cell(), потому что версии немного отличаются и используют только соответствующие части, добавляя биты выравнивания.

Затем я следовал за этой функцией в FPDF Script42, который вы упомянули, и добавил

$align=''

параметр функции Write(). Затем добавил его, чтобы он отправлял этот $ align на вызов Cell. Я на самом деле не уверен, добавил ли я $ align или он был там изначально (я сделал так много изменений, которые не помню). Затем просто передайте 'FJ' вашему вызову Write(), и он будет отправлен через Cell() для подтверждения.

$this->Write(5,stripslashes(txtentities($e)),'FJ');

Основываясь на ответе @yusuf-moola, вот два метода:

      function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link=''){
    $k=$this->k;
    if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()){
        $x=$this->x;
        $ws=$this->ws;
        if($ws>0){
            $this->ws=0;
            $this->_out('0 Tw');
        }
        $this->AddPage($this->CurOrientation);
        $this->x=$x;
        if($ws>0){
            $this->ws=$ws;
            $this->_out(sprintf('%.3F Tw',$ws*$k));
        }
    }
    if($w==0)
        $w=$this->w-$this->rMargin-$this->x;
    $s='';
    if($fill || $border==1){
        if($fill)
            $op=($border==1) ? 'B' : 'f';
        else
            $op='S';
        $s=sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
    }
    if(is_string($border)){
        $x=$this->x;
        $y=$this->y;
        if(is_int(strpos($border,'L')))
            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
        if(is_int(strpos($border,'T')))
            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
        if(is_int(strpos($border,'R')))
            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
        if(is_int(strpos($border,'B')))
            $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
    }
    if($txt!=''){
        if($align=='R')
            $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
        elseif($align=='C')
            $dx=($w-$this->GetStringWidth($txt))/2;
        elseif($align=='FJ'){
            //Set word spacing
            $wmax=($w-2*$this->cMargin);
            $nb=substr_count($txt,' ');
            if($nb>0)
                $this->ws=($wmax-$this->GetStringWidth($txt))/$nb;
            else
                $this->ws=0;
            $this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
            $dx=$this->cMargin;
        }
        else
            $dx=$this->cMargin;
        $txt=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
        if($this->ColorFlag)
            $s.='q '.$this->TextColor.' ';
        $s.=sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt);
        if($this->underline)
            $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
        if($this->ColorFlag)
            $s.=' Q';
        if($link){
            if($align=='FJ')
                $wlink=$wmax;
            else
                $wlink=$this->GetStringWidth($txt);
            $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$wlink,$this->FontSize,$link);
        }
    }
    if($s)
        $this->_out($s);
    if($align=='FJ'){
        //Remove word spacing
        $this->_out('0 Tw');
        $this->ws=0;
    }
    $this->lasth=$h;
    if($ln>0){
        $this->y+=$h;
        if($ln==1)
            $this->x=$this->lMargin;
    }
    else
        $this->x+=$w;
}

function Write($h, $txt, $link='', $align=''){
    // Output text in flowing mode
    if(!isset($this->CurrentFont))
    $this->Error('No font has been set');
    $cw = &$this->CurrentFont['cw'];
    $w = $this->w-$this->rMargin-$this->x;
    $wmax = ($w-2*$this->cMargin);
    $s = str_replace("\r",'',(string)$txt);
    if ($this->unifontSubset) {
        $nb = mb_strlen($s, 'UTF-8');
        if($nb==1 && $s==" ") {
            $this->x += $this->GetStringWidth($s);
            return;
        }
    }
    else {
        $nb = strlen($s);
    }
    $sep = -1;
    $i = 0;
    $j = 0;
    $l = 0;
    $nl = 1;
    while($i<$nb){
        // Get next character
        if ($this->unifontSubset) {
            $c = mb_substr($s,$i,1,'UTF-8');
        }
        else {
            $c = $s[$i];
        }
        if($c=="\n"){
            // Explicit line break
            if ($this->unifontSubset) {
                $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,$align,false,$link);
            }
            else {
                $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,$align,false,$link);
            }
            $i++;
            $sep = -1;
            $j = $i;
            $l = 0;
            if($nl==1)
            {
                $this->x = $this->lMargin;
                $w = $this->w-$this->rMargin-$this->x;
                $wmax = ($w-2*$this->cMargin);
            }
            $nl++;
            continue;
        }
        if($c==' ')
        $sep = $i;

        if ($this->unifontSubset) { $l += $this->GetStringWidth($c); }
        else { $l += $cw[$c]*$this->FontSize/1000; }

        if($l>$wmax){
            // Automatic line break
            if($sep==-1){
                if($this->x>$this->lMargin){
                    // Move to next line
                    $this->x = $this->lMargin;
                    $this->y += $h;
                    $w = $this->w-$this->rMargin-$this->x;
                    $wmax = ($w-2*$this->cMargin);
                    $i++;
                    $nl++;
                    continue;
                }
                if($i==$j)
                $i++;
                if ($this->unifontSubset) {
                    $this->Cell($w,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,2,$align,false,$link);
                }
                else {
                    $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,$align,false,$link);
                }
            }
            else{
                if ($this->unifontSubset) {
                    $this->Cell($w,$h,mb_substr($s,$j,$sep-$j,'UTF-8'),0,2,$align,false,$link);
                }
                else {
                    $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,$align,false,$link);
                }
                $i = $sep+1;
            }
            $sep = -1;
            $j = $i;
            $l = 0;
            if($nl==1){
                $this->x = $this->lMargin;
                $w = $this->w-$this->rMargin-$this->x;
                $wmax = ($w-2*$this->cMargin);
            }
            $nl++;
        }
        else
        $i++;
    }
    // Last chunk
    if($i!=$j) {
        if ($this->unifontSubset) {
            $this->Cell($l,$h,mb_substr($s,$j,$i-$j,'UTF-8'),0,0,$align,false,$link);
        }
        else {
            $this->Cell($l,$h,substr($s,$j),0,0,$align,false,$link);
        }
    }
}

function WriteHTML($html, $h=4.5, $align='')   {
    // $html=utf8_decode($html);
    $a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
    foreach($a as $i=>$e)
    {
        if($i%2==0)
        {
            //Texte
            if($this->HREF)
                $this->PutLink($this->HREF,$e);
            else
                $this->Write( $h, $e, '', $align);
        }
        else
        {
            //Balise
            if($e[0]=='/')
                $this->CloseTag(strtoupper(substr($e,1)));
            else
            {
                //Extraction des attributs
                $a2=explode(' ',$e);
                $tag=strtoupper(array_shift($a2));
                $prop=array();
                foreach($a2 as $v)
                {
                    if(preg_match('/([^=]*)=["\']?([^"\']*)/',$v,$a3))
                        $prop[strtoupper($a3[1])]=$a3[2];
                }
                $this->OpenTag($tag,$prop);
            }
        }
    }
}

У меня сработало с остальной частью скрипта42

Решение:

Я думаю, что вам нужно это: "Форматирование на основе тегов"

в: http://fpdf.org/en/script/script23.php

Другие вопросы по тегам