1+ function Set-OpenXML
2+ {
3+ <#
4+ . SYNOPSIS
5+ Sets OpenXML content
6+ . DESCRIPTION
7+ Sets content in an OpenXML file.
8+ . EXAMPLE
9+ Get-OpenXML ./Examples/Sample.docx |
10+ Set-OpenXML -Uri '/index.html' -Content ([xml]"<h1>Hello World</h1>") -ContentType text/html |
11+ Set-OpenXML -Uri '/404.html' -Content ([xml]"<h1>File Not Found</h1>") -ContentType text/html |
12+ Export-OpenXML ./Examples/Sample2.docx
13+ #>
14+ param (
15+ # The uri to set
16+ [Parameter (Mandatory , ParameterSetName = ' Uri' , ValueFromPipelineByPropertyName )]
17+ [Alias (' Url' )]
18+ [uri ]
19+ $Uri ,
20+
21+ # The content type. By default, `text/plain`
22+ [Parameter (ValueFromPipelineByPropertyName )]
23+ [string ]
24+ $ContentType = ' text/plain' ,
25+
26+ # The content to set.
27+ [Parameter (ValueFromPipelineByPropertyName )]
28+ [PSObject ]
29+ $Content ,
30+
31+ # The input object.
32+ # This must be a package, and it must be writeable.
33+ [Parameter (ValueFromPipeline )]
34+ [PSObject ]
35+ $InputObject
36+ )
37+
38+ process {
39+ # If there is no input, there is nothing to do
40+ if (-not $InputObject ) { return }
41+ # If the input is not a package, pass it thru.
42+ if ($InputObject -isnot [IO.Packaging.Package ]) {
43+ return $InputObject
44+ }
45+
46+ # Get or create the part
47+ $part =
48+ if ($InputObject.PartExists ($uri )) {
49+ $InputObject.GetPart ($uri )
50+ } else {
51+ $InputObject.CreatePart ($uri , $ContentType )
52+ }
53+
54+ if (-not $? ) { return }
55+
56+ # Get the stream
57+ $partStream = $part.GetStream ()
58+ # If the content was xml or could be,
59+ if ($content -is [xml ] -or ($contentXml = $content -as [xml ])) {
60+ if ($contentXml ) { $content = $contentXml }
61+ $buffer = $OutputEncoding.GetBytes ($content.OuterXml )
62+ # write it to the package.
63+ $partStream.Write ($buffer , 0 , $buffer.Length )
64+ } elseif ($content -is [string ]) {
65+ # Put strings in as a byte array.
66+ $buffer = $OutputEncoding.GetBytes ($content )
67+ $partStream.Write ($buffer , 0 , $buffer.Length )
68+ } elseif ($contentBytes = $content -as [byte []]) {
69+ # Bytes are obviously a byte array
70+ $partStream.Write ($contentBytes , 0 , $contentBytes.Length )
71+ }
72+ elseif ($ContentType -match ' [/\+]json' ) {
73+ # Explicitly typed json can be converted to json
74+ $buffer = $OutputEncoding.GetBytes ((ConvertTo-Json - InputObject $content - Depth 10 ))
75+ $partStream.Write ($buffer , 0 , $buffer.Length )
76+ }
77+ else {
78+ # and everything else is stringified
79+ $buffer = $OutputEncoding.GetBytes (" $content " )
80+ $partStream.Write ($buffer , 0 , $buffer.Length )
81+ }
82+
83+ # Close the part stream
84+ $partStream.Close ()
85+
86+ # and invalidate the parts cache on the object
87+ $inputObject.PSObject.Properties.Remove (' .Parts' )
88+ # then pass it thru so we can keep piping.
89+ $inputObject
90+ }
91+ }
0 commit comments