Anzeige
Smartes Cloud Hosting für anspruchsvolle Projekte.
↬ Loslegen und Spaces testen ↬ Jetzt testen!
Dr. Detlef Groth 18. Juni 2007

Serienbriefe für den Webbrowser mit HTML und JavaScript

Kein Beitragsbild

Nachdem wir bereits Serienbriefe mit XML- und XSL-Dokumenten erzeugen konnten, setzen wir nun auf die älteren Technologien HTML und JavaScript. Serienbriefe sind auf diese Weise überraschend einfach zu erstellen.

Anzeige

Dokumentstruktur
Auch mit den Standard-Bordmitteln moderner Webbrowser wie HTML-Code und der Programmiersprache JavaScript lassen sich anspruchsvolle und nützliche Tools für den täglichen Gebrauch erstellen. Für die Entwicklung unseres Serienbriefes teilen wir das HTML-Dokument in drei Bereiche. Im Datenbereich (datapart) haben wir eine Tabelle, welche die Einträge für unsere Briefempfänger enthält. Außerdem enthält dieser Bereich unseren Musterbrief, bei dem diese Daten einzutragen sind (Template). In den anfangs leeren Briefbereich (letterpart) werden dann die ausgefüllten Musterbriefe eingetragen (template). Über die Konfiguration der Styles für die Div-Tags wird die Sichtbarkeit im Druck- und im Bildschirmmodus mit der Eigenschaft display konfiguriert.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="de"> <head> <title>Serienbriefe mit HTML, Medienbereiche definieren</title> <style> @media screen { div#datapart { display: block; } div#letterpart { display: none; } } @media print { div#datapart { display: none; } div#letterpart { display: block; } } </style> </head> <body> <div id="datapart"> Datenteil <div id="template"> Template-Text </div> </div> <div id="letterpart"> Briefteil </div> </body> </html>
Hier zum Beispiel struktur.php5. Wechseln Sie zwischen der Normal- und der Druckansicht, um die unterschiedliche Sichtbarkeit auf den verschiedenen Ausgabemedien zu erkennen.

Die Tabelle füllen
Die Daten für das Erstellen der Serienbriefe wollen wir nun in eine Tabelle schreiben. In unserem Beispiel stehen sie direkt in der Seite. In der Praxis kann die Tabelle natürlich auch dynamisch mit einer serverseitigen Scriptsprache wie PHP erzeugt werden. Wichtig ist es zu beachten, dass die Tabelle mit dem Id-Attributwert id=“datatable“ ausgezeichnet ist. Außerdem müssen die Tabellen-Tags thead und tbody erstellt werden.
<table id="datatable"> <thead> <tr> <th>Anrede</th> <th>Name</th> <th>Vorname</th> <th>PLZ </th> <th>Ort</th> <th>Strasse</th> </tr>

Anzeige

</thead> <tbody> <tr> <td>Lieber Sportfreund</td> <td>Meyer</td> <td>Otto</td> <td>12345</td> <td>Musterdorf</td> <td>Musterweg 1</td> </tr> <tr> <td>Liebe Sportfreundin</td> <td>Müller</td> <td>Fritzi</td> <td>12346</td> <td>Musterstadt</td> <td>Nebenstr. 12a</td> </tr> </tbody> </table>
Das Template erstellen
Die Erstellung des Brieftemplates ist der komplizierte Teil unseres Projektes. Mit Standard-HTML müssen wir eine ansprechende Ausgabe für den Brief erstellen. Für die Platzierung der Inhalte werden Span-Tags benutzt. Ihr Class-Attribut entspricht dem Spaltenbezeichner der den Inhalt für diesen Bereich definiert.
<div id="template"> <div class="absender"> Abs:<br /> Posemuckl Laufclub<br /> 12356 Posemuckl<br>Am Traumschiffhafen 1 </div> <div class="small"> Abs: Posemuckl Laufclub, 12356 Posemuckl, Am Traumschiffhafen 1 </div> <div class="anschrift"> An<br /> <span class="Vorname"> Vorname </span> <span class="Name"> Name </span> <br /> <span class="Strasse"> Strasse </span> <br /> <span class="PLZ"> 12345 </span> <span class="Ort"> Ort </span> </div> <div class="anschreiben"> <div class="ueberschrift"> <span class="Anrede">Lieber Sportfreund </span> <span class="Name"> Name </span>, </div> <div class="text">

hiermit laden wir Dich recht herzlich zu unserer Mitgliederversammlung am 1.1.2010 in unser Vereinslokal am Templiner See 12 in der Gaststätte „Zum Posemuckler“ ein. Bitte teile uns – entweder telefonisch (1234567) oder per Email (info@posemuckel-laufclub.de) – mit, ob Du daran teilnehmen kannst.

</div>

<div class=“abschluss“> Dein Vorstand </div> </div> </div>
Der Text innerhalb der Tags ist lediglich für die bessere Formatierung eingefügt. Diese erfolgt dann mit Hilfe von Stylesheet-Code.
div.absender, div.anschreiben, div.ueberschrift, div.text { padding: 30px; } div.ueberschrift, div.text { padding-left: 0px; } div.absender { text-align: right; } div.small { padding: 30px 30px 5px 30px; font-size: small; } div.anschrift { padding: 5px 30px 30px 30px; } div.template { page-break-after: always; }
Werfen Sie hier einen Blick auf unser Beispieltemplate: template.php5.

Die Programmierlogik
Um selbst Serienbriefe zu erstellen, muss man den folgenden Abschnitt nicht verstehen. Prinzipiell reicht es, die Beispiel-Dateien (html-serienbriefe-beispiel.zip) auf den Rechner herunter zu laden und für die eigenen Bedürfnisse zu modifizieren.

Im window.onload-Ereignis wird nach dem vollständigen Laden des Dokumentes mit dem Analysieren der HTML-Datei begonnen. Das Template und die Tabelle werden in einer Variable gespeichert. Danach wird über die Spaltenbezeichner der Tabelle iteriert und diese werden in einem Array abgelegt. Anschließend wird über jede Datenreihe im tbody-Bereich der Datentabelle und den Bezeichner-Array iteriert. Dabei wird im Template nach den entsprechenden Span-Tags, welche das Class-Attribut des Spaltenbezeichners tragen, gesucht. Der Text der Tabellenzelle wird innerhalb dieses Span-Tags eingesetzt. Für jede Datenzeile wird nun das ausgefüllte Template am Ende des letterpart-Bereiches eingefügt. Um einen Seitenumbruch nach jedem Brief zu erzwingen, wurde in der Style-Datei für das Template die Eigenschaft page-break-after:always; gesetzt. Hier nun der JavaScript-Code welcher diese Arbeit bewerkstelligt:
function fillTemplate (template,clss, value) { // richtiges span-tag finden und fuellen var spans = template.getElementsByTagName("span"); for (var i = 0; i < spans.length; i++) { if (spans[i].hasAttribute("class") && spans[i].getAttribute("class") == clss) { spans[i].firstChild.data = value ; } } } function parseDocument() { var data = document.getElementById("datapart"); var letter = document.getElementById("letterpart"); var template = document.getElementById("template"); var bezeichner = new Array(); var ths = data.getElementsByTagName("th"); // bezeichner extrahieren for (var i = 0 ; i < ths.length;i++) { bezeichner[i] = ths[i].firstChild.data.replace(/ /g, ""); } // datenreichen extrahieren var tbody = data.getElementsByTagName("tbody")[0]; var trs = tbody.getElementsByTagName("tr"); // zellen fuer jede zeile auslesen for (var i = 0 ; i < trs.length; i++) { var tds = trs[i].getElementsByTagName("td"); for (var j = 0 ; j < tds.length;j++) { // und fuellen des templates fillTemplate(template,bezeichner[j],tds[j].firstChild.data); } var div = document.createElement("div"); div.setAttribute("class","template"); div.innerHTML = template.innerHTML; // anhaengen des ausgefuellen templates letter.appendChild(div); } } window.onload = function () { parseDocument(); }
Mit einer JavaScript-Library wie der jQuery-Bibliothek von John Resig würde sich der Code natürlich wesentlich verkürzen. So wäre die Funktion fillTemplate nur eine Zeile lang: $(„span.“+clss).firstChild.data=value;.

Performance-Betrachtungen
Wichtig für die Anwendbarkeit ist die Frage, wie schnell die Briefe aus einer größeren Tabelle heraus erstellt werden können. Wir erweitern dazu die Tabelle mit einer JavaScript-Funktion extendTable(n), um automatisch verschiedene Otto Meyers ans Ende der Tabelle anzuhängen. Außerdem brauchen wir noch zwei Hilfsfunktionen um die Performance zu messen und anzuzeigen. Hier der JavaScript-Code dazu:
function getTime() { var t = new Date(); return t.getHours()*60*60+t.getMinutes()*60+t.getSeconds(); } function statusMessage(msg) { var div = document.createElement("div"); document.appendChild(div); div.style.padding = "20px"; div.innerHTML = "<b>"+msg+"</b>"; } function extendTable(x) { var data = document.getElementById("datapart"); var tbody = data.getElementsByTagName("tbody")[0]; for (var i = 1 ; i <= x; i++) { var tr = document.createElement("tr"); var tdi = new Array("Lieber Sportfreund", "Meyer"+i,"Otto"+i, "12345","Musterdorf","Musterweg"+i); for (var j = 0 ; j < tdi.length;j++) { var td = document.createElement("td"); td.appendChild(document.createTextNode(tdi[j])); tr.appendChild(td); } tbody.appendChild(tr); } }
Diese Datei wird in unserem Beispiel-Projekt eingebunden. Unsere window.onload-Funktion würde dann so aussehen:
window.onload = function () { var start = getTime(); extendTable(500); var diff = getTime()-start; statusMessage("table generation: "+diff+" seconds"); parseDocument(); diff = getTime()-start; statusMessage("letter generation: "+diff+" seconds"); }
Auf einem älterem 1Ghz-Rechner mit 256Mb-Arbeitsspeicher werden etwa 5 Sekunden für das Erstellen der Serienbriefe benötigt. Dies sollte für die Serienbriefe der meisten deutschen Vereine ausreichend sein. Hier der Link zu unserem Beispiel: beispiel2.

Zusammenfassung
Serienbriefe mit HTML und JavaScript sind einfach zu erstellen. Im Gegensatz zu Verfahren, die auf den XML-Fähigkeiten des Browsers basieren, sind HTML/JavaScript basierte Serienbriefe wesentlich transparenter für den Anwender. Zum Erzeugen eigener Serienbriefe muss der Anwender die Zip-Datei html-serienbriefe-beispiel.zip auf seiner Festplatte abspeichern und in der darin vorhandenen HTML-Datei die notwendigen Änderungen in der Tabelle beziehungsweise dem Template durchführen. Hinweise und Anregungen zum Artikel werden wie immer gerne entgegen genommen .

Material zum Thema:

  1. Dr. Web Artikel Serienbriefe mit dem Webbrowser und XML
  2. jQuery-JavaScript-Bibliothek

Dr. Detlef Groth

Dr. Detlef Groth, von Beruf Biochemiker und IT-Konsultant, arbeitet als Bioinformatiker und Autor in Potsdam und Umgebung.

3 Kommentare

  1. Hi,
    leider funktioniert das Beispiel nicht…scheinbar ist die
    beispiel2.js nicht vorhanden.

    Viele Grüße
    tim_tom_

  2. sind repariert soweit das möglich war.

  3. Hi zusammen,

    die Links funktionieren nicht mehr.

Schreibe einen Kommentar

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