了解如何使用 C# 和 Power BI API 以及某些 JavaScript 代码将仪表板集成或嵌入到 Web 应用。

若要开始使用本演练,需要一个 Power BI 帐户。 如果还没有帐户,请参阅注册 Power BI

若要将仪表板集成到 Web 应用,请使用 Power BI API 和 Azure Active Directory (AD) 授权访问令牌来获取仪表板。 然后,使用相同的访问令牌将仪表板加载到 div 元素。 Power BI API 向某些 Power BI 资源提供了编程访问权限。 有关详细信息,请参阅 Power BI REST API 概述Power BI JavaScript API

下载示例

本文演示了 GitHub 上的集成仪表板示例中所使用的代码。 若要参照本演练操作,请下载示例。

步骤 1 - 在 Azure AD 中注册应用

若要使用 Power BI API,需要使用你的 Azure Active Directory 租户注册应用。 你需要先执行此操作以获取客户端 ID客户端密钥(用于在 Azure AD 中标识你的 Web 应用)。 没有客户端 ID客户端密钥,Azure AD 则无法对你的 Web 应用进行身份验证。 如果已下载 集成仪表板示例,请使用注册后获取的客户端 ID客户端密钥配置此示例,使其可以对 Azure AD 进行身份验证。

我们已创建一个页面,帮助你进行注册。 可以浏览到 dev.powerbi.com/apps 以执行此步骤。

  1. 转到 dev.powerbi.com/apps

  2. 选择“使用现有帐户登录”,并登录 Power BI 帐户。

  3. 输入应用名称。 在此演练中,输入集成仪表板示例

  4. 有关应用类型,从下拉列表中选择“服务器端 Web 应用”。

  5. 输入重定向 URL。 在此演练中,Azure AD 重定向回默认页面,因此输入 http://localhost:13526。 Azure Active Directory (AD) 将使用授权代码重定向到该页面。 若要了解如何使用授权代码获取访问令牌以访问Power BI仪表板,请参阅获取身份验证访问令牌

  6. 输入主页。 在此演练中,输入此示例的主页 http://localhost:13526。

  7. 对于选择要访问的 API,选择读取所有仪表板。 有关 Power BI 应用权限的所有信息,请参阅应用权限

  8. 选择注册应用,并保存客户端 ID和生成的客户端密钥客户端 ID客户端密钥用于识别 Azure AD 中的应用。

配置示例应用程序

如果你已下载集成仪表板示例,请使用注册后获取的客户端 ID客户端密钥配置此示例,使其可以对 Azure AD 进行身份验证。 若要配置示例,请在 web.config 中更改客户端 ID客户端密钥

步骤 2 - 获取仪表板

若要获取 Power BI 仪表板,请使用获取仪表板操作,它将获取 Power BI 仪表板的列表。 从仪表板的列表中,你可以获取仪表板 ID。

Azure Active Directory 访问令牌

需要先获取 Azure Active Directory 身份验证访问令牌(下称访问令牌),才能调用获取仪表板操作或任何其他 Power BI 操作。 使用访问令牌允许应用访问 Power BI 仪表板、磁贴和报表。 若要了解有关 Azure Active Directory 访问令牌流的详细信息,请参阅 Azure AD 授权代码授予流。 下一部分将演示如何在 Web 应用中获取访问令牌

从 Azure AD 获取授权代码

获取访问令牌的第一步是从 Azure AD 获取授权代码。 若要执行此操作,请构造具有以下属性的查询字符串,并重定向到 Azure AD

授权代码查询字符串

var @params = new NameValueCollection
{
    //Azure AD will return an authorization code.
    {"response_type", "code"},

    //Client ID is used by the application to identify themselves to the users that they are requesting permissions from.
    //You get the client id when you register your Azure app.
    {"client_id", Settings.Default.ClientID},

    //Resource uri to the Power BI resource to be authorized
    //The resource uri is hard-coded for sample purposes
    {"resource", "https://analysis.windows.net/powerbi/api"},

    //After app authenticates, Azure AD will redirect back to the web app. In this sample, Azure AD redirects back
    //to Default page (Default.aspx).
    { "redirect_uri", Settings.Default.RedirectUri}
};

构造查询字符串后,重定向到 Azure AD 以获取授权代码。 下面是构造授权代码查询字符串的并重定向到 Azure AD 的完整 C# 方法。 获取授权代码后,将使用授权代码获取访问令牌

获取授权代码

