SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Silverlight 4で作る新しいRIAアプリケーション

Silverlight 4におけるネイティブアプリケーションの統合

Silverlight4で作る新しいRIAアプリケーション(10)

  • X ポスト
  • このエントリーをはてなブックマークに追加

Excelの起動

 Excelのアプリケーションを起動するサンプルを確認していきましょう。今回のサンプルは、Silverlight連載の月間ページビューをExcelに表示してグラフを表示するためのものです。図3に実行イメージを示します。

図3 実行イメージ
図3 実行イメージ

 Excelのオートメーションオブジェクトを利用すれば、グラフを作成したり、セルに色をつけることも可能ですが、表示したいイメージがある程度決まっているのなら、あらかじめExcelのテンプレートを作成し、Silverlight側では単に動的に変動する値を埋める、といった単純なものにした方がいいでしょう。

 今回は、グラフの範囲設定と、ヘッダー行に色をつけた図4のExcelブックを図4のようにWebサーバーの「~/ExcelTemplate/テンプレート.xlsx」に作成しておきます。Silverlight側は、Excel起動ボタンが押されたタイミングでテンプレートをダウンロードし、ページビューのセルに値を設定してExcelを起動して、グラフを表示します。

図4 Webサイトの構成
図4 Webサイトの構成

 まずはコードの全体をリスト2に示します。

リスト2
// Excelの起動ボタンのクリック時のイベントハンドラ
private void btnExecExcel_Click(object sender, RoutedEventArgs e)
{
    // 1.Excelテンプレートのダウンロード
    var client = new WebClient();
    client.OpenReadCompleted += client_OpenReadCompleted;
    client.OpenReadAsync(new Uri(@"http://localhost:1348/ExcelTemplate/テンプレート.xlsx"));
}

// ダウンロード終了時のイベントハンドラ
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    if (e.Error != null)
        return;

    // 2.Excelテンプレートファイルの保存
    var filePath = System.IO.Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            "テンプレート.xlsx");
    var s = new BinaryReader(e.Result);
    var b = s.ReadBytes((int)e.Result.Length);
    File.WriteAllBytes(filePath, b);

    // オートメーションが利用出来るかの確認
    if (!AutomationFactory.IsAvailable) return;

    // 3.Excel オートメーションを作成して値を書き込む
    using (dynamic excel = AutomationFactory.CreateObject("Excel.Application"))
    using (var books = excel.Workbooks)
    using (var book = books.Open(@"C:\temp\テンプレート.xlsx"))
    using (var sheets = book.Worksheets)
    using (var sheet = sheets[1])
    using (var cells = sheet.Cells) {
    
        // 2010/08 - 2011/01 のページビュー
        var pageViews = new List<int>() { 1034, 6809, 2093, 1776, 1248, 1326 };

        var baseRowIndex = 3;
        var baseColIndex = 3;
        for (var index = 0; index < pageViews.Count; index++)
        {
            var cell = cells[baseRowIndex, baseColIndex + index];
            cell.Value = pageViews[index];
        }
        excel.Visible = true;
    }
}

 簡単にプログラムを確認していきましょう。このサンプルには、大きく分けて下記の3つの手順があります。

  1. Excelテンプレートのダウンロード
  2. Excelテンプレートファイルの保存
  3. Excel オートメーションを作成して値を書き込む

1. Excelテンプレートのダウンロード

 WebClientクラスのOpenReadAsyncメソッドを利用して、Webサーバーに配置されたExcelファイルをダウンロードします。同時に、ダウンロード終了時のイベントハンドラを登録しておきます。

2. Excelテンプレートファイルの保存

 ダウンロードしたデータをオートメーションから読み込むために、ユーザーのドキュメントフォルダにテンプレート.xlsxという名前で保存します。Silverlightでは、ファイルをユーザーのストレージに保存する場合はSaveFileDialogクラスを通じてユーザーがアクションを起こす必要がありますが、信頼されたアプリケーションでは特定ディレクトリであればユーザーの同意は必要ありません。詳しくは、前回の連載を確認してください。

3. Excelオートメーションを作成して値を書き込む

 前述の通り、Excelのオートメーションオブジェクトを作成し、ExcelのC3のセル(2010/08の実績)からH3(2011/01の実績)に対しそれぞれのページビューを設定して、最後にVisibleプロパティをtrueにすることで、Excelを起動してグラフを表示しています。

 単なるオートメーションの呼び出しであれば、CreateObjectメソッドで取得したオブジェクトのみをDisposeすればよいのですが、暗黙オブジェクトを生成するオートメーションには注意が必要です。

 例えば、リスト3の例では、bookオブジェクトからWorkSheets、WorkSheet、Cells、Cellの4つのオブジェクトが暗黙的に参照され、生成されています。

リスト3 暗黙に参照されるオブジェクト
book.Worksheets[1].Cells[3, 3] = "1";

 このような例では、Silverlightアプリケーションが終了するまで、Excelのプロセスが残ってしまうことがあります。多くのクライアントを相手にしたり、再起動の間隔が長いWebサイトのアプリケーション程に気を尖らすことも無いのかもしれませんが、メモリリークの原因にもなるので、暗黙のオブジェクトにも注意して廃棄を行うようにしましょう。

WMIを使ったプリンタ一覧の取得

 よく使いそうな例として、WMI(Windows Management Instrumentation)を使ったサンプルも見ておきましょう。WMIはコンピューターの情報を簡単に管理するためのライブラリで、現在のプロセスの情報やプリンタの情報などをSQLに似た言語で簡単に取得、管理できます。WMIに関する情報は、TechNetのスクリプトセンターを参照してください。

 リスト4は、現在コンピュータにインストールされているプリンタの一覧を取得する例です。

リスト4 プリンタ一覧を取得するサンプル
var printerList = new StringBuilder();
using (dynamic wmi = AutomationFactory.CreateObject("WbemScripting.SWbemLocator"))
{
    wmi.Security_.ImpersonationLevel = 3;
    wmi.Security_.AuthenticationLevel = 4;
    using (var service = wmi.ConnectServer(".", @"root\cimv2"))
    {
        foreach (var printer in service.ExecQuery("Select * from Win32_Printer"))
        {
            printerList.AppendFormat("プリンタ名: {0}  ポート名:{1}\n", printer.Name, printer.PortName);
        }
    }
}
MessageBox.Show(printerList.ToString());

 WMIのプログラムIDは、WbemScripting.SWbemLocatorです。Excelの例と同様に、CreateObjectメソッドでオートメーションオブジェクトを取得し、プリンタ情報を管理するWin32_Printerに対してクエリーを行っています。

 このサンプルを実行すると、図5のような画面が表示されます。

図5 実行結果
図5 実行結果

 現在のところ、Silverlight単体ではローカルコンピューターにインストールされたプリンタの情報を取得できません。プリンタに限らず、デバイスに関係する情報を取得するためには、多くの場合オートメーションオブジェクトに頼る必要があります。

次のページ
独自ネイティブアプリケーションの展開

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Silverlight 4で作る新しいRIAアプリケーション連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト かるあ (杉山 洋一)(カルア(スギヤマ ヨウイチ))

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5859 2011/04/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング