TableauにCSVダウンロードボタンをつける

CSVDownload

こんにちは。truestar工房の、ひらいです。

truestar工房では様々な便利ツールを開発しています。
今回は、Tableauのダッシュボードに追加できる「CSVダウンロードボタン」を紹介します。

概要

Tableauはグラフなど視覚表現を用いたVizが強力なツールですが、データをCSVでダウンロードしたいという要望はよくあります。

もちろん、Tableau Serverの標準機能でCSVのダウンロードは可能です。

  1. 対象の数表を一部分でもクリックして選択
  2. 右上の「ダウンロード」をクリック
  3. 「クロス集計表」をクリック

しかし、慣れていないユーザーにとっては、まず対象の数表を選択しないといけない点や、CSV→クロス集計表という用語の違いもあって、案外ハードルの高いものとなっています。

そこで、詳しい説明がなくても直感的に使えるよう、CSVダウンロードボタンを作ってみました。

機能はJavaScript APIを用いています。
ボタンの形状はHTML+CSSで実装しており、当該のWebページをダッシュボードに追加するだけで使えるようにしています。

ダウンロード&導入方法

下記のGitHubに公開しました。
https://github.com/atelier-truestar/CSVDownload/

ファイル一覧の右上にある「↓Code」をクリックし、「Download ZIP」をクリックすると、必要なファイルがダウンロードされます。

zipファイルを任意の場所に解凍します。
必要なファイルは CSVDownload.html のみです。このHTMLファイル単体で動作します。

CSVDownload.htmlを、Webでアクセスできる場所に格納します。
オススメは、Tableau Serverと同じ場所に格納することです。
Tableau Serverが設置されているサーバーの、
C:\ProgramData\Tableau\Tableau Server\data\tabsvc\httpd\htdocs
(Tableau Serverのインストール場所がデフォルトの場合。別の場所にインストールされている場合は適宜読み替えてください)
に格納すれば、「https:// Tableau ServerのURL /CSVDownload.html」でアクセスが可能になるはずです。

ボタンの色や形状、文字列を好みのものに変更するには、直接HTMLファイルを修正してください。
デフォルトの色や形状はBootstrap 4を使用していますが、HTML/CSS次第で自由に変更可能です。

以上で準備は完了です。

使い方

Tableau Desktopで、ダッシュボード上にオブジェクトで「Webページ」を追加します。

URLには、先ほどのCSVDownload.htmlのURLを入力します。
ダッシュボード上にシートが1つだけの場合は、これだけで動きます。
複数のシートがある場合は、CSVDownload.htmlの後ろに"#対象シート名"を追加します。

以上でダッシュボード上に「CSVダウンロード」ボタンが配置されました。

実際にパブリッシュして確かめてみましょう。

「CSVダウンロード」ボタンをクリックすると、「クロス集計が生成されました。」のダイアログボックスが出ます。「ダウンロード」を押すと、CSVファイルがダウンロードされます。

これで慣れないユーザーでも、CSVのダウンロードが簡単にできるようになりました。

応用すれば、PDFのダウンロードなども同様に可能です。

以下は開発者向けの情報です。

ポイント解説

以下が実際のJavaScriptコードです。

function exportCrossTab() {
    // Get Viz
    var vizs = window.parent.parent.tableau.VizManager.getVizs();
    var viz = vizs[0];
    // Get Sheet Name from URL#Hash
    var hash = location.hash;
    var sheetname = decodeURI(hash.substr(1));
    // Show Export CrossTab Diablog
    if (sheetname == '') {
        viz.showExportCrossTabDialog();
    } else {
        viz.showExportCrossTabDialog(sheetname);
    }
}

VizManagerの操作

あまり解説されている例が多くありませんが、ダッシュボードに埋め込まれたWebページから、window.parent.parent.tableau.VizManagerとたどれば、JavaScript APIのトップレベルクラスであるVizManagerにアクセスできます。
VizManager以下のJavaScript APIについては、「Tableau JavaScript API Reference」が詳しいです。
https://help.tableau.com/current/api/js_api/en-us/JavaScriptAPI/js_api_ref.htm

VizクラスのshowExportCrossTabDialogメソッドで、クロス集計表(CSVファイル)出力のダイアログを表示することができます。
showExportCrossTabDialogの代わりに、showExportPDFDialogやshowExportImageDialogのメソッドを使えば、PDFや画像ファイルをダウンロードすることも可能です。

