PHPWord und setValue()-Problem

Ich bastel gerade für meinen Kumpel Björn ein WordPress-Plugin, damit er über PHP Rechnungen für seinen Shop generieren kann. Dazu wird eine Word-Vorlage (docx) eingelesen und Platzhalter darin ersetzt. Dafür eignet sich PHPWord, welches auch die gewünschte Möglichkeit bietet.

PHPWord

Es können innerhalb der Word-Datei einfach beliebige Platzhalter im nachfolgenden Format verwendet werden.

${platzhalter}

Alle Platzhalter können dann mittels der Methode setValue() ersetzt werden. Da gibt es nur ein kleines Problem. Beim Bearbeiten und testen der Word-Vorlage viel mir auf, dass manche Platzhalter ersetzt wurden und manche nicht. Es gab auch keinen (sichtbaren) Unterschied zwischen Platzhaltern, welche funktionierten und denen die nicht ersetzt wurden. Es war zuerst sehr mysteriös…

Ich habe schlussendlich hier herausgefunden, warum das so ist und was man dagegen tun kann. Die Lösung ist eigentlich total einfach und ich wundere mich, warum das noch nicht in das Projekt mit eingeflossen ist.

Öffnet die Datei PHPWord/Template.php und ersetzt die Methode setValues() wie folgt:

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

Der Grund für den Fix ist auch relativ leicht gefunden: Word produziert teilweise Blödsinn.
Beim Bearbeiten der Datei wird manchmal beim Editieren aus dem Platzhalter ${Value1} ein …${Val<…>u<…>e1}…

Das wird in der originalen setValue()-Methode nicht abgefangen und die Variable demzufolge auch nicht ersetzt. Mittels regulären Ausdrucks funktioniert es aber wieder, da dort alle Tags innerhalb der ${} entfernt werden. Problem gelöst 😉

2 comments

  1. Danke für den Hinweis. Ich habe stundelang nach Lösungen für das Problem gesucht.

  2. Bitteschön. Freut mich dir damit geholfen zu haben.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.