分分钟给 PowerBI 做外挂
注意你的PowerBI版本(至少2020.7后更新的)
打开增强预览相关选项,,,
有些人获取不到相关参数,可能需要管理员权限运行更改powershell的执行策略,这个百度一下就OK了,一句话的事儿:
set-executionpolicy remotesigned
忘了说,有些人那个json文件放置地址最后两层文件夹没有的话就自己建,,,
最近外国佬又造了一个外部工具将PowerBI数据拿到excel分析:
https://www.sqlbi.com/tools/analyze-in-excel-for-power-bi-desktop/
我猜测他的核心原理就是拿到上面的服务器地址端口和数据库名称后可以重新组成olap连接语句,而excel中如果你连接一个ssas分析服务也可以保存一个odc文件(PowerBI在线版中有个在excel分析菜单命令),你可以参考odc文件中的写法,如果你直接用txt打开这个odc文件,再修改里面的连接语句不就实现你自己的excel中分析指定PowerBI文档的目的?
如果你懂点PS,那么在本机固定地址放一个odc模板文件,让你捕捉服务器地址端口及数据库名进行txt修改保存再用excel进程打开这个文档就OK?
你会js的话就更好办了,参数化引用划线部分即可,,,
$sv=$args[0]
$db=$args[1]
$x=@"
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/x-ms-odc; charset=utf-8">
<meta name=ProgId content=ODC.Cube>
<meta name=SourceType content=OLEDB>
<meta name=Catalog content=$db>
<meta name=Table content=Model>
<title>$sv $db Model</title>
<xml id=docprops><o:DocumentProperties
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns="http://www.w3.org/TR/REC-html40">
<o:Name>$sv $db Model</o:Name>
</o:DocumentProperties>
</xml><xml id=msodc><odc:OfficeDataConnection
xmlns:odc="urn:schemas-microsoft-com:office:odc"
xmlns="http://www.w3.org/TR/REC-html40">
<odc:Connection odc:Type="OLEDB">
<odc:ConnectionString>Provider=MSOLAP.8;Integrated Security=SSPI;Persist Security Info=True;Data Source=$sv;Update Isolation Level=2;Initial Catalog=$db</odc:ConnectionString>
<odc:CommandType>Cube</odc:CommandType>
<odc:CommandText>Model</odc:CommandText>
</odc:Connection>
</odc:OfficeDataConnection>
</xml>
<style>
<!--
.ODCDataSource
{
behavior: url(dataconn.htc);
}
-->
</style>
</head>
<body onload='init()' scroll=no leftmargin=0 topmargin=0 rightmargin=0 style='border: 0px'>
<table style='border: solid 1px threedface; height: 100%; width: 100%' cellpadding=0 cellspacing=0 width='100%'>
<tr>
<td id=tdName style='font-family:arial; font-size:medium; padding: 3px; background-color: threedface'>
</td>
<td id=tdTableDropdown style='padding: 3px; background-color: threedface; vertical-align: top; padding-bottom: 3px'>
</td>
</tr>
<tr>
<td id=tdDesc colspan='2' style='border-bottom: 1px threedshadow solid; font-family: Arial; font-size: 1pt; padding: 2px; background-color: threedface'>
</td>
</tr>
<tr>
<td colspan='2' style='height: 100%; padding-bottom: 4px; border-top: 1px threedhighlight solid;'>
<div id='pt' style='height: 100%' class='ODCDataSource'></div>
</td>
</tr>
</table>
<script language='javascript'>
function init() {
var sName, sDescription;
var i, j;
try {
sName = unescape(location.href)
i = sName.lastIndexOf(".")
if (i>=0) { sName = sName.substring(1, i); }
i = sName.lastIndexOf("/")
if (i>=0) { sName = sName.substring(i+1, sName.length); }
document.title = sName;
document.getElementById("tdName").innerText = sName;
sDescription = document.getElementById("docprops").innerHTML;
i = sDescription.indexOf("escription>")
if (i>=0) { j = sDescription.indexOf("escription>", i + 11); }
if (i>=0 && j >= 0) {
j = sDescription.lastIndexOf("</", j);
if (j>=0) {
sDescription = sDescription.substring(i+11, j);
if (sDescription != "") {
document.getElementById("tdDesc").style.fontSize="x-small";
document.getElementById("tdDesc").innerHTML = sDescription;
}
}
}
}
catch(e) {
}
}
</script>
</body>
</html>
"@
Set-Content C:\Users\Administrator\Desktop\test.odc -Value $x
#[Io.file]::WriteAllLines("C:\Users\Administrator\Desktop\test.odc",$x,[text.encoding]::Unicode)
Start-Sleep -s 6
Invoke-Item C:\Users\Administrator\Desktop\test.odc
看到这里有人应该已经有别的想法了:
如果我调用的不是powershell而是python解释器呢?
那么我用python脚本去与PowerBI进行交互就会非常简单,上面的在excel中分析也就自然而然了。
import sys,os
sn=sys.argv[1]
db=sys.argv[2]
x='''<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/x-ms-odc; charset=utf-8">
<meta name=ProgId content=ODC.Cube>
<meta name=SourceType content=OLEDB>
<meta name=Catalog content=$db>
<meta name=Table content=Model>
<title>'''+sn+' '+db+''' Model</title>
<xml id=docprops><o:DocumentProperties
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns="http://www.w3.org/TR/REC-html40">
<o:Name>'''+sn+' '+db+''' Model</o:Name>
</o:DocumentProperties>
</xml><xml id=msodc><odc:OfficeDataConnection
xmlns:odc="urn:schemas-microsoft-com:office:odc"
xmlns="http://www.w3.org/TR/REC-html40">
<odc:Connection odc:Type="OLEDB">
<odc:ConnectionString>Provider=MSOLAP.8;Integrated Security=SSPI;Persist Security Info=True;Data Source='''+sn+''';Update Isolation Level=2;Initial Catalog='''+db+'''</odc:ConnectionString>
<odc:CommandType>Cube</odc:CommandType>
<odc:CommandText>Model</odc:CommandText>
</odc:Connection>
</odc:OfficeDataConnection>
</xml>
<style>
<!--
.ODCDataSource
{
behavior: url(dataconn.htc);
}
-->
</style>
</head>
<body onload='init()' scroll=no leftmargin=0 topmargin=0 rightmargin=0 style='border: 0px'>
<table style='border: solid 1px threedface; height: 100%; width: 100%' cellpadding=0 cellspacing=0 width='100%'>
<tr>
<td id=tdName style='font-family:arial; font-size:medium; padding: 3px; background-color: threedface'>
</td>
<td id=tdTableDropdown style='padding: 3px; background-color: threedface; vertical-align: top; padding-bottom: 3px'>
</td>
</tr>
<tr>
<td id=tdDesc colspan='2' style='border-bottom: 1px threedshadow solid; font-family: Arial; font-size: 1pt; padding: 2px; background-color: threedface'>
</td>
</tr>
<tr>
<td colspan='2' style='height: 100%; padding-bottom: 4px; border-top: 1px threedhighlight solid;'>
<div id='pt' style='height: 100%' class='ODCDataSource'></div>
</td>
</tr>
</table>
<script language='javascript'>
function init() {
var sName, sDescription;
var i, j;
try {
sName = unescape(location.href)
i = sName.lastIndexOf(".")
if (i>=0) { sName = sName.substring(1, i); }
i = sName.lastIndexOf("/")
if (i>=0) { sName = sName.substring(i+1, sName.length); }
document.title = sName;
document.getElementById("tdName").innerText = sName;
sDescription = document.getElementById("docprops").innerHTML;
i = sDescription.indexOf("escription>")
if (i>=0) { j = sDescription.indexOf("escription>", i + 11); }
if (i>=0 && j >= 0) {
j = sDescription.lastIndexOf("</", j);
if (j>=0) {
sDescription = sDescription.substring(i+11, j);
if (sDescription != "") {
document.getElementById("tdDesc").style.fontSize="x-small";
document.getElementById("tdDesc").innerHTML = sDescription;
}
}
}
}
catch(e) {
}
}
</script>
</body>
</html>
'''
with open('C:\\Users\\Administrator\\Desktop\\test.odc',mode='w') as f:
f.write(x)
os.startfile('C:\\Users\\Administrator\\Desktop\\test.odc')
当然熟悉office数据交换的朋友可能知道,除了odc还有iqy文件也可以实现数据的连接,将下面的代码放入txt,另存为iqy后缀的文件后双击这个文件就可以获取指定网址内的相关数据:
WEB
1
https://pbihub.cn/blog/1178
Selection=EntirePage
Formatting=None
PreFormattedTextToColumns=True
ConsecutiveDelimitersAsOne=True
SingleBlockTextImport=False
DisableDateRecognition=False
DisableRedirections=False
作为面向对象编程的powershell和python你难道只局限于这一点点?还有那么多exe在向你招手,,,
另外,你们不是一直搞不定PowerBI与PP模型的交互?
有COM接口还怕个球?
关于PP模型对象参考:
https://docs.microsoft.com/zh-cn/office/vba/excel/concepts/about-the-powerpivot-model-object-in-excel
https://docs.microsoft.com/zh-cn/office/vba/api/excel.model
如果需要控制当前打开的excel实例:
$excel = [Runtime.Interopservices.Marshal]::GetActiveObject('Excel.Application')
$Y=$excel.Workbooks.Item(1).Model
$Y.ModelMeasures.Add("吹水",$Y.ModelTables.Item(1),"SUM([成绩])",$Y.ModelFormatDecimalNumber(),"")
干吧,骚年,,,
道高一尺 魔高一丈
https://pbihub.cn/users/44
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)