React アプリに Power BI レポートやダッシュボードを埋め込む

本記事では、Microsoft からリリースされている React 用の Power BI クライアントについて見ていきます。

[GitHub: powerbi-client-react](https://github.com/microsoft/PowerBI-client-react)

# powerbi-client-react とは
React Component として [powerbi-client](https://www.npmjs.com/package/powerbi-client) がラップされたもので、簡単に React アプリケーションに Power BI を埋め込めるというものでした。これは便利。では早速スクラッチで作ってみましょう。

# React アプリを作成

今回は Create React App というツールを使ってアプリを作成します。

1\.　npx で create-react-app を実行。テンプレートは自分の好みで typescript を指定。

```shell
npx create-react-app react-powerbi-embed --template typescript
```
2\. 作成が完了したらフォルダに移動してアプリを一旦実行してアプリが起動する事を確認。

```shell
cd react-powerbi-embed
yarn start
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/8168970b-0d30-f706-86f8-b8c9f3715ee7.png)

3\. powerbi-client-react を追加。

```shell
npm install powerbi-client-react
```

# Power BI レポートの選定

埋め込むレポートを用意します。どのレポートでもいいのですが、ここでは既存のアプリにあるレポートを使ってみます。

1\. Power BI より「アプリ」を選択し、「アプリの取得」ボタンをクリック。一覧より任意のアプリを選択。ここでは COVID-19 US Tracking Report を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/bb99da5f-18e1-23ae-f585-6ae0a1d0025b.png)

2\.　ワークスペースより追加されたレポートを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6d1c55ac-474f-6820-716c-8655c4421ba6.png)

3\. アドレスより report の Id をコピーしておく。Id は url の reports 直後にある GUID。

# アクセストークンの取得

Power BI の埋め込みに使えるアクセストークンは種類がいくつかあるため、この記事では説明しません。機会があれば別の記事で紹介しますが、今回は PowerShell を使って一時的に使えるものを取得します。

1\. PowerShell を起動して Power BI 用モジュールを追加。

```shell
Install-Module MicrosoftPowerBIMgmt
```

2\. Power BI に接続。ログインが求められるので認証情報を入力。

```shell
Connect-PowerBIServiceAccount
```
3\. アクセストークンの取得。出力されたトークンの Bearer 以降をコピー。

```shell
Get-PowerBIAccessToken -AsString
```
トークンは一定期間で無効となるため、エラーが出るようになったらまた再発行してください。

# Power BI レポートの埋め込み

[GitHub](https://github.com/microsoft/PowerBI-client-react) ページにあるサンプルを使っていきます。

1\. 作成した react アプリを Visual Studio Code で開き、App.tsx を選択。

2\. import を追加。GitHub の例では powerbi-clien-react だけ追加しているが、powerbi-client も必要。

```typescript
import { PowerBIEmbed } from 'powerbi-client-react';
import { models, Report} from 'powerbi-client';
```

3\. 既存の header 要素の内容を削除して、代わりにサンプルを張り付け。PowerBIEmbed は powerbi-client-react が提供する React コンポーネント。

```typescript

<PowerBIEmbed
	embedConfig = {{
		type: 'report',   // Supported types: report, dashboard, tile, visual and qna
		id: '<Report Id>',
		embedUrl: '<Embed Url>',
		accessToken: '<Access Token>',
		tokenType: models.TokenType.Embed,
		settings: {
			panes: {
				filters: {
					expanded: false,
					visible: false
				}
			},
			background: models.BackgroundType.Transparent,
		}
	}}

	eventHandlers = { 
		new Map([
			['loaded', function () {console.log('Report loaded');}],
			['rendered', function () {console.log('Report rendered');}],
			['error', function (event) {console.log(event.detail);}]
		])
	}
		
	cssClassName = { "report-style-class" }

	getEmbeddedComponent = { (embeddedReport) => {
		this.report = embeddedReport as Report;
	}}
/>
```
4\. embedConfig の id と accessToken に取得した値を張り付け。また tokenType を models.TokenType.Aad を指定。

```react
embedConfig = {{
    type: 'report',   // Supported types: report, dashboard, tile, visual and qna
    id: '<取得したレポート ID>',
    embedUrl: 'https://app.powerbi.com/reportEmbed',
    accessToken: '<取得したアクセストークン>',
    tokenType: models.TokenType.Aad,
    settings: {
        panes: {
            filters: {
                expanded: false,
                visible: false
              }
            },
            background: models.BackgroundType.Transparent,
        }
    }}
```

5\. getEmbeddedComponent ではローカル変数であろう report に対して埋め込まれたレポートを取得しているが、React ではステート使う事が多いため、React の import を変更し useState を読み込み。

```typescript
import React, { useState } from 'react';
```

6\. function 直下にステート管理用のコードを追加。

```typescript
const [report, setReport] = useState<Report>();
```

7\. 指定した setReport を使うように getEmbeddedComponent を変更。

```typescript
getEmbeddedComponent = { (embeddedReport) => {
  setReport(embeddedReport as Report);
}}
```

8\. cssClassName に "report-style-class" が指定されているが、そのようなスタイルは存在しないため、App.css に以下を追加。

```css
.report-style-class {
    height: 69vh;
    margin: 1% auto;
    width: 60%;
}
```
9\. サンプルではレポートの背景が透明に指定されているが、見辛いため Default に変更。

```react
background: models.BackgroundType.Default
```

## アプリを確認
コードが追加されたら、自動更新されたアプリを確認してみましょう。レポートが埋め込まれている事が分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/aebee3f8-c52e-5f50-0740-63c2e44b5aaf.png)

# イベントの取得

eventHandlers には各種イベントの処理を指定できます。サンプルではイベント発生時にコンソールにログを出力するようになっています。

```typescript
eventHandlers = { 
  new Map([
    ['loaded', function () {console.log('Report loaded');}],
    ['rendered', function () {console.log('Report rendered');}],
    ['error', function (event) { if(event!=undefined) console.log(event.detail);}]
  ])
}
```

ブラウザで F12 キーを押下して、コンソールを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ec2eaadf-1750-61a0-e86d-473894911e95.png)

# ダッシュボードの埋め込み

Power BI の埋め込みはレポート以外にも、ダッシュボードやタイル、QnA も埋め込めます。ここではダッシュボードを試してみます。

1\. Power BI で任意のダッシュボードを追加。ここではレポートから複数のタイルをピン止めしたダッシュボードを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/381e3e07-a418-5c61-c68f-5e336f168548.png)

2\. レポートと同様、アドレスから Id をコピー。

3\. Visual Studio に戻り、embedConfig の以下項目を変更。

- id: ダッシュボードの ID に変更
- embedUrl: 'https://app.powerbi.com/dashboardEmbed' に変更

4\. アプリを確認してダッシュボードが表示されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/b94896e8-41b8-42d4-6cce-327bb89da4b8.png)

# まとめ

今回は React 用の PowerBI クライアントを簡単に紹介しました。より詳細は実際のコードを見ていただくとともに、GitHub にあるデモアプリも使ってみてください。