Skip to content

Commit 0355bbc

Browse files
authored
Function for unzip binary contents with M
Universal function for unzip binary contents with M
1 parent 76972a0 commit 0355bbc

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

UnZip.pq

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
// Author: Mark White
3+
// Reference: http://sql10.blogspot.ru/2016/06/reading-zip-files-in-powerquery-m.html
4+
// Code Source: https://pastebin.com/KJ8MyAPb
5+
6+
// ZIPFile should be a binary!
7+
*/
8+
9+
(ZIPFile) =>
10+
let
11+
Header = BinaryFormat.Record([
12+
MiscHeader = BinaryFormat.Binary(14),
13+
BinarySize = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),
14+
FileSize = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),
15+
FileNameLen= BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian),
16+
ExtrasLen = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16, ByteOrder.LittleEndian)
17+
]),
18+
19+
HeaderChoice = BinaryFormat.Choice(
20+
BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32, ByteOrder.LittleEndian),
21+
each if _ <> 67324752 // not the IsValid number? then return a dummy formatter
22+
then BinaryFormat.Record([IsValid = false, Filename=null, Content=null])
23+
else BinaryFormat.Choice(
24+
BinaryFormat.Binary(26), // Header payload - 14+4+4+2+2
25+
each BinaryFormat.Record([
26+
IsValid = true,
27+
Filename = BinaryFormat.Text(Header(_)[FileNameLen]),
28+
Extras = BinaryFormat.Text(Header(_)[ExtrasLen]),
29+
Content = BinaryFormat.Transform(
30+
BinaryFormat.Binary(Header(_)[BinarySize]),
31+
(x) => try Binary.Buffer(Binary.Decompress(x, Compression.Deflate)) otherwise null
32+
)
33+
]),
34+
type binary // enable streaming
35+
)
36+
),
37+
38+
ZipFormat = BinaryFormat.List(HeaderChoice, each _[IsValid] = true),
39+
40+
Entries = List.Transform(
41+
List.RemoveLastN( ZipFormat(ZIPFile), 1),
42+
(e) => [FileName = e[Filename], Content = e[Content] ]
43+
)
44+
in
45+
Table.FromRecords(Entries)

0 commit comments

Comments
 (0)