如何在Streamlit中集成powerbiclient的QuickVisualize?渲染失败求助
问题分析与解决方案
根本原因
QuickVisualize是微软为Jupyter Notebook生态设计的组件,返回的是Jupyter Widget实例,而Streamlit的渲染系统不支持直接解析这类对象,所以st.write(PBI_visualize)无法正确显示仪表盘。
可行解决方案
方案1:导出Power BI报表为嵌入HTML,在Streamlit中加载
先在Jupyter环境中完成QuickVisualize的配置并将报表保存到Power BI服务,再获取嵌入代码,最后在Streamlit中用HTML组件渲染:
- 在Jupyter中执行以下步骤完成报表创建与保存:
from powerbiclient import QuickVisualize, get_dataset_config from powerbiclient.authentication import DeviceCodeLoginAuthentication import pandas as pd df = pd.read_csv('Financial Sample.csv') df = df.drop(['Month Number', 'Month Name', 'Year'], axis=1) df = df.loc[df['Units Sold'] > 1000] df['Discounted'] = df['Discount Band'] != 'None' device_auth = DeviceCodeLoginAuthentication() PBI_visualize = QuickVisualize(get_dataset_config(df), auth=device_auth) # 将报表保存到Power BI工作区(替换为你的工作区名称) PBI_visualize.save_report(name="Financial Sample Dashboard", workspace_name="你的工作区名称")
登录Power BI服务,找到保存的报表,点击嵌入 -> 发布到Web,获取生成的iframe代码。
在Streamlit中嵌入该iframe:
import streamlit as st from streamlit.components.v1 import html # 替换为你获取的Power BI嵌入iframe代码 pbi_iframe = """ <iframe width="800" height="600" src="你的Power BI报表嵌入URL" frameborder="0" allowFullScreen="true"></iframe> """ html(pbi_iframe, width=800, height=600)
方案2:使用Power BI Embedded API实现灵活嵌入(适合生产环境)
如果需要动态控制报表或数据集,可通过Power BI Embedded API获取嵌入令牌,再在Streamlit中渲染:
import streamlit as st from streamlit.components.v1 import html import requests # 替换为你的Power BI Embedded信息 tenant_id = "你的租户ID" client_id = "你的应用ID" client_secret = "你的应用密钥" workspace_id = "工作区ID" report_id = "报表ID" # 获取访问令牌 auth_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" auth_data = { "grant_type": "client_credentials", "client_id": client_id, "client_secret": client_secret, "scope": "https://analysis.windows.net/powerbi/api/.default" } auth_response = requests.post(auth_url, data=auth_data) access_token = auth_response.json()["access_token"] # 获取嵌入令牌 embed_url = f"https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/reports/{report_id}/GenerateToken" embed_body = {"accessLevel": "View"} embed_response = requests.post(embed_url, json=embed_body, headers={"Authorization": f"Bearer {access_token}"}) embed_token = embed_response.json()["token"] # 渲染报表iframe pbi_embed_html = f""" <div id="reportContainer"></div> <script src="https://microsoft.github.io/PowerBI-JavaScript/dist/powerbi.js"></script> <script> var embedConfiguration = {{ type: 'report', id: '{report_id}', embedUrl: 'https://app.powerbi.com/reportEmbed?reportId={report_id}&groupId={workspace_id}', accessToken: '{embed_token}', settings: {{ panes: {{ filters: {{ visible: false }} }} }} }}; var reportContainer = document.getElementById('reportContainer'); var report = powerbi.embed(reportContainer, embedConfiguration); </script> """ html(pbi_embed_html, width=1000, height=700)
方案3:改用Streamlit原生可视化(快速替代)
如果不需要Power BI的特定功能,直接用Streamlit自带的可视化组件基于DataFrame生成仪表盘:
import streamlit as st import pandas as pd df = pd.read_csv('Financial Sample.csv') df = df.drop(['Month Number', 'Month Name', 'Year'], axis=1) df = df.loc[df['Units Sold'] > 1000] df['Discounted'] = df['Discount Band'] != 'None' st.title("Financial Sample Dashboard") # 销量按区域分布 st.subheader("Units Sold by Region") st.bar_chart(df.groupby('Region')['Units Sold'].sum()) # 折扣与利润关系 st.subheader("Profit vs Discounted") st.box_plot(df, x='Discounted', y='Profit') # 产品类别销量占比 st.subheader("Units Sold by Product Category") st.pie_chart(df.groupby('Product Category')['Units Sold'].sum())
内容的提问来源于stack exchange,提问作者Fabrício Gama
相关产品推荐
相关产品推荐

