python不解压直接提取文件_不解压直接读取zip压缩包

我们知道Power Query能够连接很多不同格式的数据源,但同时还有很多是不能直接支持的,比如word文档、压缩包等等。

有这样一种场景:源数据来自于网络或者远程服务器,每天更新,文件格式是zip,压缩包内有csv。

如果不能直接读取zip,那么我们需要每天把zip下载下来,解压后再导入Power Query,非常麻烦,有什么办法可以解决这个问题呢?

方法一:转换二进制数据流

对于电脑来说,任何文件都是二进制的数字,而M语言中提供了大量的binary类函数,所以我们可以利用函数来间接实现不解压直接读取zip压缩包。

代码来源于Mark White,涉及非常复杂的二进制数据流知识,我也看不懂。所以我稍微改了一下,封装成unzip的自定义函数,新建一个名为unzip的空查询,把下面代码复制粘贴到高级编辑器,需要用的时候直接调用自定义函数=unzip("C:\路径.zip")就行了。

(path) =>

let

Header = BinaryFormat.Record([

MiscHeader = BinaryFormat.Binary(14),

BinarySize = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),

FileSize = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),

FileNameLen= BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian),

ExtrasLen = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian)

]),

HeaderChoice = BinaryFormat.Choice(

BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),

each if _ <> 67324752

then BinaryFormat.Record([IsValid = false, Filename=null, Content=null])

else BinaryFormat.Choice(

BinaryFormat.Binary(26),

each BinaryFormat.Record([

IsValid = true,

Filename = BinaryFormat.Text(Header(_)[FileNameLen]),

Extras = BinaryFormat.Text(Header(_)[ExtrasLen]),

Content = BinaryFormat.Transform(

BinaryFormat.Binary(Header(_)[BinarySize]),

(x) => try Binary.Buffer(Binary.Decompress(x, Compression.Deflate)) otherwise null

)

]),

type binary

)

),

ZipFormat = BinaryFormat.List(HeaderChoice, each _[IsValid] = true),

Entries = List.Transform(

List.RemoveLastN( ZipFormat(File.Contents(path)), 1),

(e) => [FileName = e[Filename], Content = e[Content] ]

)

in

Table.FromRecords(Entries)

效果如下图,测试文件中包含了xls,xlsx,csv三个文件,三种格式都可以支持,解析出来还是binary,然后再根据格式使用Excel.Workbook或Csv.Document解析成表即可:

不仅是zip,其他的文件如doc,ppt,pdf等,理论上也都可以通过二进制读出来。

方法二:在PBID中使用R语言

可以看到用Power Query的M语言,因为没有直接的函数支持,导致虽然能实现效果,但过程实在太复杂,反正我是看不懂。

而在Python和R中一两行代码就可以搞定,所以只要是R可以,就可以在Power BI Desktop中使用R.Execute来调用R。

首先得安装R,这个就不多说了。假设在桌面上有个test.zip,压缩包内有个test.csv,我们需要读取csv的数据。源数据长这样:

先来一个不依赖包的写法:

R语言代码:

unzip("C:/Users/rages/Desktop/test.zip")

read.csv("test.csv",header=F)

header=F表示不使用第一行作为标题,header=T则相反。

把R语言写到PBID的高级编辑器中就有两个地方需要注意,一个是文本引号的转义,另一个是数据需要以dataframe数据框的形式返回。

let

unzip=R.Execute("

unzip(""C:/Users/rages/Desktop/test.zip"")

data

"){0}[Value]

in

unzip

在R中还有一个叫rio的包,可以不解压直接读取压缩包,首次使用需要install.packages('rio')安装rio包。

R语言中代码为:

library(rio)

import("c:/Users/rages/Desktop/test.zip")

代码很简洁,第一步加载rio包,第二步直接读取文件路径。

改写到PBID中为:

let

unzip=R.Execute("

library(rio)

data

"){0}[Value]

in

unzip

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值