ILOG Elixir

IBM ILOG Elixir:AIRでExcel XMLスプレッドシート形式のファイルを読む

2009-09-30 08:00:00

 Flexアプリケーションなどのウェブアプリケーションでは、普通はあらかじめ定義された形式でサーバから送られるデータを読み込むため、必ずしもサードパーティが用意した形式のデータを読む必要はない(サーバがそれらの形式を解釈してくれている)。しかしデスクトップアプリケーションでは、そういった情報源からのデータを読む機能も必要になる。

 特にデータ可視化アプリケーションではその必要性が高い。これは例えば、エンドユーザーがMicrosoft Excelからデータを読み込み、データグリッドや図表を表示するコントロールで表示したいと考える場合があるからだ。

 この記事の目的は、AIR(あるいはFlex)のデータ可視化アプリケーションで、Microsoft Excelのファイルを読み込み、その結果を表示する方法を説明することだ。

 これにはいくつかの方法があり得るが、おそらくもっとも簡単なのは次のやり方だ。

  1. 読み込みたいスプレッドシートをMicrosoftのXMLスプレッドシート形式で準備する
  2. このXMLをFlexに読み込む
  3. 最初に用意したXMLを、Flexコンポーネントで解釈できるようにしたオブジェクトを作成する
  4. 作成したオブジェクトを、望んでいる表示方法に応じたデータグリッドや図表表示コンポーネントに渡す

 最初のステップは、アプリケーション提供側で準備することはできない。エンドユーザーに「名前を付けて保存...」機能を使ってExcelのXMLスプレッドシート形式でデータを保存してもらう必要がある。例えば、次のようなデータを持つスプレッドシートがあるとしよう。

列1 列2 列3 列4
4 1 4 3
4 2 2 4
7 6 5 1
4 1 4 3
1 6 7 1

 この表に対応するExcelのXMLスプレッドシート形式のファイルを参照したければ、このファイルをダウンロードしてほしい。

 このXMLデータをFlexで読む方法はいくつかある。このファイルがURLで用意されているのであれば、単にURLLoaderを使えばよく、URLLoaderのdataプロパティをXMLオブジェクトのソースとして使えばよい。もしこのファイルがファイルシステム内のどこかにあり、作ろうとしているのがAIRアプリケーションであれば、flash.filesystem APIを利用すればよい。Adobeのドキュメントでその例を見ることができる。大事なことは、最終的にプロセスの次のステップを行うために使うXMLオブジェクトを手に入れることだ。

 3つめのステップは、このXMLオブジェクトを処理してメモリ上にflexコントロールから利用できるデータソースを作ることだ。これには、基本的に次のことが必要になる。

  • タイトル行(最初の行)を見て、シート内の必要なフィールドを発見する
  • オブジェクトの配列を、上記のステップで計算されたフィールドとそのシートの続く行にあるデータで埋める

 これを行うには、E4Xを利用してXMLを処理する次の関数を利用すればよい。

private function createArrayFromExcelData(xml:XML):Array {
  var rows:XMLList = xml.Worksheet[0].Table.Row;
  var cell:XML;
  // make sure we use MS Excel namespace
  namespace msspreadsheet =
     "urn:schemas-microsoft-com:office:spreadsheet";
  use namespace msspreadsheet;
  // look at the first row of data = header for categories
  var header:XML = rows[0];
  var cells:XMLList = header.Cell;
  var categories:Array = [];
  for (var i:int = 0; i < cells.length(); i++) {
    cell = cells[i];
    // populate the categories array with each category
    categories.push(cell.Data[0].text().toString());
  }
  // now iterate over the next rows to populate the values
  // array with the data object for each row.
  // each data object is of the form:
  // { category1 : value1, category2 : value2, ... }
  var values:Array = [];
  for (var j:int = 1; j < rows.length(); j++) {
    var row:XML = rows[j];
    // create a new object placeholder for the row
    var value:Object = new Object();
    cells = row.Cell;
    var k:int = -1;
    for (i = 0; i < cells.length(); i++) {
      cell = cells[i];
      // for cells with index get the category index from the index field
      // for cells without index just increment the index
      if (cell.@Index.length() != 0) {
          k = cell.@Index - 1;
      } else {
          k++;
      }
      // get the value if any and put it in the object
      value[categories[k]] = cell.hasComplexContent() ?
        cell.Data[0].text().toString() : "";
    }
    values.push(value);
  }
  // return the array of values to be used with a Flex control
  return values;
}

 createArrayFromExcelDataが返すArrayを手に入れたら、次のMXMLのように、これを使って直接FlexのDataGridを埋めればよい。

<mx:Script>
  <![CDATA[
  private function readXML():void {
    // whatever is needed to read the XML (either file or URL)
    var xml:XML = ...;
    var values:Array = createArrayFromExcelData(xml);
    dg.dataProvider = values;
  }

  private function createArrayFromExcelData(xml:XML):Array {
    // see above
  }
  ]]>
</mx:Script>
<mx:DataGrid id="dg" width="100%" height="100%"/>

 ブラウザでこれを実行した結果は次のようになる。

 もちろん、このArrayをIBM ILOG Elixir3Dチャート2Dチャートツリーマップなどの、DataGrid以外のコンポーネント向けのデータプロバイダとして使うこともできる。

IBM ILOG Elixirについての詳細は、http://www.ilog.co.jp/product/visu/ilogelixir/をご覧ください。

※このエントリは ブロガーにより投稿されたものです。朝日インタラクティブ および ZDNet Japan編集部の見解・意向を示すものではありません。
  • 新着記事
  • 特集
  • ブログ