protected void signInButton_Click(object sender, EventArgs e)
{
    //Create a query string
    //Create a sign-in NameValueCollection for query string
    var @params = new NameValueCollection
    {
        //Azure AD will return an authorization code. 
        //See the Redirect class to see how "code" is used to AcquireTokenByAuthorizationCode
        {"response_type", "code"},

        //Client ID is used by the application to identify themselves to the users that they are requesting permissions from. 
        //You get the client id when you register your Azure app.
        {"client_id", Properties.Settings.Default.ClientID},

        //Resource uri to the Power BI resource to be authorized
        {"resource", Properties.Settings.Default.PowerBiAPI},

        //After user authenticates, Azure AD will redirect back to the web app
        {"redirect_uri", "http://localhost:13526/Redirect"}
    };

    //Create sign-in query string
    var queryString = HttpUtility.ParseQueryString(string.Empty);
    queryString.Add(@params);

    //Redirect authority
    //Authority Uri is an Azure resource that takes a client id to get an Access token
    string authorityUri = Properties.Settings.Default.AADAuthorityUri;
    var authUri = String.Format("{0}?{1}", authorityUri, queryString);
    Response.Redirect(authUri);
}

通过授权代码获取访问令牌

现在应该已有从 Azure AD 获取的授权代码。 Azure AD 使用授权代码重定向回 Web 应用后,请使用授权代码获取访问令牌。 以下是可以在 Page_Load 事件中使用的 C# 示例。

protected void Page_Load(object sender, EventArgs e)
{

    //Test for AuthenticationResult
    if (Session[authResultString] != null)
    {
        //Get the authentication result from the session
        authResult = (AuthenticationResult)Session[authResultString];

        //Show Power BI Panel
        signInStatus.Visible = true;
        signInButton.Visible = false;

        //Set user and token from authentication result
        userLabel.Text = authResult.UserInfo.DisplayableId;
        accessTokenTextbox.Text = authResult.AccessToken;
    }
}

使用访问令牌获取仪表板

拥有访问令牌后,即可调用获取仪表板操作。 获取仪表板操作将返回仪表板列表。 你可从仪表板列表中获取仪表板。 下面是获取仪表板的完整 C# 方法。 有关如何使用 Power BI REST API 的示例,请参阅 APIARY 上的 Power BI REST API

获取仪表板

protected void getDashboardsButton_Click(object sender, EventArgs e)
{
    string responseContent = string.Empty;

    //Configure dashboards request
    System.Net.WebRequest request = System.Net.WebRequest.Create(String.Format("{0}dashboards", baseUri)) as System.Net.HttpWebRequest;
    request.Method = "GET";
    request.ContentLength = 0;
    request.Headers.Add("Authorization", String.Format("Bearer {0}", authResult.AccessToken));

    //Get dashboards response from request.GetResponse()
    using (var response = request.GetResponse() as System.Net.HttpWebResponse)
    {
        //Get reader from response stream
        using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
        {
            responseContent = reader.ReadToEnd();

            //Deserialize JSON string
            PBIDashboards PBIDashboards = JsonConvert.DeserializeObject<PBIDashboards>(responseContent);

            if (PBIDashboards != null)
            {
                var gridViewDashboards = PBIDashboards.value.Select(dashboard => new {
                    Id = dashboard.id,
                    DisplayName = dashboard.displayName,
                    EmbedUrl = dashboard.embedUrl
                });

                this.GridView1.DataSource = gridViewDashboards;
                this.GridView1.DataBind();
            }
        }
    }
}

//Power BI Dashboards used to deserialize the Get Dashboards response.
public class PBIDashboards
{
    public PBIDashboard[] value { get; set; }
}
public class PBIDashboard
{
    public string id { get; set; }
    public string displayName { get; set; }
    public string embedUrl { get; set; }
    public bool isReadOnly { get; set; }
}

步骤 3 - 使用 JavaScript 加载仪表板

可以使用 JavaScript 将仪表板载入网页上的 div 元素。

<input type="text" id="tb_EmbedURL" style="width: 1024px;" />
<input type="button" id="bEmbedDashboardAction" value="Embed Dashboard" />
<div id="dashboardContainer"></div>


window.onload = function () {
    // client side click to embed a selected dashboard.
    var el = document.getElementById("bEmbedDashboardAction");
    if (el.addEventListener) {
        el.addEventListener("click", updateEmbedDashboard, false);
    } else {
        el.attachEvent('onclick', updateEmbedDashboard);
    }

    // handle server side post backs, optimize for reload scenarios
    // show embedded dashboard if all fields were filled in.
    var accessTokenElement = document.getElementById('MainContent_accessTokenTextbox');
    if (accessTokenElement !== null) {
        var accessToken = accessTokenElement.value;
        if (accessToken !== "")
            updateEmbedDashboard();
    }
};

