Menu

Any way to format text inside a MultiCell?

Help
2013-06-18
2014-08-13
  • semmelbroesel

    semmelbroesel - 2013-06-18

    Hi.
    I need to create a PDF that changes the font to bold inside the paragraph to highlight parts of the text. For speed reasons, I found I cannot use HTML code for formatting, so I am using the native Cell and MultiCell functions.
    I could produce the same result using Cell, creating a new cell for each text section that changes format, and manually play with it until I get the positions all correct, but I am hoping that there is a better solution for this.
    The paragraph also needs to have line breaks which is why I'm hoping this can work with MultiCell.
    Thanks!

     
    • Gabriel P

      Gabriel P - 2014-08-13

      Late to the party, but I created method for myself which does just this.
      :::php

      // write with ability to set bold font for parts of string
          private function _write($string, $font_size = 9)
          {
              foreach (explode('b>', $string) as $str_line)
              {
                  $ending = substr($str_line, -2);
                  if ($ending == '</')
                  {
                      $str_line = substr($str_line, 0, -2);
                      $this->SetFont('freeserif', 'B', $font_size);
                  }
                  elseif (strlen($ending) > 1 && $ending[1] == '<')
                  {
                      $str_line = substr($str_line, 0, -1);
                      $this->SetFont('freeserif', '', $font_size);
                  }
                  $this->Write(0, $str_line);
              }
          }
      
       

      Last edit: Gabriel P 2014-08-13
  • James Holland

    James Holland - 2013-06-18

    I don't think it is possible to do using Cell or Multicell.

    If you know which paragraphs contain the formatting, you could just output the paragraphs needed using html.

    Is the text already html formatted? and do you need to support anything other than bold?

     
  • semmelbroesel

    semmelbroesel - 2013-06-18

    (dang, hit the wrong button to reply...)

    Thanks for your reply.

    I was afraid you were gonna say that ... :-)

    I could use HTML formatting, and if nothing else works, I'll have to, but in my tests it has slowed down the PDF creation majorly, and I might print hundreds of pages into one document.

    The incoming text that needs to be formatted is pre-defined in my code and at this time not formatted.

    All I need at this point (until my boss comes up with more fun ideas...) is to switch between bold and regular.

     
  • James Holland

    James Holland - 2013-06-18

    I don't know the format you are starting with, but assuming you have a huge variable with all the text in it $allText.
    I would try:
    $paragraphs=explode('\r\n', $allText);//Split into paragraphs
    foreach($paragraphs as $key => $thisPara){
    if(strpos($thisPara, '')===false) //You can use a cell
    else //Need to use html
    }

    This MAY improve performance, it depends on how many paragraphs would contain html tags, without seeing the source I'd be out of ideas.

    Thanks

    James

     
  • semmelbroesel

    semmelbroesel - 2013-06-18

    I see what you're doing there, but it's in the middle of paragraphs that I need to change formatting :-/
    Example (using HTML to show what I mean):

    Click <b>"User Settings"</b> to continue.
    

    Here's what I'm doing right now in one line where it's simple without any text after it, but as you can see, it's a pain:

    $myY += 6;  // my variable to keep track of the vertical location of stuff
    $pdf->SetXY($myX, $myY);
    $pdf->Cell(9, 15, 'Click ');
    $pdf->SetFont('freesans', 'B', 11);
    $pdf->Cell(50, 15, '"Click here to register"');
    $pdf->SetFont('freesans', '', 11);
    $myY += 14;
    

    Here's an example of what the rest of the document looks like:

    $myY += 9;
    $pdf->SetXY($myX, $myY);
    $txt = <<<TXT
    Next, click <b>"Save"</b> to save your settings.
    
    Please feel free to contact us if you have any questions.
    TXT;
    $pdf->MultiCell($myWidth, 80, $txt, 0, 'L', 0, 1, '', '', true);
    

    I only added the html tags here to show where I need the formatting to happen.
    I hope this makes sense...

    Meanwhile, I've started trying to convert it all to HTML, and that seems to open more cans of worms since the left margin for some reason doesn't match the MultiCell margin and the line height inside WriteHTML doesn't match and is hard to control, but I guess it's still doable as long as it won't slow me down too much.

     
  • semmelbroesel

    semmelbroesel - 2013-06-18

    I'm not trying to be a complainer, but I'm having major difficulties with writeHTML right now... The b tag creates some kind of horizontal margin or padding around itself, and there's really weird stuff going on when I have a div with inline style for margin-bottom and a b tag in it - just before the b tag, the text gets pushed down a few pixels, and after the line break I get about the height of a line of empty space before the second line starts... Is this normal? I haven't used writeHTML before...
    PS: Same happens with span style="font-weight: bold;" ... Really weird...

     

    Last edit: semmelbroesel 2013-06-18
  • James Holland

    James Holland - 2013-06-19

    How about Write()?

    This method allows you to just output text like Cell() but without specifying a width e.g.

    $pdf->SetFont('freesans', '', 11);
    $pdf->Write(6, 'Click ');
    $pdf->SetFont('freesans', 'B', 11);
    $pdf->Write(6, 'here ');
    $pdf->SetFont('freesans', '', 11);
    $pdf->Write(6, 'for more information.');

    $pdf-SetY($pdf->GetY()+3);

    This should achieve what you want without messing around trying to keep track of your X position, and you only need to modify the Y position if you want a paragraph space.

    Don't forget to include a space at the beginning or end of each string for spacing purposes, but that should work!

     

    Last edit: James Holland 2013-06-19
  • semmelbroesel

    semmelbroesel - 2013-06-19

    (duplicate post, ignore)

     

    Last edit: semmelbroesel 2013-06-19
  • semmelbroesel

    semmelbroesel - 2013-06-19

    Huh, I have not looked at Write() yet - will that create an automatic line break when it reaches the end of the line?
    If yes, then that looks like a near perfect solution for what I need!
    What does it use for confinement, i.e. what is the "box" the defines where Write() is allowed to write?

     
  • Nicola Asuni

    Nicola Asuni - 2013-06-19

    WiteHTMLCell() works as multicell but allows you to use some HTML syntax.
    Please check the default examples for further information.

     
    • semmelbroesel

      semmelbroesel - 2013-06-19

      Thanks for the suggestion, but I tried that, and for some reason I couldn't get it to flow normally...
      I tried b and span tags, and as I described above, there was always the space of at least 4 space characters before and after the span/b tag, and inside the div, there was also space above, and that made any form of formatting completely impossible. No idea what happened there. I kept it as simple as I could with p, b, div, and span tags with minimal style information...
      So for now, I simply removed all bold formatting from the document just so I had something available for my project. But if the Write() situation works and allows me to change formatting in the middle of a line and still have normal line breaks and the same margins of the rest of the document, that would allow me to revisit the project and implement bold formatting after all :-)

       
  • Lubos Dz

    Lubos Dz - 2013-06-19

    If you are embedding pre-defined static texts of whatever graphical complexity, you could efficiently import PDF binary templates with FPDI without loosing performance - see http://www.setasign.de/products/pdf-php-solutions/fpdi/

     
    • semmelbroesel

      semmelbroesel - 2013-06-19

      Hm, that is a possibility - except it looks like it might be even more complicated to create the template and implement it than figuring out this last question ;-)

      So right now, I only have two last questions remaining regarding Write():
      Does it automatically create line breaks, and how do I define the area in which the text will go and wrap?

       

Log in to post a comment.