In meinem vorherigen Artikel „Bei SkyDrive abgelegte Excel Dateien editierbar in eigenen Websites und Blogs einbinden“ hatte ich darüber berichtet, wie bei SkyDrive gespeicherte Excel Dateien anhand eines I-Frames in eine eigene Website eingebunden werden können.
Eine weitere Methode ist das Einbetten unter Zuhilfenahme eines JavaScript Code Blocks. Wesentlicher Vorteil dieser Methode ist, das das Verhalten und Aussehen der eingebetteten Excel Datei programmiertechnisch angesteuert werden kann. Dieses Feature war bislang nur SharePoint 2010 Servern vorbehalten und ist seit Kurzem nun auch für die Excel WebApp in SkyDrive verfügbar.
In diesem Artikel, der doch ein bisschen länger geworden ist, werde ich beispielhaft eine eigene einfache Implementierung erläutern. Zur Demonstration habe ich dazu wieder meine Excel Datei mit den Übersetzungen zu den Excel Formeln verwendet. Ziel hierbei war einerseits, die Auswahl der zwei Sprachen zum Vergleich der Formeln zu ermöglichen und andererseits die Sprache für die Benutzeroberfläche anpassen zu können. Mein Ergebnis habe ich hier vor diesem Absatz eingebunden.
Lernen und Üben
Microsoft hat kürzlich die Website „Excel Mashup“ in englischer Sprache veröffentlicht, wo neben Lernmaterial und Tutorials auch einige sehr interessante Code-Beispiele zu finden sind. Ausserdem lassen sich dort die wichtigsten Links zu MSDN mit Erläuterungen der JavaScript Objekte und Methoden finden.
Über den Menüpunkt „Get Started“ gelangt man zu einer Übersichtsseite, wo Grundlagen und Links zum Publizieren von Excel Dateien bei SkyDrive vermittelt werden. Der Punkt „Mash it up!“ erläutert eine Beispielanwendung, die eine Excel Datei mit Bing Maps verbindet. Da hier der Code für Anfänger schon ein wenig komplexer ist, würde ich empfehlen, zunächst in den Bereich „Explore“ zu wechseln.
Anschließend gelangt man zu einer Seite mit den drei Auswahlmöglichkeiten „How to“, „Interactive Code Snippets“ und „Demo App“. Erste Möglichkeit führt zu einem englischen MSDN Artikel, der Grundlagen zum Einbinden des JavaScripts erläutert; dies werde im folgenden Abschnitt auch erläutern. Über „Interactive Code Snippets“ gelangt zu den einzelnen Code-Beispielen. Diese lassen sich übrigens alle interaktiv verändern und sind somit zum Experimentieren sehr gut geeignet.
Passend zu meinem Vorhaben hatte ich mir dann das Beispiel zu „Set specific cell to value“ genauer angeschaut.
Entwicklung der Beispielanwendung
Wie beim statischen Einbetten der Excel Datei in die eigene Website anhand des I-Frames, benötigt auch die Einbindung per JavaScript eine eindeutige Kennung der Excel Datei bei SkyDrive. Die einfachste Möglichkeit – und die auch genutzt werden sollte – ist das Abrufen des Codes über den entsprechenden Dialog bei SkyDrive.
Im diesem Dialog kann über einen Klick auf „JavaScript“ vom einfachen I-Frame Code zum JavaScript Code umgeschaltet werden. Anschließend kann man den Code aus diesem Feld heraus kopieren und als Ausgangsbasis für die weitere Entwicklung nehmen. Der Code enthält im Wesentlichen folgenden Inhalt:
Wie zu sehen, beinhaltet der Block zunächst einen mit einer ID gekennzeichnetes Div-Element, dem auch gleich die Breite und Höhe mit auf dem Weg gegeben wurde. Anschließend wird eine JavaScript Datei von einem Microsoft Server abgerufen und dem folgt wiederum ein JavaScript Code-Block zum Abrufen und Einbinden der Excel Datei.
Hier wird die Variable „fileToken“ mit dem Token der Datei initialisiert, der dann der Kennung der Datei entspricht. Danach wird die Funktion loadEwaOnPageLoad() dem Ereignishandler des Browsers hinzugefügt, so dass dieser beim Laden der Seite oder eines HTML-Elementes die Funktion aufrufen kann.
In der Funktion loadEwaOnPageLoad() selbst, werden zunächst werden einige Parameter initialisiert. Deren Zweck lässt sich anhand ihrer Namensgebung relativ leicht erraten; so dient „showGridlines“ zur Anzeige der Gitternetzlinien und „allowSorting“ und „allowFiltering“ legen fest, ob jeweils sortiert und/oder gefiltert werden darf. Hier ist übrigens ein Unterschied zur I-Frame Version des Einbettungscodes festzustellen, wo letztere „allowSorting“ und „allowFiltering“ zu einem einzigen Parameter „wdAllowInteractivity“ zusammengefasst wurden. Die letzte Zeile der Funktion lädt die Datei von SkyDrive und übergibt auch die ID des Div’s.
Die Funktion onEwaLoaded() dient schließlich dazu, eigenen Code direkt im Anschluss nach dem Laden der Datei auszuführen.
Nach einem Test in einer separaten HTML-Datei zu diesem Blog, ging es dann zu den eigenen Erweiterungen. Die Texte zu den Sprachen für die Benutzeroberfläche der Excel Datei (Deutsch, Englisch und Französisch) sind in der Excel Datei in der Tabelle „Resources“ abgelegt. Über die Eingabe von den Kürzeln DE, EN und FR in die Zelle $J$9 dieser Tabelle erfolgt dann eine Auswahl der Sprache; die Inhalte der weiteren Tabellen werden per Formeln berechnet. Somit müsste, um dies von außen steuern zu können, genau diese Zelle mit einem passenden Wert beschrieben werden.
Optimal ist, dass dieses beim Laden der Datei passiert und direkt über einen URL-Parameter übergeben werden kann. Und, damit der User dies komfortabel bewerkstelligen kann, stellen wir ihm einfache Links außerhalb der Excel Datei zur Verfügung.
Wir brauchen somit eine Funktion, die einerseits in die passende Zelle schreibt und den URL-Parameter berücksichtigt. Da wir später weitere Zellen in weiteren Tabelle beschreiben werden, gestalten wir die JavaScript Funktion so flexibel, dass diese den Namen der Zieltabelle, die Zeile und die Spalte der Zielzelle, den Wert des zu schreibenden Inhaltes und ob die Zieltabelle aktiviert werden soll oder nicht. Es ergibt sich als Deklaration: setValue(Sheet, Row, Column, Value, Activate) und folgender Code:
Zunächst ermitteln wir eine Referenz auf das EWA-Objekt (siehe MSDN Links am Ende dieses Artikels) und eine Referenz auf das Range-Objekt bzw. die Zelle, die wir ansprechen möchten. Wichtig zu wissen ist übrigens an dieser Stelle, dass von Null an gezählt wird, also ist $J$9 nicht (9, 10) sondern (8, 9), was ich persönlich etwas unlogisch finde, da in Excel normalerweise von Zeile 1 und Spalte 1 ausgegangen wird.
Zum Setzen eines Wertes muss ein Array zweiter Dimension gebildet werden, das wiederum an eine EWA-Methode übergeben wird. Im zuvor genannten Beispiel der Website Excel Mashup wird ein Wert in der Form [[32]] übergeben, was letztendlich einem solchen Array entspricht. Da wir das aber dynamisch halten wollen, habe ich das Array „arrValue“ deklariert. Grund für die Anforderung des Arrays ist übrigens, dass in einem Rutsch mehrere Zellen gleichzeitig gesetzt werden können.
Das Setzen des Wertes erfolgt über die asynchrone EWA-Methode setValuesAsync(), die auch die Angabe einer Callback-Funktion erwartet. Diese wird wiederum am Ende der Operation aufgerufen und ermöglich dann beispielsweise das Abfragen eines Fehlerstatus. Auf solche Fehlerabfragen bzw. Prüfung der Validität der Objekte habe ich hier jedoch zur Vereinfachung verzichtet.
Schließlich prüfe ich noch, ob der Parameter Activate gesetzt ist, und wenn ja, dann wird die Tabelle per EWA-Methode activateAsync() aktiviert.
Bliebe noch die Übergabe des Sprachcodes aus dem URL-Parameter. Hierzu werden die URL-Parameter innerhalb der Funktion getURLParam(Parameter, Default, Validator) geparst und ein gefundener gültiger Wert zurückgegeben. Das Argument „Parameter“ der Funktion beinhaltet den gesuchten Parameter (bei mir wäre das dann „UI“), „Default“ stellt den Standardwert dar und „Validator“ ist eine Zeichenkette mit allen gültigen Werten, so dass die Gültigkeit relativ einfach geprüft werden kann.
Das Ergebnis von getURLParam() habe ich zudem in der globalen „globalLanguage „ Variable abgelegt, da ich dessen Wert noch an weiteren Stellen brauchte.
Um nun die Sprache beim Laden der HTML-Datei festzulegen, packen wir nun den Aufruf setValue(„Resources“, 8, 9, globalLanguage, 0) in die Funktion onEwaLoaded(), die ja, wie bereits geschildert, nach dem Laden der Excel Datei automatisch aufgerufen wird.
Kommen wir nun zur Auswahl der Sprachen für den Vergleich der Formeln. In der Tabelle „Compare“ können die Formeln in zwei verschiedenen Sprachen miteinander verglichen werden. Dazu können in den Zellen $H$9 und $I$9 die jeweiligen Sprachcodes eingegeben werden, die wiederum in der Tabelle „Languages“ in der Spalte „Auswahl“ zu finden sind. Um die Sprache auswählen zu können, habe ich zwei Comboboxen bzw. Auswahlfelder vorgesehen. Bei einer Auswahl soll dann der entsprechende Wert in der Excel Tabelle geschrieben werden und eine Aktivierung der Tabelle geschehen; für den Fall, dass der User sich in eine anderen Tabelle befindet. Außerdem sollen beim Laden der HTML Datei beide Auswahlfelder mit der gewählten Sprache zur Benutzeroberfläche initialisiert werden.
Dem jeweiligen onChange Ereignis der Auswahlfelder habe im HTML Code die Funktion setFormulaLanguage(Target, Value) zugewiesen; wobei dann „Target“ dem Auswahlfeld entspricht und „Value“ dem gewählten Wert. In der Funktion wird dann die bereits implementierte Funktion setValue() mit entsprechenden Übergabeparametern aufgerufen.
Zu Initialisierung der Vergleichssprachen innerhalb der Excel Tabelle „Compare“ habe ich die Funktion onEwaLoaded() um die Aufrufe setValue(„Compare“ , 8, 7, globalLanguage, 0) und setValue(„Compare“ , 8, 8, globalLanguage, 0) ergänzt. Und die Funktion initFormulaLanguage() wird im HTML-Dokument im Ergeignisses „onLoad“ des Body-Tags aufgerufen.
Abschließend der wichtige Hinweis, dass das Schreiben von Zellen in der Excel Datei nur dann funktioniert, wenn auch der Parameter „allowTypingAndFormulaEntry“ in der Funktion loadEwaOnPageLoad() auf True gesetzt ist; also das Schreiben erlaubt ist. Ansonsten erscheint eine Fehlermeldung. Folgend nun der gesamte von mir modifizierte Code:
Die letzten Schritte zur Fertigstellung der HTML Datei waren dann die Erstellung von ein paar CSS-Styles, so dass die Steuerelemente zur Interaktion und die Excel Datei vom Design her nahtlos ineinander übergehen.
Einbinden in einen WordPress Blog
Diesen Abschnitt habe ich diesem Artikel eigentlich nur hinzugefügt, weil WordPress das direkte Einbinden des von SkyDrive generierten JavaScript Codes in diesem Artikel per Copy & Paste erfolgreich unterbunden hatte.
Wenn man JavaScript Code nur innerhalb einzelner Artikel einbinden möchte, ohne dazu ein Plugin zu verwenden, empfiehlt WordPress, den JavaScript Code nicht direkt in den Artikel einzubinden, sondern diesen in eine externe Datei auszulagern. Diese Datei kann dann über eine Referenzierung eingebunden werden. Beispiel: <script type=“text/javascript“ src=“http://www.excel-ticker.de/maninweb/mashups/translations.js“></script>. Allerdings sollte dann die Layout Ansicht des HTML-Editors nicht aktiv sein, sondern nur die HTML-Quellcode Ansicht.
So nebenbei, persönlich verwende ich die Layout-Ansicht sehr selten, da dieser häufig Formatierungen setzt, die nicht zum Kontext passen oder entgegen der von mir gesetzten Stylesheets arbeitet. In der Regel verwende ich eine Vorlage, die über eine Standardformatierung verfügt und wo dann Absatz für Absatz die Artikelinhalte hineinkopiert werden.
Zurück zur eingebetteten Excel Datei. Während meines Tests hatte ich zudem bemerkt, dass innerhalb der Ansicht zur Excel Datei bei der Einbindung via JavaScript einige Elemente verschoben waren. Beispielweise der untere Bereich, wo dann die Symbole durcheinander geraten waren. Ich vermute, dass dies an den von mir verwendeten Stylesheets liegt, die wohl in Konflikt mit denen der Excel Datei standen.
Andererseits habe ich ja auch zur Entwicklung eine separate HTML Datei verwendet; um nun nicht alles in den Artikel übertragen bzw. anpassen zu müssen, habe ich mich entschieden, das Einbinden in den Blog per I-Frame zu realisieren; diesmal dann aber nicht mit der Excel Datei direkt, sondern über meine externe HTML-Datei.
Ausblick und Fazit
Momentan werden die Steuerelemente beim Wechsel der Sprache zur Benutzeroberfläche nicht angepasst. Das ließe sich jedoch, denke ich recht leicht implementieren. Die Bezeichnungen der Sprachen sind in der Excel Datei selbst vorhanden und könnten ausgelesen werden. Oder man erstellt einfach ein Duplikat im JavaScript Code und generiert die Inhalte der Auswahlfelder dynamisch.
Insgesamt eröffnet das dynamischen Einbetten von Excel Dateien für quasi jedermann interessante Möglichkeiten. Ich denke da an Auswertungen, Beispiele zu Formeln und Funktionen, Tutorials, Animationen und vieles mehr.
Abschließend möchte ich an dieser Stelle die Gelegenheit nutzen, allen meinen Lesern und Leserinnen frohe und entspannte Festtage zu wünschen :-)