// update embed dashboard
function updateEmbedDashboard() {

    // check if the embed url was selected
    var embedUrl = document.getElementById('tb_EmbedURL').value;
    if (embedUrl === "")
        return;

    // get the access token.
    accessToken = document.getElementById('MainContent_accessTokenTextbox').value;

    // Embed configuration used to describe the what and how to embed.
    // This object is used when calling powerbi.embed.
    // You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
    var config = {
        type: 'dashboard',
        accessToken: accessToken,
        embedUrl: embedUrl
    };

    // Grab the reference to the div HTML element that will host the dashboard.
    var dashboardContainer = document.getElementById('dashboardContainer');

    // Embed the dashboard and display it within the div container.
    var dashboard = powerbi.embed(dashboardContainer, config);

    // dashboard.on will add an event handler which prints to Log window.
    dashboard.on("tileClicked", function (event) {
        var logView = document.getElementById('logView');
        logView.innerHTML = logView.innerHTML + "Tile Clicked<br/>";
        logView.innerHTML = logView.innerHTML + JSON.stringify(event.detail, null, "  ") + "<br/>";
        logView.innerHTML = logView.innerHTML + "---------<br/>";
    });

    // dashboard.on will add an event handler which prints to Log window.
    dashboard.on("error", function (event) {
        var logView = document.getElementById('logView');
        logView.innerHTML = logView.innerHTML + "Error<br/>";
        logView.innerHTML = logView.innerHTML + JSON.stringify(event.detail, null, "  ") + "<br/>";
        logView.innerHTML = logView.innerHTML + "---------<br/>";
    });
}

如果你下载并运行集成仪表板示例,示例外观将类似如下。

单击磁贴事件

在上述示例中,你可能已经注意到,可以处理单击仪表板上的磁贴时的事件。 有关事件的详细信息,请参阅在 JavaScript API 内处理事件

// dashboard.on will add an event handler which prints to Log window.
dashboard.on("tileClicked", function (event) {
    var logView = document.getElementById('logView');
    logView.innerHTML = logView.innerHTML + "Tile Clicked<br/>";
    logView.innerHTML = logView.innerHTML + JSON.stringify(event.detail, null, "  ") + "<br/>";
    logView.innerHTML = logView.innerHTML + "---------<br/>";
});

// dashboard.on will add an event handler which prints to Log window.
dashboard.on("error", function (event) {
    var logView = document.getElementById('logView');
    logView.innerHTML = logView.innerHTML + "Error<br/>";
    logView.innerHTML = logView.innerHTML + JSON.stringify(event.detail, null, "  ") + "<br/>";
    logView.innerHTML = logView.innerHTML + "---------<br/>";
});

如果你已下载并运行集成仪表板示例,单击磁贴将在仪表板下方输出文本。 文本如下所示。 这将允许你记录已单击磁贴,然后将用户导航到

Tile Clicked
{ "event": "TileClick", "reportEmbedUrl": "", "navigationUrl": "https://app.powerbi.com/dashboards/fcff76f9-15ff-4a8e-8242-275ac9c25b90/qna?q=count%20of%20new%20hires%20from%20July%202014%20to%20December%202014", "tileId": "0e99b45c-9b53-4920-b239-cee7d37d2369" }
---------
Tile Clicked
{ "event": "TileClick", "reportEmbedUrl": "https://app.powerbi.com/reportEmbed?reportId=ab199308-80b1-4626-9823-43a84623bd9c", "navigationUrl": "https://app.powerbi.com/reports/ab199308-80b1-4626-9823-43a84623bd9c/ReportSection1", "tileId": "ffc30447-674a-4511-944f-79e182d719de", "pageName": "ReportSection1" }
---------

处理组

对于从组嵌入仪表板,可以使用以下 REST API 调用获取组内所有可用仪表板的列表。 若要查找有关此 REST API 调用的详细信息,请参阅获取仪表板

https://api.powerbi.com/v1.0/myorg/groups/{groupId}/dashboards

以上 API 返回可用仪表板的列表。 每个仪表板均有一个已创建的 EmbedUrl 属性,用以支持组嵌入。

https://app.powerbi.com/dashboardEmbed?dashboardId={dashboardId}&groupId={groupId}

限制

  • 访问嵌入的仪表板的最终用户必须拥有 Power BI 帐户且仪表板应与其共享。

  • 在嵌入的仪表板中暂不支持问答。

  • 作为临时限制,在与安全组共享仪表板时,用户只有在 PowerBI.com 中访问仪表板后才能看到嵌入的仪表板。

另请参阅

注册 Power BI
集成仪表板示例
应用权限
Power BI JavaScript API
APIARY 上的 Power BI REST API
更多问题? 尝试参与 Power BI 社区