Wie ich in meinem vorherigen Artikel, PHP und WMI - tief in Windows mit PHP eingraben hatte, leben wir in einer Welt, in der wir PHP -Entwickler von Zeit zu Zeit mit dem Windows -Betriebssystem befassen müssen. WMI (Windows Management Interface) ist eine solche Anlässe und Microsoft Office Interop ist eine andere - eine noch wichtigere und häufiger verwendete.
In diesem Artikel werden wir eine einfache Integration zwischen Word und PHP sehen: Um ein Microsoft -Word -Dokument basierend auf den Eingaben in einem HTML -Form mit PHP (und seiner Interop -Erweiterung) zu generieren.
Stellen Sie zunächst sicher, dass in Ihrem Windows -Entwicklungsgerät eine typische WAMP -Umgebung eingerichtet wurde. Da Interop nur eine Windows -Funktion ist, müssen wir Apache und PHP unter Windows hosten. In diesem Fall verwende ich EASYPHP 14.1, was recht einfach zu installieren und zu konfigurieren ist.
Als nächstes müssen wir Microsoft Office installieren. Seine Version ist nicht so kritisch. Ich verwende Office 2013 Pro, aber jede Büroversion später als 2007 sollte funktionieren.
Wir müssen dann sicherstellen, dass die Bibliotheken eine Interop -Anwendung (PIA genannt, primäre Interop -Assemblys) entwickeln, die installiert sind. Um dies zu ermitteln, können wir den Windows Explorer öffnen und zu:
Wir sehen einen Microsoft.Office.Interop.Word -Eintrag (im Snapshot unterstrichen). Dies wird die PIA sein, die wir in dieser Demo verwenden. Bitte achten Sie besondere Aufmerksamkeit auf den Namen „Assembly“, „Version“ und „Public Key Token“. Diese sollen in unseren PHP -Skripten sehr bald verwendet werden.
In diesem Verzeichnis können wir auch andere PIAS (einschließlich der gesamten Bürofamilie) für die Programmierung (nicht nur für PHP, sondern auch für VB.NET, C#usw.) sehen
Wenn die PIAS-Liste nicht das gesamte Paket von Microsoft.Office.Interop enthält, werden wir unser Büro entweder neu installieren und PIA-Funktionen enthalten. Oder wir müssen das Paket manuell von Microsoft herunterladen und installieren. Bitte wenden Sie sich an diese MSDN -Seite, um detaillierte Anweisungen zu erhalten.
HINWEIS: Nur Microsoft Office 2010 PIA -Neuverteilung kann heruntergeladen und installiert werden. Die PIA -Version in diesem Paket ist 14.0.0. Version 15 wird nur mit Office 2013 -Installation ausgestattet.
Schließlich müssen wir die PHP -Erweiterung php_com_dotnet.dll in der Php.ini -Datei aktivieren und den Server neu starten.
Jetzt können wir zur Programmierung übergehen.
Da der Schwerpunkt dieser Demo auf der Back -End -Verarbeitung liegt, werden wir ein einfaches Frontend mit einer einfachen HTML -Form erstellen, die wie die folgende Abbildung aussieht:
Wir haben ein Textfeld für "Name", eine Optionsknopfgruppe für "Geschlecht", eine Reichweite für "Alter" und einen Textbereich für "Nachricht". und schließlich natürlich eine Schaltfläche "Senden".
Speichern Sie diese Datei in einem Verzeichnis unter dem Stammverzeichnis des virtuellen Hosts als "index.html", damit wir mit einem URI wie http: // test/test/interop darauf zugreifen können.
Die Back -End -PHP -Datei steht im Mittelpunkt unserer Diskussion. Ich werde zuerst den Code dieser Datei auflisten und ihn dann Schritt für Schritt erläutern.
<span><span><?php </span></span><span> </span><span><span>$inputs = $_POST; </span></span><span><span>$inputs['printdate']=''; </span></span><span><span>// A dummy value to avoid a PHP notice as we don't have "printdate" in the POST variables. </span></span><span> </span><span><span>$assembly = 'Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'; </span></span><span><span>$class = 'Microsoft.Office.Interop.Word.ApplicationClass'; </span></span><span> </span><span><span>$w = new DOTNET($assembly, $class); </span></span><span><span>$w->visible = true; </span></span><span> </span><span><span>$fn = __DIR__ . '\template.docx'; </span></span><span> </span><span><span>$d = $w->Documents->Open($fn); </span></span><span> </span><span><span>echo "Document opened.<br><hr>"; </span></span><span> </span><span><span>$flds = $d->Fields; </span></span><span><span>$count = $flds->Count; </span></span><span><span>echo "There are <span><span>$count</span> fields in this document.<br>"</span>; </span></span><span><span>echo "<ul>"; </span></span><span><span>$mapping = setupfields(); </span></span><span> </span><span><span>foreach ($flds as $index => $f) </span></span><span><span>{ </span></span><span> <span>$f->Select(); </span></span><span> <span>$key = $mapping[$index]; </span></span><span> <span>$value = $inputs[$key]; </span></span><span> <span>if ($key == 'gender') </span></span><span> <span>{ </span></span><span> <span>if ($value == 'm') </span></span><span> <span>$value = 'Mr.'; </span></span><span> <span>else </span></span><span> <span>$value = 'Ms.'; </span></span><span> <span>} </span></span><span> </span><span> <span>if($key=='printdate') </span></span><span> <span>$value= date ('Y-m-d H:i:s'); </span></span><span> </span><span> <span>$w->Selection->TypeText($value); </span></span><span> <span>echo "<li>Mappig field <span><span>$index</span>: <span>$key</span> with value <span>$value</span></li>"</span>; </span></span><span><span>} </span></span><span><span>echo "</ul>"; </span></span><span> </span><span><span>echo "Mapping done!<br><hr>"; </span></span><span><span>echo "Printing. Please wait...<br>"; </span></span><span> </span><span><span>$d->PrintOut(); </span></span><span><span>sleep(3); </span></span><span><span>echo "Done!"; </span></span><span> </span><span><span>$w->Quit(false); </span></span><span><span>$w=null; </span></span><span> </span><span> </span><span> </span><span><span>function setupfields() </span></span><span><span>{ </span></span><span> <span>$mapping = array(); </span></span><span> <span>$mapping[0] = 'gender'; </span></span><span> <span>$mapping[1] = 'name'; </span></span><span> <span>$mapping[2] = 'age'; </span></span><span> <span>$mapping[3] = 'msg'; </span></span><span> <span>$mapping[4] = 'printdate'; </span></span><span> </span><span> </span><span> <span>return $mapping; </span></span><span><span>}</span></span>
Nach dem Einrichten der $ Inputs Variablen, um die aus unserem Formular veröffentlichten Werte zu halten und einen Dummy -Wert für PrintDate zu erstellen - wir werden diskutieren, warum wir dies später brauchen - wir stoßen auf diese vier kritischen Zeilen:
<span>$assembly = 'Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'; </span><span>$class = 'Microsoft.Office.Interop.Word.ApplicationClass'; </span> <span>$w = new DOTNET($assembly, $class); </span><span>$w->visible = true;</span>
Eine COM -Manipulation in PHP erfordert eine Instanziierung einer „Klasse“ innerhalb einer „Assemblierung“. In unserem Fall sollen wir mit Wort arbeiten. Wenn wir über den ersten Screenshot nachdenken, den wir gezeigt haben, können wir die vollständige Signatur des Wortes PIA erstellen:
Die Klasse, die wir aufrufen sollen, ist immer der Name der Baugruppe Plus ".
Mit diesen beiden Parametern können wir ein Wortobjekt instanziieren.Dieses Objekt kann im Hintergrund bleiben oder wir können es in den Vordergrund stellen, indem wir sein sichtbares Attribut auf True setzen.
Als nächstes öffnen wir das zu verarbeitende Dokument und weisen die Instanz „Dokument“ einer $ D -Variablen zu.
In diesem Dokument haben wir einige Optionen, um Inhalte basierend auf den Eingaben aus dem HTML -Formular zu erstellen.
Der ungünstigste Weg ist, den gesamten Inhalt in PHP zu codieren und dann in das Wort Dokument auszugeben. Ich entmutige dies aus den folgenden Gründen nachdrücklich:
Eine andere Möglichkeit besteht darin, ein "Suchreplace" durchzuführen. PHP verfügt über starke integrierte Funktionen. Wir können ein Word -Dokument erstellen, das einige besondere Grenzwerte in den Platzhalterinhalten aufnimmt, die ersetzt werden sollen. Zum Beispiel können wir ein Dokument erstellen, das so etwas enthält:
{{Name}}
und in PHP können wir dies einfach durch den von uns abgerufenen "Namen" -Werte ersetzen.
Dies ist unkompliziert und vermeidet alle Nachteile in der ersten Option. Wir müssen ledig
Die dritte Option ist meine Empfehlung und ein erweitertes Thema in Word. Wir werden Felder verwenden, um die Platzhalter darzustellen, und in unserem PHP -Code werden wir die Felder direkt mit den jeweiligen Formularwerten aktualisieren.Dieser Ansatz ist flexibel, schnell und entspricht den Best Practices von Word. Es vermeidet auch die Volltextensuche in den Dokumenten, was die Leistung hilft. Beachten Sie, dass diese Option auch ihre Nachteile hat.
Wort seit seinem Debüt hat nie benannte Indizes für Felder unterstützt. Obwohl wir einen Namen für die Felder angegeben haben, die wir im Word -Dokument erstellt haben, müssen wir noch Zahlen -Einweise verwenden, um auf jedes Feld zuzugreifen. Dies erklärt auch, warum wir eine dedizierte Funktion (Setupfields) verwenden müssen, um die manuelle Zuordnung zwischen dem Feldindex und dem Namen der Formularfelder durchzuführen.
Um zu erfahren, wie Sie Felder in ein Word-Dokument einfügen (klicken Sie hier, um eine vorgefertigte Version zu erhalten), wenden Sie sich bitte an die entsprechenden Word-Hilfe-Themen und -handbücher. Für diese Demo haben wir ein Dokument mit 5 Mergefield -Feldern. Außerdem haben wir das Dokument in das gleiche Verzeichnis wie das PHP -Skript für einen einfachen Zugriff aufgenommen.
Bitte beachten Sie, dass das Feld Druckdate kein entsprechendes Formularfeld hat. Aus diesem Grund haben wir dem $ Input -Array einen Dummy -Printdate -Schlüssel hinzugefügt. Ohne dies kann das Skript weiter ausgeführt werden, aber es wird beachtet
Nachdem wir die Felder mit Formularwerten aktualisiert haben, drucken wir das Dokument mit:
Die Ausdrucksmethode hat einige optionale Parameter und wir verwenden ihre einfachste Form. Dadurch wird eine Kopie in den Standarddrucker gedruckt, der mit unserem Windows -Computer angeschlossen ist.
<span><span><?php </span></span><span> </span><span><span>$inputs = $_POST; </span></span><span><span>$inputs['printdate']=''; </span></span><span><span>// A dummy value to avoid a PHP notice as we don't have "printdate" in the POST variables. </span></span><span> </span><span><span>$assembly = 'Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'; </span></span><span><span>$class = 'Microsoft.Office.Interop.Word.ApplicationClass'; </span></span><span> </span><span><span>$w = new DOTNET($assembly, $class); </span></span><span><span>$w->visible = true; </span></span><span> </span><span><span>$fn = __DIR__ . '\template.docx'; </span></span><span> </span><span><span>$d = $w->Documents->Open($fn); </span></span><span> </span><span><span>echo "Document opened.<br><hr>"; </span></span><span> </span><span><span>$flds = $d->Fields; </span></span><span><span>$count = $flds->Count; </span></span><span><span>echo "There are <span><span>$count</span> fields in this document.<br>"</span>; </span></span><span><span>echo "<ul>"; </span></span><span><span>$mapping = setupfields(); </span></span><span> </span><span><span>foreach ($flds as $index => $f) </span></span><span><span>{ </span></span><span> <span>$f->Select(); </span></span><span> <span>$key = $mapping[$index]; </span></span><span> <span>$value = $inputs[$key]; </span></span><span> <span>if ($key == 'gender') </span></span><span> <span>{ </span></span><span> <span>if ($value == 'm') </span></span><span> <span>$value = 'Mr.'; </span></span><span> <span>else </span></span><span> <span>$value = 'Ms.'; </span></span><span> <span>} </span></span><span> </span><span> <span>if($key=='printdate') </span></span><span> <span>$value= date ('Y-m-d H:i:s'); </span></span><span> </span><span> <span>$w->Selection->TypeText($value); </span></span><span> <span>echo "<li>Mappig field <span><span>$index</span>: <span>$key</span> with value <span>$value</span></li>"</span>; </span></span><span><span>} </span></span><span><span>echo "</ul>"; </span></span><span> </span><span><span>echo "Mapping done!<br><hr>"; </span></span><span><span>echo "Printing. Please wait...<br>"; </span></span><span> </span><span><span>$d->PrintOut(); </span></span><span><span>sleep(3); </span></span><span><span>echo "Done!"; </span></span><span> </span><span><span>$w->Quit(false); </span></span><span><span>$w=null; </span></span><span> </span><span> </span><span> </span><span><span>function setupfields() </span></span><span><span>{ </span></span><span> <span>$mapping = array(); </span></span><span> <span>$mapping[0] = 'gender'; </span></span><span> <span>$mapping[1] = 'name'; </span></span><span> <span>$mapping[2] = 'age'; </span></span><span> <span>$mapping[3] = 'msg'; </span></span><span> <span>$mapping[4] = 'printdate'; </span></span><span> </span><span> </span><span> <span>return $mapping; </span></span><span><span>}</span></span>
Wir können auch PrintPreview verwenden, um sich die Ausgabe anzusehen, bevor wir uns entscheiden, das Dokument auszudrucken. In einer rein automatisierten Umgebung werden wir stattdessen natürlich den Ausdruck verwenden.
Wir müssen einige Sekunden warten, bevor wir die Wortanwendung beenden, da der Druckauftrag einige Zeit benötigt, um vollständig spulen zu werden. Ohne Verzögerung (3) wird $ w-> Quit sofort ausgeführt und der Druckauftrag wird ebenfalls getötet.
Schließlich nennen wir $ w-> beenden (false), um die von unserem PHP-Skript aufgerufene Wortanwendung zu schließen. Der einzige hier angegebene Parameter besteht darin, festzustellen, ob wir Änderungen vor dem Beenden speichern möchten. Wir haben Änderungen am Dokument vorgenommen, aber wir möchten sie wirklich nicht speichern, da wir eine saubere Vorlage für die Eingabe anderer Benutzer beibehalten möchten.
Nachdem wir den Code abgeschlossen haben, können wir die Formularseite laden, einige Werte eingeben und das Formular senden. Die folgenden Bilder zeigen die Ausgabe des PHP -Skripts und auch das aktualisierte Word -Dokument:
PHP ist eine schwach typisierte Sprache. Ein COM -Objekt ist vom Typ Objekt. Während unserer PHP -Codierung gibt es keine Möglichkeit, einen aussagekräftigen Code -Einblick aus einem Objekt herauszuholen, sei es eine Wortanwendung, ein Dokument oder ein Feld. Wir wissen nicht, welche Eigenschaften es hat oder welche Methoden es unterstützt.
Dies wird unsere Entwicklungsgeschwindigkeit stark verlangsamen. Um es schneller zu machen, würde ich empfehlen, die Funktionen in C# zuerst zu entwickeln und dann den Code zurück in PHP zu migrieren. Eine kostenlose C# ide, die ich empfehlen würde, heißt "#Develop" und kann hier heruntergeladen werden. Ich bevorzuge diese der VS -Serie, da #Develop kleiner, sauberer und schneller ist.
Die Migration des C# -Codes in PHP ist überhaupt nicht beängstigend. Lassen Sie mich Ihnen einige Zeilen von C# Code zeigen:
<span><span><?php </span></span><span> </span><span><span>$inputs = $_POST; </span></span><span><span>$inputs['printdate']=''; </span></span><span><span>// A dummy value to avoid a PHP notice as we don't have "printdate" in the POST variables. </span></span><span> </span><span><span>$assembly = 'Microsoft.Office.Interop.Word, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'; </span></span><span><span>$class = 'Microsoft.Office.Interop.Word.ApplicationClass'; </span></span><span> </span><span><span>$w = new DOTNET($assembly, $class); </span></span><span><span>$w->visible = true; </span></span><span> </span><span><span>$fn = __DIR__ . '\template.docx'; </span></span><span> </span><span><span>$d = $w->Documents->Open($fn); </span></span><span> </span><span><span>echo "Document opened.<br><hr>"; </span></span><span> </span><span><span>$flds = $d->Fields; </span></span><span><span>$count = $flds->Count; </span></span><span><span>echo "There are <span><span>$count</span> fields in this document.<br>"</span>; </span></span><span><span>echo "<ul>"; </span></span><span><span>$mapping = setupfields(); </span></span><span> </span><span><span>foreach ($flds as $index => $f) </span></span><span><span>{ </span></span><span> <span>$f->Select(); </span></span><span> <span>$key = $mapping[$index]; </span></span><span> <span>$value = $inputs[$key]; </span></span><span> <span>if ($key == 'gender') </span></span><span> <span>{ </span></span><span> <span>if ($value == 'm') </span></span><span> <span>$value = 'Mr.'; </span></span><span> <span>else </span></span><span> <span>$value = 'Ms.'; </span></span><span> <span>} </span></span><span> </span><span> <span>if($key=='printdate') </span></span><span> <span>$value= date ('Y-m-d H:i:s'); </span></span><span> </span><span> <span>$w->Selection->TypeText($value); </span></span><span> <span>echo "<li>Mappig field <span><span>$index</span>: <span>$key</span> with value <span>$value</span></li>"</span>; </span></span><span><span>} </span></span><span><span>echo "</ul>"; </span></span><span> </span><span><span>echo "Mapping done!<br><hr>"; </span></span><span><span>echo "Printing. Please wait...<br>"; </span></span><span> </span><span><span>$d->PrintOut(); </span></span><span><span>sleep(3); </span></span><span><span>echo "Done!"; </span></span><span> </span><span><span>$w->Quit(false); </span></span><span><span>$w=null; </span></span><span> </span><span> </span><span> </span><span><span>function setupfields() </span></span><span><span>{ </span></span><span> <span>$mapping = array(); </span></span><span> <span>$mapping[0] = 'gender'; </span></span><span> <span>$mapping[1] = 'name'; </span></span><span> <span>$mapping[2] = 'age'; </span></span><span> <span>$mapping[3] = 'msg'; </span></span><span> <span>$mapping[4] = 'printdate'; </span></span><span> </span><span> </span><span> <span>return $mapping; </span></span><span><span>}</span></span>
Wir können sehen, dass C# Code fast identisch mit dem zuvor gezeigten PHP -Code ist. C# ist stark tippt, sodass wir einige Typ -Casting -Aussagen sehen und unseren Variablen explizit einen Typ geben müssen.
Mit dem variablen Typ können wir Code Insight und Code -Fertigstellung genießen, sodass die Entwicklungsgeschwindigkeit viel schneller ist.
Eine andere Möglichkeit, unsere PHP -Entwicklung zu beschleunigen, besteht darin, auf Wortmakros zu tippen. Wir führen die gleichen Aktionen aus, die wir ausführen müssen, und zeichnen sie mit einem Makro auf. Das Makro ist in Visual Basic, das auch leicht in Php transformiert werden kann.
Am wichtigsten ist, dass die offizielle Dokumentation von Microsoft zu Office PIA, insbesondere die Namespace -Dokumentation für jede Büroanwendungen, immer das detaillierteste Referenzmaterial ist. Die meist verwendeten drei Anwendungen sind:In diesem Artikel haben wir gezeigt, wie ein Word -Dokument mit PHP -COM -Bibliotheken und Microsoft Office Interop -Funktionen fopuliert werden.
Windows und Büro sind im Alltag weit verbreitet. Kenntnisse über die Leistung von Büro/Windows und PHP zu haben, ist für alle PHP -Windows -Programmierer unerlässlich.
Mit der COM -Erweiterung von PHP wird die Tür zum Beherrschen dieser Kombination geöffnet.
Wenn Sie an diesem Programmbereich interessiert sind, hinterlassen Sie bitte Ihre Kommentare und wir werden in Betracht ziehen, mehr Artikel zu diesem Thema zu haben. Ich freue mich darauf, dass mehr reale Anwendungen mit diesem Ansatz entwickelt wurden.
Das obige ist der detaillierte Inhalt vonSo erstellen Sie Microsoft Word -Dokumente mit PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!