使用PowerBI_Embed實現Web訪問報表 part 3

wait4friend發表於2018-06-12

這是使用微軟Power BI Embed功能,在自定義WEB應用中嵌入報表的系列入門指南。系列文章共分為三篇,這是第三篇。

第一篇 背景和準備工作

第二篇 在PBI Desktop中開發和釋出報表

第三篇 嵌入報表到自定義WEB應用中

獲取嵌入PBI的引數

在自定義應用內訪問PBIE,呼叫JavaScript API的過程中,需要三個引數,分別是

  • embedToken 嵌入令牌,用於鑑權
  • embedURL 報表的URL地址
  • reportId 報表的唯一標誌

最重要的步驟是通過賬戶安全性認證,從 Azure AD 獲取訪問令牌和嵌入令牌,然後才能夠呼叫API嵌入報表。目前微軟提供了兩種方式來獲取Token,分別是 .Net SDK 和 REST介面。

本案例中使用Python呼叫REST介面來獲取令牌(在實際生產環境中,建議使用其他更安全的方式來獲取令牌),並構造三個引數,整個過程描述如下。

獲取Access Token

def getAccessToken (username, password, clientId):
    """
    獲取Access Token,這是下一步獲取EmbedTokken的前提條件
    :username Power BI Pro賬戶名稱
    :password Power BI Pro賬戶密碼
    :clientId 是在Azure中註冊應用得到的"應用程式ID"
    :return 字串格式的AccessToken
    """
    url =  'https://login.microsoftonline.com/common/oauth2/token'

    headers = { 'Content-Type' : 'application/x-www-form-urlencoded' }

    body = {
          'grant_type':'password',
          'client_id': clientId,
          'resource':'https://analysis.windows.net/powerbi/api',
          'scope':'openid',
          'username':username,
          'password':password
        }

    response = requests.post(url=url, headers=headers, data=body)    
    return response.json()['access_token']   
複製程式碼

獲取Embed Token

def getEmbedToken(accessToken, groupId, reportId):
    """
    結合AccessToken,報表組ID,報表ID資訊,獲取EmbedToken
    :accessToken 上一步得到的訪問令牌
    :groupId 報表組ID
    :reportId 報表ID
    :return 字串格式的嵌入令牌
    """
    url = "https://api.powerbi.com/v1.0/myorg/groups/{0}/reports/{1}/GenerateToken"\
        .format(groupId, reportId)
        
    headers = {
        'Content-Type' : 'application/x-www-form-urlencoded',
        'authorization' : "Bearer {0}".format(accessToken)
    }
    
    body = {'accessLevel':'View'}
    
    response = requests.post(url=url, headers=headers, data=body)   
    return response.json()['token']
複製程式碼

構造訪問引數

def getPowerBIEmbedParam(username, password, clientId, groupId, reportId):
    accessToken = getAccessToken(username, password, clientId)
    embedToken = getEmbedToken(accessToken, groupId, reportId)
    embedURL = "https://app.powerbi.com/reportEmbed?reportId={0}&groupId={1}".format(reportId, groupId)
    
    print(embedToken)
    print(embedURL)
    print(reportId)
複製程式碼

獲取報表資訊

下面介紹如何獲得報表組ID,報表ID。當我們釋出一個報表之後,通過PBI門戶來訪問這個報表,在瀏覽器位址列就可以看到這兩個引數。如下圖

image-20180606144911840

生成三個引數

# 這三個引數是全域性生效,不需要修改
username = 'bi***er@da*******ft.com'
password = '******'
clientId = 'c14***********************e7a9ef'

# 這三個引數是報表級別的
groupId = '7fd***********************d00b5'
reportId = '4088***********************4a4e0'

getPowerBIEmbedParam(username, password, clientId, groupId, reportId)
複製程式碼

生成的三個引數片段如下

H4sIAAAAAAAEADVWNQ7****sCBa8y0-9kplWmsDMzM7M2G4zjfbu2xpp0Wfnnv3
    
https://app.powerbi.com/reportEmbed?reportId=40***4a4e0&groupId=7fd***b5
    
40******4a4e0
複製程式碼

自定義應用嵌入PBIE

微軟線上演示工具

為了便於大家開發和測試,微軟提供了一個線上工具,使用這個工具,我們可以直接填入三個引數測試報表,也可以把樣例JS程式碼整合到自己的應用程式中。這裡我們演示一下直接使用線上demo的方式。

