読者です 読者をやめる 読者になる 読者になる

ComponentOne Information

ComponentOne Studio/Wijmo/Xuniの最新情報を公開中

CSVデータがあればExcel形式で一覧表示したくなる気持ち

Xuni

データを可視化するお話です。
モバイルアプリ用コンポーネントのXuni(ズーニー)は、データ可視化を目的としたコントロールです。データをモバイルアプリ上で表現するために、グリッドやチャートを提供しています。
表示するためには、必ず何らかの手段でデータを引き渡す必要があります。

こちらの記事ではJSON形式のデータをFlexGridを利用してグリッドビューを表示する例を解説しました。
hatena.c1.grapecity.com

今回はCSV形式のデータをもとに一覧表を作成します。
利用するのは日本郵便株式会社が提供している郵便番号データです。 CSV形式のファイルで提供されており、同社のWebサイトからダウンロードできます。

郵便番号データダウンロード - 日本郵便

使う前に郵便番号データの説明を見ると、全国版は12万件もあるとのことでした。今回はテストデータで利用するので、グレープシティ本社の郵便番号[981-3205]が含まれる宮城県版を利用します。

そこにデータがあるから

データがあれば、まずはExcelのような一覧表示をしたくなります。
見やすく可視化するためには必要な手続きです。
ダウンロードしたファイルはCSV形式ですので、Excelで読み込めば簡単に表示できます。
しかし、それでは単純なので手法を変え、Visual Studio Code(以下、VSCode)を利用してデータを表示します。

VSCodeは一般利用が可能なエディタなので、CSVファイルを読み込んでもそのまま表示され、Excelのような表示にはなりません。これはメモ帳などの他エディタと同じです。
ちなみにこの記事もVSCodeで書いています。

Excel形式で表示する拡張機能

VSCodeには拡張機能(エクステンション)を利用する仕組みが備わっており、拡張機能は自由に作成して利用でき、公開すれば他の人も利用できます。
グレープシティが公開しているVSCode用の拡張機能「Excel Viewer」はその名の通り、Excelファイルを参照可能にするエクステンションです。

marketplace.visualstudio.com

VSCodeからMarketplaceに接続すれば、簡単にインストールできます。
検索して追加するだけですので詳細な手順は割愛します。

f:id:ComponentOne_JP:20170209120235p:plain

拡張機能を利用するにはVSCodeを起動した状態で、コマンドパレットを開きます。 コマンドパレットはメニューからも開きますが、Windowsであれば「Ctrl+Shift+“P"」、macOSであれば「⌘+shift+"P"」のショートカットが利用可能です。

実は、拡張機能のインストールもコマンドパレットから実行できます。
Excel Viewerは
ext install gc-excelviewer
を実行し、VSCodeを再起動することで利用可能です。

CSVファイルを表示

それでは実際に利用してみます。
CSVファイルをExcel形式で表示するには、まず通常通りVSCodeでファイルを開きます。
[ファイル]-[開く]から対象ファイル「04MIYAGI.CSV」を選択してください。
ファイルを開くと文字コードが異なるので文字化けします。
これを正しいエンコード(Shift-JIS)で再度読み込むには、ウィンドウの右下にエンコード表示(この時点ではUTF-8)を押すと、「エンコード付きで再読み込み」を実行するコマンドパレットが開くので処理を選択します。
次にエンコードJapanese(Shift-JIS)を選択すると、ファイルが再読み込みされて日本語が正しく表示されました。

f:id:ComponentOne_JP:20170209120056p:plain

CSVで表示された状態から、前述の手法でコマンドパレットを開きます。 コマンド入力エリアにCSV: Open Previewと入力してください。実際は途中で補完され候補が表示されるので、該当する処理してEnterを押します。

f:id:ComponentOne_JP:20170209131807p:plain

すると別のタブが起動し、CSVファイルがExcel形式でプレビュー表示されます。 今回のファイルはヘッダーがないので、最初のデータがヘッダーとして扱われています。
プレビュー表示された画面では、Excelのようにヘッダー部分をクリックすることでソートが可能です。あくまでビューですので元データに変更はなく編集もできませんが、データを一通り見やすい形で確認することはできます。
Excel ViewerはmacOS版のVisual Studio Codeでも同様に利用可能です。

