Silverlight 4 RC の COM 機能を使って Excel に twitter 検索結果を流し込む
Silverlight 4 から Out of Browser でCOMオートメーション機能が使えるようになった。これにより Excel などの外部アプリケーションを直接呼び出し操作できるようになりました。
Silverlight 4 の出荷候補版も出たので試しに COM による Excel 連携機能を実装してみることにした。今回は作ったのは、twitter で検索した結果を Excel シートに流し込むアプリです。
開発環境
Windows 7 上の Visual Studio 2010 RC と Microsoft Silverlight 4 Tools for Visual Studio 2010 RC による
ポイント
COMオートメーション機能
まず COMオートメーションの機能は、βからRCになり仕様が変わっています。
AutomationFactory.CreateObject にオブジェクト名を指定してインスタンスを生成します。下記ではさらのExcelを表示して、ワークブックを追加しその最初の(アクティブ)シートを取得しています。
using System.Runtime.InteropServices.Automation; ・・・ dynamic excel = AutomationFactory.CreateObject("Excel.Application"); excel.Visible = true; dynamic workbook = excel.workbooks.Add(); dynamic excelSheet = excel.ActiveSheet;
※ dynamic を使用するには Microsoft.CSharp の参照追加が必要です。
twitter検索
ボタンのクリックイベントでsearchTextBoxに入力されてたTextでtwitter search API をたたきます。
DataContractJsonSerializer を使って、レスポンスストリームから直接 JSON を C# 上の構造体クラスのデータオブジェクトに変換しています。ToExcelに結果オブジェクトを渡して処理をします(これは後述)。
private void button1_Click(object sender, RoutedEventArgs e) { if (searchTextBox.Text.Length == 0) return; string word = System.Windows.Browser.HttpUtility.UrlEncode(searchTextBox.Text); HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create("http://search.twitter.com/search.json?q=" + word); webreq.Method = "GET"; webreq.BeginGetResponse(new AsyncCallback(WebResponseCallback), webreq); } private void WebResponseCallback(IAsyncResult ar) { try { HttpWebRequest request = (HttpWebRequest)ar.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar); Stream responseStream = response.GetResponseStream(); TwitterResult result; DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(TwitterResult)); result = ser.ReadObject(responseStream) as TwitterResult; ToExcel(result); } catch (Exception) { } }
TwitterResult, TwitterResultItem に twitter のレスポンスデータ表現を定義しています。
using System.Runtime.Serialization; [DataContract] public class TwitterResult { [DataMember(Name = "results")] public IList<TwitterResultItem> Results { get; set; } } [DataContract] public class TwitterResultItem { [DataMember(Name = "profile_image_url")] public string ProfileImageUrl { get; set; } [DataMember(Name = "created_at")] public string CreatedAt { get; set; } [DataMember(Name = "from_user")] public string FromUser { get; set; } [DataMember(Name = "to_user_id")] public string ToUserId { get; set; } [DataMember(Name = "text")] public string Text { get; set; } [DataMember(Name = "id")] public long Id { get; set; } [DataMember(Name = "from_user_id")] public string FromUserId { get; set; } [DataMember(Name = "to_user")] public string ToUser { get; set; } [DataMember(Name = "geo")] public string Geo { get; set; } [DataMember(Name = "iso_language_code")] public string IsoLanguageCode { get; set; } [DataMember(Name = "source")] public string Source { get; set; } public TwitterResultItem() { } }
データをExcelに表示
GetExcelSheet() が返すのは前述の excelSheet です。やっていることは 2行目2列目のセルを選択し、さらに行全体を選択します。その位置に対して行を挿入します。
挿入した位置の行にTwitterのユーザーIDと呟き内容を1,2列目にセットします。
以上を取得したつぶやき数だけ繰り返してします。
private void ToExcel(TwitterResult result) { dynamic sheet = GetExcelSheet(); foreach (TwitterResultItem item in result.Results) { dynamic range = sheet.Cells[2, 2]; dynamic row = range.EntireRow; row.Insert(0, false); range = sheet.Range(sheet.Cells[2, 1], sheet.Cells[2, 2]); string[] values = { item.FromUser, item.Text }; range.value = values; } }