Template setValue doesn't work proberly

Aug 6, 2011 at 11:00 AM

I am facing a very strange problem with editing templates and I'm completely stuck right now. It must be a problem with the docx files themselves

Here are some parts of my code:

$PHPWord = new PHPWord();
$template = $PHPWord->loadTemplate($file_in);

$template->setValue('main_name', $main_name);
$template->setValue('main_straße', $main_straße);
$template->setValue('main_plz', $main_plz);
$template->setValue('main_ort', $main_ort);
$template->setValue('main_www', $main_www);
$template->setValue('main_bem', $main_bem);

$template->setValue('Value1', 'Sun');
$template->setValue('Value2', 'Mercury');
$template->setValue('Value3', 'Venus');
$template->setValue('Value4', 'Earth');
$template->setValue('Value5', 'Mars');

$template->save($file_out);

All the variables are containing strings, I checked this. $file_in contains path+filename of the Template.docx. I used the one from the examples folder and added some own search patterns. Here's my docx:

${main_name}
${main_straße}
${main_plz}
${main_ort}

${value1}
${value2}
${value3}
${value4}
${Value5} // This one was typed manually
${Value5} // This one was copy-pasted from the original Template.docx fro the examples folder

This produces the following Output.docx

FH Würzburg
${main_straße}
97070
Würzburg

${value1}
${value2}
${value3}
${value4}
${Value5} // This one was typed manually
Mars // This one was copy-pasted from the original Template.docx fro the examples folder

 

What the hell is going on ???

 

 

Aug 6, 2011 at 11:02 AM

By the way, I am using Office2010, no doc2docx conversion or something like that is involved...

Aug 8, 2011 at 3:55 PM

Nobody an idea???

I guess I have to implement it myself. Already lost two days with this...

Aug 9, 2011 at 1:18 AM

So, some setValue work and other do not.

What is the difference between the setValue that work and the setValue that don't work?

What I see is the the setValue that don't work have either:

  • a German character Eszett  http://en.wikipedia.org/wiki/%C3%9F
  • incorrect case: value1 vs Value1

Try removing the Eszett and correct your case.

Please post back if that solves your problem.

Aug 9, 2011 at 1:56 PM

Thanks for the hint.

But I'm afraid I can't see any logic difference between those strings that are replaced and those which are not.

I already checked for case sensivity and the special characters. Even very simple strings sometimes work and sometimes do not.

This is clearly shown by my example with ${Value5}. In my template there where two lines which contained exactly the same string. The first string was copied from the original Template.docx in the examples folder. The second string was typed in by myself manually. But the two strings look exactly equal.

One of them is replaced, the other is not...

 

Another example...

I have a complete template containing many strings that should be replaced. Some of them are replaced, others are not. All strings where just copy-pasted from the same source. For example the string "${main_plz}" is replaced correctly. Now I create another template, that is containing this one single string "${main_plz}", run the same code as before and the string is not replaced...

 

 

Aug 9, 2011 at 3:18 PM

Okay. It's helpful to post the actual code you use; otherwise we chase wild geese (value1 vs Value1).

You might check these links:

http://phpword.codeplex.com/workitem/15

http://phpword.codeplex.com/discussions/261365

http://phpword.codeplex.com/discussions/232636

Good luck

Aug 9, 2011 at 6:54 PM

Unbelievable, finally it is working!! :)

 

I checked your links and found some usefull hints. There was no problem in my code, only in my docx-files.

I always like to use underscores, like in ${main_name} for example. It seems that in the xml format these strings are split into pieces and the search pattern can't be found any more. I tried some other names like ${MAINname}, but no success. It seems that 2 or more uppercase letters also cause problems. Special characters like the german "ß" are also not working.

Finally I only used simple words like ${Name}... it worked! 8)

 

Thanks a lot!!!

 

By the way... how can I look into the xml structure? I already had the idea of checking the docx-xml structure myseld but only got a bunch of unreadable characters when I tried to open it with an editor...

 

 

 

Aug 9, 2011 at 7:23 PM

Hmm... it's working. But it is very annoying to create working templates.

For example, I have a template with text and many Variables all over the text that are all replaced correctly.

Then I open the template again and just change the text style of a whole line to bold. Afterwards 90% of the variables are not replaced any more...

The same problem when I want to align right or change the color of the text... I did not manage to create a formatted working template yet... but I'll keep trying...

Aug 9, 2011 at 7:53 PM

Just found out that docx-files are zip archives... :)

this is getting stranger and stranger...

Aug 9, 2011 at 8:01 PM

Ok, finally I am getting into it.

Right now I just realize the accomplishment of the developers... Understanding and working with this docx-format is very difficult. Now that I managed to see the real xml structure by unzipping the docx-archive I understand all the problems that I had. Most problems where caused by the spell checker. Some others by the format. Finally I succeeded creating a template that is completely working like it is supposed to.

Thanks for your support! I will be able to go on by myself now :)

Aug 10, 2011 at 2:37 AM

Great news! And good for you for pursuing the problem. Also much appreciate documentation of the various solutions that helped you solve your issues.

I too was amazed that a Word .doc (or .docx) file is really a zip archive, and saving it as a .zip file allows you to view the underlying XML file which instructs Word how to format the document. The XML in Word is so complex, and easily broken, eh? And so your Word templates must be formatted carefully to not create problems.

You might experiment by modifying the Template.php code with the suggestion on this page: http://phpword.codeplex.com/workitem/15

There is a big need for reliable template code, so you do us all a service to test and report back.

public function setValue($search, $replace) {
if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
$search = '/\${.*?'.$search.'.*?}/';
}

if(!is_array($replace)) {
$replace = utf8_encode($replace);
}

$this->_documentXML = preg_replace($search, $replace, $this->_documentXML,1);
}

Thank you.

Aug 22, 2011 at 12:24 PM
Edited Aug 22, 2011 at 12:28 PM

I solve this problem next way. I add in function setValue some code

public function setValue($search, $replace) {
        if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
            $search = '${'.$search.'}';
        }
		
        preg_match_all('/\$[^\$]+?}/', $this->_documentXML, $matches);
		
		for ($i=0;$i<count($matches[0]);$i++){

		$matches_new[$i] = preg_replace('/(<[^<]+?>)/','', $matches[0][$i]);
		
		$this->_documentXML = str_replace($matches[0][$i], $matches_new[$i], $this->_documentXML);
		}


				
		
	$this->_documentXML = str_replace($search, $replace, $this->_documentXML);
		
		
		
    }


Inserting code deletes xml-tags inside ${}. 

For example, we create template Template.docx and insert ${Value1}. In document.xml Template.docx we can see ...${Val<....>u<....>e1}... Using regular expressions function setValue find construction ${} and deletes tags. Finnally, we get in document.xml  ...${Value1}... and it can replace correctly.

Nov 21, 2012 at 11:34 PM
Edited Nov 21, 2012 at 11:36 PM

He tenido problema con PhpWord, en este momento me reemplaza las variables en el cuerpo del documento de la Plantilla Word pero no en los encabezados, me pueden ayudar gracias

Nov 21, 2012 at 11:37 PM
Edited Nov 21, 2012 at 11:42 PM

He tenido problema con PhpWord, en este momento me reemplaza las variables en el cuerpo del documento de la Plantilla Word pero las variables que estan  en los encabezados No las reemplaza, me pueden ayudar gracias

Nov 21, 2012 at 11:38 PM
yurygarin wrote:

He tenido problema con PhpWord, en este momento me reemplaza las variables en el cuerpo del documento de la Plantilla Word pero no en los encabezados, me pueden ayudar gracias

 

Nov 22, 2012 at 5:23 PM

Si lo puedes explicar en inglés, tal vez podemos ayudar ;)

Dec 4, 2012 at 12:27 PM

An question, Is posible to change an color for setValue ? thx

Dec 6, 2012 at 6:58 PM

sorry for mi broken english, but i have the same problem, Setvalue is not working for ${Value} in Header Section!.

Dec 6, 2012 at 7:26 PM
mic_programator wrote:

An question, Is posible to change an color for setValue ? thx

There is no need to change the color within the code. Just use the color you like in your word template! Only the variables will be replaced, the color will remain the same.

Dec 6, 2012 at 7:39 PM
Beyonder wrote:

sorry for mi broken english, but i have the same problem, Setvalue is not working for ${Value} in Header Section!.

If some variables are replaced there is most likely no problem in the code.

Look for the problem in your word file! I had the same problem and it was driving me crazy! Until I realized that docx files are zip archives...

Take your template.docx, rename it to template.zip, then extract it to a new folder. Open the folder and you will find a subfolder called "word" and in there you will find an xml file document.xml. Open this file in your favorite text editor and have a very close look... Somewhere in there you can find the text of your word document as an xml structure. 

For example: <w:t>${test}</w:t>

If your Variables look like this, setValue will work fine... 

But for several reasons your variable could also look like this:

<w:t>${</w:t></w:r><w:r w:rsidR="009D2466"><w:t>test</w:t></w:r><w:r><w:t>}</w:t>

Of yourse this will not work, because setValue will search for "${test}" but can't find anything...

 

First of all you should turn off your spellchecker ;) THis caused most of the problems I had. In some cases you might also have to change the format. Just try a few things until it works. It will always be helpful to look at document.xml!

Dec 28, 2012 at 12:20 PM

I had the exact problem as some people above, after completing the template and testing it all variables were successfully replaced. But after reopening the template, edit and saving it no variables were replaced.

I inserted the code from 2tamara into the file PHPWord/template.php and now it works like a charm :)

Thanks alot ! really helpfull thread

Jul 17, 2013 at 4:39 AM
To get something like this
$document->setValue('Value3', $Classificazione2); to work.

In your word document (not template file - no need) and filling in the values
you must type straight. ${Value3}.

If you are like me and you do something like ${}, come back to fill the Value3, it would not work.
just type ${Value3} continuously, without using the back space, back space has a way of messing up the variable.
Apr 15, 2014 at 6:54 AM
Yes it works!

Thanks a lot, man. It really make me confued for a long time.