如下圖,在演示頁面填入三個引數之後,點選【Run】即可顯示嵌入報表。

image-20180606151616867

JS - 呼叫PBIE

參考官方提供的樣例和手冊,我們很容易實現一個用JavaScript呼叫PBIE介面的應用。首先從這裡獲取SDK(powerbi.js),然後編寫一個簡單的html檔案。

<html>
<head>
  <title>PBIE Test</title>
  <meta charset="utf-8"> 
  <script src="scripts/powerbi.js"></script>
</head>
<body>
  <div id="captionArea">
    <h1>Power BI Embed 測試</h1>
  </div>
  <button onclick="show_default()">展示預設報表</button>
  <div id="embedContainer" style="height:90%">
  </div>
  <script>
    // 用於訪問PBIE的三個引數,僅供測試,正式環境下不能明文寫在這裡!!!
    var txtAccessToken = 'H4sIAA***AAA==';
    var txtEmbedUrl =
    'https://app.powerbi.com/reportEmbed?reportId=40**0b5';
    var txtEmbedReportId = '408**a4e0';
      
    // 預設方式,不做特殊處理直接顯示報表  
    function show_default () {
      var models = window['powerbi-client'].models;
      var permissions = models.Permissions.All;
      var config = {
        type: 'report',
        tokenType: models.TokenType.Embed,
        accessToken: txtAccessToken,
        embedUrl: txtEmbedUrl,
        id: txtEmbedReportId,
        permissions: permissions,
        settings: {
          filterPaneEnabled: true,
          navContentPaneEnabled: true
        }
      };
 
      var embedContainer = document.getElementById('embedContainer');
      var report = powerbi.embed(embedContainer, config);
    }
  </script>
</body>
</html>
複製程式碼

執行這個html檔案的效果如下圖,可以看到整個PBI報表被嵌入到自定義的網頁中了。

image-20180607114359834

JS - 設定過濾器

嵌入PBIE的一個常見場景是,根據當前登入人員對資料集進行過濾,實現行級別資料許可權的控制。SDK中提供了設定全域性過濾器的方法,和前面演示的程式碼相比,有兩個變化

  • 建立一個filter物件,這裡使用的是basic型別(這裡沒有演示的另一種過濾器是advanced型別,可以支援多個條件組合)
  • 在config中指定要使用這個filter物件

如下程式碼片段,我們對PBI模型中的人力成本表中的部門欄位進行了篩選,可以簡單的理解為在特定表上執行了一個過濾條件。

    // 對報表資料進行篩選之後再展示,可以用來控制行級別的資料許可權  
    function show_pre_filter () {
        // 設定一個過濾器
		const filter = {
		  $schema: "http://powerbi.com/product/schema#basic",
		  target: {
		    table: "人力成本",
		    column: "部門"
		  },
		  operator: "In",
		  values: ["研發中心"]
		};      

      var models = window['powerbi-client'].models;
      var permissions = models.Permissions.All;
      var config = {
        type: 'report',
        tokenType: models.TokenType.Embed,
        accessToken: txtAccessToken,
        embedUrl: txtEmbedUrl,
        id: txtEmbedReportId,
        permissions: permissions,
        // 使用過濾器  
        filters: [filter],
        settings: {
          filterPaneEnabled: true,
          navContentPaneEnabled: true
        }
      };
 
      var embedContainer = document.getElementById('embedContainer');
      var report = powerbi.embed(embedContainer, config);
    }
複製程式碼

執行這個帶有前置過濾器的效果如下圖,可以看到PBI報表中和部門相關的資料發生了變化。在崗人數這個指標從預設條件下的131變成了11。

image-20180608101910760

總結

微軟提供的PBIE功能,使我們可以用比較低的成本把Power BI報表整合到我們已有的Web應用中。採用這種方案的好處包括但不限於費用的降低(更詳細的費用方案請參考本文末的參考資料定價部分),更靈活的許可權處理方式,更炫酷的資料視覺化效果,等等。

本文用一個簡單常見的案例,從頭到尾演示了採用PBIE整合方案的各個環節。因為篇幅和時間的原因,我們沒有涉及到PBIE提供的更多複雜功能,這部分內容請參考官方文件資料。

參考資料

獲取令牌的流程和方法

Power BI JavaScript Libarary,Wiki,及樣例原始碼

Power BI Embedded文件

Power BI JavaScript 演示

Power BI REST API

Power BI Premium 常見問題解答

Power BI Embedded 定價

相關文章