Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addText() function and text formatting (new line "\n") #553

Open
simogeo opened this issue Jun 12, 2015 · 27 comments
Open

addText() function and text formatting (new line "\n") #553

simogeo opened this issue Jun 12, 2015 · 27 comments

Comments

@simogeo
Copy link

simogeo commented Jun 12, 2015

Hi,

I have a problem regarding formatting text. Actually, it seems, all \n are not interpreted when opening file with Word 2007. Here are some screenshots :

This is how it appears in LibreOffice :
lo

And how it (sadly) appears in Word 2007 :

w2007

ANy help would be welcome ! I use last stable version - 0.12.0. Thanks !


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@simogeo simogeo mentioned this issue Jun 15, 2015
@RKaczmarek
Copy link

Hi,

you maybe misunderstood how phpword works.

addText is for adding a paragraph with text. The text is not seperated by line breaks. If you would like to add line breaks then use addTextRun.

With a textrun you can add text and textbreaks within one paragraph.

$text = "foo\nbar\nfoobar";
$textlines = explode("\n", $text);

$textrun = $section->addTextRun();
$textrun->addText(array_shift($textlines));
foreach($textlines as $line) {
    $textrun->addTextBreak();
    // maybe twice if you want to seperate the text
    // $textrun->addTextBreak(2);
    $textrun->addText($line);
}

@simogeo
Copy link
Author

simogeo commented Jun 17, 2015

Thanks for your interest on that.
But why not an optional parameter for commodity ? here is my proposed idea (not sure it works since it is not tested)

@morrido
Copy link

morrido commented Sep 9, 2015

How to apply this in the template?
e.g.: $templateProcessor->setValue....

@cbloss
Copy link

cbloss commented Oct 26, 2015

I second morrido. How do you do it in a template?

@Motchouk
Copy link

$text = "foo\nbar\nfoobar";
$textlines = explode("\n", $text);

$textrun = $section->addTextRun();
$textrun->addText(array_shift($textlines));
foreach($textlines as $line) {
$textrun->addTextBreak();
// maybe twice if you want to seperate the text
// $textrun->addTextBreak(2);
$textrun->addText($line);
}

This also works (I just used it) :

$text = "foo\nbar\nfoobar";
$textlines = explode("\n", $text);

for ($i = 0; $i < sizeof($textlines); $i++) {
    $section->addText($textlines[$i]);
}

@feakuru
Copy link

feakuru commented Dec 15, 2016

I, just like @morrido and @cbloss here, would like to know if this is usable in a template. Please answer. Thx in advance

@Dvlv
Copy link

Dvlv commented Jan 5, 2017

@feakuru @morrido @cbloss
Looks for me like <w:br /> is interpreted as a newline in proper Word.
In libreoffice it just looks like a space (was frustrating me).

so e.g.

$templateProcessor->setValue(name_address, 'John <w:br /> 123 fake street');

@BafS
Copy link

BafS commented Feb 3, 2017

I used "\n" and then the regex $text = preg_replace('~\R~u', '</w:t><w:br/><w:t>', $text);.

@geigel
Copy link

geigel commented Oct 18, 2017

Awesome @RKaczmarek, exactly what I needed. Thank you. The solution works for addListItemRuns as well as that is what I was using.

@guenter47
Copy link

@RKaczmarek & @BafS
in my case:
$text='aaa\nbbb'
$text = preg_replace('\Ru', '</w:t><w:br/><w:t>', $text);
$templateProcessor->setValue('sp'.$i.'z1#'.$j,$text);

write in word:
'aaa\nbbb'

@simogeo
Copy link
Author

simogeo commented Nov 25, 2017

replace simple quotes by double quotes :

$text="aaa\nbbb"

@nacesprin
Copy link

@feakuru @morrido @cbloss
Looks for me like <w:br /> is interpreted as a newline in proper Word.
In libreoffice it just looks like a space (was frustrating me).

so e.g.

$templateProcessor->setValue(name_address, 'John <w:br /> 123 fake street');

#838

@joaodos3v
Copy link

@feakuru @morrido @cbloss
Looks for me like <w:br /> is interpreted as a newline in proper Word.
In libreoffice it just looks like a space (was frustrating me).