f:id:ComponentOne_JP:20170209120124p:plain


モバイルアプリで一覧表示する

ここからがXuni(ズーニー)Xamarinのお話です。
Xamarin.Formsを利用し、C#でAndroid、iOSのサンプルアプリを作成します。
前項で確認した郵便番号データをを表示するアプリです。 手順は以下になります。

1.  Xamarin.Formsのプロジェクトを作成  
2.  Xuniを利用する設定  
3.  データをプロジェクトに組み込む  
4.  データを読み込むクラスを作成  
5.  表示する画面の設定  

1と2の説明は省略します。すでにXuniの利用準備が整っているプロジェクトを公開していますので、これを改造して利用します。プロジェクトは以下からダウンロード可能です。

[http://www.goxuni.com/jp/technical-information/how-to-use/#quick:embed:cite]

データをプロジェクトに組み込む

ダウンロードしたプロジェクトをVisual StudioまたはXamarin Studioで開きます。
読み込むためのCSVファイル「04MIYAGI.CSV」はPCLプロジェクトの配下に保存します。 ここでは「Xuni_QuickStart」プロジェクトの直下に、既存ファイルとして追加します。 追加したファイルのプロパティページを開き、以下の設定を行います。
ビルドアクション:EmbeddedResource
そして読み込み時に利用するリソースIDをメモしておきます。
Xuni_QuickStart.Postal_04MIYAGI.csv

データモデルを作成

データモデルのクラスを作成します。データ構造を定義し、読み込んだCSVファイルからList型のデータセットを作成します。 リソースからデータを読み込む際には、メモしておいたリソースIDを指定します。

// 郵便番号データのモデル
public class PostalCodeModel
{
    public String ID { get; set; }      // ID
    public String ZIP { get; set; }    // 郵便番号の上3桁
    public String Postal7 { get; set; }  // 7桁の郵便番号
    public String Pref { get; set; }   // 都道府県
    public String City { get; set; }   // 市区町村
    public String Town { get; set; }   // 地番

    public PostalCodeModel()
    {
    }

    public static List<PostalCodeModel> getPostalCodeList()
    {
        var _postalCodeList = new List<PostalCodeModel>();  //リストを作成

        var assembly = typeof(PostalCodeModel).GetTypeInfo().Assembly;
        //データファイルからデータを読み込み
        Stream stream = assembly.GetManifestResourceStream("Xuni_QuickStart.Postal_04MIYAGI.csv");
        using (var sr = new System.IO.StreamReader(stream))
        {
            int count = 1;
            while (!sr.EndOfStream)
            {
                //1行ずつ読み込む
                var sn = sr.ReadLine().Split(',');
                if (sn.Length > 1 && sn[0].Trim().Length > 0)
                {
                    var data = new PostalCodeModel();
                    data.ID = sn[0].ToString();
                    //郵便番号データを格納
                    data.ZIP = sn[1].ToString();
                    // 数値データを郵便番号形式にフォーマット
                    data.Postal7 = String.Format("{0:000-0000}", int.Parse(sn[2].ToString()));
                    data.Pref = sn[3].ToString();
                    data.City = sn[4].ToString();
                    data.Town = sn[5].ToString();
                    _postalCodeList.Add(data); //データをリストに追加
                    count++;
                }
            }
        }
        return _postalCodeList;
    }
}
ビューモデルを作成

データをビューであるFlexGridに表示するための、ViewModelを作成します。 ViewModelの内部で、データモデルから郵便番号データを読み込んだListを取得し、 FlexGridのItemsSourceに接続するプロパティにセットします。

// 郵便番号データのビューモデル- FlexGridのBindingContextに設定 
public class PostalCodeViewModel
{
    public PostalCodeViewModel()
    {
    }

    // データセットを返すプロパティ-FlexGridのItemsSourceに接続
    public List<PostalCodeModel> PostalCodeList
    {
        // データモデルから郵便番号リストを取得
        get { return PostalCodeModel.getPostalCodeList();}
    }
}
ビューを作成

最後にデータを表示するFlexGridを配置したビューを作成します。プロジェクトにあらかじめ作成済みのサンプルページには必要な設定が完了していますので、一部を変更するだけです。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="Xuni_QuickStart.Xuni_QuickStartPage"
            xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:Xuni_QuickStart"
            xmlns:xuni="clr-namespace:Xuni.Forms.FlexGrid;assembly=Xuni.Forms.FlexGrid"
            Padding="0,20,0,0">

    <Grid VerticalOptions="FillAndExpand">
        <xuni:FlexGrid x:Name="grid" ItemsSource="{Binding PostalCodeList}"/>
    </Grid>

</ContentPage>
コードビハインドの記述

ビューのコードビハインドにFlexGridの設定を追加します。
FlexGridとビューモデルを接続するために、BindingContextに設定します。 また、FlexGridの設定をデータを表示する各列を定義します。コード全体は以下です。
これで、FlexGridに渡されたデータソースを表示できるようになります。

public Xuni_QuickStartPage()
{
    InitializeComponent();
    // ViewModelをBindingContextに設定
    grid.BindingContext = new PostalCodeViewModel();

    // 先頭の2列は非表示
    grid.Columns[0].IsVisible = false;
    grid.Columns[1].IsVisible = false;
    // FlexGridに表示する列のヘッダーを指定
    grid.Columns[2].Header = "郵便番号";
    grid.Columns[3].Header = "都道府県";
    grid.Columns[4].Header = "市区町村";
    grid.Columns[5].Header = "地番";
    // 列幅を比率で指定するスターサイズ機能
    grid.Columns[2].Width =  new GridLength(1,GridUnitType.Star);
    grid.Columns[3].Width = new GridLength(1.5, GridUnitType.Star);
    grid.Columns[4].Width = new GridLength(1.5, GridUnitType.Star);
    grid.Columns[5].Width = new GridLength(2, GridUnitType.Star);

    // 列ヘッダーのみを表示する
    grid.HeadersVisibility = Xuni.Forms.FlexGrid.GridHeadersVisibility.Column;
}
iOSの設定

iOSアプリでは、Xuniの初期化処理を追加する必要があります。
iOSプロジェクトのAppDelegate.csを開いて、FinishedLaunchingメソッドに以下のようにコードを追加してください。

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.Init();

    // Xuniのコンポーネントを初期化
    Xuni.Forms.FlexGrid.Platform.iOS.Forms.Init();

    LoadApplication(new App());
    return base.FinishedLaunching(app, options);
}

これはXamarin.Formsのカスタムコントロールでは、必要になる手続きです。
他のXuniコントロールや他のカスタムコントロールでも同様になります。Androidでは不要です。

完成

以上で準備が整いました。実行すると郵便番号一覧を表示します。
FlexGridの基本機能にソートがあるので、前述のVSCode同様にヘッダー部分をタップするとソートができます。 f:id:ComponentOne_JP:20170209120141p:plain

まとめ

今回データグリッドを表示したXuniのコントロールはFlexGridです。
その前に紹介した「Excel Viewer」は、JavaScriptライブラリ製品Wijmo(ウィジモ)のFlexGridを利用して開発しています。
データがあるならExcel形式で表示という要望に応えるために、多種多様なプラットフォームでFlexGridを揃えています。

FlexGrid (フレックスグリッド)
FlexGrid for WPF - ComponentOne Studio(コンポーネントワンスタジオ)
FlexGrid for WinForms - ComponentOne Studio
FlexGrid for UWP - ComponentOne Studio
FlexGrid for ASP.NET MVC - ComponentOne Studio
FlexGrid for Silverlight - ComponentOne Studio
FlexGrid - JavaScript/TypeScript/Angular - Wijmo(ウィジモ)
FlexGrid - Xamarin/Android/iOS - Xuni(ズーニー)
ComponentOne