引数の指定

ダッシュボード上にワークシートが1つだけであれば、showExportCrossTabDialogの引数に何も指定しなくてよいのですが、複数のワークシートがある場合は特定のシート名を指定してやらないといけません。
これを解決する方法として、URLの後ろに「#ハッシュ」としてシート名を付加することにしました。

「#ハッシュ」はページ内の位置を表す要素ですが、JavaScriptではlocation.hashで取得可能なので、これをシート名のパラメーターとして利用しています。
location.hashでは頭の"#"も付いて取得されるため、先頭の1文字(#)を除去して、さらにシート名が日本語などの場合に対応できるようURIデコード(%xxの形式に変換)しています。

このURLに「#ハッシュ」を付加する方法は、JavaScript APIに何らかのパラメーターを送る際に有効だと思いますので、ぜひ活用してみてください。

さて、非常に便利かつ手軽に導入できる「CSVダウンロードボタン」ですが、ダッシュボードの構成によっては上手く動かない罠があります。

以下、弊社で実際に直面した問題と、それをどう解決したかについて解説します。

罠① URLアクションのターゲットが変わる

このCSVダウンロードボタンとURLアクションが共存している場合、URLアクションのターゲットウィンドウがCSVダウンロードボタンのフレーム(iframe)に設定されてしまいました。

この動きは下記にある通り、Tableauの仕様のようです。

https://kb.tableau.com/articles/howto/opening-links-in-separate-browser-windows-or-tabs?lang=ja-jp
URLアクションとWebオブジェクトが同一ダッシュボードに存在する場合、リンクはWebオブジェクトで開きます。この動作は設計上のものです。

仕方ないので、URLアクションの部分もWebオブジェクトにして、JavaScriptで以下のようにやって解決しました。

window.open(url, '_blank');

同一画面でURLアクションを使用していなければ、特に問題ありません。

罠② embed=yesだと動かない

弊社のケースでは、Tableauのヘッダー部分を隠すために、URLに「embed=yes」を付けて発行していたのですが、この場合、トップレベルの tableau.VizManager が生成されないため、ダウンロードボタンが機能しませんでした。

本来「embed=yes」は、ページ埋め込みのためのオプションで、Tableauのヘッダーが非表示になるのは副次的な機能なんですよね。
ページ埋め込みの場合は、その外側のWebページでVizManagerを使って制御するのが普通かと思われます。それとの重複を避けるため、敢えてVizManagerを生成しないようにしているのでしょう。

というわけでかなりムリヤリですが、JavaScriptでCSSを制御して、Tableauのヘッダー部分を隠すようにしました。
具体的には、以下のJavaScriptを含んだHTMLファイルを作成して、CSVDownload.htmlと同じ場所に格納します。そしてそれをWebページとしてダッシュボードに追加しました。サイズは1×1ピクセルの最小限で十分です。

<!DOCTYPE html>
  <html>
    <head>
      <title>Tableauのヘッダーを隠す</title>
      <script type="text/javascript">
        var w = window.parent.parent;
        var current_url = w.location;
        var regexp = new RegExp(':toolbar=top', 'i');
        if (regexp.test(current_url.href)) {
          w.document.querySelector("div[tb-top='topBarSettings.height']").style.top = '0px';
          w.document.querySelector("div[settings='topBarSettings']").style.display = 'none';
          w.document.querySelector("div.tb-vizviewer-widget-container").style.display = 'none';
          w.document.querySelector("div.tb-vizviewer").style.top = '0px';
        }
      </script>
      </head>
    <body>
  </body>
</html>

ヘッダー部分のHTMLの構造はTableau Serverのバージョンによって違うようで、上記のJavaScriptは2018.3で動作します。最新のバージョンだと構造が異なるため、上記では動作しません。querySelectorの中身を適宜変更すれば動作すると思います。

これで問題なくCSVダウンロードボタンが機能するようになりましたが、最初の読み込み時の一瞬はTableauのヘッダーが表示されてしまうので、あまりスマートではないですね。
もっと良いやり方をご存じでしたら、ぜひご教示ください。

まとめ

ベータ版での無償共有ですので、動作保証や利用によって生じた不具合等の責任は一切負いかねます。ご了承ください。

導入支援やカスタマイズなどのサポートは、有償にて承っております。
下記のお問い合わせページから、ぜひお問い合わせください!
https://www.truestar.co.jp/contact/

では!