so e.g.

$templateProcessor->setValue(name_address, 'John <w:br /> 123 fake street');

As @BafS answered, add \n to the text you want to format, like this:
$templateProcessor->setValue("value_to_change", "value\nthat _will_replace");

After that, go to your TemplateProcessor.php file and find the setValueForPart($ search, $ replace, $ documentPartXML, $ limit). In the first line of this function, add:
$replace = preg_replace('~\R~u', '</w:t><w:br/><w:t>', $replace);

This worked perfectly for me in LibreOffice and Word.
I hope this helps someone.

@Francesco-Manicardi
Copy link

Here's the true answer to "How to add newline while template processing"

You can't just replace \n with </w:t><w:br/><w:t> because that will BREAK PARAGRAPHS.
This means that tab stops that have been set on the placeholder will not carry over to the next line!

The real solution is to always use a complex type instead of using strings.

So in my function instead of returning a string I do this:

            $res = "some text\n with\n newlines\tand\ttabs
            $textlines = explode("\n", $res);
            $textrun = new PhpOffice\PhpWord\Element\TextRun();
            $textrun->addText(array_shift($textlines));
            foreach ($textlines as $line) {
                $textrun->addTextBreak();
                $textrun->addText($line);
            }
            return $textrun;

and in the template processor driver I use:

$templateProcessor->setComplexValue($key, $textrun);

this will result in newlines and tab stops and other paragraph related things are preserved in the next lines!

This allows you to create basic tables with tab stops and not worry about them breaking after the new lines.

@jjdejong
Copy link

setComplexValue($key, $textrun) throws an error when there are multiple lines. Apparently setComplexBlock($key, $textrun) should be used instead, but that deletes all the other text present in the same line.

@Francesco-Manicardi
Copy link

setComplexValue($key, $textrun) throws an error when there are multiple lines.

What is the error thrown? I'm using it in production right now and I'm not having any problems.
Also, it looks like setComplexValue also deletes all other text in the same line.

@jjdejong
Copy link

I get "Trying to access array offset on value of type bool" in line 277 of TemplateProcessor.php.

So if the "Value" flavor also deletes all other text, what's the difference between the "Value" and "Block" flavors ?

@jjdejong
Copy link

I'll take that back, the "Value" flavor does work in most cases, but there is just one situation in my application where it throws the error. I need to find out still.

@Francesco-Manicardi
Copy link

That's the same error I have, but in PhpSpreadsheet instead.
Let me know if you get to the root of it, i still haven't understood what causes it.
My solutino was just putting everything in a try catch block and call it a day

@jjdejong
Copy link

Also, it looks like setComplexValue also deletes all other text in the same line.

Are you sure ? Not in my case. That would be the difference between the Block and Value flavors.

@Francesco-Manicardi
Copy link

Yes, i have a .docx template like this:
image

As you can see there's content to the right of the placeholder.
when i call setComplexValue with a textRun, that text gets deleted
this is the result of the setComplexValue
image

@jjdejong
Copy link

jjdejong commented Jan 13, 2021

As you can see there's content to the right of the placeholder.
when i call setComplexValue with a textRun, that text gets deleted
this is the result of the setComplexValue

Ah, in my case it's text on the left that is preserved.

@jjdejong
Copy link

jjdejong commented Jan 13, 2021

That's the same error I have, but in PhpSpreadsheet instead.
Let me know if you get to the root of it, i still haven't understood what causes it.
My solution was just putting everything in a try catch block and call it a day

This happens when the ${macro} is not present in the template. Maybe a bug, because this should not generate an error.

@geigel
Copy link

geigel commented Jan 13, 2021

@jjdejong @Pocciox what versions of PHP are you using?

@Francesco-Manicardi
Copy link

Francesco-Manicardi commented Jan 13, 2021 via email

@jjdejong
Copy link

7.4 too

@damienfa
Copy link

I'm on 7.4 too.
I agree with @jjdejong , in my case the text on the left is well preserved when I use setComplexValue instead of setComplexBlock (this last one deletes all the content which already exists in the paragraph where the macro is applied).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests