mirror of
https://github.com/dfinke/ImportExcel.git
synced 2025-12-06 00:23:20 +00:00
Compare commits
155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1976bf3a9 | ||
|
|
ffcdd39ae9 | ||
|
|
b4b5e75d28 | ||
|
|
4c3eb792d6 | ||
|
|
c4ef920bdf | ||
|
|
d81c2055e9 | ||
|
|
4528f3b052 | ||
|
|
5acec641fe | ||
|
|
04d06ff008 | ||
|
|
1974beef2d | ||
|
|
49f0c97635 | ||
|
|
0710724e2d | ||
|
|
a6438d468a | ||
|
|
ce92461efc | ||
|
|
b3c4a334b5 | ||
|
|
6b2190bfff | ||
|
|
5822ef330e | ||
|
|
d78e3fff98 | ||
|
|
85bd85ee69 | ||
|
|
04e8faaccc | ||
|
|
2c062a4e5d | ||
|
|
80c1a945f0 | ||
|
|
1d5ec26b04 | ||
|
|
860b2724f5 | ||
|
|
c38648a654 | ||
|
|
dcd730a4d1 | ||
|
|
0fdaeb977b | ||
|
|
61173d5e40 | ||
|
|
d26f0c66dd | ||
|
|
fe4fcff444 | ||
|
|
01c58faea8 | ||
|
|
dce2f6d108 | ||
|
|
49afad6977 | ||
|
|
b7add5f9e1 | ||
|
|
c07fc81dfe | ||
|
|
3835ceeebb | ||
|
|
6683bed799 | ||
|
|
20aade4bdd | ||
|
|
b6965e0724 | ||
|
|
9d85c6cb81 | ||
|
|
a17fc95415 | ||
|
|
ecb045274a | ||
|
|
e5c4a715d6 | ||
|
|
e27e98a9eb | ||
|
|
9da8bf8bf7 | ||
|
|
50905c7989 | ||
|
|
91a7c17341 | ||
|
|
3c18af50b9 | ||
|
|
66f5d09ace | ||
|
|
fa64299760 | ||
|
|
c36e5fb582 | ||
|
|
5158addc36 | ||
|
|
bf2e37ac9f | ||
|
|
d22d40cdc2 | ||
|
|
df49e04c6c | ||
|
|
f60ca87358 | ||
|
|
cef95f9ebe | ||
|
|
288071035f | ||
|
|
414d1ac72b | ||
|
|
1c7241774f | ||
|
|
7c773ff915 | ||
|
|
46de6c5934 | ||
|
|
955c737bb7 | ||
|
|
74e5fee161 | ||
|
|
c3331e8f09 | ||
|
|
1951a61699 | ||
|
|
5b29ccd9c2 | ||
|
|
d8bd5a8cb6 | ||
|
|
820722b481 | ||
|
|
08c82977f5 | ||
|
|
a2dd42fc80 | ||
|
|
c1d778ef85 | ||
|
|
7abb5dde89 | ||
|
|
0f15f3e3e5 | ||
|
|
3194bb0ee4 | ||
|
|
b1f716f0d5 | ||
|
|
a8f7a13248 | ||
|
|
d200a2929b | ||
|
|
99e69bd6c0 | ||
|
|
4f0c0d7c28 | ||
|
|
968d5a57b6 | ||
|
|
bdefb45095 | ||
|
|
4297d2ef82 | ||
|
|
a49bdb3abc | ||
|
|
a983ecd765 | ||
|
|
5a7d84e624 | ||
|
|
e0f5d9f789 | ||
|
|
7d3bcb810c | ||
|
|
8975aa2e95 | ||
|
|
77f30f105b | ||
|
|
972142f727 | ||
|
|
cfd1ac99b2 | ||
|
|
e09c5e5207 | ||
|
|
3ff59907ff | ||
|
|
ef4ac9777b | ||
|
|
65b1f79d53 | ||
|
|
ecad48acb3 | ||
|
|
f47887f7fe | ||
|
|
061ae22bfe | ||
|
|
53b63b3780 | ||
|
|
378a20a094 | ||
|
|
7edf5f8a3a | ||
|
|
6393701a2f | ||
|
|
71c22d647d | ||
|
|
ef656f72b3 | ||
|
|
dfd9b23cd7 | ||
|
|
f94a075f52 | ||
|
|
cea9713129 | ||
|
|
343687c418 | ||
|
|
d4d2b4a856 | ||
|
|
bed52d456d | ||
|
|
31e6eaf59b | ||
|
|
d770646dc7 | ||
|
|
bc65699068 | ||
|
|
ce3fd2021f | ||
|
|
10f670b4e6 | ||
|
|
c49b7b6db0 | ||
|
|
f768634214 | ||
|
|
07342235b9 | ||
|
|
2793ff1c21 | ||
|
|
121346f939 | ||
|
|
dc8a096732 | ||
|
|
c63512e658 | ||
|
|
e46fe6d3e9 | ||
|
|
6ae50c3193 | ||
|
|
ee2378150c | ||
|
|
259c7e8ae6 | ||
|
|
ae30bfe6c3 | ||
|
|
3756cd6ad8 | ||
|
|
1014250e0b | ||
|
|
951364da51 | ||
|
|
c1604fc08a | ||
|
|
5a235e309e | ||
|
|
af77580b5e | ||
|
|
b06a5059c5 | ||
|
|
edab941c44 | ||
|
|
91fb314bca | ||
|
|
d07affcd46 | ||
|
|
2b3228d041 | ||
|
|
34c5177dfc | ||
|
|
f52ba1c50a | ||
|
|
b50cc67bb3 | ||
|
|
42e2b11a88 | ||
|
|
b6509d3f5c | ||
|
|
29503861fb | ||
|
|
196497e3a0 | ||
|
|
d9fe0a31c3 | ||
|
|
26bf4b9a64 | ||
|
|
a0719b22f0 | ||
|
|
42d56ac557 | ||
|
|
9b9c1de8fd | ||
|
|
e3fdbf9fcc | ||
|
|
abb971be88 | ||
|
|
77fb51da8d | ||
|
|
61c73461ca |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,6 +2,8 @@
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
*.gitignore
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
@@ -14,6 +16,8 @@ $RECYCLE.BIN/
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
*.dll
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
9
.vscode/spellright.dict
vendored
9
.vscode/spellright.dict
vendored
@@ -26,3 +26,12 @@ EPPLus
|
||||
intellisense
|
||||
PivtoTableName
|
||||
New-Excelchart
|
||||
paypal
|
||||
dll
|
||||
enums
|
||||
Numberformat
|
||||
ChartDefiniton
|
||||
hashtables
|
||||
Agramont
|
||||
AGramont
|
||||
Jhoneill
|
||||
|
||||
@@ -1,135 +1,270 @@
|
||||
Function Add-ConditionalFormatting {
|
||||
<#
|
||||
.Synopsis
|
||||
Adds contitional formatting to worksheet.
|
||||
Adds conditional formatting to all or part of a worksheet.
|
||||
.Description
|
||||
Conditional formatting allows Excel to:
|
||||
* Mark cells with icons depending on their value
|
||||
* Show a databar whose length indicates the value or a two or three color scale where the color indicates the relative value
|
||||
* Change the color, font, or number format of cells which meet given criteria
|
||||
Add-ConditionalFormatting allows these parameters to be set; for fine tuning of
|
||||
the rules, the -PassThru switch will return the rule so that you can modify
|
||||
things which are specific to that type of rule, example, the values which
|
||||
correspond to each icon in an Icon-Set.
|
||||
.Example
|
||||
>
|
||||
$excel = $avdata | Export-Excel -Path (Join-path $FilePath "\Machines.XLSX" ) -WorksheetName "Server Anti-Virus" -AutoSize -FreezeTopRow -AutoFilter -PassThru
|
||||
|
||||
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "b2:b1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "2003"
|
||||
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "i2:i1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "Disabled"
|
||||
$excel.Workbook.Worksheets[1].Cells["D1:G1048576"].Style.Numberformat.Format = [cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
|
||||
$excel.Workbook.Worksheets[1].Row(1).style.font.bold = $true
|
||||
$excel.Save() ; $excel.Dispose()
|
||||
|
||||
Here Export-Excel is called with the -passThru parameter so the Excel Package object is stored in $Excel
|
||||
The desired worksheet is selected and the then columns B and i are conditially formatted (excluding the top row) to show red text if
|
||||
the columns contain "2003" or "Disabled respectively. A fixed date formats are then applied to columns D..G, and the top row is formatted.
|
||||
Finally the workbook is saved and the Excel object closed.
|
||||
Here Export-Excel is called with the -PassThru parameter so the ExcelPackage object
|
||||
representing Machines.XLSX is stored in $Excel.The desired worksheet is selected
|
||||
and then columns" B" and "I" are conditionally formatted (excluding the top row)
|
||||
to show red text if they contain "2003" or "Disabled" respectively.
|
||||
A fixed date format is then applied to columns D to G, and the top row is formatted.
|
||||
Finally the workbook is saved and the Excel package object is closed.
|
||||
.Example
|
||||
C:\> $r = Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Range "B1:B100" -ThreeIconsSet Flags -Passthru
|
||||
C:\> $r.Reverse = $true ; $r.Icon1.Type = "Num"; $r.Icon2.Type = "Num" ; $r.Icon2.value = 100 ; $r.Icon3.type = "Num" ;$r.Icon3.value = 1000
|
||||
>
|
||||
$r = Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Range "B1:B100" -ThreeIconsSet Flags -Passthru
|
||||
$r.Reverse = $true ; $r.Icon1.Type = "Num"; $r.Icon2.Type = "Num" ; $r.Icon2.value = 100 ; $r.Icon3.type = "Num" ;$r.Icon3.value = 1000
|
||||
|
||||
Again Export-Excel has been called with -PassThru leaving a package object
|
||||
in $Excel. This time B1:B100 has been conditionally formatted with 3 icons,
|
||||
using the "Flags" Icon-Set. Add-ConditionalFormatting does not provide access
|
||||
to every option in the formatting rule, so -PassThru has been used and the
|
||||
rule is modified to apply the flags in reverse order, and transitions
|
||||
between flags are set to 100 and 1000.
|
||||
.Example
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
||||
|
||||
This time $sheet holds an ExcelWorkshseet object and databars are added to
|
||||
column D, excluding the top row.
|
||||
.Example
|
||||
Add-ConditionalFormatting -Address $worksheet.cells["FinishPosition"] -RuleType Equal -ConditionValue 1 -ForeGroundColor Purple -Bold -Priority 1 -StopIfTrue
|
||||
|
||||
In this example a named range is used to select the cells where the condition
|
||||
should apply, and instead of specifying a sheet and range within the sheet as
|
||||
separate parameters, the cells where the format should apply are specified
|
||||
directly. If a cell in the "FinishPosition" range is 1, then the text is
|
||||
turned to Bold & Purple. This rule is moved to first in the priority list,
|
||||
and where cells have a value of 1, no other rules will be processed.
|
||||
.Example
|
||||
>
|
||||
$excel = Get-ChildItem | Select-Object -Property Name,Length,LastWriteTime,CreationTime | Export-Excel "$env:temp\test43.xlsx" -PassThru -AutoSize
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
$ws.Cells["E1"].Value = "SavedAt"
|
||||
$ws.Cells["F1"].Value = [datetime]::Now
|
||||
$ws.Cells["F1"].Style.Numberformat.Format = (Expand-NumberFormat -NumberFormat 'Date-Time')
|
||||
$lastRow = $ws.Dimension.End.Row
|
||||
|
||||
Add-ConditionalFormatting -WorkSheet $ws -address "A2:A$Lastrow" -RuleType LessThan -ConditionValue "A" -ForeGroundColor Gray
|
||||
Add-ConditionalFormatting -WorkSheet $ws -address "B2:B$Lastrow" -RuleType GreaterThan -ConditionValue 1000000 -NumberFormat '#,###,,.00"M"'
|
||||
Add-ConditionalFormatting -WorkSheet $ws -address "C2:C$Lastrow" -RuleType GreaterThan -ConditionValue "=INT($F$1-7)" -ForeGroundColor Green -StopIfTrue
|
||||
Add-ConditionalFormatting -WorkSheet $ws -address "D2:D$Lastrow" -RuleType Equal -ConditionValue "=C2" -ForeGroundColor Blue -StopIfTrue
|
||||
|
||||
Close-ExcelPackage -Show $excel
|
||||
|
||||
The first few lines of code export a list of file and directory names, sizes
|
||||
and dates to a spreadsheet. It puts the date of the export in cell F1.
|
||||
The first Conditional format changes the color of files and folders that begin
|
||||
with a ".", "_" or anything else which sorts before "A".
|
||||
The second Conditional format changes the Number format of numbers bigger than
|
||||
1 million, for example 1,234,567,890 will dispay as "1,234.57M"
|
||||
The third highlights datestamps of files less than a week old when the export
|
||||
was run; the = is necessary in the condition value otherwise the rule will
|
||||
look for the the text INT($F$1-7), and the cell address for the date is fixed
|
||||
using the standard Excel $ notation.
|
||||
The final Conditional format looks for files which have not changed since they
|
||||
were created. Here the condition value is "=C2". The = sign means C2 is treated
|
||||
as a formula, not literal text. Unlike the file age, we want the cell used to
|
||||
change for each cell where the conditional format applies. The first cell in
|
||||
the conditional format range is D2, which is compared against C2, then D3 is
|
||||
compared against C3 and so on. A common mistake is to include the title row in
|
||||
the range and accidentally apply conditional formatting to it, or to begin the
|
||||
range at row 2 but use row 1 as the starting point for comparisons.
|
||||
.Example
|
||||
Add-ConditionalFormatting $ws.Cells["B:B"] GreaterThan 10000000 -Fore Red -Stop -Pri 1
|
||||
|
||||
This version shows the shortest syntax - the Address, Ruletype, and
|
||||
Conditionvalue can be identified from their position, and ForegroundColor,
|
||||
StopIfTrue and Priority can all be shortend.
|
||||
|
||||
Again Export excel has been called with -passthru leaving a package object in $Excel
|
||||
This time B1:B100 has been conditionally formatted with 3 icons, using the flags icon set.
|
||||
Add-ConditionalFormatting does not provide access to every option in the formatting rule, so passthru has been used and the
|
||||
rule is to apply the flags in reverse order, and boundaries for the number which will set the split are set to 100 and 1000
|
||||
#>
|
||||
Param (
|
||||
#The worksheet where the format is to be applied
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
|
||||
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
|
||||
#The area of the worksheet where the format is to be applied
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
|
||||
[OfficeOpenXml.ExcelAddress]$Range ,
|
||||
#One or more row(s), column(s) and/or block(s) of cells to format
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
|
||||
#A block of cells to format - you can use a named range with -Address $ws.names[1] or $ws.cells["RangeName"]
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[Alias("Range")]
|
||||
$Address ,
|
||||
#One of the standard named rules - Top / Bottom / Less than / Greater than / Contains etc.
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 3)]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress", Position = 3)]
|
||||
#The worksheet where the format is to be applied
|
||||
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
|
||||
#A standard named-rule - Top / Bottom / Less than / Greater than / Contains etc.
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 1)]
|
||||
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
|
||||
#Text colour for matching objects
|
||||
[Alias("ForeGroundColour")]
|
||||
[System.Drawing.Color]$ForeGroundColor,
|
||||
#colour for databar type charts
|
||||
#Text color for matching objects
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[Alias("ForegroundColour")]
|
||||
$ForegroundColor,
|
||||
#Color for databar type charts
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
|
||||
[Alias("DataBarColour")]
|
||||
[System.Drawing.Color]$DataBarColor,
|
||||
$DataBarColor,
|
||||
#One of the three-icon set types (e.g. Traffic Lights)
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
|
||||
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting3IconsSetType]$ThreeIconsSet,
|
||||
#A four-icon set name
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
|
||||
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting4IconsSetType]$FourIconsSet,
|
||||
#A five-icon set name
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
|
||||
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
|
||||
#Use the icon set in reverse order
|
||||
#Use the Icon-Set in reverse order, or reverse the orders of Two- & Three-Color Scales
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[Parameter(ParameterSetName = "ThreeIconSet")]
|
||||
[Parameter(ParameterSetName = "ThreeIconSetAddress")]
|
||||
[Parameter(ParameterSetName = "FourIconSet")]
|
||||
[Parameter(ParameterSetName = "FourIconSetAddress")]
|
||||
[Parameter(ParameterSetName = "FiveIconSet")]
|
||||
[Parameter(ParameterSetName = "FiveIconSetAddress")]
|
||||
[switch]$Reverse,
|
||||
#A value for the condition (e.g. "2000" if the test is 'lessthan 2000')
|
||||
[string]$ConditionValue,
|
||||
#A second value for the conditions like "between x and Y"
|
||||
[string]$ConditionValue2,
|
||||
#Background colour for matching items
|
||||
[System.Drawing.Color]$BackgroundColor,
|
||||
#A value for the condition (for example 2000 if the test is 'lessthan 2000'; Formulas should begin with "=" )
|
||||
[Parameter(ParameterSetName = "NamedRule",Position = 2)]
|
||||
$ConditionValue,
|
||||
#A second value for the conditions like "Between X and Y"
|
||||
[Parameter(ParameterSetName = "NamedRule",Position = 3)]
|
||||
$ConditionValue2,
|
||||
#Background color for matching items
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
$BackgroundColor,
|
||||
#Background pattern for matching items
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::None ,
|
||||
#Secondary colour when a background pattern requires it
|
||||
[System.Drawing.Color]$PatternColor,
|
||||
#Secondary color when a background pattern requires it
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
$PatternColor,
|
||||
#Sets the numeric format for matching items
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
$NumberFormat,
|
||||
#Put matching items in bold face
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[switch]$Bold,
|
||||
#Put matching items in italic
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[switch]$Italic,
|
||||
#Underline matching items
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[switch]$Underline,
|
||||
#Strikethrough text of matching items
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[switch]$StrikeThru,
|
||||
#Prevent the processing of subsequent rules
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[switch]$StopIfTrue,
|
||||
#Set the sequence for rule processing
|
||||
[int]$Priority,
|
||||
#If specified pass the rule back to the caller to allow additional customization.
|
||||
[switch]$Passthru
|
||||
[switch]$PassThru
|
||||
)
|
||||
#Allow conditional formatting to work like Set-Format (with single ADDRESS parameter), split it to get worksheet and range of cells.
|
||||
If ($Address -and -not $WorkSheet -and -not $Range) {
|
||||
$WorkSheet = $Address.Worksheet[0]
|
||||
$Range = $Address.Address
|
||||
}
|
||||
If ($ThreeIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Range , $ThreeIconsSet)}
|
||||
elseif ($FourIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Range , $FourIconsSet) }
|
||||
elseif ($FiveIconsSet) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Range , $IconType) }
|
||||
elseif ($DataBarColor) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Range , $DataBarColor) }
|
||||
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Range)}
|
||||
if ($reverse) {$rule.reverse = $true}
|
||||
if ($ConditionValue -and $RuleType -match "Top|Botom") {$rule.Rank = $ConditionValue }
|
||||
if ($ConditionValue -and $RuleType -match "StdDev") {$rule.StdDev = $ConditionValue }
|
||||
if ($ConditionValue -and $RuleType -match "Than|Equal|Expression") {$rule.Formula = $ConditionValue }
|
||||
if ($ConditionValue -and $RuleType -match "Text|With") {$rule.Text = $ConditionValue }
|
||||
if ($ConditionValue -and
|
||||
$ConditionValue2 -and $RuleType -match "Between") {
|
||||
$rule.Formula = $ConditionValue
|
||||
$rule.Formula2 = $ConditionValue2
|
||||
}
|
||||
|
||||
if ($NumberFormat) {$rule.Style.NumberFormat.Format = $NumberFormat }
|
||||
if ($Underline) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
|
||||
if ($Bold) {$rule.Style.Font.Bold = $true }
|
||||
if ($Italic) {$rule.Style.Font.Italic = $true }
|
||||
if ($StrikeThru) {$rule.Style.Font.Strike = $true }
|
||||
if ($ForeGroundColor) {$rule.Style.Font.Color.color = $ForeGroundColor }
|
||||
if ($BackgroundColor) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
|
||||
if ($BackgroundPattern) {$rule.Style.Fill.PatternType = $BackgroundPattern }
|
||||
if ($PatternColor) {$rule.Style.Fill.PatternColor.color = $PatternColor }
|
||||
if ($Passthru) {$rule}
|
||||
#Allow conditional formatting to work like Set-ExcelRange (with single ADDRESS parameter), split it to get worksheet and range of cells.
|
||||
If ($Address -is [OfficeOpenXml.Table.ExcelTable]) {
|
||||
$WorkSheet = $Address.Address.Worksheet
|
||||
$Address = $Address.Address.Address
|
||||
}
|
||||
elseif ($Address.Address -and $Address.Worksheet -and -not $WorkSheet) { #Address is a rangebase or similar
|
||||
$WorkSheet = $Address.Worksheet[0]
|
||||
$Address = $Address.Address
|
||||
}
|
||||
elseif ($Address -is [String] -and $WorkSheet -and $WorkSheet.Names[$Address] ) { #Address is the name of a named range.
|
||||
$Address = $WorkSheet.Names[$Address].Address
|
||||
}
|
||||
if (($Address -is [OfficeOpenXml.ExcelRow] -and -not $WorkSheet) -or
|
||||
($Address -is [OfficeOpenXml.ExcelColumn] -and -not $WorkSheet) ){ #EPPLUs Can't get the worksheet object from a row or column object, so bail if that was tried
|
||||
Write-Warning -Message "Add-ConditionalFormatting does not support Row or Column objects as an address; use a worksheet and/or specify 'R:R' or 'C:C' instead. "; return
|
||||
}
|
||||
elseif ($Address -is [OfficeOpenXml.ExcelRow]) { #But if we have a column or row object and a worksheet (I don't know *why*) turn them into a string for the range
|
||||
$Address = "$($Address.Row):$($Address.Row)"
|
||||
}
|
||||
elseif ($Address -is [OfficeOpenXml.ExcelColumn]) {
|
||||
$Address = [OfficeOpenXml.ExcelAddress]::new(1,$address.ColumnMin,1,$address.ColumnMax).Address -replace '1',''
|
||||
if ($Address -notmatch ':') {$Address = "$Address`:$Address"}
|
||||
}
|
||||
if ( $Address -is [string] -and $Address -match "!") {$Address = $Address -replace '^.*!',''}
|
||||
#By this point we should have a worksheet object whose ConditionalFormatting collection we will add to. If not, bail.
|
||||
if (-not $worksheet -or $WorkSheet -isnot [OfficeOpenXml.ExcelWorksheet]) {write-warning "You need to provide a worksheet object." ; return}
|
||||
#region create a rule of the right type
|
||||
if ($RuleType -match 'IconSet$') {Write-warning -Message "You cannot configure a Icon-Set rule in this way; please use -$RuleType <SetName>." ; return}
|
||||
if ($PSBoundParameters.ContainsKey("DataBarColor" ) ) {if ($DataBarColor -is [string]) {$DataBarColor = [System.Drawing.Color]::$DataBarColor }
|
||||
$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Address , $DataBarColor )
|
||||
}
|
||||
elseif ($PSBoundParameters.ContainsKey("ThreeIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Address , $ThreeIconsSet)}
|
||||
elseif ($PSBoundParameters.ContainsKey("FourIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Address , $FourIconsSet )}
|
||||
elseif ($PSBoundParameters.ContainsKey("FiveIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Address , $FiveIconsSet )}
|
||||
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Address ) }
|
||||
if ($Reverse) {
|
||||
if ($rule.type -match 'IconSet$' ) {$rule.reverse = $true}
|
||||
elseif ($rule.type -match 'ColorScale$') {$temp =$rule.LowValue.Color ; $rule.LowValue.Color = $rule.HighValue.Color; $rule.HighValue.Color = $temp}
|
||||
else {Write-Warning -Message "-Reverse was ignored because $ruletype does not support it."}
|
||||
}
|
||||
#endregion
|
||||
#region set the rule conditions
|
||||
#for lessThan/GreaterThan/Equal/Between conditions make sure that strings are wrapped in quotes. Formulas should be passed with = which will be stripped.
|
||||
if ($RuleType -match "Than|Equal|Between" ) {
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" )) {
|
||||
$number = $Null
|
||||
#if the condition type is not a value type, but parses as a number, make it the number
|
||||
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
|
||||
$ConditionValue = $number
|
||||
} #else if it is not a value type, or a formula, or wrapped in quotes, wrap it in quotes.
|
||||
elseif (($ConditionValue -isnot [System.ValueType])-and ($ConditionValue -notmatch '^=') -and ($ConditionValue -notmatch '^".*"$') ) {
|
||||
$ConditionValue = '"' + $ConditionValue +'"'
|
||||
}
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue2")) {
|
||||
$number = $Null
|
||||
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue2, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
|
||||
$ConditionValue2 = $number
|
||||
}
|
||||
elseif (($ConditionValue -isnot [System.ValueType]) -and ($ConditionValue2 -notmatch '^=') -and ($ConditionValue2 -notmatch '^".*"$') ) {
|
||||
$ConditionValue2 = '"' + $ConditionValue2 + '"'
|
||||
}
|
||||
}
|
||||
}
|
||||
#But we don't usually want quotes round containstext | beginswith type rules. Can't be Certain they need to be removed, so warn the user their condition might be wrong
|
||||
if ($RuleType -match "Text|With" -and $ConditionValue -match '^".*"$' ) {
|
||||
Write-Warning -Message "The condition will look for the quotes at the start and end."
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
|
||||
$RuleType -match "Top|Botom" ) {$rule.Rank = $ConditionValue }
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
|
||||
$RuleType -match "StdDev" ) {$rule.StdDev = $ConditionValue }
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
|
||||
$RuleType -match "Than|Equal|Expression" ) {$rule.Formula = ($ConditionValue -replace '^=','') }
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
|
||||
$RuleType -match "Text|With" ) {$rule.Text = ($ConditionValue -replace '^=','') }
|
||||
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
|
||||
$PSBoundParameters.ContainsKey("ConditionValue2") -and
|
||||
$RuleType -match "Between" ) {
|
||||
$rule.Formula = ($ConditionValue -replace '^=','');
|
||||
$rule.Formula2 = ($ConditionValue2 -replace '^=','')
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey("StopIfTrue") ) {$rule.StopIfTrue = $StopIfTrue }
|
||||
if ($PSBoundParameters.ContainsKey("Priority") ) {$rule.Priority = $Priority }
|
||||
#endregion
|
||||
#region set the rule format
|
||||
if ($PSBoundParameters.ContainsKey("NumberFormat" ) ) {$rule.Style.NumberFormat.Format = (Expand-NumberFormat $NumberFormat) }
|
||||
if ($Underline ) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
|
||||
elseif ($PSBoundParameters.ContainsKey("Underline" ) ) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::None }
|
||||
if ($PSBoundParameters.ContainsKey("Bold" ) ) {$rule.Style.Font.Bold = [boolean]$Bold }
|
||||
if ($PSBoundParameters.ContainsKey("Italic" ) ) {$rule.Style.Font.Italic = [boolean]$Italic }
|
||||
if ($PSBoundParameters.ContainsKey("StrikeThru" ) ) {$rule.Style.Font.Strike = [boolean]$StrikeThru }
|
||||
if ($PSBoundParameters.ContainsKey("ForeGroundColor" ) ) {if ($ForeGroundColor -is [string]) {$ForeGroundColor = [System.Drawing.Color]::$ForeGroundColor }
|
||||
$rule.Style.Font.Color.color = $ForeGroundColor }
|
||||
if ($PSBoundParameters.ContainsKey("BackgroundColor" ) ) {if ($BackgroundColor -is [string]) {$BackgroundColor = [System.Drawing.Color]::$BackgroundColor }
|
||||
$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
|
||||
if ($PSBoundParameters.ContainsKey("BackgroundPattern") ) {$rule.Style.Fill.PatternType = $BackgroundPattern }
|
||||
if ($PSBoundParameters.ContainsKey("PatternColor" ) ) {if ($PatternColor -is [string]) {$PatternColor = [System.Drawing.Color]::$PatternColor }
|
||||
$rule.Style.Fill.PatternColor.color = $PatternColor }
|
||||
#endregion
|
||||
#Allow further tweaking by returning the rule, if passthru specified
|
||||
if ($Passthru) {$rule}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
|
||||
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName TabColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Join-Worksheet -ParameterName TitleBackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Merge-Worksheet -ParameterName AddBackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Merge-Worksheet -ParameterName ChangeBackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Merge-Worksheet ` -ParameterName DeleteBackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
@@ -25,14 +26,16 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
|
||||
Register-ArgumentCompleter -CommandName Merge-MulipleSheets -ParameterName KeyFontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Format -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Format -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Format -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Format -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Column -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Column -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Column -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Row -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Row -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-Row -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName ConditionalTextColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
|
||||
}
|
||||
@@ -1,18 +1,21 @@
|
||||
Function ConvertTo-ExcelXlsx {
|
||||
[CmdletBinding()]
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Converts an Excel xls to a xlsx using -ComObject
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[parameter(Mandatory=$true, ValueFromPipeline)]
|
||||
[parameter(Mandatory = $true, ValueFromPipeline)]
|
||||
[string]$Path,
|
||||
[parameter(Mandatory=$false)]
|
||||
[parameter(Mandatory = $false)]
|
||||
[switch]$Force
|
||||
)
|
||||
Process
|
||||
{
|
||||
if(-Not ($Path | Test-Path) ){
|
||||
throw "File not found"
|
||||
Process {
|
||||
if (-Not ($Path | Test-Path) ) {
|
||||
throw "File not found"
|
||||
}
|
||||
if(-Not ($Path | Test-Path -PathType Leaf) ){
|
||||
if (-Not ($Path | Test-Path -PathType Leaf) ) {
|
||||
throw "Folder paths are not allowed"
|
||||
}
|
||||
|
||||
@@ -20,26 +23,29 @@ Function ConvertTo-ExcelXlsx {
|
||||
$xlsFile = Get-Item -Path $Path
|
||||
$xlsxPath = "{0}x" -f $xlsFile.FullName
|
||||
|
||||
if($xlsFile.Extension -ne ".xls"){
|
||||
if ($xlsFile.Extension -ne ".xls") {
|
||||
throw "Expected .xls extension"
|
||||
}
|
||||
|
||||
if(Test-Path -Path $xlsxPath){
|
||||
if($Force){
|
||||
if (Test-Path -Path $xlsxPath) {
|
||||
if ($Force) {
|
||||
try {
|
||||
Remove-Item $xlsxPath -Force
|
||||
} catch {
|
||||
}
|
||||
catch {
|
||||
throw "{0} already exists and cannot be removed. The file may be locked by another application." -f $xlsxPath
|
||||
}
|
||||
Write-Verbose $("Removed {0}" -f $xlsxPath)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw "{0} already exists!" -f $xlsxPath
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
$Excel = New-Object -ComObject "Excel.Application"
|
||||
} catch {
|
||||
}
|
||||
catch {
|
||||
throw "Could not create Excel.Application ComObject. Please verify that Excel is installed."
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
function Copy-ExcelWorkSheet {
|
||||
[CmdletBinding()]
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Copies a worksheet between workbooks or within the same workbook.
|
||||
@@ -27,6 +26,7 @@
|
||||
because -Show is not specified, so other steps can be carried using the package object, at the end the file is saved by Close-ExcelPackage
|
||||
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
|
||||
[Parameter(Mandatory=$true)]
|
||||
|
||||
18
DoTests.ps1
18
DoTests.ps1
@@ -1,14 +1,24 @@
|
||||
param(
|
||||
[Switch]$DontCreateZip
|
||||
)
|
||||
|
||||
##
|
||||
# Used in Appveyor.yml
|
||||
##
|
||||
|
||||
$PSVersionTable.PSVersion
|
||||
|
||||
## Create the zip before the tests run
|
||||
## Otherwise the EPPlus.dll is in use after the Pester run
|
||||
$ModuleVersion = (Get-Content -Raw .\ImportExcel.psd1) | Invoke-Expression | ForEach-Object ModuleVersion
|
||||
|
||||
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
|
||||
Compress-Archive -Path . -DestinationPath .\$dest
|
||||
if (!$DontCreateZip) {
|
||||
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
|
||||
Compress-Archive -Path . -DestinationPath .\$dest
|
||||
}
|
||||
|
||||
if ((Get-Module -ListAvailable pester) -eq $null) {
|
||||
Install-Module -Name Pester -Repository PSGallery -Force
|
||||
if ($null -eq (Get-Module -ListAvailable pester)) {
|
||||
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
|
||||
}
|
||||
|
||||
$result = Invoke-Pester -Script $PSScriptRoot\__tests__ -Verbose -PassThru
|
||||
|
||||
15
Examples/AddWorkSheet/AddMultiWorkSheet.ps1
Normal file
15
Examples/AddWorkSheet/AddMultiWorkSheet.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$xlSourcefile = "$env:TEMP\Source.xlsx"
|
||||
write-host "Save location: $xlSourcefile"
|
||||
|
||||
Remove-Item $xlSourcefile -ErrorAction Ignore
|
||||
|
||||
#Put some simple data in a worksheet and Get an excel package object to represent the file
|
||||
$TabData1 = 1..5 | Export-Excel $xlSourcefile -WorksheetName 'Tab 1' -AutoSize -AutoFilter
|
||||
|
||||
#Add another tab. Replace the $TabData2 with your data
|
||||
$TabData2 = 1..10 | Export-Excel $xlSourcefile -WorksheetName 'Tab 2' -AutoSize -AutoFilter
|
||||
|
||||
#Add another tab. Replace the $TabData3 with your data
|
||||
$TabData3 = 1..15 | Export-Excel $xlSourcefile -WorksheetName 'Tab 3' -AutoSize -AutoFilter -Show
|
||||
@@ -4,8 +4,9 @@ $xlSourcefile = "$env:TEMP\Source.xlsx"
|
||||
|
||||
Remove-Item $xlSourcefile -ErrorAction Ignore
|
||||
|
||||
#Put some simple data in a worksheet and Get an excel package object to represent the file
|
||||
$excel = 1..10 | Export-Excel $xlSourcefile -PassThru
|
||||
|
||||
#Add a new worksheet named 'NewSheet' and copying the sheet that was just made (Sheet1) to the new sheet
|
||||
Add-WorkSheet -ExcelPackage $excel -WorkSheetname "NewSheet" -CopySource $excel.Workbook.Worksheets["Sheet1"]
|
||||
|
||||
#Save and open in Excel
|
||||
Close-ExcelPackage -ExcelPackage $excel -Show
|
||||
|
||||
@@ -11,7 +11,7 @@ A,B,C,Date
|
||||
$c = New-ExcelChartDefinition -Title Impressions `
|
||||
-ChartType Line `
|
||||
-XRange "Impressions[Date]" `
|
||||
-YRange "Impressions[B]" # @("Impressions[B]","Impressions[A]") `
|
||||
-YRange @("Impressions[B]","Impressions[A]") `
|
||||
-SeriesHeader 'B data','A data' `
|
||||
-Row 0 -Column 0
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ function plot {
|
||||
$file = 'C:\temp\plot.xlsx'
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
|
||||
$c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
|
||||
# $c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
|
||||
|
||||
$(for ($i = $minx; $i -lt $maxx-.1; $i+=.1) {
|
||||
[pscustomobject]@{
|
||||
X=$i.ToString("N1")
|
||||
Y=(&$f $i)
|
||||
}
|
||||
}) | Export-Excel $file -Show -AutoNameRange -ExcelChartDefinition $c
|
||||
}) | Export-Excel $file -Show -AutoNameRange -LineChart -NoLegend #-ExcelChartDefinition $c
|
||||
}
|
||||
|
||||
function pi {[math]::pi}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
echo Last7Days LastMonth LastWeek NextMonth NextWeek ThisMonth ThisWeek Today Tomorrow Yesterday |
|
||||
% {
|
||||
Foreach-Object {
|
||||
$text = @"
|
||||
`$f = ".\testExport.xlsx"
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$file = ".\conditionalTextFormatting.xlsx"
|
||||
$file = "$env:temp\conditionalTextFormatting.xlsx"
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
|
||||
Get-Service |
|
||||
Select-Object Status, Name, DisplayName, ServiceName |
|
||||
Export-Excel $file -Show -AutoSize -AutoFilter -ConditionalText $(
|
||||
New-ConditionalText stop
|
||||
New-ConditionalText runn darkblue cyan
|
||||
New-ConditionalText -ConditionalType EndsWith svc wheat green
|
||||
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat
|
||||
New-ConditionalText stop #Stop is the condition value, the rule is defaults to 'Contains text' and the default Colors are used
|
||||
New-ConditionalText runn darkblue cyan #runn is the condition value, the rule is defaults to 'Contains text'; the foregroundColur is darkblue and the background is cyan
|
||||
New-ConditionalText -ConditionalType EndsWith svc wheat green #the rule here is 'Ends with' and the value is 'svc' the forground is wheat and the background dark green
|
||||
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat #this is 'Begins with "Windows"' the forground is dark green and the background wheat
|
||||
)
|
||||
@@ -1,5 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
#Define a "Contains blanks" rule. No format is specified so it default to dark-red text on light-pink background.
|
||||
$ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks
|
||||
|
||||
$data = $(
|
||||
@@ -11,7 +12,8 @@ $data = $(
|
||||
New-PSItem g h i
|
||||
)
|
||||
|
||||
$file ="c:\temp\testblanks.xlsx"
|
||||
$file ="$env:temp\testblanks.xlsx"
|
||||
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
#use the conditional format definition created above
|
||||
$data | Export-Excel $file -show -ConditionalText $ContainsBlanks
|
||||
@@ -1,23 +1,32 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
Remove-Item -Path .\test.xlsx -ErrorAction Ignore
|
||||
$path = "$env:temp\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction Ignore
|
||||
|
||||
#Export processes, and get an ExcelPackage object representing the file.
|
||||
$excel = Get-Process |
|
||||
Select-Object -Property Name,Company,Handles,CPU,PM,NPM,WS |
|
||||
Export-Excel -Path .\test.xlsx -ClearSheet -WorkSheetname "Processes" -PassThru
|
||||
Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -PassThru
|
||||
|
||||
$sheet = $excel.Workbook.Worksheets["Processes"]
|
||||
$sheet.Column(1) | Set-Format -Bold -AutoFit
|
||||
|
||||
#Apply fixed formatting to columns. Set-Format is an Alias for Set-Excel Range, -NFormat is an alias for numberformat
|
||||
$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit
|
||||
$sheet.Column(2) | Set-Format -Width 29 -WrapText
|
||||
$sheet.Column(3) | Set-Format -HorizontalAlignment Right -NFormat "#,###"
|
||||
|
||||
Set-Format -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
|
||||
Set-Format -Address $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
|
||||
Set-ExcelRange -Range -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
|
||||
#Set-Format is an alias for Set-ExcelRange
|
||||
Set-Format -Range $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
|
||||
#In Set-ExcelRange / Set-Format "-Address" is an alias for "-Range"
|
||||
Set-Format -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
|
||||
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red
|
||||
#Create a Red Data-bar for the values in Column D
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Address "D2:D1048576" -DataBarColor Red
|
||||
# Conditional formatting applies to "Addreses" aliases allow either "Range" or "Address" to be used in Set-ExcelRange or Add-Conditional formatting.
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red
|
||||
|
||||
foreach ($c in 5..9) {Set-Format -Address $sheet.Column($c) -AutoFit }
|
||||
|
||||
#Create a pivot and save the file.
|
||||
Export-Excel -ExcelPackage $excel -WorkSheetname "Processes" -IncludePivotChart -ChartType ColumnClustered -NoLegend -PivotRows company -PivotData @{'Name'='Count'} -Show
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$f = ".\testExport.xlsx"
|
||||
$f = "$env:TEMP\testExport.xlsx"
|
||||
|
||||
Remove-Item $f -ErrorAction Ignore
|
||||
|
||||
@@ -21,6 +21,8 @@ $data = $(
|
||||
New-PSItem Westerly 120
|
||||
New-PSItem SouthWest 118
|
||||
)
|
||||
# in this example instead of doing $variable = New-Conditional text <parameters> .... ; Export-excel -conditionalText $variable <other parameters>
|
||||
# the syntax is used is Export-excel -conditionalText (New-Conditional text <parameters>) <other parameters>
|
||||
|
||||
|
||||
#$data | Export-Excel $f -Show -AutoSize -ConditionalText (New-ConditionalText -ConditionalType AboveAverage)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
Remove-Item .\testExport.xlsx -ErrorAction Ignore
|
||||
Remove-Item "$env:TEMP\testExport.xlsx" -ErrorAction Ignore
|
||||
|
||||
Get-Process | Where-Object Company | Select-Object Company, Name, PM, Handles, *mem* |
|
||||
|
||||
Export-Excel .\testExport.xlsx -Show -AutoSize -AutoNameRange `
|
||||
#This example creates a 3 Icon set for the values in the "PM column, and Highlights company names (anywhere in the data) with different colors
|
||||
|
||||
Export-Excel "$env:TEMP\testExport.xlsx" -Show -AutoSize -AutoNameRange `
|
||||
-ConditionalFormat $(
|
||||
New-ConditionalFormattingIconSet -Range "C:C" `
|
||||
-ConditionalFormat ThreeIconSet -IconType Arrows
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
cls
|
||||
|
||||
ipmo ..\..\ImportExcel.psd1 -Force
|
||||
try {ipmo ..\..\ImportExcel.psd1 -Force} catch {}
|
||||
|
||||
$data = $(
|
||||
New-PSItem 100 (echo test testx)
|
||||
@@ -10,8 +8,8 @@ $data = $(
|
||||
New-PSItem 500
|
||||
)
|
||||
|
||||
$file1 = "tryComparison1.xlsx"
|
||||
$file2 = "tryComparison2.xlsx"
|
||||
$file1 = "$env:Temp\tryComparison1.xlsx"
|
||||
$file2 = "$env:Temp\tryComparison2.xlsx"
|
||||
|
||||
rm $file1 -ErrorAction Ignore
|
||||
rm $file2 -ErrorAction Ignore
|
||||
@@ -22,6 +20,6 @@ $data | Export-Excel $file1 -Show -ConditionalText $(
|
||||
)
|
||||
|
||||
$data | Export-Excel $file2 -Show -ConditionalText $(
|
||||
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
|
||||
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
|
||||
New-ConditionalText -ConditionalType LessThanOrEqual 250 -BackgroundColor cyan
|
||||
)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -8,7 +8,7 @@
|
||||
$sign=@{sign=echo + -}
|
||||
$location=@{location=echo Atlanta Newark Washington Chicago Philadelphia Houston Phoneix}
|
||||
|
||||
$(1..6 | % {
|
||||
$(1..6 | Foreach-Object {
|
||||
|
||||
$from=$to=""
|
||||
while($from -eq $to) {
|
||||
|
||||
101
Examples/HyperLinks/First10Races.csv
Normal file
101
Examples/HyperLinks/First10Races.csv
Normal file
@@ -0,0 +1,101 @@
|
||||
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
|
||||
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
|
||||
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
|
||||
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
|
||||
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
|
||||
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
|
||||
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
|
||||
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
|
||||
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
|
||||
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
|
||||
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
|
||||
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
|
||||
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
|
||||
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
|
||||
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
|
||||
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
|
||||
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
|
||||
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
|
||||
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
|
||||
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
|
||||
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
|
||||
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
|
||||
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
|
||||
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
|
||||
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
|
||||
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
|
||||
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
|
||||
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
|
||||
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
|
||||
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
|
||||
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
|
||||
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
|
||||
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
|
||||
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
|
||||
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
|
||||
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
|
||||
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
|
||||
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
|
||||
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
|
||||
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
|
||||
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
|
||||
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
|
||||
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
|
||||
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
|
||||
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
|
||||
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
|
||||
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
|
||||
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
|
||||
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
|
||||
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
|
||||
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
|
||||
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
|
||||
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
|
||||
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
|
||||
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
|
||||
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
|
||||
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
|
||||
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
|
||||
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
|
||||
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
|
||||
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
|
||||
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
|
||||
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
|
||||
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
|
||||
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
|
||||
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
|
||||
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
|
||||
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
|
||||
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
|
||||
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
|
||||
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
|
||||
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
|
||||
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
|
||||
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
|
||||
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
|
||||
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
|
||||
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
|
||||
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
|
||||
French,24/06/2018,8,Carlos Sainz,7,Renault,4
|
||||
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
|
||||
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
|
||||
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
|
||||
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
|
||||
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
|
||||
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
|
||||
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
|
||||
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
|
||||
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
|
||||
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
|
||||
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
|
||||
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
|
||||
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
|
||||
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
|
||||
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
|
||||
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
|
||||
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
|
||||
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
|
||||
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
|
||||
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
|
||||
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
|
||||
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
|
||||
|
27
Examples/HyperLinks/Races.ps1
Normal file
27
Examples/HyperLinks/Races.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
#First 10 races is a CSV file containing the top 10 finishers for the first 10 Formula one races of 2018. Read this file and group the results by race
|
||||
#We will create links to each race in the first 10 rows of the spreadSheet
|
||||
#The next row will be column labels
|
||||
#After that will come a block for each race.
|
||||
|
||||
#Read the data, and decide how much space to leave for the hyperlinks
|
||||
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
|
||||
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
|
||||
$results = Import-Csv -Path $dataPath | Group-Object -Property RACE
|
||||
$topRow = $lastDataRow = 1 + $results.Count
|
||||
|
||||
#Export the first row of the first group (race) with headers.
|
||||
$path = "$env:TEMP\Results.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$excel = $results[0].Group[0] | Export-Excel -Path $path -StartRow $TopRow -BoldTopRow -PassThru
|
||||
|
||||
#export each group (race) below the last one, without headers, and create a range for each using the group (Race) name
|
||||
foreach ($r in $results) {
|
||||
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow +1) -RangeName $R.Name -PassThru -AutoSize
|
||||
$lastDataRow += $R.Group.Count
|
||||
}
|
||||
|
||||
#Create a hyperlink for each property with display text of "RaceNameGP" which links to the range created when the rows were exported a
|
||||
$results | ForEach-Object {(New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList "Sheet1!$($_.Name)" , "$($_.name) GP")} |
|
||||
Export-Excel -ExcelPackage $excel -AutoSize -Show
|
||||
|
||||
41
Examples/Index - Music.ps1
Normal file
41
Examples/Index - Music.ps1
Normal file
@@ -0,0 +1,41 @@
|
||||
#requires -modules "Get-IndexedItem"
|
||||
[cmdletbinding()]
|
||||
Param()
|
||||
Remove-Item ~\documents\music.xlsx -ErrorAction SilentlyContinue
|
||||
[System.Diagnostics.Stopwatch]$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
#Query system index for .MP3 files in C:\Users, where album artist is non-blank. Leave sorted table with columns of interest in $Music.
|
||||
|
||||
Get-IndexedItem "itemtype='.mp3'","AlbumArtist like '%'" -Recurse C:\Users -OutputVariable Music `
|
||||
-OrderBy AlbumArtist, AlbumTitle, TrackNumber, Title -NoFiles `
|
||||
-Property AlbumArtist, AlbumTitle, TrackNumber, Title, Duration, Size, SampleRate
|
||||
Write-Verbose -Message ("Fetched " + $music.Rows.Count + " rows from index: " + $stopwatch.Elapsed.TotalSeconds)
|
||||
#Send Table in $Music to Excel, format as a table, point $ws to the Worksheet
|
||||
$excel = Send-SQLDataToExcel -Path ~\documents\music.xlsx -DataTable $music -WorkSheetname Music -TableName Music -Passthru
|
||||
Write-Verbose -Message ("Inserted into Excel: " + $stopwatch.Elapsed.TotalSeconds)
|
||||
$ws = $excel.Music
|
||||
|
||||
#Strip "SYSTEM.", "SYSTEM.AUDIO", "SYSTEM.MEDIA", "SYSTEM.MUSIC" from the column headings
|
||||
#Convert Duration (column 5) from 100ns ticks to days and format as minutes, seconds, decimal
|
||||
#Format filesize and sample rate nicely
|
||||
#Autofit the columns.
|
||||
Set-ExcelRow -Worksheet $ws -Row 1 -Value {($worksheet.cells[$row,$column].value -replace '^SYSTEM\.','') -replace '^MEDIA\.|^AUDIO\.|^MUSIC\.','' }
|
||||
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'mm:ss.0' -StartRow 2 -Value {$worksheet.cells[$row,$column].value / 864000000000 }
|
||||
Write-Verbose -Message ("Cells Reset: " + $stopwatch.Elapsed.TotalSeconds)
|
||||
Set-Column -Worksheet $ws -Column 6 -NumberFormat '#.#,,"MB"'
|
||||
Set-ExcelColumn -Worksheet $ws -Column 7 -NumberFormat '0.0,"KHz"'
|
||||
$ws.Cells[$ws.Dimension].AutoFitColumns()
|
||||
|
||||
#Make a Pivot table for sum of space and count of tracks by artist. Sort by artist, apply formatting to space, give it nice titles.
|
||||
$pt = Add-PivotTable -PassThru -PivotTableName SpaceUsedByMusic -ExcelPackage $excel -SourceWorkSheet $ws `
|
||||
-PivotRows ALBUMARTIST -PivotData ([ordered]@{"Size"="Sum"; "Duration"="Count"}) -PivotDataToColumn
|
||||
|
||||
$pt.RowFields[0].Sort = [OfficeOpenXml.Table.PivotTable.eSortType]::Ascending
|
||||
$pt.DataFields[0].Format = '#.0,,"MB"'
|
||||
$pt.DataFields[0].Name = 'Space Used'
|
||||
$pt.DataFields[1].Name = 'Tracks'
|
||||
|
||||
#Save the file, and load it into Excel
|
||||
$stopwatch.Stop()
|
||||
Write-Verbose -Message ("Pivot Done: " + $stopwatch.Elapsed.TotalSeconds)
|
||||
Close-ExcelPackage -show $excel
|
||||
@@ -40,4 +40,4 @@ $ptdef = New-PivotTableDefinition -PivotTableName "Summary" -PivotRows "Store" -
|
||||
#Put in a title and freeze to top of the sheet including title and colmun headings
|
||||
#Add the Pivot table.
|
||||
#Show the result
|
||||
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Summary" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef -show
|
||||
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Combined" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef -show
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
Get-WmiObject -Class win32_logicaldisk |
|
||||
#Export disk volume, and Network adapter to their own sheets.
|
||||
Get-WmiObject -Class win32_logicaldisk |
|
||||
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
||||
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
|
||||
Get-NetAdapter |
|
||||
Select-Object -Property Name,InterfaceDescription,MacAddress,LinkSpeed |
|
||||
Export-Excel -Path $path -WorkSheetname NetAdapters
|
||||
|
||||
#Create a summary page with a title of Summary, label the blocks with the name of the sheet they came from and hide the source sheets
|
||||
Join-Worksheet -Path $path -HideSource -WorkSheetName Summary -NoHeader -LabelBlocks -AutoSize -Title "Summary" -TitleBold -TitleSize 22 -show
|
||||
|
||||
@@ -11,12 +11,13 @@ $params = @{
|
||||
ExcelChartDefinition = New-ExcelChartDefinition -XRange Item -YRange UnitSold -Title 'Units Sold'
|
||||
Path = $xlfile
|
||||
}
|
||||
|
||||
#Import 4 sets of sales data from 4 CSV files, using the parameters above.
|
||||
Import-Csv $PSScriptRoot\NorthSales.csv | Export-Excel -WorkSheetname North @params
|
||||
Import-Csv $PSScriptRoot\EastSales.csv | Export-Excel -WorkSheetname East @params
|
||||
Import-Csv $PSScriptRoot\SouthSales.csv | Export-Excel -WorkSheetname South @params
|
||||
Import-Csv $PSScriptRoot\WestSales.csv | Export-Excel -WorkSheetname West @params
|
||||
|
||||
#Join the 4 worksheets together on a sheet named Allsales, use the same parameters, except for AutoNameRange and ExcelChartDefinition.
|
||||
$params.Remove("AutoNameRange")
|
||||
$params.Remove("ExcelChartDefinition")
|
||||
Join-Worksheet -WorkSheetName AllSales -Show @params
|
||||
21
Examples/MergeWorkSheet/Merge_2_Servers_Services.ps1
Normal file
21
Examples/MergeWorkSheet/Merge_2_Servers_Services.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
|
||||
#Get a subset of services into $s and export them
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property *
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
|
||||
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
|
||||
$s[2].DisplayName = "Changed from the orginal" #This will be row 4 in Excel - this should be highlighted as a change
|
||||
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d) #This will be row 5 in Excel - this should be highlighted as a new item
|
||||
|
||||
$s.RemoveAt(5) #This will be row 7 in Excel - this should be highlighted as deleted item
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server2.xlsx
|
||||
|
||||
#This use of Merge-worksheet Assumes a default worksheet name, (sheet1) We will check and output Name (the key), DisplayName and StartType and ignore other properties.
|
||||
Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined1.xlsx" -Property name,displayname,startType -Key name -Show
|
||||
34
Examples/MergeWorkSheet/Merge_3_Servers_Services.ps1
Normal file
34
Examples/MergeWorkSheet/Merge_3_Servers_Services.ps1
Normal file
@@ -0,0 +1,34 @@
|
||||
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
|
||||
#Get a subset of services into $s and export them
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name,DisplayName,StartType
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
|
||||
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
$s[2].DisplayName = "Changed from the orginal" #This will be excel row 4 and Server 2 will show as changed.
|
||||
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d) #This will be Excel row 5 and server 2 will show as changed - so will Server 3
|
||||
|
||||
$s.RemoveAt(5) #This will be Excel row 7 and Server 2 will show as missing.
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server2.xlsx
|
||||
|
||||
#Make some more changes to $s and export it to a third file
|
||||
$s[2].displayname = $row4Displayname #Server 3 row 4 will match server 1 so won't be highlighted
|
||||
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Second Service"
|
||||
$d.Name = "Service2"
|
||||
$s.Insert(6,$d) #This will be an extra row in Server 3 at row 8. It will show as missing in Server 2.
|
||||
$s.RemoveAt(8) #This will show as missing in Server 3 at row 11 ()
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server3.xlsx
|
||||
|
||||
#Now bring the three files together.
|
||||
|
||||
Merge-MultipleSheets -Path "$env:temp\server1.xlsx", "$env:temp\Server2.xlsx","$env:temp\Server3.xlsx" -OutputFile "$env:temp\combined3.xlsx" -Property name,displayname,startType -Key name -Show
|
||||
@@ -3,7 +3,7 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
$xlfile = "$env:TEMP\testThis.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction Ignore
|
||||
|
||||
1..10 | Export-Excel $xlfile -WorkSheetname First
|
||||
11..20 | Export-Excel $xlfile -WorkSheetname Second -MoveToStart
|
||||
21..30 | Export-Excel $xlfile -WorkSheetname Third -MoveBefore First
|
||||
31..40 | Export-Excel $xlfile -WorkSheetname Fourth -MoveAfter Third -Show
|
||||
1..10 | Export-Excel $xlfile -WorkSheetname First #'First' will be the only sheet
|
||||
11..20 | Export-Excel $xlfile -WorkSheetname Second -MoveToStart #'Second' is moved before first so the order is 'Second', 'First'
|
||||
21..30 | Export-Excel $xlfile -WorkSheetname Third -MoveBefore First #'Second' is moved before first so the order is 'Second', 'Third', 'First'
|
||||
31..40 | Export-Excel $xlfile -WorkSheetname Fourth -MoveAfter Third -Show #'Fourth' is moved after third so the order is ' 'Second', 'Third', 'Fourth' First'
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$file = "disks.xlsx"
|
||||
$file = "$env:TEMP\disks.xlsx"
|
||||
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
|
||||
@@ -11,5 +11,5 @@ $data = $(
|
||||
New-PSItem -3.2 -4.1
|
||||
New-PSItem -5.2 6.1
|
||||
)
|
||||
|
||||
#Set the numbers throughout the sheet to format as positive in blue with a + sign, negative in Red with a - sign.
|
||||
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat "[Blue]+0.#0;[Red]-0.#0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$file = "disks.xlsx"
|
||||
$file = "$env:temp\disks.xlsx"
|
||||
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
|
||||
@@ -12,6 +12,5 @@ $data = $(
|
||||
New-PSItem -5.2 6.1
|
||||
New-PSItem 1000 -2000
|
||||
)
|
||||
|
||||
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||
|
||||
#Number format can expand terms like Currency, to the local currency format
|
||||
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat 'Currency'
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,20 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$file = "sales.xlsx"
|
||||
$file = "$env:Temp\sales.xlsx"
|
||||
|
||||
Remove-Item $file -ErrorAction Ignore
|
||||
|
||||
#Using -Passthru with Export-Excel returns an Excel Package object.
|
||||
$xlPkg = Import-Csv .\sales.csv | Export-Excel $file -PassThru
|
||||
|
||||
$ws = $xlPkg.Workbook.WorkSheets[1]
|
||||
#We add script properties to the package so $xlPkg.Sheet1 is equivalent to $xlPkg.Workbook.WorkSheets["Sheet1"]
|
||||
$ws = $xlPkg.Sheet1
|
||||
|
||||
#We can manipulate the cells ...
|
||||
$ws.Cells["E1"].Value = "TotalSold"
|
||||
$ws.Cells["F1"].Value = "Add 10%"
|
||||
|
||||
#This is for illustration - there are more efficient ways to do this.
|
||||
2..($ws.Dimension.Rows) |
|
||||
ForEach-Object {
|
||||
$ws.Cells["E$_"].Formula = "=C$_+D$_"
|
||||
@@ -19,7 +23,7 @@ $ws.Cells["F1"].Value = "Add 10%"
|
||||
|
||||
$ws.Cells.AutoFitColumns()
|
||||
|
||||
#You can call close-ExcelPackage $xlPkg -show, but here we will do the ssteps explicitly
|
||||
$xlPkg.Save()
|
||||
$xlPkg.Dispose()
|
||||
|
||||
Invoke-Item $file
|
||||
Binary file not shown.
@@ -1,15 +1,25 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
Remove-Item .\test1.xlsx -ErrorAction Ignore
|
||||
|
||||
$ExcelParams = @{
|
||||
Path = ".\test1.xlsx"
|
||||
Path = "$env:TEMP\test1.xlsx"
|
||||
IncludePivotTable = $true
|
||||
PivotRows = 'Company'
|
||||
PivotTableName = 'MyTable'
|
||||
PivotData = @{'Handles' = 'sum'}
|
||||
Show = $true
|
||||
Activate = $true
|
||||
}
|
||||
Remove-Item $ExcelParams.Path -ErrorAction Ignore
|
||||
Get-Process | Select-Object Company, Handles | Export-Excel @ExcelParams
|
||||
|
||||
Get-Process | Select-Object Company, Handles |
|
||||
Export-Excel @ExcelParams
|
||||
<# Builds a pivot table that looks like this:
|
||||
|
||||
Sum of Handles
|
||||
Row Labels Total
|
||||
Adobe Systems Incorporated 3100
|
||||
(blank) 214374
|
||||
Apple Inc. 215
|
||||
etc
|
||||
etc
|
||||
Grand Total 365625
|
||||
#>
|
||||
26
Examples/PivotTable/TableAndPivotTable.ps1
Normal file
26
Examples/PivotTable/TableAndPivotTable.ps1
Normal file
@@ -0,0 +1,26 @@
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
remove-item -path $path -ErrorAction SilentlyContinue
|
||||
|
||||
#Export some sales data to Excel, format it as a table and put a data-bar in. For this example we won't create the pivot table during the export
|
||||
$excel = ConvertFrom-Csv @"
|
||||
Product, City, Gross, Net
|
||||
Apple, London , 300, 250
|
||||
Orange, London , 400, 350
|
||||
Banana, London , 300, 200
|
||||
Orange, Paris, 600, 500
|
||||
Banana, Paris, 300, 200
|
||||
Apple, New York, 1200,700
|
||||
"@ | Export-Excel -PassThru -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"}
|
||||
|
||||
#Add a pivot table, specify its address to put it on the same sheet, use the data that was just exported set the table style and number format.
|
||||
#Use the "City" for the row names, and "Product" for the columnnames, and sum both the gross and net values for each City/Product combination; add grand totals to rows and columns.
|
||||
# activate the sheet and add a pivot chart (defined in a hash table)
|
||||
Add-PivotTable -Address $excel.Sheet1.Cells["F1"] -SourceWorkSheet $Excel.Sheet1 -SourceRange $Excel.Sheet1.Dimension.Address -PivotTableName "Sales" -PivotTableStyle "Medium12" -PivotNumberFormat "$#,##0.00" `
|
||||
-PivotRows "City" -PivotColumns "Product" -PivotData @{Gross="Sum";Net="Sum"}-PivotTotals "Both" -Activate -PivotChartDefinition @{
|
||||
Title="Gross and net by city and product";
|
||||
ChartType="ColumnClustered";
|
||||
Column=11; Width=500; Height=360;
|
||||
YMajorUnit=500; YMinorUnit=100; YAxisNumberformat="$#,##0"
|
||||
LegendPosition="Bottom"}
|
||||
#Save and open in excel
|
||||
Close-ExcelPackage $excel -Show
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$xlFile=".\testPivot.xlsx"
|
||||
$xlFile="$env:TEMP\testPivot.xlsx"
|
||||
Remove-Item $xlFile -ErrorAction Ignore
|
||||
|
||||
$data =@"
|
||||
@@ -18,4 +18,18 @@ $data |
|
||||
-AutoSize -AutoFilter `
|
||||
-IncludePivotTable `
|
||||
-PivotRows Product `
|
||||
-PivotData @{"Units"="sum"} -PivotFilter Region, Area
|
||||
-PivotData @{"Units"="sum"} -PivotFilter Region, Area -Activate
|
||||
|
||||
<#
|
||||
Creates a Pivot table that looks like
|
||||
Region All^
|
||||
Area All^
|
||||
|
||||
Sum of Units
|
||||
Row Labels Total
|
||||
Apple 100
|
||||
Pear 240
|
||||
Grape 280
|
||||
Banana 160
|
||||
Grand Total 780
|
||||
#>
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$plt = New-Plot
|
||||
$plt.Plot((Get-Range 0 5 .02|%{[math]::Cos(2*[math]::pi*$_)}))
|
||||
$plt.Plot((Get-Range 0 5 .02|Foreach-Object {[math]::Cos(2*[math]::pi*$_)}))
|
||||
$plt.SetChartSize(800,300)
|
||||
$plt.Show()
|
||||
@@ -1,5 +1,7 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
#requires -modules "getSql"
|
||||
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
#download f1Results from https://1drv.ms/f/s!AhfYu7-CJv4egbt5FD7Cdxi8jSz3aQ and update the path below
|
||||
Get-SQL -Session f1 -Excel -Connection C:\Users\mcp\OneDrive\Public\F1\f1Results.xlsx -showtables -Verbose
|
||||
|
||||
Remove-Item .\demo3.xlsx
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$p = Get-Process | Select-Object Company, Handles | Export-Excel c:\temp\testBackgroundColor.xlsx -ClearSheet -KillExcel -PassThru
|
||||
$path = "$env:TEMP\testBackgroundColor.xlsx"
|
||||
|
||||
$p = Get-Process | Select-Object Company, Handles | Export-Excel $path -ClearSheet -PassThru
|
||||
|
||||
$ws = $p.Workbook.WorkSheets[1]
|
||||
$totalRows = $ws.Dimension.Rows
|
||||
|
||||
Set-Format -Address $ws.Cells["B2:B$($totalRows)"] -BackgroundColor LightBlue
|
||||
#Set the range from B2 to the last active row. s
|
||||
Set-ExcelRange -Range $ws.Cells["B2:B$($totalRows)"] -BackgroundColor LightBlue
|
||||
|
||||
Export-Excel -ExcelPackage $p -show -AutoSize
|
||||
@@ -3,7 +3,7 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
#. ..\New-PSItem.ps1
|
||||
|
||||
Remove-Item *.xlsx
|
||||
Remove-Item "$env:temp\functions.xlsx" -ErrorAction SilentlyContinue
|
||||
|
||||
$(
|
||||
New-PSItem 12001 Nails 37 3.99 =C2*D2 (echo ID Product Quantity Price Total)
|
||||
@@ -11,4 +11,4 @@ $(
|
||||
New-PSItem 12003 Saw 12 15.37 =C4*D4
|
||||
New-PSItem 12010 Drill 20 8 =C5*D5
|
||||
New-PSItem 12011 Crowbar 7 23.48 =C6*D6
|
||||
) | Export-Excel functions.xlsx -AutoSize -Show
|
||||
) | Export-Excel "$env:temp\functions.xlsx"-AutoSize -Show
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
Remove-Item *.xlsx
|
||||
Remove-Item "$env:temp\functions.xlsx" -ErrorAction SilentlyContinue
|
||||
|
||||
$(
|
||||
New-PSItem =2%/12 60 500000 "=pmt(rate,nper,pv)" (echo rate nper pv pmt)
|
||||
@@ -9,4 +9,4 @@ $(
|
||||
New-PSItem =5%/12 60 500000 "=pmt(rate,nper,pv)"
|
||||
New-PSItem =6%/12 60 500000 "=pmt(rate,nper,pv)"
|
||||
New-PSItem =7%/12 60 500000 "=pmt(rate,nper,pv)"
|
||||
) | Export-Excel functions.xlsx -AutoNameRange -AutoSize -Show
|
||||
) | Export-Excel "$env:temp\functions.xlsx" -AutoNameRange -AutoSize -Show
|
||||
@@ -1,10 +1,10 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
Remove-Item *.xlsx
|
||||
Remove-Item "$env:temp\hyperlink.xlsx" -ErrorAction SilentlyContinue
|
||||
|
||||
$(
|
||||
New-PSItem '=Hyperlink("http://dougfinke.com/blog","Doug Finke")' @("Link")
|
||||
New-PSItem '=Hyperlink("http://blogs.msdn.com/b/powershell/","PowerShell Blog")'
|
||||
New-PSItem '=Hyperlink("http://blogs.technet.com/b/heyscriptingguy/","Hey, Scripting Guy")'
|
||||
|
||||
) | Export-Excel hyperlink.xlsx -AutoSize -Show
|
||||
) | Export-Excel "$env:temp\hyperlink.xlsx" -AutoSize -Show
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$xlfile = "testData.xlsx"
|
||||
Remove-Item *.xlsx
|
||||
$xlfile = "$env:Temp\testData.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$r = Get-ChildItem C:\WINDOWS\system32
|
||||
|
||||
@@ -23,16 +23,19 @@ $top10ByFileSize = $r |
|
||||
Select-Object -First 10 Name, @{n="Size";e={$_.Length}} #,Extension,Path
|
||||
|
||||
|
||||
$top10BySize | Export-Excel $xlfile -WorkSheetname FileInfo -TableName ExtSize
|
||||
$top10ByCount | Export-Excel $xlfile -WorkSheetname FileInfo -StartRow 13 -TableName ExtCount
|
||||
$top10ByFileSize | Export-Excel $xlfile -WorkSheetname FileInfo -StartRow 25 -AutoSize -TableName FileSize
|
||||
$xlPkg = $top10BySize | Export-Excel -path $xlfile -WorkSheetname FileInfo -TableName ExtSize -PassThru
|
||||
$xlPkg = $top10ByCount | Export-Excel -ExcelPackage $xlPkg -WorkSheetname FileInfo -StartRow 13 -TableName ExtCount -PassThru
|
||||
$xlPkg = $top10ByFileSize | Export-Excel -ExcelPackage $xlPkg -WorkSheetname FileInfo -StartRow 25 -TableName FileSize -PassThru -AutoSize
|
||||
|
||||
#worksheets.tables["Name1","Name2"] returns 2 tables. Set-ExcelRange can process those and will set the number format over both
|
||||
Set-ExcelRange -Range $xlpkg.Workbook.Worksheets[1].Tables["ExtSize","FileSize"] -NumberFormat '0,,"MB"'
|
||||
|
||||
$ps = Get-Process | Where-Object Company
|
||||
|
||||
$ps |
|
||||
Sort-Object handles -Descending |
|
||||
Select-Object -First 10 company, handles |
|
||||
Export-Excel $xlfile -WorkSheetname Handles -AutoSize -TableName Handles
|
||||
Export-Excel -ExcelPackage $xlPkg -WorkSheetname Handles -AutoSize -TableName Handles
|
||||
|
||||
$ps |
|
||||
Sort-Object PM -Descending |
|
||||
|
||||
Binary file not shown.
@@ -2,6 +2,6 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
. $PSScriptRoot\TestAPIReadXls.ps1
|
||||
|
||||
Test-APIReadXls $PSScriptRoot\testlist.xlsx | % {
|
||||
Test-APIReadXls $PSScriptRoot\testlist.xlsx | Foreach-Object {
|
||||
Invoke-Pester -Script $_.fullname -PassThru -Show None
|
||||
}
|
||||
1150
Export-Excel.ps1
1150
Export-Excel.ps1
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,9 @@ function Get-HtmlTable {
|
||||
|
||||
if(!$propertyNames) {
|
||||
if($cells[0].tagName -eq 'th') {
|
||||
$propertyNames = @($cells | foreach {$_.innertext -replace ' ',''})
|
||||
$propertyNames = @($cells | ForEach-Object {$_.innertext -replace ' ',''})
|
||||
} else {
|
||||
$propertyNames = @(1..($cells.Count + 2) | % { "P$_" })
|
||||
$propertyNames = @(1..($cells.Count + 2) | Foreach-Object { "P$_" })
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
function Get-XYRange {
|
||||
param($targetData)
|
||||
|
||||
$record = $targetData| select -First 1
|
||||
$record = $targetData | Select-Object -First 1
|
||||
$p=$record.psobject.Properties.name
|
||||
|
||||
$infer = for ($idx = 0; $idx -lt $p.Count; $idx++) {
|
||||
@@ -20,7 +20,7 @@ function Get-XYRange {
|
||||
}
|
||||
|
||||
[PSCustomObject]@{
|
||||
XRange = $infer | ? {$_.datatype -match 'string'} | select -First 1 excelcolumn, name
|
||||
YRange = $infer | ? {$_.datatype -match 'int|double'} |select -First 1 excelcolumn, name
|
||||
XRange = $infer | Where-Object -FilterScript {$_.datatype -match 'string'} | Select-Object -First 1 -Property excelcolumn, name
|
||||
YRange = $infer | Where-Object -FilterScript {$_.datatype -match 'int|double'} | Select-Object -First 1 -Property excelcolumn, name
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ Function Get-ExcelTableName {
|
||||
$Stream.Close()
|
||||
$Stream.Dispose()
|
||||
$Excel.Dispose()
|
||||
$Excel = $null
|
||||
$Excel = $null
|
||||
}
|
||||
|
||||
Function Get-ExcelTable {
|
||||
@@ -66,7 +66,7 @@ Function Get-ExcelTable {
|
||||
$propertyNames = for($col=$startCol; $col -lt ($startCol+$colCount); $col+= 1) {
|
||||
$Worksheet.Cells[$startRow, $col].value
|
||||
}
|
||||
|
||||
|
||||
$startRow++
|
||||
for($row=$startRow; $row -lt ($startRow+$rowCount); $row += 1) {
|
||||
$nr=[ordered]@{}
|
||||
@@ -89,16 +89,14 @@ function ConvertFrom-ExcelColumnName {
|
||||
|
||||
$sum=0
|
||||
$columnName.ToCharArray() |
|
||||
ForEach {
|
||||
ForEach-Object {
|
||||
$sum*=26
|
||||
$sum+=[char]$_.tostring().toupper()-[char]'A'+1
|
||||
}
|
||||
}
|
||||
$sum
|
||||
}
|
||||
|
||||
cls
|
||||
|
||||
ipmo .\ImportExcel.psd1 -Force
|
||||
|
||||
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
|
||||
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
|
||||
Get-ExcelTable .\testTable.xlsx Table3
|
||||
156
ImportExcel.psd1
156
ImportExcel.psd1
@@ -1,120 +1,120 @@
|
||||
@{
|
||||
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'ImportExcel.psm1'
|
||||
# Script module or binary module file associated with this manifest.
|
||||
RootModule = 'ImportExcel.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '5.1.0'
|
||||
# Version number of this module.
|
||||
ModuleVersion = '5.4.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
|
||||
|
||||
# Author of this module
|
||||
Author = 'Douglas Finke'
|
||||
# Author of this module
|
||||
Author = 'Douglas Finke'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Doug Finke'
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Doug Finke'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'c 2015 All rights reserved.'
|
||||
# Copyright statement for this module
|
||||
Copyright = 'c 2015 All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = @'
|
||||
# Description of the functionality provided by this module
|
||||
Description = @'
|
||||
PowerShell module to import/export Excel spreadsheets, without Excel.
|
||||
Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5uoqS92stXioZw-u-ze_NtvSo0k0K0kq
|
||||
'@
|
||||
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
# PowerShellVersion = ''
|
||||
# Minimum version of the Windows PowerShell engine required by this module
|
||||
# PowerShellVersion = ''
|
||||
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
# Name of the Windows PowerShell host required by this module
|
||||
# PowerShellHostName = ''
|
||||
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
# Minimum version of the Windows PowerShell host required by this module
|
||||
# PowerShellHostVersion = ''
|
||||
|
||||
# Minimum version of Microsoft .NET Framework required by this module
|
||||
# DotNetFrameworkVersion = ''
|
||||
# Minimum version of Microsoft .NET Framework required by this module
|
||||
# DotNetFrameworkVersion = ''
|
||||
|
||||
# Minimum version of the common language runtime (CLR) required by this module
|
||||
# CLRVersion = ''
|
||||
# Minimum version of the common language runtime (CLR) required by this module
|
||||
# CLRVersion = ''
|
||||
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
# Processor architecture (None, X86, Amd64) required by this module
|
||||
# ProcessorArchitecture = ''
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
# RequiredModules = @()
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
# RequiredModules = @()
|
||||
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
# Assemblies that must be loaded prior to importing this module
|
||||
# RequiredAssemblies = @()
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
# Type files (.ps1xml) to be loaded when importing this module
|
||||
# TypesToProcess = @()
|
||||
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
# Format files (.ps1xml) to be loaded when importing this module
|
||||
# FormatsToProcess = @()
|
||||
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||
# NestedModules = @()
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = '*'
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = '*'
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
# Variables to export from this module
|
||||
VariablesToExport = '*'
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = '*'
|
||||
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
# List of all modules packaged with this module
|
||||
# ModuleList = @()
|
||||
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
# List of all files packaged with this module
|
||||
# FileList = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
||||
PrivateData = @{
|
||||
# PSData is module packaging and gallery metadata embedded in PrivateData
|
||||
# It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
|
||||
# We had to do this because it's the only place we're allowed to extend the manifest
|
||||
# https://connect.microsoft.com/PowerShell/feedback/details/421837
|
||||
PSData = @{
|
||||
# The primary categorization of this module (from the TechNet Gallery tech tree).
|
||||
Category = "Scripting Excel"
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
||||
PrivateData = @{
|
||||
# PSData is module packaging and gallery metadata embedded in PrivateData
|
||||
# It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
|
||||
# We had to do this because it's the only place we're allowed to extend the manifest
|
||||
# https://connect.microsoft.com/PowerShell/feedback/details/421837
|
||||
PSData = @{
|
||||
# The primary categorization of this module (from the TechNet Gallery tech tree).
|
||||
Category = "Scripting Excel"
|
||||
|
||||
# Keyword tags to help users find this module via navigations and search.
|
||||
Tags = @("Excel","EPPlus","Export","Import")
|
||||
# Keyword tags to help users find this module via navigations and search.
|
||||
Tags = @("Excel", "EPPlus", "Export", "Import")
|
||||
|
||||
# The web address of an icon which can be used in galleries to represent this module
|
||||
#IconUri = "http://pesterbdd.com/images/Pester.png"
|
||||
# The web address of an icon which can be used in galleries to represent this module
|
||||
#IconUri = "http://pesterbdd.com/images/Pester.png"
|
||||
|
||||
# The web address of this module's project or support homepage.
|
||||
ProjectUri = "https://github.com/dfinke/ImportExcel"
|
||||
# The web address of this module's project or support homepage.
|
||||
ProjectUri = "https://github.com/dfinke/ImportExcel"
|
||||
|
||||
# The web address of this module's license. Points to a page that's embeddable and linkable.
|
||||
LicenseUri = "https://github.com/dfinke/ImportExcel/blob/master/LICENSE.txt"
|
||||
# The web address of this module's license. Points to a page that's embeddable and linkable.
|
||||
LicenseUri = "https://github.com/dfinke/ImportExcel/blob/master/LICENSE.txt"
|
||||
|
||||
# Release notes for this particular version of the module
|
||||
#ReleaseNotes = $True
|
||||
# Release notes for this particular version of the module
|
||||
#ReleaseNotes = $True
|
||||
|
||||
# If true, the LicenseUrl points to an end-user license (not just a source license) which requires the user agreement before use.
|
||||
# RequireLicenseAcceptance = ""
|
||||
# If true, the LicenseUrl points to an end-user license (not just a source license) which requires the user agreement before use.
|
||||
# RequireLicenseAcceptance = ""
|
||||
|
||||
# Indicates this is a pre-release/testing version of the module.
|
||||
IsPrerelease = 'False'
|
||||
# Indicates this is a pre-release/testing version of the module.
|
||||
IsPrerelease = 'False'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
# HelpInfo URI of this module
|
||||
# HelpInfoURI = ''
|
||||
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
|
||||
# DefaultCommandPrefix = ''
|
||||
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
. $PSScriptRoot\New-PSItem.ps1
|
||||
. $PSScriptRoot\Open-ExcelPackage.ps1
|
||||
. $PSScriptRoot\Pivot.ps1
|
||||
. $PSScriptRoot\PivotTable.ps1
|
||||
. $PSScriptRoot\Send-SQLDataToExcel.ps1
|
||||
. $PSScriptRoot\Set-CellStyle.ps1
|
||||
. $PSScriptRoot\Set-Column.ps1
|
||||
@@ -62,7 +63,7 @@ function Import-Excel {
|
||||
.DESCRIPTION
|
||||
The Import-Excel cmdlet creates custom objects from the rows in an Excel worksheet. Each row represents one object. All of this is possible without installing Microsoft Excel and by using the .NET library ‘EPPLus.dll’.
|
||||
|
||||
By default, the property names of the objects are retrieved from the column headers. Because an object cannot have a blanc property name, only columns with column headers will be imported.
|
||||
By default, the property names of the objects are retrieved from the column headers. Because an object cannot have a blank property name, only columns with column headers will be imported.
|
||||
|
||||
If the default behavior is not desired and you want to import the complete worksheet ‘as is’, the parameter ‘-NoHeader’ can be used. In case you want to provide your own property names, you can use the parameter ‘-HeaderName’.
|
||||
|
||||
@@ -220,7 +221,7 @@ function Import-Excel {
|
||||
|
||||
Notice that empty rows and empty columns are not imported.
|
||||
|
||||
.EXAMPLE
|
||||
.EXAMPLE
|
||||
Import data from an Excel worksheet. One object is created for each row. The property names are provided with the ‘-HeaderName’ parameter. The import will start from row 2 and empty columns and rows are not imported.
|
||||
|
||||
----------------------------------------------------------
|
||||
@@ -240,6 +241,16 @@ function Import-Excel {
|
||||
|
||||
Notice that only 1 object is imported with only 3 properties. Column B and row 2 are empty and have been disregarded by using the switch '-DataOnly'. The property names have been named with the values provided with the parameter '-HeaderName'. Row number 1 with ‘Chuck Norris’ has not been imported, because we started the import from row 2 with the parameter ‘-StartRow 2’.
|
||||
|
||||
.EXAMPLE
|
||||
>
|
||||
PS> ,(Import-Excel -Path .\SysTables_AdventureWorks2014.xlsx) |
|
||||
Write-SqlTableData -ServerInstance localhost\DEFAULT -Database BlankDB -SchemaName dbo -TableName MyNewTable_fromExcel -Force
|
||||
|
||||
Imports data from an Excel file and pipe the data to the Write-SqlTableData to be INSERTed into a table in a SQL Server database.
|
||||
The ",( ... )" around the Import-Excel command allows all rows to be imported from the Excel file, prior to pipelining to the Write-SqlTableData cmdlet. This helps prevent a RBAR scenario and is important when trying to import thousands of rows.
|
||||
The -Force parameter will be ignored if the table already exists. However, if a table is not found that matches the values provided by -SchemaName and -TableName parameters, it will create a new table in SQL Server database. The Write-SqlTableData cmdlet will inherit the column names & datatypes for the new table from the object being piped in.
|
||||
NOTE: You need to install the SqlServer module from the PowerShell Gallery in oder to get the Write-SqlTableData cmdlet.
|
||||
|
||||
.LINK
|
||||
https://github.com/dfinke/ImportExcel
|
||||
|
||||
@@ -321,28 +332,25 @@ function Import-Excel {
|
||||
}
|
||||
|
||||
Process {
|
||||
Try {
|
||||
#region Open file
|
||||
#region Open file
|
||||
try {
|
||||
$Path = (Resolve-Path $Path).ProviderPath
|
||||
Write-Verbose "Import Excel workbook '$Path' with worksheet '$Worksheetname'"
|
||||
|
||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
|
||||
}
|
||||
Catch {throw "Could not open $Path ; $_ "}
|
||||
|
||||
if ($Password) {
|
||||
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
|
||||
|
||||
Try {
|
||||
$Excel.Load($Stream,$Password)
|
||||
}
|
||||
Catch {
|
||||
throw "Password '$Password' is not correct."
|
||||
}
|
||||
}
|
||||
else {
|
||||
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
||||
}
|
||||
#endregion
|
||||
|
||||
if ($Password) {
|
||||
Try {$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
|
||||
$excel.Load( $Stream,$Password)}
|
||||
Catch { throw "Could not read $Path with the provided password." }
|
||||
}
|
||||
else {
|
||||
try {$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream}
|
||||
Catch {throw "Failed to read $Path"}
|
||||
}
|
||||
#endregion
|
||||
Try {
|
||||
#region Select worksheet
|
||||
if ($WorksheetName) {
|
||||
if (-not ($Worksheet = $Excel.Workbook.Worksheets[$WorkSheetName])) {
|
||||
@@ -396,12 +404,13 @@ function Import-Excel {
|
||||
else {
|
||||
#region Create one object per row
|
||||
foreach ($R in $Rows) {
|
||||
Write-Verbose "Import row '$R'"
|
||||
#Disabled write-verbose for speed
|
||||
# Write-Verbose "Import row '$R'"
|
||||
$NewRow = [Ordered]@{}
|
||||
|
||||
foreach ($P in $PropertyNames) {
|
||||
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
|
||||
Write-Verbose "Import cell '$($Worksheet.Cells[$R, $P.Column].Address)' with property name '$($p.Value)' and value '$($Worksheet.Cells[$R, $P.Column].Value)'."
|
||||
# Write-Verbose "Import cell '$($Worksheet.Cells[$R, $P.Column].Address)' with property name '$($p.Value)' and value '$($Worksheet.Cells[$R, $P.Column].Value)'."
|
||||
}
|
||||
|
||||
[PSCustomObject]$NewRow
|
||||
@@ -512,3 +521,20 @@ function Export-MultipleExcelSheets {
|
||||
|
||||
if($Show) {Invoke-Item $Path}
|
||||
}
|
||||
|
||||
Function WorksheetArgumentCompleter {
|
||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||
$xlPath = $fakeBoundParameter['Path']
|
||||
if (Test-Path -Path $xlPath) {
|
||||
$xlpkg = Open-ExcelPackage -Path $xlPath
|
||||
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name
|
||||
Close-ExcelPackage -nosave -ExcelPackage $xlpkg
|
||||
$WorksheetNames.where({$_ -like "*$wordToComplete*"}) | foreach-object {
|
||||
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'",
|
||||
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) ,$_
|
||||
}
|
||||
}
|
||||
}
|
||||
If (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
|
||||
Register-ArgumentCompleter -CommandName 'Import-Excel' -ParameterName 'WorksheetName' -ScriptBlock $Function:WorksheetArgumentCompleter
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ function Invoke-AllTests {
|
||||
)
|
||||
|
||||
$resultCount=0
|
||||
$tests.GetEnumerator() | ForEach {
|
||||
$tests.GetEnumerator() | ForEach-Object {
|
||||
|
||||
$result=& $_.Value $target
|
||||
|
||||
|
||||
@@ -1,89 +1,3 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Install the module in the PowerShell module folder.
|
||||
$fullPath = 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel'
|
||||
|
||||
.DESCRIPTION
|
||||
Install the module in the PowerShell module folder by copying all the files.
|
||||
#>
|
||||
|
||||
[CmdLetBinding()]
|
||||
Param (
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$ModuleName = 'ImportExcel',
|
||||
[ValidateScript({Test-Path -Path $_ -Type Container})]
|
||||
[String]$ModulePath = 'C:\Program Files\WindowsPowerShell\Modules'
|
||||
)
|
||||
|
||||
Begin {
|
||||
Try {
|
||||
Write-Verbose "$ModuleName module installation started"
|
||||
|
||||
$Files = @(
|
||||
'*.dll',
|
||||
'*.psd1',
|
||||
'*.psm1',
|
||||
'AddConditionalFormatting.ps1',
|
||||
'Charting.ps1',
|
||||
'ColorCompletion.ps1',
|
||||
'Compare-Worksheet.ps1',
|
||||
'ConvertFromExcelData.ps1',
|
||||
'ConvertFromExcelToSQLInsert.ps1',
|
||||
'ConvertExcelToImageFile.ps1',
|
||||
'ConvertToExcelXlsx.ps1',
|
||||
'Copy-ExcelWorkSheet.ps1',
|
||||
'Export-Charts.ps1',
|
||||
'Export-Excel.ps1',
|
||||
'Export-ExcelSheet.ps1',
|
||||
'formatting.ps1',
|
||||
'Get-ExcelColumnName.ps1',
|
||||
'Get-ExcelSheetInfo.ps1',
|
||||
'Get-ExcelWorkbookInfo.ps1',
|
||||
'Get-HtmlTable.ps1',
|
||||
'Get-Range.ps1',
|
||||
'Get-XYRange.ps1',
|
||||
'Import-Html.ps1',
|
||||
'InferData.ps1',
|
||||
'Invoke-Sum.ps1',
|
||||
'Join-Worksheet.ps1',
|
||||
'Merge-Worksheet.ps1',
|
||||
'New-ConditionalFormattingIconSet.ps1',
|
||||
'New-ConditionalText.ps1',
|
||||
'New-ExcelChart.ps1',
|
||||
'New-PSItem.ps1',
|
||||
'Open-ExcelPackage.ps1',
|
||||
'Pivot.ps1',
|
||||
'Plot.ps1',
|
||||
'Send-SQLDataToExcel.ps1',
|
||||
'Set-CellStyle.ps1',
|
||||
'Set-Column.ps1',
|
||||
'Set-Row.ps1',
|
||||
'SetFormat.ps1',
|
||||
'TrackingUtils.ps1',
|
||||
'Update-FirstObjectProperties.ps1'
|
||||
)
|
||||
}
|
||||
Catch {
|
||||
throw "Failed installing the module '$ModuleName': $_"
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
Try {
|
||||
$TargetPath = Join-Path -Path $ModulePath -ChildPath $ModuleName
|
||||
|
||||
if (-not (Test-Path $TargetPath)) {
|
||||
New-Item -Path $TargetPath -ItemType Directory -EA Stop | Out-Null
|
||||
Write-Verbose "$ModuleName created module folder '$TargetPath'"
|
||||
}
|
||||
|
||||
Get-ChildItem $Files | ForEach-Object {
|
||||
Copy-Item -Path $_.FullName -Destination "$($TargetPath)\$($_.Name)"
|
||||
Write-Verbose "$ModuleName installed module file '$($_.Name)'"
|
||||
}
|
||||
|
||||
Write-Verbose "$ModuleName module installation successful"
|
||||
}
|
||||
Catch {
|
||||
throw "Failed installing the module '$ModuleName': $_"
|
||||
}
|
||||
}
|
||||
Robocopy . $fullPath /mir /XD .vscode .git examples testimonials images spikes /XF appveyor.yml .gitattributes .gitignore
|
||||
@@ -1,59 +1,72 @@
|
||||
function Join-Worksheet {
|
||||
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Combines data on all the sheets in an Excel worksheet onto a single sheet.
|
||||
.DESCRIPTION
|
||||
Join worksheet can work in two main ways:
|
||||
Either Combining data which has the same layout from many pages into one, or combining pages which have nothing in common.
|
||||
In the former case the header row is copied from the first sheet and, by default, each row of data is labelled with the name of the sheet it came from.
|
||||
In the latter case -NoHeader is specified, and each copied block can have the sheet it came from placed above it as a title.
|
||||
Join-Worksheet can work in two main ways, either
|
||||
Combining data which has the same layout from many pages into one, or
|
||||
combining pages which have nothing in common.
|
||||
In the former case the header row is copied from the first sheet and,
|
||||
by default, each row of data is labelled with the name of the sheet it came from.
|
||||
In the latter case -NoHeader is specified, and each copied block can have the
|
||||
sheet it came from placed above it as a title.
|
||||
.EXAMPLE
|
||||
foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
|
||||
Get-Service -ComputerName $computerName | Select-Object -Property Status, Name, DisplayName, StartType |
|
||||
>
|
||||
PS> foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
|
||||
Get-Service -ComputerName $computerName | Select-Object -Property Status, Name, DisplayName, StartType |
|
||||
Export-Excel -Path .\test.xlsx -WorkSheetname $computerName -AutoSize
|
||||
}
|
||||
$ptDef =New-PivotTableDefinition -PivotTableName "Pivot1" -SourceWorkSheet "Combined" -PivotRows "Status" -PivotFilter "MachineName" -PivotData @{Status='Count'} -IncludePivotChart -ChartType BarClustered3D
|
||||
Join-Worksheet -Path .\test.xlsx -WorkSheetName combined -FromLabel "MachineName" -HideSource -AutoSize -FreezeTopRow -BoldTopRow -PivotTableDefinition $pt -Show
|
||||
}
|
||||
PS> $ptDef =New-PivotTableDefinition -PivotTableName "Pivot1" -SourceWorkSheet "Combined" -PivotRows "Status" -PivotFilter "MachineName" -PivotData @{Status='Count'} -IncludePivotChart -ChartType BarClustered3D
|
||||
PS> Join-Worksheet -Path .\test.xlsx -WorkSheetName combined -FromLabel "MachineName" -HideSource -AutoSize -FreezeTopRow -BoldTopRow -PivotTableDefinition $pt -Show
|
||||
|
||||
The foreach command gets the services running on four servers and exports each to its own page in Test.xlsx.
|
||||
$PtDef= creates a defintion for a single Pivot table.
|
||||
The Join-Worksheet command uses the same file and merges the results onto a sheet named "Combined". It sets a column header of "Machinename",
|
||||
this column will contain the name of the sheet the data was copied from; after copying the data to the sheet "combined", the other sheets will be hidden.
|
||||
Join-Worksheet finishes by calling export-Excel to AutoSize cells, freeze the top row and make it bold and add the Pivot table.
|
||||
The foreach command gets the services running on four servers and exports each
|
||||
to its own page in Test.xlsx.
|
||||
$PtDef= creates a definition for a PivotTable.
|
||||
The Join-Worksheet command uses the same file and merges the results into a sheet
|
||||
named "Combined". It sets a column header of "Machinename", this column will
|
||||
contain the name of the sheet the data was copied from; after copying the data
|
||||
to the sheet "Combined", the other sheets will be hidden.
|
||||
Join-Worksheet finishes by calling Export-Excel to AutoSize cells, freeze the
|
||||
top row and make it bold and add thePivotTable.
|
||||
|
||||
.EXAMPLE
|
||||
Get-WmiObject -Class win32_logicaldisk | select -Property DeviceId,VolumeName, Size,Freespace |
|
||||
Export-Excel -Path "$env:computerName.xlsx" -WorkSheetname Volumes -NumberFormat "0,000"
|
||||
Get-NetAdapter | Select-Object Name,InterfaceDescription,MacAddress,LinkSpeed |
|
||||
Export-Excel -Path "$env:COMPUTERNAME.xlsx" -WorkSheetname NetAdapter
|
||||
Join-Worksheet -Path "$env:COMPUTERNAME.xlsx" -WorkSheetName Summary -Title "Summary" -TitleBold -TitleSize 22 -NoHeader -LabelBlocks -AutoSize -HideSource -show
|
||||
>
|
||||
PS> Get-WmiObject -Class win32_logicaldisk | Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
||||
Export-Excel -Path "$env:computerName.xlsx" -WorkSheetname Volumes -NumberFormat "0,000"
|
||||
PS> Get-NetAdapter | Select-Object Name,InterfaceDescription,MacAddress,LinkSpeed |
|
||||
Export-Excel -Path "$env:COMPUTERNAME.xlsx" -WorkSheetname NetAdapter
|
||||
PS> Join-Worksheet -Path "$env:COMPUTERNAME.xlsx" -WorkSheetName Summary -Title "Summary" -TitleBold -TitleSize 22 -NoHeader -LabelBlocks -AutoSize -HideSource -show
|
||||
|
||||
The first two command get logical disk and network card information; each type is exported to its own sheet in a workbook.
|
||||
The Join-worksheet command copies both onto a page named "Summary". Because the data is disimilar -NoHeader is specified, ensuring the whole of each page is copied.
|
||||
Specifying -LabelBlocks causes each sheet's name to become a title on the summary page above the copied data.
|
||||
The source data is hidden, a title is addded in 22 point boldface and the columns are sized to fit the data.
|
||||
The first two commands get logical-disk and network-card information; each type
|
||||
is exported to its own sheet in a workbook.
|
||||
The Join-Worksheet command copies both onto a page named "Summary". Because
|
||||
the data is dissimilar, -NoHeader is specified, ensuring the whole of each
|
||||
page is copied. Specifying -LabelBlocks causes each sheet's name to become
|
||||
a title on the summary page above the copied data. The source data is
|
||||
hidden, a title is added in 22 point boldface and the columns are sized
|
||||
to fit the data.
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
param (
|
||||
# Path to a new or existing .XLSX file.
|
||||
[Parameter(ParameterSetName = "Default", Position = 0)]
|
||||
[Parameter(ParameterSetName = "Table" , Position = 0)]
|
||||
[String]$Path ,
|
||||
# An object representing an Excel Package - usually this is returned by specifying -Passthru allowing multiple commands to work on the same Workbook without saving and reloading each time.
|
||||
# An object representing an Excel Package - either from Open-Excel Package or specifying -PassThru to Export-Excel.
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageDefault")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
# The name of a sheet within the workbook where the other sheets will be joined together - "Combined" by default.
|
||||
$WorkSheetName = 'Combined',
|
||||
# If specified any pre-existing target for the joined data will be deleted and re-created; otherwise data will be appended on this sheet.
|
||||
# If specified ,any pre-existing target for the joined data will be deleted and re-created; otherwise data will be appended on this sheet.
|
||||
[switch]$Clearsheet,
|
||||
#Join-Worksheet assumes each sheet has identical headers and the headers should be copied to the target sheet, unless -NoHeader is specified.
|
||||
[switch]$NoHeader,
|
||||
#If -NoHeader is NOT specified, then rows of data will be labeled with the name of the sheet they came, FromLabel is the header for this column. If it is null or empty, the labels will be omitted.
|
||||
$FromLabel = "From" ,
|
||||
#If -NoHeader is NOT specified, then rows of data will be labeled with the name of the sheet they came from. FromLabel is the header for this column. If it is null or empty, the labels will be omitted.
|
||||
[string]$FromLabel = "From" ,
|
||||
#If specified, the copied blocks of data will have the name of the sheet they were copied from inserted above them as a title.
|
||||
[switch]$LabelBlocks,
|
||||
#Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
|
||||
#Sets the width of the Excel columns to display all the data in their cells.
|
||||
[Switch]$AutoSize,
|
||||
#Freezes headers etc. in the top row.
|
||||
[Switch]$FreezeTopRow,
|
||||
@@ -63,30 +76,31 @@
|
||||
[Switch]$FreezeTopRowFirstColumn,
|
||||
# Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
|
||||
[Int[]]$FreezePane,
|
||||
#Enables the 'Filter' in Excel on the complete header row. So users can easily sort, filter and/or search the data in the select column from within Excel.
|
||||
#Enables the Excel filter on the headers of the combined sheet.
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'PackageDefault')]
|
||||
[Switch]$AutoFilter,
|
||||
#Makes the top Row boldface.
|
||||
#Makes the top row boldface.
|
||||
[Switch]$BoldTopRow,
|
||||
#If Specified hides the sheets that the data is copied from.
|
||||
#If specified, hides the sheets that the data is copied from.
|
||||
[switch]$HideSource,
|
||||
#Text of a title to be placed in Cell A1.
|
||||
[String]$Title,
|
||||
#Sets the fill pattern for the title cell.
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
|
||||
#Sets the cell background color for the title cell.
|
||||
[System.Drawing.Color]$TitleBackgroundColor,
|
||||
$TitleBackgroundColor,
|
||||
#Sets the title in boldface type.
|
||||
[Switch]$TitleBold,
|
||||
#Sets the point size for the title.
|
||||
[Int]$TitleSize = 22,
|
||||
#Hashtable(s) with Sheet PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values to specify a definition for one or more pivot table(s).
|
||||
#Hashtable(s) with Sheet PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values to specify a definition for one or morePivotTable(s).
|
||||
[Hashtable]$PivotTableDefinition,
|
||||
#A hashtable containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
|
||||
[Object[]]$ExcelChartDefinition,
|
||||
#One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
|
||||
[Object[]]$ConditionalFormat,
|
||||
#Applies a 'Conditional formatting rule' in Excel on all the cells. When specific conditions are met a rule is triggered.
|
||||
#Applies a Conditional formatting rule defined with New-ConditionalText. When specific conditions are met the format is applied
|
||||
[Object[]]$ConditionalText,
|
||||
#Makes each column a named range.
|
||||
[switch]$AutoNameRange,
|
||||
@@ -104,12 +118,13 @@
|
||||
})]
|
||||
[Parameter(ParameterSetName = 'Table' , Mandatory = $true)]
|
||||
[Parameter(ParameterSetName = 'PackageTable' , Mandatory = $true)]
|
||||
# Makes the data in the worksheet a table with a name applies a style to it. Name must not contain spaces.
|
||||
# Makes the data in the worksheet a table with a name and applies a style to it. Name must not contain spaces.
|
||||
[String]$TableName,
|
||||
[Parameter(ParameterSetName = 'Table')]
|
||||
[Parameter(ParameterSetName = 'PackageTable')]
|
||||
#Selects the style for the named table - defaults to "Medium6".
|
||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
||||
#Selects the style for the named table - defaults to 'Medium6'.
|
||||
#If specified, returns the range of cells in the combined sheet, in the format "A1:Z100".
|
||||
[switch]$ReturnRange,
|
||||
#Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
||||
[switch]$Show,
|
||||
@@ -134,6 +149,7 @@
|
||||
if ($TitleBold) {$destinationSheet.Cells[1, 1].Style.Font.Bold = $True }
|
||||
#Can only set TitleBackgroundColor if TitleFillPattern is something other than None.
|
||||
if ($TitleBackgroundColor -AND ($TitleFillPattern -ne 'None')) {
|
||||
if ($TitleBackgroundColor -is [string]) {$TitleBackgroundColor = [System.Drawing.Color]::$TitleBackgroundColor }
|
||||
$destinationSheet.Cells[1, 1].Style.Fill.PatternType = $TitleFillPattern
|
||||
$destinationSheet.Cells[1, 1].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
|
||||
}
|
||||
@@ -145,6 +161,7 @@
|
||||
#Assume every row has titles in row 1, copy row 1 from first sheet to new sheet.
|
||||
$destinationSheet.Select("A$row")
|
||||
$ExcelPackage.Workbook.Worksheets[1].cells["1:1"].Copy($destinationSheet.SelectedRange)
|
||||
#fromlabel can't be an empty string
|
||||
if ($FromLabel ) {
|
||||
#Add a column which says where the data comes from.
|
||||
$fromColumn = ($destinationSheet.Dimension.Columns + 1)
|
||||
|
||||
@@ -1,83 +1,103 @@
|
||||
Function Merge-Worksheet {
|
||||
<#
|
||||
.Synopsis
|
||||
Merges two worksheets (or other objects) into a single worksheet with differences marked up.
|
||||
Merges two Worksheets (or other objects) into a single Worksheet with differences marked up.
|
||||
.Description
|
||||
The Compare-Worksheet command takes two worksheets and marks differences in the source document, and optionally outputs a grid showing the changes.
|
||||
By contrast the Merge-Worksheet command takes the worksheets and combines them into a single sheet showing the old and new data side by side .
|
||||
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* worksheets, or a merge *to* worksheet.
|
||||
The Compare-Worksheet command takes two Worksheets and marks differences in the source document, and optionally outputs a grid showing the changes.
|
||||
By contrast the Merge-Worksheet command takes the Worksheets and combines them into a single sheet showing the old and new data side by side.
|
||||
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* Worksheets, or a merge *to* a Worksheet.
|
||||
.Example
|
||||
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -show
|
||||
The workbooks contain audit information for two servers, one page contains a list of services. This command creates a worksheet named 54-55
|
||||
in a workbook named services which shows all the services and their differences, and opens it in Excel.
|
||||
Merge-Worksheet "Server54.xlsx" "Server55.xlsx" -WorksheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -show
|
||||
The workbooks contain audit information for two servers, one sheet contains
|
||||
a list of services. This command creates a worksheet named "54-55" in a
|
||||
workbook named "services.xlsx" which shows all the services and their
|
||||
differences, and opens the new workbook in Excel.
|
||||
.Example
|
||||
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
|
||||
This modifies the previous command to hide the equal rows in the output sheet and changes the color used to mark rows added to the second file.
|
||||
Merge-Worksheet "Server54.xlsx" "Server55.xlsx" -WorksheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
|
||||
This modifies the previous command to hide the equal rows in the output
|
||||
sheet and changes the color used to mark rows added to the second file.
|
||||
.Example
|
||||
merge-worksheet -OutputFile .\j1.xlsx -OutputSheetName test11 -ReferenceObject (dir .\ImportExcel\4.0.7) -DifferenceObject (dir .\ImportExcel\4.0.8) -Property Length -Show
|
||||
Merge-Worksheet -OutputFile .\j1.xlsx -OutputSheetName test11 -ReferenceObject (dir .\ImportExcel\4.0.7) -DifferenceObject (dir .\ImportExcel\4.0.8) -Property Length -Show
|
||||
This version compares two directories, and marks what has changed.
|
||||
Because no "Key" property is given, "Name" is assumed to be the key and the only other property examined is length.
|
||||
Files which are added or deleted or have changed size will be highlighed in the output sheet. Changes to dates or other attributes will be ignored.
|
||||
Because no "Key" property is given, "Name" is assumed to be the key
|
||||
and the only other property examined is length. Files which are added
|
||||
or deleted or have changed size will be highlighed in the output sheet.
|
||||
Changes to dates or other attributes will be ignored.
|
||||
.Example
|
||||
merge-worksheet -RefO (dir .\ImportExcel\4.0.7) -DiffO (dir .\ImportExcel\4.0.8) -Pr Length | Out-GridView
|
||||
This time no file is written and the results -which include all properties, not just length, are output and sent to Out-Gridview.
|
||||
This version uses aliases to shorten the parameters,
|
||||
(OutputFileName can be "outFile" and the sheet "OutSheet" : DifferenceObject & ReferenceObject can be DiffObject & RefObject).
|
||||
Merge-Worksheet -RefO (dir .\ImportExcel\4.0.7) -DiffO (dir .\ImportExcel\4.0.8) -Pr Length | Out-GridView
|
||||
This time no file is written and the results - which include all properties,
|
||||
not just length, are output and sent to Out-Gridview. This version uses
|
||||
aliases to shorten the parameters, (OutputFileName can be "outFile" and
|
||||
the Sheet can be"OutSheet"; DifferenceObject & ReferenceObject can be
|
||||
DiffObject & RefObject respectively).
|
||||
#>
|
||||
[cmdletbinding(SupportsShouldProcess=$true)]
|
||||
Param(
|
||||
#First Excel file to compare. You can compare two Excel files or two other objects but not one of each.
|
||||
[parameter(ParameterSetName='A',Mandatory=$true,Position=0)]
|
||||
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)]
|
||||
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)]
|
||||
#First Excel file to compare. You can compare two Excel files or two other objects or a reference obhct against a difference file, but not a reference file against an object.
|
||||
[parameter(ParameterSetName='A',Mandatory=$true,Position=0)] #A = Compare two files default headers
|
||||
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)] #B = Compare two files user supplied headers
|
||||
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)] #C = Compare two files headers P1, P2, P3 etc
|
||||
$Referencefile ,
|
||||
|
||||
#Second Excel file to compare.
|
||||
[parameter(ParameterSetName='A',Mandatory=$true,Position=1)]
|
||||
[parameter(ParameterSetName='B',Mandatory=$true,Position=1)]
|
||||
[parameter(ParameterSetName='C',Mandatory=$true,Position=1)]
|
||||
[parameter(ParameterSetName='E',Mandatory=$true,Position=1)]
|
||||
[parameter(ParameterSetName='E',Mandatory=$true,Position=1)] #D Compare two objects; E = Compare one object one file that uses default headers
|
||||
[parameter(ParameterSetName='F',Mandatory=$true,Position=1)] #F = Compare one object one file that uses user supplied headers
|
||||
[parameter(ParameterSetName='G',Mandatory=$true,Position=1)] #G Compare one object one file that uses headers P1, P2, P3 etc
|
||||
$Differencefile ,
|
||||
|
||||
#Name(s) of worksheets to compare,
|
||||
[parameter(ParameterSetName='A',Position=2)]
|
||||
#Name(s) of Worksheets to compare.
|
||||
[parameter(ParameterSetName='A',Position=2)] #Applies to all sets EXCEPT D which is two objects (no sheets)
|
||||
[parameter(ParameterSetName='B',Position=2)]
|
||||
[parameter(ParameterSetName='C',Position=2)]
|
||||
[parameter(ParameterSetName='E',Position=2)]
|
||||
$WorkSheetName = "Sheet1",
|
||||
[parameter(ParameterSetName='F',Position=2)]
|
||||
[parameter(ParameterSetName='G',Position=2)]
|
||||
$WorksheetName = "Sheet1",
|
||||
|
||||
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
|
||||
[parameter(ParameterSetName='A')]
|
||||
[parameter(ParameterSetName='A')] #Applies to all sets EXCEPT D which is two objects (no sheets, so no start row )
|
||||
[parameter(ParameterSetName='B')]
|
||||
[parameter(ParameterSetName='C')]
|
||||
[parameter(ParameterSetName='E')]
|
||||
[parameter(ParameterSetName='F')]
|
||||
[parameter(ParameterSetName='G')]
|
||||
[int]$Startrow = 1,
|
||||
|
||||
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
|
||||
[Parameter(ParameterSetName='B',Mandatory=$true)]
|
||||
#Specifies custom property names to use, instead of the values defined in the column headers of the Start ROw.
|
||||
[Parameter(ParameterSetName='B',Mandatory=$true)] #Compare object + sheet or 2 sheets with user supplied headers
|
||||
[Parameter(ParameterSetName='F',Mandatory=$true)]
|
||||
[String[]]$Headername,
|
||||
|
||||
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
|
||||
[Parameter(ParameterSetName='C',Mandatory=$true)]
|
||||
#Automatically generate property names (P1, P2, P3, ..) instead of using the values the top row of the sheet.
|
||||
[Parameter(ParameterSetName='C',Mandatory=$true)] #Compare object + sheet or 2 sheets with headers of P1, P2, P3 ...
|
||||
[Parameter(ParameterSetName='G',Mandatory=$true)]
|
||||
[switch]$NoHeader,
|
||||
|
||||
#Object to compare if a worksheet is NOT being used.
|
||||
#Reference object to compare if a Worksheet is NOT being used. Reference object can combine with a difference sheet or difference object
|
||||
[parameter(ParameterSetName='D',Mandatory=$true)]
|
||||
[parameter(ParameterSetName='E',Mandatory=$true)]
|
||||
[parameter(ParameterSetName='F',Mandatory=$true)]
|
||||
[parameter(ParameterSetName='G',Mandatory=$true)]
|
||||
[Alias('RefObject')]
|
||||
$ReferenceObject ,
|
||||
#Object to compare if a worksheet is NOT being used.
|
||||
#Difference object to compare if a Worksheet is NOT being used for either half. Can't have a reference sheet and difference object.
|
||||
[parameter(ParameterSetName='D',Mandatory=$true,Position=1)]
|
||||
[Alias('DiffObject')]
|
||||
$DifferenceObject ,
|
||||
[parameter(ParameterSetName='D',Position=2)]
|
||||
[parameter(ParameterSetName='E',Position=3)]
|
||||
[parameter(ParameterSetName='E',Position=2)]
|
||||
[parameter(ParameterSetName='F',Position=2)]
|
||||
[parameter(ParameterSetName='G',Position=2)]
|
||||
#If there isn't a filename to use to label data from the "Difference" side, DiffPrefix is used, it defaults to "=>"
|
||||
$DiffPrefix = "=>" ,
|
||||
#File to hold merged data.
|
||||
[parameter(Position=3)]
|
||||
[Alias('OutFile')]
|
||||
$OutputFile ,
|
||||
#Name of worksheet to output - if none specified will use the reference worksheet name.
|
||||
#Name of Worksheet to output - if none specified will use the reference Worksheet name.
|
||||
[parameter(Position=4)]
|
||||
[Alias('OutSheet')]
|
||||
$OutputSheetName = "Sheet1",
|
||||
@@ -88,51 +108,54 @@
|
||||
#Name of a column which is unique used to pair up rows from the refence and difference side, default is "Name".
|
||||
$Key = "Name" ,
|
||||
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
|
||||
[System.Drawing.Color]$KeyFontColor = "DarkRed",
|
||||
$KeyFontColor = [System.Drawing.Color]::DarkRed ,
|
||||
#Sets the background color for changed rows.
|
||||
[System.Drawing.Color]$ChangeBackgroundColor = "Orange",
|
||||
$ChangeBackgroundColor = [System.Drawing.Color]::Orange,
|
||||
#Sets the background color for rows in the reference but deleted from the difference sheet.
|
||||
[System.Drawing.Color]$DeleteBackgroundColor = "LightPink",
|
||||
$DeleteBackgroundColor = [System.Drawing.Color]::LightPink,
|
||||
#Sets the background color for rows not in the reference but added to the difference sheet.
|
||||
[System.Drawing.Color]$AddBackgroundColor = "PaleGreen",
|
||||
#if Specified hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
|
||||
$AddBackgroundColor = [System.Drawing.Color]::PaleGreen,
|
||||
#if specified, hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
|
||||
[switch]$HideEqual ,
|
||||
#If specified outputs the data to the pipeline (you can add -whatif so it the command only outputs to the pipeline).
|
||||
#If specified, outputs the data to the pipeline (you can add -WhatIf so the command only outputs to the pipeline).
|
||||
[switch]$Passthru ,
|
||||
#If specified, opens the output workbook.
|
||||
[Switch]$Show
|
||||
)
|
||||
|
||||
#region Read Excel data
|
||||
if ($Referencefile -and $Differencefile) {
|
||||
if ($Differencefile -is [System.IO.FileInfo]) {$Differencefile = $Differencefile.FullName}
|
||||
if ($Referencefile -is [System.IO.FileInfo]) {$Referencefile = $Referencefile.FullName}
|
||||
if ($Referencefile -and $Differencefile) {
|
||||
#if the filenames don't resolve, give up now.
|
||||
try { $oneFile = ((Resolve-Path -Path $Referencefile -ErrorAction Stop).path -eq (Resolve-Path -Path $Differencefile -ErrorAction Stop).path)}
|
||||
Catch { Write-Warning -Message "Could not Resolve the filenames." ; return }
|
||||
|
||||
#If we have one file , we must have two different worksheet names. If we have two files $worksheetName can be a single string or two strings.
|
||||
if ($onefile -and ( ($WorkSheetName.count -ne 2) -or $WorkSheetName[0] -eq $WorkSheetName[1] ) ) {
|
||||
Write-Warning -Message "If both the Reference and difference file are the same then worksheet name must provide 2 different names"
|
||||
#If we have one file , we must have two different Worksheet names. If we have two files $WorksheetName can be a single string or two strings.
|
||||
if ($onefile -and ( ($WorksheetName.count -ne 2) -or $WorksheetName[0] -eq $WorksheetName[1] ) ) {
|
||||
Write-Warning -Message "If both the Reference and difference file are the same then Worksheet name must provide 2 different names"
|
||||
return
|
||||
}
|
||||
if ($WorkSheetName.count -eq 2) {$workSheet2 = $DiffPrefix = $WorkSheetName[1] ; $worksheet1 = $WorkSheetName[0] ; }
|
||||
elseif ($WorkSheetName -is [string]) {$worksheet2 = $workSheet1 = $WorkSheetName ;
|
||||
if ($WorksheetName.count -eq 2) {$Worksheet2 = $DiffPrefix = $WorksheetName[1] ; $Worksheet1 = $WorksheetName[0] ; }
|
||||
elseif ($WorksheetName -is [string]) {$Worksheet2 = $Worksheet1 = $WorksheetName ;
|
||||
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$","" }
|
||||
else {Write-Warning -Message "You must provide either a single worksheet name or two names." ; return }
|
||||
else {Write-Warning -Message "You must provide either a single Worksheet name or two names." ; return }
|
||||
|
||||
$params= @{ ErrorAction = [System.Management.Automation.ActionPreference]::Stop }
|
||||
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
||||
try {
|
||||
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
|
||||
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
|
||||
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $Worksheet1 @params
|
||||
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $Worksheet2 @Params
|
||||
}
|
||||
Catch {Write-Warning -Message "Could not read the worksheet from $Referencefile::$worksheet1 and/or $Differencefile::$worksheet2." ; return }
|
||||
Catch {Write-Warning -Message "Could not read the Worksheet from $Referencefile::$Worksheet1 and/or $Differencefile::$Worksheet2." ; return }
|
||||
if ($NoHeader) {$firstDataRow = $Startrow } else {$firstDataRow = $Startrow + 1}
|
||||
}
|
||||
elseif ( $Differencefile) {
|
||||
if ($WorkSheetName -isnot [string]) {Write-Warning -Message "You must provide a single worksheet name." ; return }
|
||||
$params = @{WorkSheetName=$WorkSheetName; Path=$Differencefile; ErrorAction = [System.Management.Automation.ActionPreference]::Stop ;}
|
||||
if ($WorksheetName -isnot [string]) {Write-Warning -Message "You must provide a single Worksheet name." ; return }
|
||||
$params = @{WorksheetName=$WorksheetName; Path=$Differencefile; ErrorAction=[System.Management.Automation.ActionPreference]::Stop }
|
||||
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
||||
try {$DifferenceObject = Import-Excel @Params }
|
||||
Catch {Write-Warning -Message "Could not read the worksheet '$WorkSheetName' from $Differencefile::$WorkSheetName." ; return }
|
||||
Catch {Write-Warning -Message "Could not read the Worksheet '$WorksheetName' from $Differencefile::$WorksheetName." ; return }
|
||||
if ($DiffPrefix -eq "=>" ) {
|
||||
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$",""
|
||||
}
|
||||
@@ -148,7 +171,7 @@
|
||||
$headings = $DifferenceObject[0].psobject.Properties.Name # This preserves the sequence - using get-member would sort them alphabetically! There may be extra properties in
|
||||
if ($NoHeader -and "Name" -eq $Key) {$Key = "p1"}
|
||||
if ($headings -notcontains $Key -and
|
||||
('*' -ne $Key)) {Write-Warning -Message "You need to specify one of the headings in the sheet '$worksheet1' as a key." ; return }
|
||||
('*' -ne $Key)) {Write-Warning -Message "You need to specify one of the headings in the sheet '$Worksheet1' as a key." ; return }
|
||||
foreach ($p in $Property) { $propList += ($headings.where({$_ -like $p}) )}
|
||||
foreach ($p in $ExcludeProperty) { $propList = $propList.where({$_ -notlike $p}) }
|
||||
if (($propList -notcontains $Key) -and
|
||||
@@ -198,19 +221,29 @@
|
||||
else {$Rowhash[$row.$key] = $rowNo }
|
||||
$rowNo ++
|
||||
}
|
||||
if ($DifferenceObject.count -gt $Rowhash.Keys.Count) {
|
||||
Write-Warning -Message "Difference object has $($DifferenceObject.Count) rows; but only $($Rowhash.keys.count) unique keys"
|
||||
}
|
||||
if ($Key -eq '*') {$key = "_ALL"}
|
||||
#endregion
|
||||
#We need to know all the properties we've met on the objects we've diffed
|
||||
$eDiffProps = [ordered]@{}
|
||||
#When we do a compare object changes will result in two rows so we group them and join them together.
|
||||
$expandedDiff = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $propList -PassThru -IncludeEqual |
|
||||
Group-Object -Property $key | ForEach-Object {
|
||||
#The value of the key column is the name of the group.
|
||||
#The value of the key column is the name of the Group.
|
||||
$keyval = $_.name
|
||||
#we're going to create a custom object from a hash table. ??Might no longer need to preserve the field order
|
||||
#we're going to create a custom object from a hash table.
|
||||
$hash = [ordered]@{}
|
||||
foreach ($result in $_.Group) {
|
||||
if ($result.SideIndicator -ne "=>") {$hash["_Row"] = $result._Row }
|
||||
elseif (-not $hash["$DiffPrefix Row"]) {$hash["_Row"] = "" }
|
||||
#if we have already set the side, be this must the second record, so set side to indicate "changed"
|
||||
if ($hash.Side) {$hash.Side = "<>"} else {$hash["Side"] = $result.SideIndicator}
|
||||
#if we have already set the side, this must be the second record, so set side to indicate "changed"; if we got two "Same" indicators we may have a classh of keys
|
||||
if ($hash.Side) {
|
||||
if ($hash.Side -eq $result.SideIndicator) {Write-Warning -Message "'$keyval' may be a duplicate."}
|
||||
$hash.Side = "<>"
|
||||
}
|
||||
else {$hash["Side"] = $result.SideIndicator}
|
||||
switch ($hash.side) {
|
||||
'==' { $hash["$DiffPrefix is"] = 'Same' }
|
||||
'=>' { $hash["$DiffPrefix is"] = 'Added' }
|
||||
@@ -223,7 +256,7 @@
|
||||
}
|
||||
'<=' { $hash["$DiffPrefix is"] = 'Removed'}
|
||||
}
|
||||
#find the number of the row in the the "difference" object which has this key. If it is the object is only the reference this will be blank.
|
||||
#find the number of the row in the the "difference" object which has this key. If it is the object is only in the reference this will be blank.
|
||||
$hash["$DiffPrefix Row"] = $Rowhash[$keyval]
|
||||
$hash[$key] = $keyval
|
||||
#Create FieldName and/or =>FieldName columns
|
||||
@@ -235,6 +268,8 @@
|
||||
elseif ($result.SideIndicator -eq "=>") { $hash[("$DiffPrefix $p")] = $result.$P}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($k in $hash.keys) {$eDiffProps[$k] = $true}
|
||||
[Pscustomobject]$hash
|
||||
} | Sort-Object -Property "_row"
|
||||
|
||||
@@ -245,35 +280,35 @@
|
||||
$expandedDiff = $expandedDiff | Sort-Object -Property "$DiffPrefix Row"
|
||||
for ($i = 1; $i -lt $expandedDiff.Count; $i++) {if (-not $expandedDiff[$i]."_Row") {$expandedDiff[$i]."_Row" = $expandedDiff[$i-1]."_Row" } }
|
||||
|
||||
$AllProps = @("_Row") + $OutputProps + $expandedDiff[0].psobject.properties.name.where({$_ -notin ($outputProps + @("_row","side","SideIndicator","_ALL" ))})
|
||||
$AllProps = @("_Row") + $OutputProps + $eDiffProps.keys.where({$_ -notin ($outputProps + @("_row","side","SideIndicator","_ALL" ))})
|
||||
|
||||
if ($PassThru -or -not $OutputFile) {return ($expandedDiff | Select-Object -Property $allprops | Sort-Object -Property "_row", "$DiffPrefix Row" | Update-FirstObjectProperties ) }
|
||||
if ($PassThru -or -not $OutputFile) {return ($expandedDiff | Select-Object -Property $allprops | Sort-Object -Property "_row", "$DiffPrefix Row" ) }
|
||||
elseif ($PSCmdlet.ShouldProcess($OutputFile,"Write Output to Excel file")) {
|
||||
$expandedDiff = $expandedDiff | Sort-Object -Property "_row", "$DiffPrefix Row"
|
||||
$xl = $expandedDiff | Select-Object -Property $OutputProps | Update-FirstObjectProperties |
|
||||
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
|
||||
Export-Excel -Path $OutputFile -Worksheetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
|
||||
$ws = $xl.Workbook.Worksheets[$OutputSheetName]
|
||||
for ($i = 0; $i -lt $expandedDiff.Count; $i++ ) {
|
||||
if ( $expandedDiff[$i].side -ne "==" ) {
|
||||
Set-Format -WorkSheet $ws -Range ("A" + ($i + 2 )) -FontColor $KeyFontColor
|
||||
Set-ExcelRange -Worksheet $ws -Range ("A" + ($i + 2 )) -FontColor $KeyFontColor
|
||||
}
|
||||
elseif ( $HideEqual ) {$ws.row($i+2).hidden = $true }
|
||||
if ( $expandedDiff[$i].side -eq "<>" ) {
|
||||
$range = $ws.Dimension -replace "\d+", ($i + 2 )
|
||||
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
|
||||
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
|
||||
}
|
||||
elseif ( $expandedDiff[$i].side -eq "<=" ) {
|
||||
$rangeR1C1 = "R[{0}]C[1]:R[{0}]C[{1}]" -f ($i + 2 ) , $lastRefColNo
|
||||
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
||||
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
|
||||
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
|
||||
}
|
||||
elseif ( $expandedDiff[$i].side -eq "=>" ) {
|
||||
if ($propList.count -gt 1) {
|
||||
$rangeR1C1 = "R[{0}]C[{1}]:R[{0}]C[{2}]" -f ($i + 2 ) , $FirstDiffColNo , $lastDiffColNo
|
||||
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
||||
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $AddBackgroundColor
|
||||
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $AddBackgroundColor
|
||||
}
|
||||
Set-Format -WorkSheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
|
||||
Set-ExcelRange -Worksheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
|
||||
}
|
||||
}
|
||||
Close-ExcelPackage -ExcelPackage $xl -Show:$Show
|
||||
@@ -281,84 +316,104 @@
|
||||
}
|
||||
|
||||
Function Merge-MultipleSheets {
|
||||
[cmdletbinding()]
|
||||
[Alias("Merge-MulipleSheets")]
|
||||
<#
|
||||
.Synopsis
|
||||
Merges worksheets into a single worksheet with differences marked up.
|
||||
Merges Worksheets into a single Worksheet with differences marked up.
|
||||
.Description
|
||||
The Merge worksheet command combines 2 sheets. Merge-MultipleSheets is designed to merge more than 2.
|
||||
So if asked to merge sheets A,B,C which contain Services, with a Name, Displayname and Start mode, where "name" is treated as the key
|
||||
Merge-MultipleSheets calls Merge-Worksheet to merge Name, Displayname and Start mode, from sheets A and C
|
||||
the result has column headings -Row, Name, DisplayName, Startmode, C-DisplayName, C-StartMode C-Is, C-Row
|
||||
Merge-MultipleSheets then calls Merge-Worsheet with this result and sheet B, comparing 'Name', 'Displayname' and 'Start mode' columns on each side
|
||||
which outputs _Row, Name, DisplayName, Startmode, B-DisplayName, B-StartMode B-Is, B-Row, C-DisplayName, C-StartMode C-Is, C-Row
|
||||
Any columns in the "reference" side which are not used in the comparison are appended on the right, which is we compare the sheets in reverse order.
|
||||
The Merge Worksheet command combines two sheets. Merge-MultipleSheets is
|
||||
designed to merge more than two. So if asked to merge sheets A,B,C which
|
||||
contain Services, with a Name, Displayname and Start mode, where "Name" is
|
||||
treated as the key, Merge-MultipleSheets calls Merge-Worksheet to merge
|
||||
"Name", "Displayname" and "Startmode" from sheets A and C; the result has
|
||||
column headings "_Row", "Name", "DisplayName", "Startmode", "C-DisplayName",
|
||||
"C-StartMode", "C-Is" and "C-Row".
|
||||
Merge-MultipleSheets then calls Merge-Worksheet again passing it the
|
||||
intermediate result and sheet B, comparing "Name", "Displayname" and
|
||||
"Start mode" columns on each side, and gets a result with columns "_Row",
|
||||
"Name", "DisplayName", "Startmode", "B-DisplayName", "B-StartMode", "B-Is",
|
||||
"B-Row", "C-DisplayName", "C-StartMode", "C-Is" and "C-Row". Any columns on
|
||||
the "reference" side which are not used in the comparison are added on the
|
||||
right, which is why we compare the sheets in reverse order.
|
||||
|
||||
The "Is" column holds "Same", "Added", "Removed" or "Changed" and is used for conditional formatting in the output sheet (this is hidden by default),
|
||||
and when the data is written to Excel the "reference" columns, in this case "DisplayName" and "Start" are renamed to reflect their source,
|
||||
so become "A-DisplayName" and "A-Start".
|
||||
The "Is" columns hold "Same", "Added", "Removed" or "Changed" and is used for
|
||||
conditional formatting in the output sheet (these columns are hidden by default),
|
||||
and when the data is written to Excel the "reference" columns, in this case
|
||||
"DisplayName" and "Start" are renamed to reflect their source, so become
|
||||
"A-DisplayName" and "A-Start".
|
||||
|
||||
Conditional formatting is also applied to the "key" column (name in this case) so the view can be filtered to rows with changes by filtering this column on color.
|
||||
Conditional formatting is also applied to the Key column ("Name" in this
|
||||
case) so the view can be filtered to rows with changes by filtering this
|
||||
column on color.
|
||||
|
||||
Note: the processing order can affect what is seen as a change. For example if there is an extra item in sheet B in the example above,
|
||||
Sheet C will be processed and that row and will not be seen to be missing. When sheet B is processed it is marked as an addition, and the conditional formatting marks
|
||||
the entries from sheet A to show that a values were added in at least one sheet.
|
||||
However if Sheet B is the reference sheet, A and C will be seen to have an item removed;
|
||||
and if B is processed before C, the extra item is known when C is processed and so C is considered to be missing that item.
|
||||
Note: the processing order can affect what is seen as a change. For example
|
||||
if there is an extra item in sheet B in the example above, Sheet C will be
|
||||
processed and that row and will not be seen to be missing. When sheet B is
|
||||
processed it is marked as an addition, and the conditional formatting marks
|
||||
the entries from sheet A to show that a values were added in at least one
|
||||
sheet. However if Sheet B is the reference sheet, A and C will be seen to
|
||||
have an item removed; and if B is processed before C, the extra item is
|
||||
known when C is processed and so C is considered to be missing that item.
|
||||
.Example
|
||||
dir Server*.xlsx | Merge-MulipleSheets -WorkSheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
|
||||
We are auditing servers and each one has a workbook in the current directory which contains a "Services" worksheet (the result of
|
||||
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode
|
||||
No key is specified so the key is assumed to be the "Name" column. The files are merged and the result is opened on completion.
|
||||
dir Server*.xlsx | Merge-MulipleSheets -WorksheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
|
||||
Here we are auditing servers and each one has a workbook in the current
|
||||
directory which contains a "Services" Worksheet (the result of
|
||||
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode)
|
||||
No key is specified so the key is assumed to be the "Name" column.
|
||||
The files are merged and the result is opened on completion.
|
||||
.Example
|
||||
dir Serv*.xlsx | Merge-MulipleSheets -WorkSheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
|
||||
The server audit files in the previous example also have "Software" worksheet, but no single field on that sheet works as a key.
|
||||
Specifying "*" for the key produces a compound key using all non-excluded fields (and the installation date and file location are excluded).
|
||||
dir Serv*.xlsx | Merge-MulipleSheets -WorksheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
|
||||
The server audit files in the previous example also have "Software" worksheet,
|
||||
but no single field on that sheet works as a key. Specifying "*" for the key
|
||||
produces a compound key using all non-excluded fields (and the installation
|
||||
date and file location are excluded).
|
||||
.Example
|
||||
Merge-MulipleSheets -Path hotfixes.xlsx -WorkSheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
|
||||
This time all the servers have written their hofix information to their own worksheets in a shared Excel workbook named "Hotfixes"
|
||||
(the information was obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
|
||||
This ignores any sheets which are not named "Serv*", and uses the HotfixID as the key ; in this version the row numbers are hidden.
|
||||
Merge-MulipleSheets -Path hotfixes.xlsx -WorksheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
|
||||
This time all the servers have written their hotfix information to their own
|
||||
worksheets in a shared Excel workbook named "Hotfixes.xlsx" (the information was
|
||||
obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
|
||||
This ignores any sheets which are not named "Serv*", and uses the HotfixID as
|
||||
the key; in this version the row numbers are hidden.
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
#[Alias("Merge-MulipleSheets")] #There was a spelling error in the first release. This was there to ensure things didn't break but intelisense gave the alias first.
|
||||
param (
|
||||
#Paths to the files to be merged. Files are also accepted
|
||||
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
|
||||
[string[]]$Path ,
|
||||
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
|
||||
$Path ,
|
||||
#The row from where we start to import data, all rows above the Start row are disregarded. By default this is the first row.
|
||||
[int]$Startrow = 1,
|
||||
|
||||
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
|
||||
#Specifies custom property names to use, instead of the values defined in the column headers of the Start row.
|
||||
[String[]]$Headername,
|
||||
|
||||
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
|
||||
#If specified, property names will be automatically generated (P1, P2, P3, ..) instead of using the values from the start row.
|
||||
[switch]$NoHeader,
|
||||
|
||||
#Name(s) of worksheets to compare,
|
||||
$WorkSheetName = "Sheet1",
|
||||
#File to write output to
|
||||
#Name(s) of Worksheets to compare.
|
||||
$WorksheetName = "Sheet1",
|
||||
#File to write output to.
|
||||
[Alias('OutFile')]
|
||||
$OutputFile = ".\temp.xlsx",
|
||||
#Name of worksheet to output - if none specified will use the reference worksheet name.
|
||||
#Name of Worksheet to output - if none specified will use the reference Worksheet name.
|
||||
[Alias('OutSheet')]
|
||||
$OutputSheetName = "Sheet1",
|
||||
#Properties to include in the DIFF - supports wildcards, default is "*".
|
||||
#Properties to include in the comparison - supports wildcards, default is "*".
|
||||
$Property = "*" ,
|
||||
#Properties to exclude from the the search - supports wildcards.
|
||||
#Properties to exclude from the the comparison - supports wildcards.
|
||||
$ExcludeProperty ,
|
||||
#Name of a column which is unique used to pair up rows from the refence and difference side, default is "Name".
|
||||
#Name of a column which is unique used to pair up rows from the reference and difference sides, default is "Name".
|
||||
$Key = "Name" ,
|
||||
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
|
||||
[System.Drawing.Color]$KeyFontColor = "Red",
|
||||
#Sets the font color for the Key field; this means you can filter by color to get only changed rows.
|
||||
$KeyFontColor = [System.Drawing.Color]::Red,
|
||||
#Sets the background color for changed rows.
|
||||
[System.Drawing.Color]$ChangeBackgroundColor = "Orange",
|
||||
$ChangeBackgroundColor = [System.Drawing.Color]::Orange,
|
||||
#Sets the background color for rows in the reference but deleted from the difference sheet.
|
||||
[System.Drawing.Color]$DeleteBackgroundColor = "LightPink",
|
||||
$DeleteBackgroundColor = [System.Drawing.Color]::LightPink,
|
||||
#Sets the background color for rows not in the reference but added to the difference sheet.
|
||||
[System.Drawing.Color]$AddBackgroundColor = "Orange",
|
||||
#if Specified hides the columns in the spreadsheet that contain the row numbers
|
||||
$AddBackgroundColor = [System.Drawing.Color]::Orange,
|
||||
#If specified, hides the columns in the spreadsheet that contain the row numbers.
|
||||
[switch]$HideRowNumbers ,
|
||||
#If specified outputs the data to the pipeline (you can add -whatif so it the command only outputs to the command)
|
||||
#If specified, outputs the data to the pipeline (you can add -whatif so it the command only outputs to the pipeline).
|
||||
[switch]$Passthru ,
|
||||
#If specified, opens the output workbook.
|
||||
[Switch]$Show
|
||||
@@ -366,50 +421,51 @@ Function Merge-MultipleSheets {
|
||||
begin { $filestoProcess = @() }
|
||||
process { $filestoProcess += $Path}
|
||||
end {
|
||||
if ($filestoProcess.Count -eq 1 -and $WorkSheetName -match '\*') {
|
||||
if ($filestoProcess.Count -eq 1 -and $WorksheetName -match '\*') {
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Expanding * to names of sheets in $($filestoProcess[0]). "
|
||||
$excel = Open-ExcelPackage -Path $filestoProcess
|
||||
$WorksheetName = $excel.Workbook.Worksheets.Name.where({$_ -like $WorkSheetName})
|
||||
$WorksheetName = $excel.Workbook.Worksheets.Name.where({$_ -like $WorksheetName})
|
||||
Close-ExcelPackage -NoSave -ExcelPackage $excel
|
||||
}
|
||||
|
||||
#Merge indentically named sheets in different work books;
|
||||
if ($filestoProcess.Count -ge 2 -and $WorkSheetName -is "string" ) {
|
||||
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorkSheetName' -ErrorAction SilentlyContinue |
|
||||
#Merge identically named sheets in different work books;
|
||||
if ($filestoProcess.Count -ge 2 -and $WorksheetName -is "string" ) {
|
||||
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorksheetName' -ErrorAction SilentlyContinue |
|
||||
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
|
||||
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($filestoProcess[-1]) against $($filestoProcess[0]). "
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "comparing '$WorksheetName' in $($filestoProcess[-1]) against $($filestoProcess[0]). "
|
||||
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[-1]
|
||||
$nextFileNo = 2
|
||||
while ($nextFileNo -lt $filestoProcess.count -and $merged) {
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($filestoProcess[-$nextFileNo]) against $($filestoProcess[0]). "
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "comparing '$WorksheetName' in $($filestoProcess[-$nextFileNo]) against $($filestoProcess[0]). "
|
||||
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[-$nextFileNo]
|
||||
$nextFileNo ++
|
||||
|
||||
}
|
||||
}
|
||||
#Merge different sheets from one workbook
|
||||
elseif ($filestoProcess.Count -eq 1 -and $WorkSheetName.Count -ge 2 ) {
|
||||
elseif ($filestoProcess.Count -eq 1 -and $WorksheetName.Count -ge 2 ) {
|
||||
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty' -ErrorAction SilentlyContinue |
|
||||
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
|
||||
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-1]) against $($WorkSheetName[0]). "
|
||||
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[0] -WorkSheetName $WorkSheetName[0,-1]
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorksheetName[-1]) against $($WorksheetName[0]). "
|
||||
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[0,-1]
|
||||
$nextSheetNo = 2
|
||||
while ($nextSheetNo -lt $WorkSheetName.count -and $merged) {
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-$nextSheetNo]) against $($WorkSheetName[0]). "
|
||||
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[0] -WorkSheetName $WorkSheetName[-$nextSheetNo] -DiffPrefix $WorkSheetName[-$nextSheetNo]
|
||||
while ($nextSheetNo -lt $WorksheetName.count -and $merged) {
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorksheetName[-$nextSheetNo]) against $($WorksheetName[0]). "
|
||||
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[-$nextSheetNo] -DiffPrefix $WorksheetName[-$nextSheetNo]
|
||||
$nextSheetNo ++
|
||||
}
|
||||
}
|
||||
#We either need one worksheet name and many files or one file and many sheets.
|
||||
#We either need one Worksheet name and many files or one file and many sheets.
|
||||
else { Write-Warning -Message "Need at least two files to process" ; return }
|
||||
#if the process didn't return data then abandon now.
|
||||
if (-not $merged) {Write-Warning -Message "The merge operation did not return any data."; return }
|
||||
|
||||
$orderByProperties = $merged[0].psobject.properties.where({$_.name -match "row$"}).name
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Creating output sheet '$OutputSheetName' in $OutputFile"
|
||||
$excel = $merged | Sort-Object -Property $orderByProperties | Update-FirstObjectProperties |
|
||||
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "creating output sheet '$OutputSheetName' in $OutputFile"
|
||||
$excel = $merged | Sort-Object -Property $orderByProperties |
|
||||
Export-Excel -Path $OutputFile -Worksheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
|
||||
$sheet = $excel.Workbook.Worksheets[$OutputSheetName]
|
||||
|
||||
#We will put in a conditional format for "if all the others are not flagged as 'same'" to mark rows where something is added, removed or changed
|
||||
@@ -423,8 +479,8 @@ Function Merge-MultipleSheets {
|
||||
if ($filesToProcess.Count -ge 2) {
|
||||
$refPrefix = (Split-Path -Path $filestoProcess[0] -Leaf) -replace "\.xlsx$"," "
|
||||
}
|
||||
else {$refPrefix = $WorkSheetName[0] }
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Applying formatting to sheet '$OutputSheetName' in $OutputFile"
|
||||
else {$refPrefix = $WorksheetName[0] }
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "applying formatting to sheet '$OutputSheetName' in $OutputFile"
|
||||
#Find the column headings which are in the form "diffFile is"; which will hold 'Same', 'Added' or 'Changed'
|
||||
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -match "\sIS$"}) ) {
|
||||
#Work leftwards across the headings applying conditional formatting which says
|
||||
@@ -433,7 +489,7 @@ Function Merge-MultipleSheets {
|
||||
$columnNo = $cell.start.Column -1
|
||||
$cellAddr = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R1C$columnNo",1,$columnNo)
|
||||
while ($sheet.cells[$cellAddr].value -match $prefix) {
|
||||
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='None'; WorkSheet=$sheet; Range=$([OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[1]C[$columnNo]:R[1048576]C[$columnNo]",0,0)) }
|
||||
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='Solid'; Worksheet=$sheet; StopIfTrue=$true; Range=$([OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[1]C[$columnNo]:R[1048576]C[$columnNo]",0,0)) }
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Added"' ) -BackgroundColor $AddBackgroundColor
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Changed"') -BackgroundColor $ChangeBackgroundColor
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Removed"') -BackgroundColor $DeleteBackgroundColor
|
||||
@@ -449,15 +505,16 @@ Function Merge-MultipleSheets {
|
||||
$nameRegex = $colNames -Join '|'
|
||||
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -Notmatch $nameRegex}) ) {
|
||||
$cell.Value = $refPrefix + $cell.Value
|
||||
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='None'; WorkSheet=$sheet; Range=[OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[2]C[$($cell.start.column)]:R[1048576]C[$($cell.start.column)]",0,0)}
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("OR(" +(($sameChecks -join ",") -replace '<>"Same"','="Added"') +")" ) -BackgroundColor $DeleteBackgroundColor
|
||||
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='Solid'; Worksheet=$sheet; StopIfTrue=$true; Range=[OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[2]C[$($cell.start.column)]:R[1048576]C[$($cell.start.column)]",0,0)}
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("OR(" +(($sameChecks -join ",") -replace '<>"Same"','="Added"' ) +")" ) -BackgroundColor $DeleteBackgroundColor
|
||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("AND(" +(($sameChecks -join ",") -replace '<>"Same"','="Changed"') +")" ) -BackgroundColor $ChangeBackgroundColor
|
||||
}
|
||||
#We've made a bunch of things wider so now is the time to autofit columns. Any hiding has to come AFTER this, because it unhides things
|
||||
$sheet.Cells.AutoFitColumns()
|
||||
|
||||
#if we have a key field (we didn't concatenate all fields) use what we built up in $sameChecks to apply conditional formatting to it (Row no will be in column A, Key in Column B)
|
||||
if ($Key -ne '*') {
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "B2:B1048576" -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ("OR(" +($sameChecks -join ",") +")" )
|
||||
Add-ConditionalFormatting -Worksheet $sheet -Range "B2:B1048576" -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ("OR(" +($sameChecks -join ",") +")" )
|
||||
$sheet.view.FreezePanes(2, 3)
|
||||
}
|
||||
else {$sheet.view.FreezePanes(2, 2) }
|
||||
@@ -472,8 +529,8 @@ Function Merge-MultipleSheets {
|
||||
$sheet.Column($cell.start.Column).HIDDEN = $true
|
||||
}
|
||||
}
|
||||
|
||||
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
|
||||
if ($Passthru) {$excel}
|
||||
else {Close-ExcelPackage -ExcelPackage $excel -Show:$Show}
|
||||
Write-Progress -Activity "Merging sheets" -Completed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
function New-ConditionalFormattingIconSet {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates an object which describes a conditional formatting rule a for 3,4 or 5 icon set.
|
||||
.DESCRIPTION
|
||||
Export-Excel takes a -ConditionalFormat parameter which can hold one or more descriptions for conditional formats;
|
||||
this command builds the defintion of a Conditional formatting rule for an icon set.
|
||||
.PARAMETER Range
|
||||
The range of cells that the conditional format applies to.
|
||||
.PARAMETER ConditionalFormat
|
||||
The type of rule: one of "ThreeIconSet","FourIconSet" or "FiveIconSet"
|
||||
.PARAMETER IconType
|
||||
The name of an iconSet - different icons are available depending on whether 3,4 or 5 icon set is selected.
|
||||
.PARAMETER Reverse
|
||||
Use the icons in the reverse order.
|
||||
.Example
|
||||
$cfRange = [OfficeOpenXml.ExcelAddress]::new($topRow, $column, $lastDataRow, $column)
|
||||
$cfdef = New-ConditionalFormattingIconSet -Range $cfrange -ConditionalFormat ThreeIconSet -IconType Arrows
|
||||
Export-Excel -ExcelPackage $excel -ConditionalFormat $cfdef -show
|
||||
|
||||
The first line creates a range - one column wide in the column $column, running
|
||||
from $topRow to $lastDataRow.
|
||||
The second line creates a definition object using this range
|
||||
and the third uses Export-Excel with an open package to apply the format and
|
||||
save and open the file.
|
||||
.Link
|
||||
Add-Add-ConditionalFormatting
|
||||
New-ConditionalText
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Range,
|
||||
|
||||
@@ -1,35 +1,84 @@
|
||||
function New-ConditionalText {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates an object which describes a conditional formatting rule for single valued rules.
|
||||
.DESCRIPTION
|
||||
Some Conditional formatting rules don't apply styles to a cell (IconSets and Databars).
|
||||
Some take two parameters (Between).
|
||||
Some take none (ThisWeek, ContainsErrors, AboveAverage etc).
|
||||
The others take a single parameter (Top, BottomPercent, GreaterThan, Contains etc).
|
||||
This command creates an object to describe the last two categories, which can then be passed to Export-Excel.
|
||||
.PARAMETER Range
|
||||
The range of cells that the conditional format applies to; if none is specified the range will be apply to all the data in the sheet.
|
||||
.PARAMETER ConditionalType
|
||||
One of the supported rules; by default "ContainsText" is selected.
|
||||
.PARAMETER Text
|
||||
The text (or other value) to use in the rule. Note that Equals, GreaterThan/LessThan rules require text to wrapped in double quotes.
|
||||
.PARAMETER ConditionalTextColor
|
||||
The font color for the cell - by default: "DarkRed".
|
||||
.PARAMETER BackgroundColor
|
||||
The fill color for the cell - by default: "LightPink".
|
||||
.PARAMETER PatternType
|
||||
The background pattern for the cell - by default: "Solid"
|
||||
.EXAMPLE
|
||||
>
|
||||
$ct = New-ConditionalText -Text 'Ferrari'
|
||||
Export-Excel -ExcelPackage $excel -ConditionalTest $ct -show
|
||||
|
||||
The first line creates a definition object which will highlight the word
|
||||
"Ferrari" in any cell. and the second uses Export-Excel with an open package
|
||||
to apply the format and save and open the file.
|
||||
.EXAMPLE
|
||||
>
|
||||
$ct = New-ConditionalText -Text "Ferrari"
|
||||
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalTextColor Red -BackgroundColor White
|
||||
Export-Excel -ExcelPackage $excel -ConditionalText $ct,$ct2 -show
|
||||
|
||||
This builds on the previous example, and specifies a condition of <=3 with
|
||||
a format of red text on a white background; this applies to a named range
|
||||
"Finish Position". The range could be written "C:C" to specify a named
|
||||
column, or "C2:C102" to specify certain cells in the column.
|
||||
.Link
|
||||
Add-Add-ConditionalFormatting
|
||||
New-ConditionalFormattingIconSet
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
#[Parameter(Mandatory=$true)]
|
||||
[Alias("ConditionValue")]
|
||||
$Text,
|
||||
[System.Drawing.Color]$ConditionalTextColor="DarkRed",
|
||||
[System.Drawing.Color]$BackgroundColor="LightPink",
|
||||
[Alias("ForeGroundColor")]
|
||||
$ConditionalTextColor=[System.Drawing.Color]::DarkRed,
|
||||
$BackgroundColor=[System.Drawing.Color]::LightPink,
|
||||
[String]$Range,
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$PatternType=[OfficeOpenXml.Style.ExcelFillStyle]::Solid,
|
||||
[ValidateSet(
|
||||
"LessThan","LessThanOrEqual","GreaterThan","GreaterThanOrEqual",
|
||||
"NotEqual","Equal","ContainsText","NotContainsText","BeginsWith","EndsWith",
|
||||
"Last7Days","LastMonth","LastWeek",
|
||||
"NextMonth","NextWeek",
|
||||
"ThisMonth","ThisWeek",
|
||||
"Today","Tomorrow","Yesterday",
|
||||
"DuplicateValues",
|
||||
"AboveOrEqualAverage","BelowAverage","AboveAverage",
|
||||
"Top", "TopPercent", "ContainsBlanks"
|
||||
"LessThan", "LessThanOrEqual", "GreaterThan", "GreaterThanOrEqual",
|
||||
"Equal", "NotEqual",
|
||||
"Top", "TopPercent", "Bottom", "BottomPercent",
|
||||
"ContainsText", "NotContainsText", "BeginsWith", "EndsWith",
|
||||
"ContainsBlanks", "NotContainsBlanks", "ContainsErrors", "NotContainsErrors",
|
||||
"DuplicateValues", "UniqueValues",
|
||||
"Tomorrow", "Today", "Yesterday", "Last7Days",
|
||||
"NextWeek", "ThisWeek", "LastWeek",
|
||||
"NextMonth", "ThisMonth", "LastMonth",
|
||||
"AboveAverage", "AboveOrEqualAverage", "BelowAverage", "BelowOrEqualAverage"
|
||||
)]
|
||||
[Alias("RuleType")]
|
||||
$ConditionalType="ContainsText"
|
||||
)
|
||||
|
||||
$obj = [PSCustomObject]@{
|
||||
Text = $Text
|
||||
ConditionalTextColor = $ConditionalTextColor
|
||||
ConditionalType = $ConditionalType
|
||||
PatternType = $PatternType
|
||||
ConditionalType = $ConditionalType
|
||||
PatternType = $PatternType
|
||||
Range = $Range
|
||||
BackgroundColor = $BackgroundColor
|
||||
BackgroundColor = $BackgroundColor
|
||||
}
|
||||
|
||||
$obj.pstypenames.Clear()
|
||||
$obj.pstypenames.Add("ConditionalText")
|
||||
$obj
|
||||
$obj
|
||||
}
|
||||
@@ -1,6 +1,102 @@
|
||||
function New-ExcelChartDefinition {
|
||||
[cmdletbinding()]
|
||||
function New-ExcelChartDefinition {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a Definition of a chart which can be added using Export-Excel, or Add-PivotTable
|
||||
.DESCRIPTION
|
||||
All the parameters which are passed to Add-ExcelChart can be added to an object and
|
||||
passed to Export-Excel with the -ExcelChartDefinition parameter,
|
||||
or to Add-PivotTable with the -PivotChartDefinition parameter.
|
||||
This command sets up those definitions.
|
||||
.PARAMETER Title
|
||||
The title for the chart.
|
||||
.PARAMETER TitleBold
|
||||
Sets the title in bold face.
|
||||
.PARAMETER TitleSize
|
||||
Sets the point size for the title.
|
||||
.PARAMETER ChartType
|
||||
One of the built-in chart types, such as Pie, ClusteredColumn, Line etc. Defaults to "ColumnStacked".
|
||||
.PARAMETER XRange
|
||||
The range of cells containing values for the X-Axis - usually labels.
|
||||
.PARAMETER YRange
|
||||
The range(s) of cells holding values for the Y-Axis - usually "data".
|
||||
.PARAMETER Width
|
||||
Width of the chart in pixels. Defaults to 500.
|
||||
.PARAMETER Height
|
||||
Height of the chart in pixels. Defaults to 350.
|
||||
.PARAMETER Row
|
||||
Row position of the top left corner of the chart. 0 places at the top of the sheet, 1 below row 1 and so on.
|
||||
.PARAMETER RowOffSetPixels
|
||||
Offset to position the chart by a fraction of a row.
|
||||
.PARAMETER Column
|
||||
Column position of the top left corner of the chart. 0 places at the edge of the sheet 1 to the right of column A and so on.
|
||||
.PARAMETER ColumnOffSetPixels
|
||||
Offset to position the chart by a fraction of a column.
|
||||
.PARAMETER NoLegend
|
||||
If specified, turns off display of the key. If you only have one data series it may be preferable to use the title to say what the chart is.
|
||||
.PARAMETER SeriesHeader
|
||||
Specifies explicit name(s) for the data series, which will appear in the legend/key
|
||||
.PARAMETER LegendPosition
|
||||
Location of the key, either "Left", "Right", "Top", "Bottom" or "TopRight".
|
||||
.PARAMETER LegendSize
|
||||
Font size for the key.
|
||||
.PARAMETER LegendBold
|
||||
Sets the key in bold type.
|
||||
.PARAMETER ShowCategory
|
||||
Attaches a category label in charts which support this.
|
||||
.PARAMETER ShowPercent
|
||||
Attaches a percentage label in charts which support this.
|
||||
.PARAMETER XAxisTitleText
|
||||
Specifies a title for the X-axis.
|
||||
.PARAMETER XAxisTitleBold
|
||||
Sets the X-axis title in bold face.
|
||||
.PARAMETER XAxisTitleSize
|
||||
Sets the font size for the axis title.
|
||||
.PARAMETER XAxisNumberformat
|
||||
A number formatting string, like "#,##0.00", for numbers along the X-axis.
|
||||
.PARAMETER XMajorUnit
|
||||
Spacing for the major gridlines / tick marks along the X-axis.
|
||||
.PARAMETER XMinorUnit
|
||||
Spacing for the minor gridlines / tick marks along the X-axis.
|
||||
.PARAMETER XMaxValue
|
||||
Maximum value for the scale along the X-axis.
|
||||
.PARAMETER XMinValue
|
||||
Minimum value for the scale along the X-axis.
|
||||
.PARAMETER xAxisPosition
|
||||
Position for the X-axis ("Top" or" Bottom").
|
||||
.PARAMETER YAxisTitleText
|
||||
Specifies a title for the Y-axis.
|
||||
.PARAMETER YAxisTitleBold
|
||||
Sets the Y-axis title in bold face.
|
||||
.PARAMETER YAxisTitleSize
|
||||
Sets the font size for the Y-axis title.
|
||||
.PARAMETER YAxisNumberformat
|
||||
A number formatting string, like "#,##0.00", for numbers on the Y-axis
|
||||
.PARAMETER YMajorUnit
|
||||
Spacing for the major gridlines / tick marks on the Y-axis.
|
||||
.PARAMETER YMinorUnit
|
||||
Spacing for the minor gridlines / tick marks on the Y-axis.
|
||||
.PARAMETER YMaxValue
|
||||
Maximum value on the Y-axis.
|
||||
.PARAMETER YMinValue
|
||||
Minimum value on the Y-axis.
|
||||
.PARAMETER YAxisPosition
|
||||
Position for the Y-axis ("Left" or "Right").
|
||||
.PARAMETER Header
|
||||
No longer used. This may be removed in future versions.
|
||||
.Example
|
||||
>
|
||||
PS> $cDef = New-ExcelChartDefinition -ChartType line -XRange "X" -YRange "Sinx" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
|
||||
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
|
||||
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
|
||||
-SeriesHeader "Sin(x)" -LegendSize 8 -legendBold -LegendPosition Bottom
|
||||
|
||||
0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -now -WorkSheetname SinX -ExcelChartDefinition $cDef -Show
|
||||
|
||||
This reworks an example from Add-Excel-Chart but here the chart is defined
|
||||
and the defintion stored in $cDef and then Export-Excel uses $cDef .
|
||||
#>
|
||||
[Alias("New-ExcelChart")] #This was the former name. The new name reflects that we are defining a chart, not making one in the workbook.
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
$Title = "Chart Title",
|
||||
$Header,
|
||||
@@ -13,8 +109,9 @@ function New-ExcelChartDefinition {
|
||||
$RowOffSetPixels = 10,
|
||||
$Column = 6,
|
||||
$ColumnOffSetPixels = 5,
|
||||
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
|
||||
$LegendSize,
|
||||
[Switch]$legendBold,
|
||||
[Switch]$LegendBold,
|
||||
[Switch]$NoLegend,
|
||||
[Switch]$ShowCategory,
|
||||
[Switch]$ShowPercent,
|
||||
@@ -53,12 +150,15 @@ function New-ExcelChartDefinition {
|
||||
RowOffSetPixels = $RowOffSetPixels
|
||||
Column = $Column
|
||||
ColumnOffSetPixels = $ColumnOffSetPixels
|
||||
LegendPosition = $LegendPosition
|
||||
LegendSize = $LegendSize
|
||||
Legendbold = $LegendBold
|
||||
NoLegend = $NoLegend -as [Boolean]
|
||||
ShowCategory = $ShowCategory -as [Boolean]
|
||||
ShowPercent = $ShowPercent -as [Boolean]
|
||||
SeriesHeader = $SeriesHeader
|
||||
TitleBold = $TitleBold -as [Boolean]
|
||||
TitleSize = $TitleSize
|
||||
SeriesHeader = $SeriesHeader
|
||||
XAxisTitleText = $XAxisTitleText
|
||||
XAxisTitleBold = $XAxisTitleBold -as [Boolean]
|
||||
XAxisTitleSize = $XAxisTitleSize
|
||||
@@ -78,4 +178,280 @@ function New-ExcelChartDefinition {
|
||||
YMinValue = $YMinValue
|
||||
YAxisPosition = $YAxisPosition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Add-ExcelChart {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Creates a chart in an existing Excel worksheet.
|
||||
.DESCRIPTION
|
||||
Creates a chart. It is possible to configure the type of chart, the range of X values (labels) and Y values.
|
||||
the title, the legend, the ranges for both axes, the format and position of the axes.
|
||||
Normally the command does not return anything, but if -passthru is specified the chart is returned so that it can be customized.
|
||||
.PARAMETER Worksheet
|
||||
An existing Sheet where the chart will be created.
|
||||
.PARAMETER Title
|
||||
The title for the chart.
|
||||
.PARAMETER TitleBold
|
||||
Sets the title in bold face.
|
||||
.PARAMETER TitleSize
|
||||
Sets the point size for the title.
|
||||
.PARAMETER ChartType
|
||||
One of the built-in chart types, such as Pie, ClusteredColumn, Line etc. Defaults to "ColumnStacked".
|
||||
.PARAMETER XRange
|
||||
The range of cells containing values for the X-Axis - usually labels.
|
||||
.PARAMETER YRange
|
||||
The range(s) of cells holding values for the Y-Axis - usually "data".
|
||||
.PARAMETER PivotTable
|
||||
Instead of specify X and Y ranges, get data from a PivotTable by passing a PivotTable Object.
|
||||
.PARAMETER Width
|
||||
Width of the chart in Pixels. Defaults to 500.
|
||||
.PARAMETER Height
|
||||
Height of the chart in Pixels. Defaults to 350.
|
||||
.PARAMETER Row
|
||||
Row position of the top left corner of the chart. 0 places at the top of the sheet, 1 below row 1 and so on.
|
||||
.PARAMETER RowOffSetPixels
|
||||
Offset to position the chart by a fraction of a row.
|
||||
.PARAMETER Column
|
||||
Column position of the top left corner of the chart. 0 places at the edge of the sheet 1 to the right of column A and so on.
|
||||
.PARAMETER ColumnOffSetPixels
|
||||
Offset to position the chart by a fraction of a column.
|
||||
.PARAMETER NoLegend
|
||||
If specified, turns of display of the key. If you only have one data series it may be preferable to use the title to say what the chart is.
|
||||
.PARAMETER SeriesHeader
|
||||
Specify explicit name(s) for the data series, which will appear in the legend/key. The contents of a cell can be specified in the from =Sheet9!Z10 .
|
||||
.PARAMETER LegendPosition
|
||||
Location of the key, either left, right, top, bottom or TopRight.
|
||||
.PARAMETER LegendSize
|
||||
Font size for the key.
|
||||
.PARAMETER LegendBold
|
||||
Sets the key in bold type.
|
||||
.PARAMETER ShowCategory
|
||||
Attaches a category label in charts which support this.
|
||||
.PARAMETER ShowPercent
|
||||
Attaches a percentage label in charts which support this.
|
||||
.PARAMETER XAxisTitleText
|
||||
Specifies a title for the X-axis.
|
||||
.PARAMETER XAxisTitleBold
|
||||
Sets the X-axis title in bold face.
|
||||
.PARAMETER XAxisTitleSize
|
||||
Sets the font size for the axis title.
|
||||
.PARAMETER XAxisNumberformat
|
||||
A number formatting string, like "#,##0.00", for numbers along the X-axis.
|
||||
.PARAMETER XMajorUnit
|
||||
Spacing for the major gridlines / tick marks along the X-axis.
|
||||
.PARAMETER XMinorUnit
|
||||
Spacing for the minor gridlines / tick marks along the X-axis.
|
||||
.PARAMETER XMaxValue
|
||||
Maximum value for the scale along the X-axis.
|
||||
.PARAMETER XMinValue
|
||||
Minimum value for the scale along the X-axis.
|
||||
.PARAMETER xAxisPosition
|
||||
Position for the X-axis (Top or Bottom).
|
||||
.PARAMETER YAxisTitleText
|
||||
Specifies a title for the Y-axis.
|
||||
.PARAMETER YAxisTitleBold
|
||||
Sets the Y-axis title in bold face.
|
||||
.PARAMETER YAxisTitleSize
|
||||
Sets the font size for the Y-axis title
|
||||
.PARAMETER YAxisNumberformat
|
||||
A number formatting string, like "#,##0.00", for numbers on the Y-axis.
|
||||
.PARAMETER YMajorUnit
|
||||
Spacing for the major gridlines / tick marks on the Y-axis.
|
||||
.PARAMETER YMinorUnit
|
||||
Spacing for the minor gridlines / tick marks on the Y-axis.
|
||||
.PARAMETER YMaxValue
|
||||
Maximum value on the Y-axis.
|
||||
.PARAMETER YMinValue
|
||||
Minimum value on the Y-axis.
|
||||
.PARAMETER YAxisPosition
|
||||
Position for the Y-axis (Left or Right).
|
||||
.PARAMETER PassThru
|
||||
Add-Excel chart doesn't normally return anything, but if -PassThru is specified it returns the newly created chart to allow it to be fine tuned.
|
||||
.EXAMPLE
|
||||
>
|
||||
PS> $Excel = ConvertFrom-Csv @"
|
||||
Product, City, Sales
|
||||
Apple, London , 300
|
||||
Orange, London , 400
|
||||
Banana, London , 300
|
||||
Orange, Paris, 600
|
||||
Banana, Paris, 300
|
||||
Apple, New York, 1200
|
||||
"@ | Export-Excel -Path test.xlsx -PassThru
|
||||
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -ChartType "Doughnut" -XRange "A2:B7" -YRange "C2:C7" -width 500
|
||||
Close-ExcelPackage -Show $Excel
|
||||
|
||||
The first command expands a multi-line string into 6 rows of data which is exported to new Excel file; leaving an ExcelPackage object in $excel
|
||||
The second command adds a chart - the cell ranges are explicitly specified. Note that the XRange (labels) is TWO columns wide and the chart will
|
||||
combine the name of the product and the name of the City to create the label.
|
||||
The width of the chart is set explictly, the default legend is used and there is no Chart title.
|
||||
.EXAMPLE
|
||||
>
|
||||
PS> $Excel = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize | Export-Excel $path -AutoSize -ExcelChartDefinition $c -AutoNameRange -PassThru
|
||||
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -Title "VM use" -ChartType PieExploded3D -XRange "Name" -YRange "VirtualMemorySize" -NoLegend -ShowCategory
|
||||
Close-ExcelPackage $Excel -Show
|
||||
|
||||
The first line exports information and creates named ranges for each column.
|
||||
The Second line uses the ranges to specify a chart - the labels come from the range "Name" and the data from the range "VirtualMemorySize"
|
||||
The chart is specified as a 3D exploded PIE chart, with a title of "VM Use" and instead of a legend the the pie slices are identified with a label.
|
||||
.EXAMPLE
|
||||
>
|
||||
PS> $Excel = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize | Export-Excel test.xlsx -TableName Processes -PassThru
|
||||
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -Title Stats -ChartType LineMarkersStacked -XRange "Processes[Name]" -YRange "Processes[PM]", "Processes[VirtualMemorySize]" -SeriesHeader 'PM', 'VMSize'
|
||||
Close-ExcelPackage $Excel -Show
|
||||
|
||||
The first line exports information to a table in new file; and captures the excel Package object in $Excel
|
||||
The second line creates a chart on the first page of the work sheet, using the notation "TableName[ColumnnName]" to refer to the data,
|
||||
the labels come Name column in the table, and the data series from its PM and VirtualMemorySize columns. The display names for these in the header are set to PM and VMSize
|
||||
.EXAMPLE
|
||||
>
|
||||
PS> $excel = 0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path Text.xlsx -WorkSheetname SinX -PassThru
|
||||
Add-ExcelChart -Worksheet $excel.Workbook.Worksheets["Sinx"] -ChartType line -XRange "X" -YRange "Sinx" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
|
||||
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
|
||||
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
|
||||
-SeriesHeader "Sin(x)" -LegendSize 8 -legendBold -LegendPosition Bottom
|
||||
Close-ExcelPackage $Excel -Show
|
||||
|
||||
The first line puts numbers from 0 to 360 into a sheet, as the first column, and
|
||||
a formula to calculate the Sine of that number of number of degrees in the second column.
|
||||
It creates named-ranges for the two columns - "X" and "SinX" respectively
|
||||
The Add-ExcelChart command adds a chart to that worksheet, specifying a line chart
|
||||
with the X values coming from named-range "X" and the Y values coming from named-range "SinX".
|
||||
The chart has a title, and is positioned to the right of column 2 and sized 800 pixels wide
|
||||
The X-axis is labelled "Degrees", in bold 12 point type and runs from 0 to 361 with labels every 30,
|
||||
and minor tick marks every 10. Degrees are shown padded to 3 digits.
|
||||
The Y-axis is labelled "Sine" and to allow some room above and below its scale runs from -1.25 to 1.25,
|
||||
and is marked off in units of 0.25 shown to two decimal places.
|
||||
The key will for the chart will be at the bottom in 8 point bold type and the line will be named "Sin(x)".
|
||||
#>
|
||||
[cmdletbinding(DefaultParameterSetName='Worksheet')]
|
||||
[OutputType([OfficeOpenXml.Drawing.Chart.ExcelChart])]
|
||||
param(
|
||||
[Parameter(ParameterSetName='Workshet',Mandatory=$true)]
|
||||
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
|
||||
[Parameter(ParameterSetName='PivotTable',Mandatory=$true)]
|
||||
[OfficeOpenXml.Table.PivotTable.ExcelPivotTable]$PivotTable ,
|
||||
[String]$Title,
|
||||
#$Header, Not used but referenced previously
|
||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
|
||||
$XRange,
|
||||
$YRange,
|
||||
[int]$Width = 500,
|
||||
[int]$Height = 350,
|
||||
[int]$Row = 0,
|
||||
[int]$RowOffSetPixels = 10,
|
||||
[int]$Column = 6,
|
||||
[int]$ColumnOffSetPixels = 5,
|
||||
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
|
||||
$LegendSize,
|
||||
[Switch]$LegendBold,
|
||||
[Switch]$NoLegend,
|
||||
[Switch]$ShowCategory,
|
||||
[Switch]$ShowPercent,
|
||||
[String[]]$SeriesHeader,
|
||||
[Switch]$TitleBold,
|
||||
[Int]$TitleSize ,
|
||||
[String]$XAxisTitleText,
|
||||
[Switch]$XAxisTitleBold,
|
||||
$XAxisTitleSize ,
|
||||
[string]$XAxisNumberformat,
|
||||
$XMajorUnit,
|
||||
$XMinorUnit,
|
||||
$XMaxValue,
|
||||
$XMinValue,
|
||||
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$XAxisPosition ,
|
||||
[String]$YAxisTitleText,
|
||||
[Switch]$YAxisTitleBold,
|
||||
$YAxisTitleSize,
|
||||
[string]$YAxisNumberformat,
|
||||
$YMajorUnit,
|
||||
$YMinorUnit,
|
||||
$YMaxValue,
|
||||
$YMinValue,
|
||||
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition,
|
||||
[Switch]$PassThru
|
||||
)
|
||||
try {
|
||||
if ($PivotTable) {
|
||||
$Worksheet = $PivotTable.WorkSheet
|
||||
$chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ),$ChartType,$PivotTable)
|
||||
}
|
||||
else {
|
||||
$ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', ''
|
||||
$chart = $Worksheet.Drawings.AddChart($ChartName, $ChartType)
|
||||
$chartDefCount = @($YRange).Count
|
||||
if ($chartDefCount -eq 1) {
|
||||
$Series = $chart.Series.Add($YRange, $XRange)
|
||||
if ($SeriesHeader) { $Series.Header = $SeriesHeader}
|
||||
else { $Series.Header = 'Series 1'}
|
||||
}
|
||||
else {
|
||||
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
|
||||
if ($Yrange.count -eq $xrange.count) {
|
||||
$Series = $chart.Series.Add($YRange[$idx], $XRange[$idx])
|
||||
}
|
||||
else {
|
||||
$Series = $chart.Series.Add($YRange[$idx], $XRange)
|
||||
}
|
||||
if ($SeriesHeader.Count -gt 0) {
|
||||
if ($SeriesHeader[$idx] -match '^=') {$Series.HeaderAddress = $SeriesHeader[$idx] -replace '^=',''}
|
||||
else {$Series.Header = $SeriesHeader[$idx] }
|
||||
}
|
||||
else { $Series.Header = "Series $($idx)"}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Title) {
|
||||
$chart.Title.Text = $Title
|
||||
if ($TitleBold) {$chart.Title.Font.Bold = $true}
|
||||
if ($TitleSize) {$chart.Title.Font.Size = $TitleSize}
|
||||
}
|
||||
if ($NoLegend) { $chart.Legend.Remove() }
|
||||
else {
|
||||
if ($PSBoundParameters.ContainsKey('LegendPosition')) {$chart.Legend.Position = $LegendPosition}
|
||||
if ($PSBoundParameters.ContainsKey('LegendBold')) {$chart.Legend.Font.Bold = [boolean]$LegendBold}
|
||||
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
|
||||
}
|
||||
|
||||
if ($XAxisTitleText) {
|
||||
$chart.XAxis.Title.Text = $XAxisTitleText
|
||||
if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) {
|
||||
$chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold
|
||||
}
|
||||
if ($XAxisTitleSize) {$chart.XAxis.Title.Font.Size = $XAxisTitleSize}
|
||||
}
|
||||
if ($XAxisPosition) {Write-Warning "X-axis position is not being set propertly at the moment, parameter ignored" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
|
||||
if ($XMajorUnit) {$chart.XAxis.MajorUnit = $XMajorUnit}
|
||||
if ($XMinorUnit) {$chart.XAxis.MinorUnit = $XMinorUnit}
|
||||
if ($null -ne $XMinValue) {$chart.XAxis.MinValue = $XMinValue}
|
||||
if ($null -ne $XMaxValue) {$chart.XAxis.MaxValue = $XMaxValue}
|
||||
if ($XAxisNumberformat) {$chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat)}
|
||||
|
||||
if ($YAxisTitleText) {
|
||||
$chart.YAxis.Title.Text = $YAxisTitleText
|
||||
if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) {
|
||||
$chart.YAxis.Title.Font.Bold = [boolean]$YAxisTitleBold
|
||||
}
|
||||
if ($YAxisTitleSize) {$chart.YAxis.Title.Font.Size = $YAxisTitleSize}
|
||||
}
|
||||
if ($YAxisPosition) {Write-Warning "Y-axis position is not being set propertly at the moment, parameter ignored" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
|
||||
if ($YMajorUnit) {$chart.YAxis.MajorUnit = $YMajorUnit}
|
||||
if ($YMinorUnit) {$chart.YAxis.MinorUnit = $YMinorUnit}
|
||||
if ($null -ne $YMinValue){$chart.YAxis.MinValue = $YMinValue}
|
||||
if ($null -ne $YMaxValue){$chart.YAxis.MaxValue = $YMaxValue}
|
||||
if ($YAxisNumberformat) {$chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat)}
|
||||
if ($null -ne $chart.Datalabel) {
|
||||
$chart.Datalabel.ShowCategory = [boolean]$ShowCategory
|
||||
$chart.Datalabel.ShowPercent = [boolean]$ShowPercent
|
||||
}
|
||||
|
||||
$chart.SetPosition($Row, $RowOffsetPixels, $Column, $ColumnOffsetPixels)
|
||||
$chart.SetSize($Width, $Height)
|
||||
|
||||
if ($PassThru) {return $chart}
|
||||
}
|
||||
catch {Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_"}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,44 @@
|
||||
Function Open-ExcelPackage {
|
||||
<#
|
||||
.Synopsis
|
||||
Returns an Excel Package Object with for the specified XLSX ile
|
||||
Returns an ExcelPackage object for the specified XLSX fil.e
|
||||
.Description
|
||||
Import-Excel and Export-Excel open an Excel file, carry out their tasks and close it again.
|
||||
Sometimes it is necessary to open a file and do other work on it.
|
||||
Open-ExcelPackage allows the file to be opened for these tasks.
|
||||
It takes a -KillExcel switch to make sure Excel is not holding the file open;
|
||||
a -Password parameter for existing protected files,
|
||||
and a -Create switch to set-up a new file if no file already exists.
|
||||
.Example
|
||||
$excel = Open-ExcelPackage -path $xlPath
|
||||
>
|
||||
PS> $excel = Open-ExcelPackage -Path "$env:TEMP\test99.xlsx" -Create
|
||||
$ws = Add-WorkSheet -ExcelPackage $excel
|
||||
|
||||
This will create a new file in the temp folder if it doesn't already exist.
|
||||
It then adds a worksheet - because no name is specified it will use the
|
||||
default name of "Sheet1"
|
||||
.Example
|
||||
>
|
||||
PS> $excel = Open-ExcelPackage -path "$xlPath" -Password $password
|
||||
$sheet1 = $excel.Workbook.Worksheets["sheet1"]
|
||||
Set-Format -Address $sheet1.Cells["E1:S1048576"], $sheet1.Cells["V1:V1048576"] -NFormat ([cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern)
|
||||
Set-ExcelRange -Range $sheet1.Cells["E1:S1048576"], $sheet1.Cells["V1:V1048576"] -NFormat ([cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern)
|
||||
Close-ExcelPackage $excel -Show
|
||||
|
||||
This will open the file at $xlPath, select sheet1 apply formatting to two blocks of the sheet and save the package, and launch it in Excel.
|
||||
This will open the password protected file at $xlPath using the password stored
|
||||
in $Password. Sheet1 is selected and formatting applied to two blocks of the sheet;
|
||||
then the file is and saved and loaded into Excel.
|
||||
#>
|
||||
[CmdLetBinding()]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
||||
[OutputType([OfficeOpenXml.ExcelPackage])]
|
||||
Param (
|
||||
#The Path to the file to open
|
||||
#The path to the file to open.
|
||||
[Parameter(Mandatory=$true)]$Path,
|
||||
#If specified, any running instances of Excel will be terminated before opening the file.
|
||||
[switch]$KillExcel,
|
||||
#By default open only opens an existing file; -Create instructs it to create a new file if required.
|
||||
#The password for a protected worksheet, as a [normal] string (not a secure string).
|
||||
[String]$Password,
|
||||
#By default Open-ExcelPackage will only opens an existing file; -Create instructs it to create a new file if required.
|
||||
[switch]$Create
|
||||
)
|
||||
|
||||
@@ -27,7 +49,7 @@
|
||||
|
||||
$Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
|
||||
#If -Create was not specified only open the file if it exists already (send a warning if it doesn't exist).
|
||||
if ($Create) {
|
||||
if ($Create -and -not (Test-Path -Path $path)) {
|
||||
#Create the directory if required.
|
||||
$targetPath = Split-Path -Parent -Path $Path
|
||||
if (!(Test-Path -Path $targetPath)) {
|
||||
@@ -36,32 +58,72 @@
|
||||
}
|
||||
New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path
|
||||
}
|
||||
elseif (Test-Path -Path $path) {New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path }
|
||||
elseif (Test-Path -Path $path) {
|
||||
if ($Password) {$pkgobj = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path , $Password }
|
||||
else {$pkgobj = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Path }
|
||||
if ($pkgobj) {
|
||||
foreach ($w in $pkgobj.Workbook.Worksheets) {
|
||||
$sb = [scriptblock]::Create(('$this.workbook.Worksheets["{0}"]' -f $w.name))
|
||||
Add-Member -InputObject $pkgobj -MemberType ScriptProperty -Name $w.name -Value $sb
|
||||
}
|
||||
return $pkgobj
|
||||
}
|
||||
}
|
||||
else {Write-Warning "Could not find $path" }
|
||||
}
|
||||
|
||||
Function Close-ExcelPackage {
|
||||
<#
|
||||
.Synopsis
|
||||
Closes an Excel Package, saving, saving under a new name or abandoning changes and opening the file in Excel as required.
|
||||
#>
|
||||
<#
|
||||
.Synopsis
|
||||
Closes an Excel Package, saving, saving under a new name or abandoning changes and opening the file in Excel as required.
|
||||
.Description
|
||||
When working with an ExcelPackage object, the Workbook is held in memory and not saved until the .Save() method of the package is called.
|
||||
Close-ExcelPackage saves and disposes of the Package object. It can be called with -NoSave to abandon the file without saving, with a new "SaveAs" filename,
|
||||
and/or with a password to protect the file. And -Show will open the file in Excel;
|
||||
-Calculate will try to update the workbook, although not everything can be recalculated
|
||||
.Example
|
||||
Close-ExcelPackage -show $excel
|
||||
$excel holds a package object, this saves the workbook and loads it into Excel.
|
||||
.Example
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
$excel holds a package object, this disposes of it without writing it to disk.
|
||||
#>
|
||||
[CmdLetBinding()]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
||||
Param (
|
||||
#File to close.
|
||||
#Package to close.
|
||||
[parameter(Mandatory=$true, ValueFromPipeline=$true)]
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
#Open the file.
|
||||
#Open the file in Excel.
|
||||
[switch]$Show,
|
||||
#Abandon the file without saving.
|
||||
[Switch]$NoSave,
|
||||
#Save file with a new name (ignored if -NoSave Specified).
|
||||
$SaveAs
|
||||
$SaveAs,
|
||||
#Password to protect the file.
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$Password,
|
||||
#Attempt to recalculation the workbook before saving
|
||||
[switch]$Calculate
|
||||
)
|
||||
if ( $NoSave) {$ExcelPackage.Dispose()}
|
||||
else {
|
||||
if ($SaveAs) {$ExcelPackage.SaveAs( $SaveAs ) }
|
||||
Else {$ExcelPackage.Save(); $SaveAs = $ExcelPackage.File.FullName }
|
||||
if ($Calculate) {
|
||||
try { [OfficeOpenXml.CalculationExtension]::Calculate($ExcelPackage.Workbook) }
|
||||
Catch { Write-Warning "One or more errors occured while calculating, save will continue, but there may be errors in the workbook."}
|
||||
}
|
||||
if ($SaveAs) {
|
||||
$SaveAs = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($SaveAs)
|
||||
if ($Password) {$ExcelPackage.SaveAs( $SaveAs, $Password ) }
|
||||
else {$ExcelPackage.SaveAs( $SaveAs)}
|
||||
}
|
||||
Else {
|
||||
if ($Password) {$ExcelPackage.Save($Password) }
|
||||
else {$ExcelPackage.Save() }
|
||||
$SaveAs = $ExcelPackage.File.FullName
|
||||
}
|
||||
$ExcelPackage.Dispose()
|
||||
if ($show) {Start-Process -FilePath $SaveAs }
|
||||
if ($Show) {Start-Process -FilePath $SaveAs }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
338
PivotTable.ps1
Normal file
338
PivotTable.ps1
Normal file
@@ -0,0 +1,338 @@
|
||||
function Add-PivotTable {
|
||||
<#
|
||||
.Synopsis
|
||||
Adds a PivotTable (and optional PivotChart) to a workbook.
|
||||
.Description
|
||||
If the PivotTable already exists, the source data will be updated.
|
||||
.Example
|
||||
>
|
||||
PS> $excel = Get-Service | Export-Excel -Path test.xlsx -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -TableName ServiceTable -Title "Services on $Env:COMPUTERNAME"
|
||||
Add-PivotTable -ExcelPackage $excel -PivotTableName ServiceSummary -SourceRange $excel.Workbook.Worksheets[1].Tables[0].Address -PivotRows Status -PivotData Name -NoTotalsInPivot -Activate
|
||||
Close-ExcelPackage $excel -Show
|
||||
|
||||
This exports data to new workbook and creates a table with the data in.
|
||||
The Pivot table is added on its own page, the table created in the first command is used as the source for the PivotTable; which counts the service names in for each Status. At the end the Pivot page is made active.
|
||||
.Example
|
||||
>
|
||||
PS> $chartdef = New-ExcelChartDefinition -Title "Gross and net by city and product" -ChartType ColumnClustered `
|
||||
-Column 11 -Width 500 -Height 360 -YMajorUnit 500 -YMinorUnit 100 -YAxisNumberformat "$#,##0" -LegendPosition Bottom
|
||||
|
||||
$excel = ConvertFrom-Csv @"
|
||||
Product, City, Gross, Net
|
||||
Apple, London , 300, 250
|
||||
Orange, London , 400, 350
|
||||
Banana, London , 300, 200
|
||||
Orange, Paris, 600, 500
|
||||
Banana, Paris, 300, 200
|
||||
Apple, New York, 1200,700
|
||||
"@ | Export-Excel -Path "test.xlsx" -TableStyle Medium13 -tablename "RawData" -PassThru
|
||||
|
||||
Add-PivotTable -PivotTableName Sales -Address $excel.Workbook.Worksheets[1].Cells["F1"] `
|
||||
-SourceWorkSheet $excel.Workbook.Worksheets[1] -PivotRows City -PivotColumns Product -PivotData @{Gross="Sum";Net="Sum"} `
|
||||
-PivotNumberFormat "$#,##0.00" -PivotTotals Both -PivotTableStyle Medium12 -PivotChartDefinition $chartdef
|
||||
Close-ExcelPackage -show $excel
|
||||
|
||||
|
||||
This script starts by defining a chart. Then it exports some data to an XLSX file and keeps the file open.
|
||||
The next step is to add the pivot table, normally this would be on its own sheet in the workbook,
|
||||
but here -Address is specified to place it beside the data. The Add-Pivot table is given the chart definition and told to create a tale
|
||||
using the City field to create rows, the Product field to create columns and the data should be the sum of the gross field and the sum of the net field;
|
||||
grand totals for both gross and net are included for rows (Cities) and columns (product) and the data is explicitly formatted as a currency.
|
||||
Not that in the chart definition the number format for the axis does not include any fraction part.
|
||||
#>
|
||||
[cmdletbinding(defaultParameterSetName='ChartbyParams')]
|
||||
[OutputType([OfficeOpenXml.Table.PivotTable.ExcelPivotTable])]
|
||||
param (
|
||||
#Name for the new PivotTable - this will be the name of a sheet in the Workbook.
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$PivotTableName,
|
||||
#By default, a PivotTable will be created on its own sheet, but it can be created on an existing sheet by giving the address where the top left corner of the table should go. (Allow two rows for the filter if one is used.)
|
||||
[OfficeOpenXml.ExcelAddressBase]
|
||||
$Address,
|
||||
#An excel package object for the workbook.
|
||||
$ExcelPackage,
|
||||
#Worksheet where the data is found.
|
||||
$SourceWorkSheet,
|
||||
#Address range in the worksheet e.g "A10:F20" - the first row must be column names: if not specified the whole sheet will be used.
|
||||
$SourceRange,
|
||||
#Fields to set as rows in the PivotTable.
|
||||
$PivotRows,
|
||||
#A hash table in form "FieldName"="Function", where function is one of
|
||||
#Average, Count, CountNums, Max, Min, Product, None, StdDev, StdDevP, Sum, Var, VarP.
|
||||
$PivotData,
|
||||
#Fields to set as columns in the PivotTable.
|
||||
$PivotColumns,
|
||||
#Fields to use to filter in the PivotTable.
|
||||
$PivotFilter,
|
||||
#If there are multiple data items in a PivotTable, by default they are shown on separate rows; this switch makes them separate columns.
|
||||
[Switch]$PivotDataToColumn,
|
||||
#Define whether totals should be added to rows, columns neither, or both (the default is both).
|
||||
[ValidateSet("Both","Columns","Rows","None")]
|
||||
[String]$PivotTotals = "Both",
|
||||
#Included for compatibility - equivalent to -PivotTotals "None".
|
||||
[Switch]$NoTotalsInPivot,
|
||||
#Number format to apply to the data cells in the PivotTable.
|
||||
[string]$PivotNumberFormat,
|
||||
#Apply a table style to the PivotTable.
|
||||
[OfficeOpenXml.Table.TableStyles]$PivotTableStyle,
|
||||
#Use a chart definition instead of specifying chart settings one by one.
|
||||
[Parameter(ParameterSetName='ChartbyDef', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
|
||||
$PivotChartDefinition,
|
||||
#If specified, a chart will be included.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$IncludePivotChart,
|
||||
#Optional title for the pivot chart, by default the title omitted.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[String]$ChartTitle = "",
|
||||
#Height of the chart in Pixels (400 by default).
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[int]$ChartHeight = 400 ,
|
||||
#Width of the chart in Pixels (600 by default).
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[int]$ChartWidth = 600,
|
||||
#Cell position of the top left corner of the chart, there will be this number of rows above the top edge of the chart (default is 0, chart starts at top edge of row 1).
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartRow = 0 ,
|
||||
#Cell position of the top left corner of the chart, there will be this number of cells to the left of the chart (default is 4, chart starts at left edge of column E).
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartColumn = 4,
|
||||
#Vertical offset of the chart from the cell corner.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartRowOffSetPixels = 0 ,
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
#Horizontal offset of the chart from the cell corner.
|
||||
[Int]$ChartColumnOffSetPixels = 0,
|
||||
#Type of chart; defaults to "Pie".
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
||||
#If specified hides the chart legend.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$NoLegend,
|
||||
#If specified attaches the category to slices in a pie chart : not supported on all chart types, this may give errors if applied to an unsupported type.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$ShowCategory,
|
||||
#If specified attaches percentages to slices in a pie chart.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$ShowPercent,
|
||||
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified.
|
||||
[switch]$Activate,
|
||||
#Return the PivotTable so it can be customized.
|
||||
[Switch]$PassThru
|
||||
)
|
||||
if ($PivotTableName.length -gt 250) {
|
||||
Write-warning -Message "PivotTable name will be truncated"
|
||||
$PivotTableName = $PivotTableName.Substring(0,250)
|
||||
}
|
||||
if ($Address) {
|
||||
[OfficeOpenXml.ExcelWorksheet]$wsPivot = $address.Worksheet
|
||||
}
|
||||
else {
|
||||
try {
|
||||
if (-not $ExcelPackage) {Write-Warning -message "This combination of Parameters needs to include the ExcelPackage." ; return }
|
||||
[OfficeOpenXml.ExcelWorksheet]$wsPivot = Add-WorkSheet -ExcelPackage $ExcelPackage -WorksheetName $pivotTableName -Activate:$Activate
|
||||
if ($wsPivot.Name -ne $PivotTableName) {Write-Warning -Message "The Worksheet name for the PivotTable does not match the table name '$PivotTableName'; probably because excess or illegal characters were removed." }
|
||||
if ($PivotFilter) {$Address = $wsPivot.Cells["A3"]} else { $Address = $wsPivot.Cells["A1"]}
|
||||
}
|
||||
catch {throw "Could not create the sheet for the PivotTable. $_" }
|
||||
}
|
||||
#if the pivot doesn't exist, create it.
|
||||
if (-not $wsPivot) {throw "There was a problem getting the worksheet for the PivotTable"}
|
||||
if (-not $wsPivot.PivotTables[$pivotTableName] ) {
|
||||
try {
|
||||
#Accept a string or a worksheet object as $SourceWorksheet - we don't need a worksheet if we have a Rangebase .
|
||||
if ( $SourceWorkSheet -is [string]) {
|
||||
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets.where( {$_.name -Like $SourceWorkSheet})[0]
|
||||
}
|
||||
elseif ( $SourceWorkSheet -is [int] ) {
|
||||
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets[$SourceWorkSheet]
|
||||
}
|
||||
if ( $SourceRange -is [OfficeOpenXml.Table.ExcelTable]) {$SourceRange = $SourceRange.Address }
|
||||
if ( $sourceRange -is [OfficeOpenXml.ExcelRange] -or
|
||||
$SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
||||
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceRange, $pivotTableName)
|
||||
}
|
||||
elseif (-not $SourceRange) {
|
||||
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceWorkSheet.cells[$SourceWorkSheet.Dimension.Address], $pivotTableName)
|
||||
}
|
||||
elseif ($SourceWorkSheet -isnot [OfficeOpenXml.ExcelWorksheet] ) {
|
||||
Write-Warning -Message "Could not find source Worksheet for pivot-table '$pivotTableName'." ; return
|
||||
}
|
||||
elseif ( $SourceRange -is [String] -or $SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
||||
$pivotTable = $wsPivot.PivotTables.Add($Address,$SourceWorkSheet.Cells[$SourceRange], $pivotTableName)
|
||||
}
|
||||
else {Write-warning "Could not create a PivotTable with the Source Range provided."; return}
|
||||
foreach ($Row in $PivotRows) {
|
||||
try {$null = $pivotTable.RowFields.Add($pivotTable.Fields[$Row]) }
|
||||
catch {Write-Warning -message "Could not add '$row' to Rows in PivotTable $pivotTableName." }
|
||||
}
|
||||
foreach ($Column in $PivotColumns) {
|
||||
try {$null = $pivotTable.ColumnFields.Add($pivotTable.Fields[$Column])}
|
||||
catch {Write-Warning -message "Could not add '$Column' to Columns in PivotTable $pivotTableName." }
|
||||
}
|
||||
if ($PivotData -is [HashTable] -or $PivotData -is [System.Collections.Specialized.OrderedDictionary]) {
|
||||
$PivotData.Keys | ForEach-Object {
|
||||
try {
|
||||
$df = $pivotTable.DataFields.Add($pivotTable.Fields[$_])
|
||||
$df.Function = $PivotData.$_
|
||||
if ($PivotNumberFormat) {$df.Format = (Expand-NumberFormat -NumberFormat $PivotNumberFormat)}
|
||||
}
|
||||
catch {Write-Warning -message "Problem adding data fields to PivotTable $pivotTableName." }
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach ($field in $PivotData) {
|
||||
try {
|
||||
$df = $pivotTable.DataFields.Add($pivotTable.Fields[$field])
|
||||
$df.Function = 'Count'
|
||||
}
|
||||
catch {Write-Warning -message "Problem adding data field '$field' to PivotTable $pivotTableName." }
|
||||
}
|
||||
}
|
||||
foreach ( $pFilter in $PivotFilter) {
|
||||
try { $null = $pivotTable.PageFields.Add($pivotTable.Fields[$pFilter])}
|
||||
catch {Write-Warning -message "Could not add '$pFilter' to Filter/Page fields in PivotTable $pivotTableName." }
|
||||
}
|
||||
if ($NoTotalsInPivot) {$PivotTotals = "None" }
|
||||
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Columns") { $pivotTable.RowGrandTotals = $false }
|
||||
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Rows") { $pivotTable.RowGrandTotals = $true }
|
||||
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Rows") { $pivotTable.ColumGrandTotals = $false } # Epplus spelling mistake, not mine!
|
||||
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Columns") { $pivotTable.ColumGrandTotals = $true }
|
||||
if ($PivotDataToColumn ) { $pivotTable.DataOnRows = $false }
|
||||
if ($PivotTableStyle) { $pivotTable.TableStyle = $PivotTableStyle}
|
||||
}
|
||||
catch {Write-Warning -Message "Failed adding PivotTable '$pivotTableName': $_"}
|
||||
}
|
||||
else {
|
||||
Write-Warning -Message "PivotTable defined in $($pivotTableName) already exists, only the data range will be changed."
|
||||
$pivotTable = $wsPivot.PivotTables[$pivotTableName]
|
||||
if (-not $SourceRange) { $SourceRange = $SourceWorkSheet.Dimension.Address}
|
||||
$pivotTable.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref = $SourceRange
|
||||
}
|
||||
|
||||
#Create the chart if it doesn't exist, leave alone if it does.
|
||||
if ($IncludePivotChart -and -not $wsPivot.Drawings["Chart$pivotTableName"] ) {
|
||||
try {Add-ExcelChart -PivotTable $pivotTable -ChartType $ChartType -Width $ChartWidth -Height $ChartHeight -Row $ChartRow -Column $ChartColumn -RowOffSetPixels $ChartRowOffSetPixels -ColumnOffSetPixels $ChartColumnOffSetPixels -Title $ChartTitle -NoLegend:$NoLegend -ShowCategory:$ShowCategory -ShowPercent:$ShowPercent }
|
||||
catch {Write-Warning -Message "Failed adding chart for pivotable '$pivotTableName': $_"}
|
||||
}
|
||||
elseif ($PivotChartDefinition -and -not $wsPivot.Drawings["Chart$pivotTableName"]) {
|
||||
if ($PivotChartDefinition -is [System.Management.Automation.PSCustomObject]) {
|
||||
$params = @{PivotTable= $pivotTable }
|
||||
$PivotChartDefinition.PSObject.Properties | ForEach-Object {if ( $null -ne $_.value) {$params[$_.name] = $_.value}}
|
||||
Add-ExcelChart @params
|
||||
}
|
||||
elseif ($PivotChartDefinition -is [hashtable] -or $PivotChartDefinition -is[System.Collections.Specialized.OrderedDictionary]) {
|
||||
Add-ExcelChart -PivotTable $pivotTable @PivotChartDefinition
|
||||
}
|
||||
}
|
||||
if ($PassThru) {return $pivotTable}
|
||||
}
|
||||
|
||||
function New-PivotTableDefinition {
|
||||
<#
|
||||
.Synopsis
|
||||
Creates PivotTable definitons for Export-Excel
|
||||
.Description
|
||||
Export-Excel allows a single PivotTable to be defined using the parameters -IncludePivotTable, -PivotColumns -PivotRows,
|
||||
-PivotData, -PivotFilter, -PivotTotals, -PivotDataToColumn, -IncludePivotChart and -ChartType.
|
||||
Its -PivotTableDefintion paramater allows multiple PivotTables to be defined, with additional parameters.
|
||||
New-PivotTableDefinition is a convenient way to build these definitions.
|
||||
.Example
|
||||
>
|
||||
PS> $pt = New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet "Sheet1" -PivotRows "Status" -PivotData @{Status='Count' } -PivotFilter 'StartType' -IncludePivotChart -ChartType BarClustered3D
|
||||
$Pt += New-PivotTableDefinition -PivotTableName "PT2" -SourceWorkSheet "Sheet2" -PivotRows "Company" -PivotData @{Company='Count'} -IncludePivotChart -ChartType PieExploded3D -ShowPercent -ChartTitle "Breakdown of processes by company"
|
||||
Get-Service | Select-Object -Property Status,Name,DisplayName,StartType | Export-Excel -Path .\test.xlsx -AutoSize
|
||||
Get-Process | Select-Object -Property Name,Company,Handles,CPU,VM | Export-Excel -Path .\test.xlsx -AutoSize -WorksheetName 'sheet2'
|
||||
$excel = Export-Excel -Path .\test.xlsx -PivotTableDefinition $pt -Show
|
||||
|
||||
This is a re-work of one of the examples in Export-Excel - instead of writing out the pivot definition hash table it is built by calling New-PivotTableDefinition.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[Alias("PivtoTableName")]#Previous typo - use alias to avoid breaking scripts
|
||||
$PivotTableName,
|
||||
#Worksheet where the data is found
|
||||
$SourceWorkSheet,
|
||||
#Address range in the worksheet e.g "A10:F20" - the first row must be column names: if not specified the whole sheet will be used/
|
||||
$SourceRange,
|
||||
#Fields to set as rows in the PivotTable
|
||||
$PivotRows,
|
||||
#A hash table in form "FieldName"="Function", where function is one of
|
||||
#Average, Count, CountNums, Max, Min, Product, None, StdDev, StdDevP, Sum, Var, VarP
|
||||
[hashtable]$PivotData,
|
||||
#Fields to set as columns in the PivotTable
|
||||
$PivotColumns,
|
||||
#Fields to use to filter in the PivotTable
|
||||
$PivotFilter,
|
||||
#If there are multiple datasets in a PivotTable, by default they are shown seperatate rows under the given row heading; this switch makes them seperate columns.
|
||||
[Switch]$PivotDataToColumn,
|
||||
#By default PivotTables have Totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
|
||||
#Define whther totals should be added to rows, columns neither, or both (the default is both)
|
||||
[ValidateSet("Both","Columns","Rows","None")]
|
||||
[String]$PivotTotals = "Both",
|
||||
#Included for compatibility - equivalent to -PivotTotals "None"
|
||||
[Switch]$NoTotalsInPivot,
|
||||
#Number format to apply to the data cells in the PivotTable
|
||||
[string]$PivotNumberFormat,
|
||||
#Apply a table style to the PivotTable
|
||||
[OfficeOpenXml.Table.TableStyles]$PivotTableStyle,
|
||||
#Use a chart definition instead of specifying chart settings one by one
|
||||
[Parameter(ParameterSetName='ChartbyDef', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
|
||||
$PivotChartDefinition,
|
||||
#If specified a chart Will be included.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$IncludePivotChart,
|
||||
#Optional title for the pivot chart, by default the title omitted.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[String]$ChartTitle,
|
||||
#Height of the chart in Pixels (400 by default)
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[int]$ChartHeight = 400 ,
|
||||
#Width of the chart in Pixels (600 by default)
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[int]$ChartWidth = 600,
|
||||
#Cell position of the top left corner of the chart, there will be this number of rows above the top edge of the chart (default is 0, chart starts at top edge of row 1).
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartRow = 0 ,
|
||||
#Cell position of the top left corner of the chart, there will be this number of cells to the left of the chart (default is 4, chart starts at left edge of column E)
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartColumn = 4,
|
||||
#Vertical offset of the chart from the cell corner.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartRowOffSetPixels = 0 ,
|
||||
#Horizontal offset of the chart from the cell corner.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Int]$ChartColumnOffSetPixels = 0,
|
||||
#Type of chart
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
||||
#If specified hides the chart legend
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$NoLegend,
|
||||
#if specified attaches the category to slices in a pie chart : not supported on all chart types, this may give errors if applied to an unsupported type.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$ShowCategory,
|
||||
#If specified attaches percentages to slices in a pie chart.
|
||||
[Parameter(ParameterSetName='ChartbyParams')]
|
||||
[Switch]$ShowPercent,
|
||||
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
|
||||
[switch]$Activate
|
||||
)
|
||||
$validDataFuntions = [system.enum]::GetNames([OfficeOpenXml.Table.PivotTable.DataFieldFunctions])
|
||||
|
||||
if ($PivotData.values.Where({$_ -notin $validDataFuntions}) ) {
|
||||
Write-Warning -Message ("Pivot data functions might not be valid, they should be one of " + ($validDataFuntions -join ", ") + ".")
|
||||
}
|
||||
|
||||
$parameters = @{} + $PSBoundParameters
|
||||
if ($NoTotalsInPivot) {
|
||||
$parameters.Remove('NoTotalsInPivot')
|
||||
$parameters["PivotTotals"] = "None"
|
||||
}
|
||||
$parameters.Remove('PivotTableName')
|
||||
if ($PivotChartDefinition) {
|
||||
$parameters.PivotChartDefinition.XRange = $null
|
||||
$parameters.PivotChartDefinition.YRange = $null
|
||||
$parameters.PivotChartDefinition.SeriesHeader = $null
|
||||
}
|
||||
@{$PivotTableName = $parameters}
|
||||
}
|
||||
82
README.md
82
README.md
@@ -13,6 +13,7 @@ If this project helped you reduce the time to get your job done, let me know.
|
||||
<br/>
|
||||
<p align="center">
|
||||
<a href="https://ci.appveyor.com/project/dfinke/importexcel/branch/master"><img src="https://ci.appveyor.com/api/projects/status/21hko6eqtpccrkba/branch/master?svg=true"></a>
|
||||
<a href="https://dougfinke.visualstudio.com/ImportExcel/_build?definitionId=10"><img src="https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/ImportExcel-CI?branchName=master"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -52,7 +53,84 @@ Install-Module ImportExcel -scope CurrentUser
|
||||
Install-Module ImportExcel
|
||||
```
|
||||
|
||||
# What's new to 18th July 18
|
||||
# What's new 5.4
|
||||
|
||||
- Thank you to Conrad Agramont, Twitter: [@AGramont](https://twitter.com/@AGramont) for the `AddMultiWorkSheet.ps1` example. Much appreciated!
|
||||
- Fixed several more bugs where parameters were ignored if passed a zero value
|
||||
- Fixed bug where chart series headers could not come form a cell reference (=Sheet1!Z10 now works as a header reference)
|
||||
- Add-Chart will now allow a single X range, or as many X ranges as there are Y ranges.
|
||||
- Merge-MultipleSheets is more robust.
|
||||
- Set-ExcelRow and Set-ExcelColumn trap attempts to process a sheet with no rows/columns.
|
||||
- Help has been proof-read (thanks to Mrs. @Jhoneill !).
|
||||
|
||||
# What's new 5.3.4
|
||||
|
||||
- HotFix for parameter PivotTableSyle should be PivotTableStyle https://github.com/dfinke/ImportExcel/issues/453
|
||||
|
||||
# What's new 5.3.3
|
||||
|
||||
- Thank you to (lazywinadmin)[https://github.com/lazywinadmin] - Expand aliases in examples and elsewhere
|
||||
- In Export-Excel fixed a bug where -AutoNameRange on pre-existing data included the header in the range.
|
||||
- In Export-Excel fixed a bug which caused a zero, null, or empty string in a list of simple objects to be skipped.
|
||||
- In Export-Excel improved the behaviour when a new worksheet is created without data, and Tables etc are added to it.
|
||||
- In Join-Worksheet: added argument completer to -TitleBackgroundColor and set default for -TitleBackgroundStyle to 'Solid'.
|
||||
- In Add-Excel chart, New-ExcelChart, tests and Examples fixed mis-spelling of "Position"
|
||||
- In Send-SqlDataToExcel: improved robustness of check for no data returned.
|
||||
- In Set-ExcelColumn: -column can come from the pipeline (supporting an array introduces complications for supporting script blocks); -AutoNameRange no longer requires heading to specified (so you can do 1..10 | Set-ExcelColumn -AutoNameRange ); In Set-ExcelRow: -Row can come from the pipeline
|
||||
- Improved test coverage (back over 80%).
|
||||
- Help and example improvements. In "Index - music.ps1" the module for querying the index can be downloaded from PowerShell gallery #requires set to demand it. In SQL+FillColumns+Pivot\example2.ps1 the GetSQL module can be downloaded and #Requires has been set. The F1 results spreadsheet is available from one drive and a link is provided.
|
||||
|
||||
- Added Azure DevOps continuous integration and badges <a href="https://dougfinke.visualstudio.com/ImportExcel/_build?definitionId=10"><img src="https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/ImportExcel-CI?branchName=master"></a>
|
||||
|
||||
|
||||
|
||||
# What's new in Release 5.3
|
||||
|
||||
- Help improvements and tidying up of examples and extra examples
|
||||
- Open-Excel Package and Add-Worksheet now add worksheets as script properties so `$Excel = Open-ExcelPackage -path test.xlsx ; $excel.sheet1` will return the sheet named "sheet1" `$Excel.SheetName` is a script property which is defined as `$this.workbook.worksheets["Sheetname"]`
|
||||
- Renamed Set-Column to `Set-ExcelColumn`, Set-Row to `Set-ExcelRow`, and Set-Format, to `Set-ExcelRange`. Added aliases so the old names still work.
|
||||
- `Set-ExcelRange` (or set-Format) used "Address" and "Range" incorrectly. There is now a single parameter `-Range`, with an alias of "Address". If the worksheet parameter is present, the function accepts a string specifying cells ("A1:Z10") or a the name of range. Without the worksheet it accepts an object representing a named range or a Table; or a tables's address, or part of the worksheet.cells collection.
|
||||
- `Add-ConditionalFormatting`: Used "address" correctly, and it will accept ranges in the address parameter (range is now an alias for address). It now wraps conditional value strings in quotes when needed (for = <= >= operations string needs to be in double quotes see issue #424). Parameter intellisense has been improved. There are new parameters: `-StopIfTrue` and `-Priority` and support for using the `-Reverse` parameter with Color-scale rules (issue #430). Booleans in the sheet are now supported as the value for a condition. Also brought the two different kinds of condition together inside Export-Excel, and fixed a bug where named-ranges didn't work in some places. In `New-ConditionalText`, more types of conditional format are supported, and the argument completer for -ConditionalTextColor was missing and has been added.
|
||||
- Improved handling of hyperlinks in `Export-Excel` (see issue #426)s
|
||||
- `Export-Excel` has better checking of Table and PivotTable names (for uniqueness) and a new test in quick charts that there is suitable data for charting. It also accepts hash tables for chart, pivot table and conditional formatting parameters which are splatted into the functions which add these.
|
||||
- Moved logic for adding a named-range out of Export-Excel and into a new function named `Add-ExcelName`, and logic for adding a table into a function named `Add-ExcelTable`; this is to make it easier to do these things independently of Export-Excel, but minimize duplication. The Add-ExcelTable command has extra parameters to toggle the options from table tools toolbar (show totals etc.) and set options in the totals row.
|
||||
- Moved PivotTable Functions out of Export-Excel.PS1 into their own file and moved Add-ExcelChart out of Export-Excel.ps1 into New-ExcelChart.ps1
|
||||
- Fixed bug in Merge-MultipleSheets where background pattern was set to None, making background color invisible.
|
||||
- Fixed issues where formatting could be reset when using Export-Excel to manipulate an existing sheet without appending data; this applied to number-formats and tables.
|
||||
- `Add-PivotTable` has some new parameters `-PassThru` returns the pivot table (e.g. to allow names /sort orders of data series to be tweaked ) `-Address` allows Pivot to be placed on an existing sheet; `-PivotTableStyle` allows a change from "Medium6", `-PivotNumberFormat` formats data cells. It is more flexible about how the source data is specified - copying the range options in Set-ExcelRange. `Add-ExcelChart` is now used for creating PivotCharts, and `-PivotChartDefinition` allows a definition created with `New-ExcelChartDefinition` to be used when setting up a PivotTable. This opens up all the things that Add-ExcelChart can do without duplicating the parameters on Add-Pivot table and Export-Excel. Definition, TableStyle, Numberformat and ChartDefiniton can be used in `New-PivotTableDefinition` .
|
||||
- `Add-ExcelChart` now supports -PassThru to return the chart for tweaking after creation; there is now a -PivotTable parameter to allow Add-PivotTable to call the code in Add-ExcelChart. And in `New-ExcelChartDefinition` Legend parameters (for size, bold & position ) are now supported
|
||||
- ChartDefinition and conditional formatting parameters can now be hashtables - anything that splats Add-ExcelChart or Add-ConditionalFormatting, it should be acceptable as a definition.
|
||||
|
||||
|
||||
# What's new in Release 5.2
|
||||
- Value does not need to be mandatory in Set-Row or Set-Column, also tidied their parameters a little.
|
||||
- Added support for array formulas in Set-Format (it really should be set range now that it sets values, formulas and hyperlinks - that can go on the to-do list )
|
||||
- Fixed a bug with -Append in Export-Excel which caused it to overwrite the last row if the new data was a simple type.
|
||||
- NumberFormat in Export-Excel now sets the default for on a new / blank sheet; but [still] sets individual cells when adding to a sheet
|
||||
- Added support for timespans in Export excel ; set as elapsed hours, mins, secs [h]:mm:sss
|
||||
- In Export-Excel improved the catch-all handler for insuring values to cope better with nested objects (#419) and reduce the number of parse operations
|
||||
- Added -Calculate switch to Export-Excel and Close-Excel Package; EPPlus needs formulas to OMIT the leading = sign so where formula is set it now strips a leading = sign
|
||||
- Added -PivotTotals parameter where there was already -NoTotalsInPivot new one allows None, Both, Rows, Columns. (#415)
|
||||
- When appending Export-Excel only extended tables and ranges if they were explicitly specified. It now does it automatically.
|
||||
- Compare and Merge worksheet originally had a problem with > 26 columns, I fixed merge turns out I hadn't fixed compare ... I have now
|
||||
- Fixed bug where Export-Excel would not recognize it had to set $TitleFillPattern - made the default 'Solid'
|
||||
- ExcludeProperty in Export-Excel now supports wildcards.
|
||||
- Added DateTime to the list of types which can be exported as single column.
|
||||
- Added Password support to Open- and Close-ExcelPackage (password was not doing anything in Export-Excel)
|
||||
- Gave Expand-NumberFormat a better grasp of currency layouts - it follows .NET which is not always the same as Excel would set:-(
|
||||
|
||||
# What's new in Release 5.1.1
|
||||
- Set-Row and Set-Column will now create hyperlinks and insert dates correctly
|
||||
- Import-Excel now has an argument completer for Worksheet name - this can be slow on large files
|
||||
- The NumberFormat parameter (in Export-Excel, Set-Row, Set-Column, Set-Format and Add-ConditionalFormat) and X&YAxisNumberFormat parameters (in New-ExcelChartDefinition and Add-ExcelChart) now have an argument completer and the names Currency, Number, Percentage, Scientific, Fraction, Short Date ,Short time,Long time, Date-Time and Text will be converted to the correct Excel formatting strings.
|
||||
- Added new function Select-Worksheet to make a named sheet active: Added -Activate switch to Add-Worksheet, to make current sheet active, Export-Excel and Add-PivotTable support -Activate and pass it to Add-Worksheet, and New-PivotTableDefinition allows it to be part of the Pivot TableDefinition.
|
||||
- Fixed a bug in Set-Format which caused -Hidden not to work
|
||||
- Made the same changes to Add-Conditional format as set format so -switch:$false is processed, and 0 enums and values are processed correctly
|
||||
- In Export-Excel, wrapped calls to Add-CellValue in a try catch so a value which causes an issue doesn't crash the whole export but generates a warning instead (#410) .
|
||||
- Additional tests.
|
||||
|
||||
# What's new to July 18
|
||||
- Changed parameter evaluation in Set-Format to support -bold:$false (and other switches so that if false is specified the attribute will be removed ), and to bug were enums with a value of zero, and other zero parameters were not set.
|
||||
- Moved chart creation into its own function (Add-Excel chart) within Export-Excel.ps1. Renamed New-Excelchart to New-ExcelChartDefinition to make it clearer that it is not making anything in the workbook (but for compatibility put an alias of New-ExcelChart in so existing code does not break). Found that -Header does nothing, so it isn't Add-Excel chart and there is a message that does nothing in New-ExcelChartDefinition .
|
||||
- Added -BarChart -ColumnChart -LineChart -PieChart parameters to Export-Excel for quick charts without giving a full chart definition.
|
||||
- Added parameters for managing chart Axes and legend
|
||||
@@ -871,4 +949,4 @@ You can also find EPPLus on [Nuget](https://www.nuget.org/packages/EPPlus/).
|
||||
|
||||
* Using `-IncludePivotTable`, if that pivot table name exists, you'll get an error.
|
||||
* Investigating a solution
|
||||
* *Workaround* delete the Excel file first, then do the export
|
||||
* *Workaround* delete the Excel file first, then do the export
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage $Path
|
||||
|
||||
$workSheet = $Excel.Workbook.Worksheets[$WorkSheetName]
|
||||
|
||||
|
||||
if($workSheet) {
|
||||
if($Excel.Workbook.Worksheets.Count -gt 1) {
|
||||
$Excel.Workbook.Worksheets.Delete($workSheet)
|
||||
@@ -22,14 +22,13 @@
|
||||
}
|
||||
|
||||
$Excel.Save()
|
||||
$Excel.Dispose()
|
||||
$Excel.Dispose()
|
||||
}
|
||||
|
||||
cls
|
||||
|
||||
ipmo .\ImportExcel.psd1 -Force
|
||||
Import-Module .\ImportExcel.psd1 -Force
|
||||
|
||||
$names = Get-ExcelSheetInfo C:\Temp\testDelete.xlsx
|
||||
$names | % { Remove-WorkSheet C:\Temp\testDelete.xlsx $_.Name}
|
||||
$names = Get-ExcelSheetInfo C:\Temp\testDelete.xlsx
|
||||
$names | Foreach-Object { Remove-WorkSheet C:\Temp\testDelete.xlsx $_.Name}
|
||||
|
||||
##Remove-WorkSheet C:\Temp\testDelete.xlsx sheet6
|
||||
@@ -3,21 +3,26 @@
|
||||
.SYNOPSIS
|
||||
Inserts a DataTable - returned by SQL query into an ExcelSheet, more efficiently than sending it via Export-Excel
|
||||
.DESCRIPTION
|
||||
This command can accept a data table object or take a SQL command and run it against a database connection.
|
||||
If running the SQL command, it accepts an object representing a session with a SQL server or ODBC database, or a connection String to make a session.
|
||||
It the DataTable is inserted into the Excel sheet
|
||||
It takes most of the parameters of Export-Excel, but it is more efficient than getting dataRows and piping them into Export-Excel,
|
||||
data-rows have additional properties which need to be stripped off.
|
||||
This command can accept a data table object or take a SQL statement and run it against a database connection.
|
||||
If running a SQL statement, the accepts either
|
||||
* an object representing a session with a SQL server or ODBC database, or
|
||||
* a connection String to make a session.
|
||||
The command takes most of the parameters of Export-Excel, and after inserting the table into the worksheet it
|
||||
calls Export-Excel to carry out other tasks on the sheet. It is more efficient to do this than to get data-rows
|
||||
and pipe them into Export-Excel, stripped off the database 'housekeeping' properties.
|
||||
.PARAMETER DataTable
|
||||
A System.Data.DataTable object containing the data to be inserted into the spreadsheet without running a query.
|
||||
.PARAMETER Session
|
||||
An active ODBC Connection or SQL connection object representing a session with a database which will be queried to get the data .
|
||||
.PARAMETER Connection
|
||||
Database connection string; either DSN=ODBC_Data_Source_Name, a full odbc or SQL Connection string, or the name of a SQL server. This is used to create a database session.
|
||||
A database connection string to be used to create a database session; either
|
||||
* A Data source name written in the form DSN=ODBC_Data_Source_Name, or
|
||||
* A full odbc or SQL Connection string, or
|
||||
* The name of a SQL server.
|
||||
.PARAMETER MSSQLServer
|
||||
Specifies the connection string is for SQL server, not ODBC .
|
||||
Specifies the connection string is for SQL server, not ODBC.
|
||||
.PARAMETER SQL
|
||||
The SQL query to run against the session which was passed in -Session or set up from $Connection.
|
||||
The SQL query to run against the session which was passed in -Session or set up from -Connection.
|
||||
.PARAMETER Database
|
||||
Switches to a specific database on a SQL server.
|
||||
.PARAMETER QueryTimeout
|
||||
@@ -25,9 +30,9 @@
|
||||
.PARAMETER Path
|
||||
Path to a new or existing .XLSX file.
|
||||
.PARAMETER WorkSheetName
|
||||
The name of a sheet within the workbook - "Sheet1" by default .
|
||||
The name of a sheet within the workbook - "Sheet1" by default.
|
||||
.PARAMETER KillExcel
|
||||
Closes Excel - prevents errors writing to the file because Excel has it open
|
||||
Closes Excel - prevents errors writing to the file because Excel has it open.
|
||||
.PARAMETER Title
|
||||
Text of a title to be placed in the top left cell.
|
||||
.PARAMETER TitleBold
|
||||
@@ -52,6 +57,8 @@
|
||||
Name(s) columns from the spreadhseet which will provide the Filter name(s) in a pivot table created from command line parameters.
|
||||
.PARAMETER PivotData
|
||||
In a pivot table created from command line parameters, the fields to use in the table body is given as a Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP .
|
||||
.PARAMETER PivotDataToColumn
|
||||
If there are multiple datasets in a PivotTable, by default they are shown seperatate rows under the given row heading; this switch makes them seperate columns.
|
||||
.PARAMETER NoTotalsInPivot
|
||||
In a pivot table created from command line parameters, prevents the addition of totals to rows and columns.
|
||||
.PARAMETER IncludePivotChart
|
||||
@@ -111,6 +118,9 @@
|
||||
Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
|
||||
.PARAMETER Show
|
||||
Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
||||
.PARAMETER CellStyleSB
|
||||
A script block which is run at the end of the process to apply styles to cells (although it can be used for other purposes).
|
||||
The script block is given three paramaters; an object containing the current worksheet, the Total number of Rows and the number of the last column.
|
||||
.PARAMETER ReturnRange
|
||||
If specified, Export-Excel returns the range of added cells in the format "A1:Z100"
|
||||
.PARAMETER PassThru
|
||||
@@ -118,20 +128,32 @@
|
||||
|
||||
.EXAMPLE
|
||||
C:\> Send-SQLDataToExcel -MsSQLserver -Connection localhost -SQL "select name,type,type_desc from [master].[sys].[all_objects]" -Path .\temp.xlsx -WorkSheetname master -AutoSize -FreezeTopRow -AutoFilter -BoldTopRow
|
||||
Connects to the local SQL server and selects 3 columns from [Sys].[all_objects] and exports then to a sheet named master with some basic header manager
|
||||
|
||||
Connects to the local SQL server and selects 3 columns from [Sys].[all_objects] and exports then to a sheet named master with some basic header management
|
||||
.EXAMPLE
|
||||
C:\> $SQL="SELECT top 25 Name,Length From TestData ORDER BY Length DESC"
|
||||
C:\> $Connection = ' Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\Users\James\Documents\Database1.accdb;'
|
||||
|
||||
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Sizes" -AutoSize
|
||||
|
||||
This declares a SQL statement and creates an ODBC connection string to read from an Access file and extracts data from it and sends it to a new worksheet
|
||||
|
||||
.EXAMPLE
|
||||
C:\> $SQL="SELECT top 25 DriverName, Count(RaceDate) as Races, Count(Win) as Wins, Count(Pole) as Poles, Count(FastestLap) as Fastlaps FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
|
||||
C:\> $Connection = 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DriverId=790;ReadOnly=0;Dbq=C:\users\James\Documents\f1Results.xlsx;'
|
||||
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange
|
||||
C:\> $Connection = 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=C:\users\James\Documents\f1Results.xlsx;'
|
||||
|
||||
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange -ConditionalFormat @{DataBarColor="Blue"; Range="Wins"}
|
||||
|
||||
This declares a SQL statement and creates an ODBC connection string to read from an Excel file, it then runs the statement and outputs the resulting data to a new spreadsheet.
|
||||
The spreadsheet is formatted and a data bar added to show make the drivers' wins clearer.
|
||||
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
|
||||
.EXAMPLE
|
||||
C:\> $SQL = "SELECT top 25 DriverName, Count(RaceDate) as Races, Count(Win) as Wins, Count(Pole) as Poles, Count(FastestLap) as Fastlaps FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
|
||||
C:\> Get-SQL -Session F1 -excel -Connection "C:\Users\mcp\OneDrive\public\f1\f1Results.xlsx" -sql $sql -OutputVariable Table | out-null
|
||||
|
||||
C:\> Send-SQLDataToExcel -DataTable $Table -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -TableName winners -TableStyle Light6 -show
|
||||
|
||||
This uses Get-SQL (at least V1.1 download from the gallery with Install-Module -Name GetSQL - note the function is get-SQL the module is GetSQL without the "-" )
|
||||
This uses Get-SQL (at least V1.1 - download from the gallery with Install-Module -Name GetSQL - note the function is Get-SQL the module is GetSQL without the "-" )
|
||||
to simplify making database connections and building /submitting SQL statements.
|
||||
Here it uses the same SQL statement as before; -OutputVariable leaves a System.Data.DataTable object in $table
|
||||
and Send-SQLDataToExcel puts $table into the worksheet and sets it as an Excel table.
|
||||
@@ -140,7 +162,7 @@
|
||||
C:\> $SQL = "SELECT top 25 DriverName, Count(Win) as Wins FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
|
||||
C:\> Send-SQLDataToExcel -Session $DbSessions["f1"] -SQL $sql -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -ColumnChart
|
||||
|
||||
Like the previous example, this uses Get-SQL (download from the gallery with Install-Module -Name GetSQL).It uses the connection which Get-SQL made rather than an ODFBC connection string
|
||||
Like the previous example, this uses Get-SQL (download from the gallery with Install-Module -Name GetSQL). It uses the connection which Get-SQL made rather than an ODFBC connection string
|
||||
Here the data is presented as a quick chart.
|
||||
.EXAMPLE
|
||||
C:\> Send-SQLDataToExcel -path .\demo3.xlsx -WorkSheetname "LR" -Connection "DSN=LR" -sql "SELECT name AS CollectionName FROM AgLibraryCollection Collection ORDER BY CollectionName"
|
||||
@@ -174,7 +196,7 @@
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
|
||||
[Switch]$TitleBold,
|
||||
[Int]$TitleSize = 22,
|
||||
[System.Drawing.Color]$TitleBackgroundColor,
|
||||
$TitleBackgroundColor,
|
||||
[String]$Password,
|
||||
[Hashtable]$PivotTableDefinition,
|
||||
[Switch]$IncludePivotTable,
|
||||
@@ -249,7 +271,7 @@
|
||||
$rowCount = $dataAdapter.fill($dataTable)
|
||||
Write-Verbose -Message "Query returned $rowCount row(s)"
|
||||
}
|
||||
if ($DataTable.Rows) {
|
||||
if ($DataTable.Rows.Count) {
|
||||
#ExportExcel user a -NoHeader parameter so that's what we use here, but needs to be the other way around.
|
||||
$printHeaders = -not $NoHeader
|
||||
if ($Title) {$r = $StartRow +1 }
|
||||
@@ -258,6 +280,13 @@
|
||||
$excelPackage = Export-Excel -Path $Path -WorkSheetname $WorkSheetname -PassThru
|
||||
$excelPackage.Workbook.Worksheets[$WorkSheetname].Cells[$r,$StartColumn].LoadFromDataTable($dataTable, $printHeaders ) | Out-Null
|
||||
|
||||
#Apply date format
|
||||
for ($c=0 ; $c -lt $DataTable.Columns.Count ; $c++) {
|
||||
if ($DataTable.Columns[$c].DataType -eq [datetime]) {
|
||||
Set-ExcelColumn -Worksheet $excelPackage.Workbook.Worksheets[$WorkSheetname] -Column ($c +1) -NumberFormat 'Date-Time'
|
||||
}
|
||||
}
|
||||
|
||||
#Call export-excel with any parameters which don't relate to the SQL query
|
||||
"Connection", "Database" , "Session", "MsSQLserver", "Destination" , "SQL" , "DataTable", "Path" | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
|
||||
Export-Excel -ExcelPackage $excelPackage @PSBoundParameters
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
$Row,
|
||||
$LastColumn,
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$Pattern,
|
||||
[System.Drawing.Color]$Color
|
||||
$Color
|
||||
)
|
||||
|
||||
if ($Color -is [string]) {$Color = [System.Drawing.Color]::$Color }
|
||||
$t=$WorkSheet.Cells["A$($Row):$($LastColumn)$($Row)"]
|
||||
$t.Style.Fill.PatternType=$Pattern
|
||||
$t.Style.Fill.BackgroundColor.SetColor($Color)
|
||||
|
||||
246
Set-Column.ps1
246
Set-Column.ps1
@@ -1,132 +1,192 @@
|
||||
Function Set-Column {
|
||||
Function Set-ExcelColumn {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds a column to the existing data area in an Excel sheet, fills values and sets formatting
|
||||
Adds or modifies a column in an Excel worksheet, filling values, setting formatting and/or creating named ranges.
|
||||
.DESCRIPTION
|
||||
Set-Column takes a value which is either string containing a value or formula or a scriptblock
|
||||
which evaluates to a string, and optionally a column number and fills that value down the column.
|
||||
A column name can be specified and the new column can be made a named range.
|
||||
The column can be formatted.
|
||||
.Example
|
||||
C:> Set-Column -Worksheet $ws -Heading "WinsToFastLaps" -Value {"=E$row/C$row"} -Column 7 -AutoSize -AutoNameRange
|
||||
Here $WS already contains a worksheet which contains counts of races won and fastest laps recorded by racing drivers (in columns C and E)
|
||||
Set-Column specifies that Column 7 should have a heading of "WinsToFastLaps" and the data cells should contain =E2/C2 , =E3/C3
|
||||
the data cells should become a named range, which will also be "WinsToFastLaps" the column width will be set automatically
|
||||
Set-ExcelColumn can take a value which is either a string containing a
|
||||
value or formula or a scriptblock which evaluates to a string,
|
||||
and optionally a column number and fills that value down the column.
|
||||
A column heading can be specified, and the column can be made a named range.
|
||||
The column can be formatted in the same operation.
|
||||
.EXAMPLE
|
||||
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
||||
|
||||
$ws contains a worksheet object - and column "E" is set to use the
|
||||
local currency format. Intelisense will complete the names of predefined
|
||||
number formats. You can see how currency is interpreted on the
|
||||
local computer with the command
|
||||
Expand-NumberFormat currency
|
||||
.EXAMPLE
|
||||
Set-ExcelColumn -Worksheet $ws -Heading "WinsToFastLaps" -Value {"=E$row/C$row"} -Column 7 -AutoSize -AutoNameRange
|
||||
|
||||
Here, $WS already contains a worksheet which holds counts of races won
|
||||
and fastest laps recorded by racing drivers (in columns C and E).
|
||||
Set-ExcelColumn specifies that Column 7 should have a heading of
|
||||
"WinsToFastLaps" and the data cells should contain =E2/C2 , =E3/C3 etc
|
||||
the new data cells should become a named range, which will also be
|
||||
named "WinsToFastLaps" and the column width will be set automatically.
|
||||
.EXAMPLE
|
||||
Set-ExcelColumn -Worksheet $ws -Heading "Link" -Value {"https://en.wikipedia.org" + $worksheet.cells["B$Row"].value } -AutoSize
|
||||
|
||||
In this example, the worksheet in $ws has partial links to Wikipedia
|
||||
pages in column B. The -Value parameter is a script block which
|
||||
outputs a string beginning "https..." and ending with the value of
|
||||
the cell at column B in the current row.
|
||||
When given a valid URI, Set-ExcelColumn makes it a hyperlink.
|
||||
The column will be autosized to fit the links.
|
||||
.EXAMPLE
|
||||
4..6 | Set-ExcelColumn -Worksheet $ws -AutoNameRange
|
||||
|
||||
Again $ws contains a worksheet. Here columns 4 to 6 are made into
|
||||
named ranges, row 1 is used for the range name
|
||||
and the rest of the column becomes the range.
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Column")]
|
||||
[OutputType([OfficeOpenXml.ExcelColumn],[String])]
|
||||
Param (
|
||||
#If specifying the worksheet by name, the ExcelPackage object which contains the worksheet also needs to be passed.
|
||||
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
#The sheet to update can be a given as a name or an Excel Worksheet object - this sets it by name
|
||||
#The sheet to update can be given as a name or an Excel Worksheet object - this sets it by name.
|
||||
[Parameter(ParameterSetName="Package")]
|
||||
#The sheet to update can be a given as a name or an Excel Worksheet object - $workSheet contains the object
|
||||
$Worksheetname = "Sheet1",
|
||||
[String]$Worksheetname = "Sheet1",
|
||||
#This passes the worksheet object instead of passing a sheet name and an Excelpackage object.
|
||||
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
|
||||
[OfficeOpenXml.ExcelWorksheet]
|
||||
$Worksheet,
|
||||
#Column to fill down - first column is 1. 0 will be interpreted as first unused column
|
||||
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
|
||||
#Column to fill down - the first column is 1. 0 will be interpreted as first empty column.
|
||||
[Parameter(ValueFromPipeline=$true)]
|
||||
[ValidateRange(0,16384)]
|
||||
$Column = 0 ,
|
||||
#First row to fill data in
|
||||
#First row to fill data in.
|
||||
[ValidateRange(1,1048576)]
|
||||
[Int]$StartRow ,
|
||||
#value, formula or script block for to fill in. Script block can use $row, $column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
|
||||
[parameter(Mandatory=$true)]
|
||||
#A value, formula or scriptblock to fill in. A script block can use $worksheet, $row, $column [number], $columnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn.
|
||||
$Value ,
|
||||
#Optional column heading
|
||||
#Optional column heading.
|
||||
$Heading ,
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc.
|
||||
[Alias("NFormat")]
|
||||
$NumberFormat,
|
||||
#Style of border to draw around the row
|
||||
#Style of border to draw around the row.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||
#Colour for the text - if none specified it will be left as it it is
|
||||
[System.Drawing.Color]$FontColor,
|
||||
#Make text bold; use -Bold:$false to remove bold
|
||||
[switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic
|
||||
[switch]$Italic,
|
||||
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
|
||||
[switch]$Underline,
|
||||
#Should Underline use single or double, normal or accounting mode : default is single normal
|
||||
#Colour for the text - if none specified it will be left as it it is.
|
||||
$FontColor,
|
||||
#Make text bold; use -Bold:$false to remove bold.
|
||||
[Switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic.
|
||||
[Switch]$Italic,
|
||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||
[Switch]$Underline,
|
||||
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||
#Strike through text; use -Strikethru:$false to remove Strike through
|
||||
[switch]$StrikeThru,
|
||||
#Subscript or superscript (or none)
|
||||
#Strike through text; use -StrikeThru:$false to remove strike through.
|
||||
[Switch]$StrikeThru,
|
||||
#Subscript or Superscript (or None).
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||
#Font to use - Excel defaults to Calibri
|
||||
#Font to use - Excel defaults to Calibri.
|
||||
[String]$FontName,
|
||||
#Point size for the text
|
||||
#Point size for the text.
|
||||
[float]$FontSize,
|
||||
#Change background colour
|
||||
[System.Drawing.Color]$BackgroundColor,
|
||||
#Background pattern - solid by default
|
||||
#Change background color.
|
||||
$BackgroundColor,
|
||||
#Background pattern - "Solid" by default.
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||
#Secondary colour for background pattern
|
||||
#Secondary color for background pattern.
|
||||
[Alias("PatternColour")]
|
||||
[System.Drawing.Color]$PatternColor,
|
||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
|
||||
[switch]$WrapText,
|
||||
#Position cell contents to left, right, center etc. default is 'General'
|
||||
$PatternColor,
|
||||
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||
[Switch]$WrapText,
|
||||
#Position cell contents to Left, Right, Center etc. Default is "General".
|
||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||
#Position cell contents to top bottom or centre
|
||||
#Position cell contents to Top, Bottom or Center.
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
||||
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise.
|
||||
[ValidateRange(-90, 90)]
|
||||
[int]$TextRotation ,
|
||||
#Autofit cells to width
|
||||
#Attempt to auto-fit cells to the width their contents.
|
||||
[Alias("AutoFit")]
|
||||
[Switch]$AutoSize,
|
||||
#Set cells to a fixed width, ignored if Autosize is specified
|
||||
#Set cells to a fixed width, ignored if -AutoSize is specified.
|
||||
[float]$Width,
|
||||
#Set the inserted data to be a named range (ignored if header is not specified)
|
||||
#Set the inserted data to be a named range.
|
||||
[Switch]$AutoNameRange,
|
||||
#If Sepecified returns the range of cells which affected
|
||||
[switch]$ReturnRange,
|
||||
#If Specified, return an ExcelPackage object to allow further work to be done on the file.
|
||||
[switch]$PassThru
|
||||
#Hide the column.
|
||||
[Switch]$Hide,
|
||||
#If specified, returns the range of cells which were affected.
|
||||
[Switch]$Specified,
|
||||
#If specified, return an object representing the Column, to allow further work to be done on it.
|
||||
[Switch]$PassThru
|
||||
)
|
||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
|
||||
|
||||
#In a script block to build a formula, we may want any of corners or the columnname,
|
||||
#if column and startrow aren't specified, assume first unused column, and first row
|
||||
if (-not $StartRow) {$startRow = $Worksheet.Dimension.Start.Row }
|
||||
$StartColumn = $Worksheet.Dimension.Start.Column
|
||||
$endColumn = $Worksheet.Dimension.End.Column
|
||||
$endRow = $Worksheet.Dimension.End.Row
|
||||
if ($Column -lt 2 ) {$Column = $endColumn + 1 }
|
||||
$ColumnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
begin {
|
||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
|
||||
|
||||
Write-Verbose -Message "Updating Column $ColumnName"
|
||||
#If there is a heading, insert it and use it as the name for a range (if we're creating one)
|
||||
if ($Heading) {
|
||||
$Worksheet.Cells[$StartRow, $Column].Value = $heading
|
||||
$startRow ++
|
||||
if ($AutoNameRange) { $Worksheet.Names.Add( $heading, ($Worksheet.Cells[$startrow, $Column, $endRow, $Column]) ) | Out-Null }
|
||||
#In a script block to build a formula, we may want any of corners or the column name,
|
||||
#if Column and Startrow aren't specified, assume first unused column, and first row
|
||||
if (-not $StartRow) {$startRow = $Worksheet.Dimension.Start.Row }
|
||||
$startColumn = $Worksheet.Dimension.Start.Column
|
||||
$endColumn = $Worksheet.Dimension.End.Column
|
||||
$endRow = $Worksheet.Dimension.End.Row
|
||||
}
|
||||
#Fill in the data
|
||||
if ($PSBoundParameters.ContainsKey('value')) { foreach ($row in ($StartRow.. $endRow)) {
|
||||
if ($Value -is [scriptblock]) { #re-create the script block otherwise variables from this function are out of scope.
|
||||
$cellData = & ([scriptblock]::create( $Value ))
|
||||
Write-Verbose -Message $cellData
|
||||
process {
|
||||
if ($null -eq $workSheet.Dimension) {Write-Warning "Can't format an empty worksheet."; return}
|
||||
if ($Column -eq 0 ) {$Column = $endColumn + 1 }
|
||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
Write-Verbose -Message "Updating Column $columnName"
|
||||
#If there is a heading, insert it and use it as the name for a range (if we're creating one)
|
||||
if ($PSBoundParameters.ContainsKey('Heading')) {
|
||||
$Worksheet.Cells[$StartRow, $Column].Value = $Heading
|
||||
$StartRow ++
|
||||
if ($AutoNameRange) {
|
||||
Add-ExcelName -Range $Worksheet.Cells[$StartRow, $Column, $endRow, $Column] -RangeName $Heading
|
||||
}
|
||||
}
|
||||
else { $cellData = $Value}
|
||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $Column].Formula = $cellData }
|
||||
else { $Worksheet.Cells[$Row, $Column].Value = $cellData }
|
||||
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
|
||||
}}
|
||||
#region Apply formatting
|
||||
$params = @{}
|
||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru','FontSize','FontShift','NumberFormat','TextRotation',
|
||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Autosize', 'Width', 'FontColor'
|
||||
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||
elseif ($AutoNameRange) {
|
||||
Add-ExcelName -Range $Worksheet.Cells[($StartRow+1), $Column, $endRow, $Column] -RangeName $Worksheet.Cells[$StartRow, $Column].Value
|
||||
}
|
||||
|
||||
#Fill in the data -it can be zero null or and empty string.
|
||||
if ($PSBoundParameters.ContainsKey('Value')) { foreach ($row in ($StartRow..$endRow)) {
|
||||
if ($Value -is [scriptblock]) { #re-create the script block otherwise variables from this function are out of scope.
|
||||
$cellData = & ([scriptblock]::create( $Value ))
|
||||
Write-Verbose -Message $cellData
|
||||
}
|
||||
else { $cellData = $Value}
|
||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $Column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
|
||||
elseif ( [System.Uri]::IsWellFormedUriString($cellData , [System.UriKind]::Absolute)) {
|
||||
# Save a hyperlink : internal links can be in the form xl://sheet!E419 (use A1 as goto sheet), or xl://RangeName
|
||||
if ($cellData -match "^xl://internal/") {
|
||||
$referenceAddress = $cellData -replace "^xl://internal/" , ""
|
||||
$display = $referenceAddress -replace "!A1$" , ""
|
||||
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
||||
$Worksheet.Cells[$Row, $Column].HyperLink = $h
|
||||
}
|
||||
else {$Worksheet.Cells[$Row, $Column].HyperLink = $cellData }
|
||||
$Worksheet.Cells[$Row, $Column].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
||||
$Worksheet.Cells[$Row, $Column].Style.Font.UnderLine = $true
|
||||
}
|
||||
else { $Worksheet.Cells[$Row, $Column].Value = $cellData }
|
||||
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
|
||||
if ($cellData -is [timespan]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = '[h]:mm:ss' }
|
||||
}}
|
||||
|
||||
#region Apply formatting
|
||||
$params = @{}
|
||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru', 'FontName', 'FontSize','FontShift','NumberFormat','TextRotation',
|
||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Autosize', 'Width', 'FontColor'
|
||||
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||
}
|
||||
if ($params.Count) {
|
||||
$theRange = "$columnName$StartRow`:$columnName$endRow"
|
||||
Set-ExcelRange -WorkSheet $Worksheet -Range $theRange @params
|
||||
}
|
||||
#endregion
|
||||
if ($PSBoundParameters.ContainsKey('Hide')) {$workSheet.Column($Column).Hidden = [bool]$Hide}
|
||||
#return the new data if -passthru was specified.
|
||||
if ($PassThru) { $Worksheet.Column($Column)}
|
||||
elseif ($ReturnRange) { $theRange}
|
||||
}
|
||||
$theRange = "$ColumnName$startRow`:$ColumnName$endRow"
|
||||
if ($params.Count) {
|
||||
Set-Format -WorkSheet $Worksheet -Range $theRange @params
|
||||
}
|
||||
#endregion
|
||||
#return the new data if -passthru was specified.
|
||||
if ($passThru) { $Worksheet.Column( $Column)}
|
||||
elseif ($ReturnRange) { $theRange}
|
||||
}
|
||||
245
Set-Row.ps1
245
Set-Row.ps1
@@ -1,131 +1,184 @@
|
||||
Function Set-Row {
|
||||
Function Set-ExcelRow {
|
||||
<#
|
||||
.Synopsis
|
||||
Fills values into a [new] row in an Excel spreadsheet. To format a row without setting values, use Set-Format.
|
||||
Fills values into a [new] row in an Excel spreadsheet, and sets row formats.
|
||||
.Description
|
||||
Set-Row accepts either a Worksheet object or an Excel package object returned by Export-Excel and the name of a sheet,
|
||||
and inserts the chosen contents into a row of the sheet.
|
||||
The contents can be a constant "42" , a formula or a script block which is converted into a constant or formula.
|
||||
The first cell of the row can optional be given a heading.
|
||||
Set-ExcelRow accepts either a Worksheet object or an ExcelPackage object
|
||||
returned by Export-Excel and the name of a sheet, and inserts the chosen
|
||||
contents into a row of the sheet. The contents can be a constant,
|
||||
like "42", a formula or a script block which is converted into a
|
||||
constant or a formula.
|
||||
The first cell of the row can optionally be given a heading.
|
||||
.Example
|
||||
Set-row -Worksheet $ws -Heading Total -Value {"=sum($columnName`2:$columnName$endrow)" }
|
||||
Set-ExcelRow -Worksheet $ws -Heading Total -Value {"=sum($columnName`2:$columnName$endrow)" }
|
||||
|
||||
$Ws contains a worksheet object, and no Row number is specified so Set-Row will select the next row after the end of the data in the sheet
|
||||
The first cell will contain "Total", and each other cell will contain
|
||||
=Sum(xx2:xx99) - where xx is the column name, and 99 is the last row of data.
|
||||
Note the use of `2 to Prevent 2 becoming part of the variable "ColumnName"
|
||||
The script block can use $row, $column, $ColumnName, $startRow/Column $endRow/Column
|
||||
$Ws contains a worksheet object, and no Row number is specified so
|
||||
Set-ExcelRow will select the next row after the endof the data in
|
||||
the sheet. The first cell in the row will contain "Total", and
|
||||
each of the other cells will contain
|
||||
=Sum(xx2:xx99)
|
||||
where xx is the column name, and 99 is the last row of data.
|
||||
Note the use of `2 to Prevent 2 becoming part of the variable "ColumnName"
|
||||
The script block can use $Worksheet, $Row, $Column (number),
|
||||
$ColumnName (letter), $StartRow/Column and $EndRow/Column.
|
||||
.Example
|
||||
Set-ExcelRow -Worksheet $ws -Heading Total -HeadingBold -Value {"=sum($columnName`2:$columnName$endrow)" } -NumberFormat 'Currency' -StartColumn 2 -Bold -BorderTop Double -BorderBottom Thin
|
||||
|
||||
This builds on the previous example, but this time the label "Total"
|
||||
appears in column 2 and the formula fills from column 3 onwards.
|
||||
The formula and heading are set in bold face, and the formula is
|
||||
formatted for the local currency, and given a double line border
|
||||
above and single line border below.
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Row")]
|
||||
[OutputType([OfficeOpenXml.ExcelRow],[String])]
|
||||
Param (
|
||||
#An Excel package object - e.g. from Export-Excel -passthru - requires a sheet name
|
||||
#An Excel package object - e.g. from Export-Excel -PassThru - requires a sheet name.
|
||||
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
#the name to update in the package
|
||||
#The name of the sheet to update in the package.
|
||||
[Parameter(ParameterSetName="Package")]
|
||||
$Worksheetname = "Sheet1",
|
||||
#A worksheet object
|
||||
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
|
||||
[OfficeOpenXml.Excelworksheet]
|
||||
$Worksheet,
|
||||
#Row to fill right - first row is 1. 0 will be interpreted as first unused row
|
||||
#A worksheet object instead of passing a name and package.
|
||||
[Parameter(ParameterSetName="Sheet",Mandatory=$true)]
|
||||
[OfficeOpenXml.Excelworksheet] $Worksheet,
|
||||
#Row to fill right - first row is 1. 0 will be interpreted as first unused row.
|
||||
[Parameter(ValueFromPipeline = $true)]
|
||||
$Row = 0 ,
|
||||
#Position in the row to start from
|
||||
[Int]$StartColumn,
|
||||
#value, formula or script block for to fill in. Script block can use $row, $column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
|
||||
[parameter(Mandatory=$true)]
|
||||
#Position in the row to start from.
|
||||
[int]$StartColumn,
|
||||
#Value, Formula or ScriptBlock to fill in. A ScriptBlock can use $worksheet, $row, $Column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn.
|
||||
$Value,
|
||||
#Optional Row heading
|
||||
#Optional row-heading.
|
||||
$Heading ,
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc
|
||||
#Set the heading in bold type.
|
||||
[Switch]$HeadingBold,
|
||||
#Change the font-size of the heading.
|
||||
[Int]$HeadingSize ,
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc.
|
||||
[Alias("NFormat")]
|
||||
$NumberFormat,
|
||||
#Style of border to draw around the row
|
||||
#Style of border to draw around the row.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||
#Colour for the text - if none specified it will be left as it it is
|
||||
[System.Drawing.Color]$FontColor,
|
||||
#Make text bold; use -Bold:$false to remove bold
|
||||
[switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic
|
||||
[switch]$Italic,
|
||||
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
|
||||
[switch]$Underline,
|
||||
#Should Underline use single or double, normal or accounting mode : default is single normal
|
||||
#Color of the border.
|
||||
$BorderColor=[System.Drawing.Color]::Black,
|
||||
#Style for the bottom border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
||||
#Style for the top border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderTop,
|
||||
#Style for the left border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
|
||||
#Style for the right border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||
#Color for the text - if none specified it will be left as it it is.
|
||||
$FontColor,
|
||||
#Make text bold; use -Bold:$false to remove bold.
|
||||
[Switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic.
|
||||
[Switch]$Italic,
|
||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||
[Switch]$Underline,
|
||||
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||
#Strike through text; use -Strikethru:$false to remove Strike through
|
||||
[switch]$StrikeThru,
|
||||
#Subscript or superscript (or none)
|
||||
#Strike through text; use -StrikeThru:$false to remove strike through.
|
||||
[Switch]$StrikeThru,
|
||||
#Subscript or Superscript (or none).
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||
#Font to use - Excel defaults to Calibri.
|
||||
[String]$FontName,
|
||||
#Point size for the text
|
||||
#Point size for the text.
|
||||
[float]$FontSize,
|
||||
#Change background colour
|
||||
[System.Drawing.Color]$BackgroundColor,
|
||||
#Background pattern - solid by default
|
||||
#Change background color.
|
||||
$BackgroundColor,
|
||||
#Background pattern - solid by default.
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||
#Secondary colour for background pattern
|
||||
#Secondary color for background pattern.
|
||||
[Alias("PatternColour")]
|
||||
[System.Drawing.Color]$PatternColor,
|
||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
|
||||
[switch]$WrapText,
|
||||
#Position cell contents to left, right, center etc. default is 'General'
|
||||
$PatternColor,
|
||||
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||
[Switch]$WrapText,
|
||||
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||
#Position cell contents to top bottom or centre
|
||||
#Position cell contents to Top, Bottom or Center.
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
||||
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise
|
||||
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise.
|
||||
[ValidateRange(-90, 90)]
|
||||
[int]$TextRotation ,
|
||||
#Set cells to a fixed hieght
|
||||
#Set cells to a fixed height.
|
||||
[float]$Height,
|
||||
#If Sepecified returns the range of cells which affected
|
||||
[switch]$ReturnRange,
|
||||
#If Specified, return a row object to allow further work to be done
|
||||
[switch]$PassThru
|
||||
#Hide the row.
|
||||
[Switch]$Hide,
|
||||
#If sepecified, returns the range of cells which were affected.
|
||||
[Switch]$ReturnRange,
|
||||
#If Specified, return a row object to allow further work to be done.
|
||||
[Switch]$PassThru
|
||||
)
|
||||
begin {
|
||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.worksheets[$Worksheetname] }
|
||||
|
||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.worksheets[$Worksheetname] }
|
||||
|
||||
#In a script block to build a formula, we may want any of corners or the columnname,
|
||||
#if row and start column aren't specified assume first unused row, and first column
|
||||
if (-not $StartColumn) {$StartColumn = $Worksheet.Dimension.Start.Column }
|
||||
$startRow = $Worksheet.Dimension.Start.Row + 1
|
||||
$endColumn = $Worksheet.Dimension.End.Column
|
||||
$endRow = $Worksheet.Dimension.End.Row
|
||||
if ($Row -lt 2 ) {$Row = $endRow + 1 }
|
||||
Write-Verbose -Message "Updating Row $Row"
|
||||
#Add a row label
|
||||
if ($Heading) {
|
||||
$Worksheet.Cells[$Row, $StartColumn].Value = $Heading
|
||||
$StartColumn ++
|
||||
#In a script block to build a formula, we may want any of corners or the columnname,
|
||||
#if row and start column aren't specified assume first unused row, and first column
|
||||
if (-not $StartColumn) {$StartColumn = $Worksheet.Dimension.Start.Column }
|
||||
$startRow = $Worksheet.Dimension.Start.Row + 1
|
||||
$endColumn = $Worksheet.Dimension.End.Column
|
||||
$endRow = $Worksheet.Dimension.End.Row
|
||||
}
|
||||
#Fill in the data
|
||||
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$EndColumn)) {
|
||||
#We might want the column name in a script block
|
||||
$ColumnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
if ($Value -is [scriptblock] ) {
|
||||
#re-create the script block otherwise variables from this function are out of scope.
|
||||
$cellData = & ([scriptblock]::create( $Value ))
|
||||
Write-Verbose -Message $cellData
|
||||
process {
|
||||
if ($null -eq $workSheet.Dimension) {Write-Warning "Can't format an empty worksheet."; return}
|
||||
if ($Row -eq 0 ) {$Row = $endRow + 1 }
|
||||
Write-Verbose -Message "Updating Row $Row"
|
||||
#Add a row label
|
||||
if ($Heading) {
|
||||
$Worksheet.Cells[$Row, $StartColumn].Value = $Heading
|
||||
if ($HeadingBold) {$Worksheet.Cells[$Row, $StartColumn].Style.Font.Bold = $true}
|
||||
if ($HeadingSize) {$Worksheet.Cells[$Row, $StartColumn].Style.Font.Size = $HeadingSize}
|
||||
$StartColumn ++
|
||||
}
|
||||
else{$cellData = $Value}
|
||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = $cellData }
|
||||
else { $Worksheet.Cells[$Row, $column].Value = $cellData }
|
||||
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $column].Style.Numberformat.Format = 'm/d/yy h:mm' } # This is not a custom format, but a preset recognized as date and localized.
|
||||
}}
|
||||
#region Apply formatting
|
||||
$params = @{}
|
||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru','FontSize', 'FontShift','NumberFormat','TextRotation',
|
||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Height', 'FontColor'
|
||||
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||
#Fill in the data
|
||||
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) {
|
||||
#We might want the column name in a script block
|
||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
if ($Value -is [scriptblock] ) {
|
||||
#re-create the script block otherwise variables from this function are out of scope.
|
||||
$cellData = & ([scriptblock]::create( $Value ))
|
||||
Write-Verbose -Message $cellData
|
||||
}
|
||||
else{$cellData = $Value}
|
||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
|
||||
elseif ( [System.Uri]::IsWellFormedUriString($cellData , [System.UriKind]::Absolute)) {
|
||||
# Save a hyperlink : internal links can be in the form xl://sheet!E419 (use A1 as goto sheet), or xl://RangeName
|
||||
if ($cellData -match "^xl://internal/") {
|
||||
$referenceAddress = $cellData -replace "^xl://internal/" , ""
|
||||
$display = $referenceAddress -replace "!A1$" , ""
|
||||
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
||||
$Worksheet.Cells[$Row, $Column].HyperLink = $h
|
||||
}
|
||||
else {$Worksheet.Cells[$Row, $Column].HyperLink = $cellData }
|
||||
$Worksheet.Cells[$Row, $Column].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
||||
$Worksheet.Cells[$Row, $Column].Style.Font.UnderLine = $true
|
||||
}
|
||||
else { $Worksheet.Cells[$Row, $column].Value = $cellData }
|
||||
if ($cellData -is [datetime]) { $Worksheet.Cells[$Row, $column].Style.Numberformat.Format = 'm/d/yy h:mm' } #This is not a custom format, but a preset recognized as date and localized.
|
||||
if ($cellData -is [timespan]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = '[h]:mm:ss' }
|
||||
}}
|
||||
#region Apply formatting
|
||||
$params = @{}
|
||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru', 'FontName', 'FontSize', 'FontShift','NumberFormat','TextRotation',
|
||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Height', 'FontColor'
|
||||
'BorderAround', 'BorderBottom', 'BorderTop', 'BorderLeft', 'BorderRight', 'BorderColor',
|
||||
'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||
}
|
||||
if ($params.Count) {
|
||||
$theRange = [OfficeOpenXml.ExcelAddress]::New($Row, $StartColumn, $Row, $endColumn)
|
||||
Set-ExcelRange -WorkSheet $Worksheet -Range $theRange @params
|
||||
}
|
||||
#endregion
|
||||
if ($PSBoundParameters.ContainsKey('Hide')) {$workSheet.Row($Row).Hidden = [bool]$Hide}
|
||||
#return the new data if -passthru was specified.
|
||||
if ($passThru) {$Worksheet.Row($Row)}
|
||||
elseif ($ReturnRange) {$theRange}
|
||||
}
|
||||
$theRange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$Row]C[$StartColumn]:R[$Row]C[$EndColumn]",0,0)
|
||||
if ($params.Count) {
|
||||
Set-Format -WorkSheet $Worksheet -Range $theRange @params
|
||||
}
|
||||
#endregion
|
||||
#return the new data if -passthru was specified.
|
||||
if ($passThru) {$Worksheet.Row($Row)}
|
||||
elseif ($ReturnRange) {$theRange}
|
||||
}
|
||||
402
SetFormat.ps1
402
SetFormat.ps1
@@ -1,205 +1,377 @@
|
||||
Function Set-Format {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Applies Number, font, alignment and colour formatting to a range of Excel Cells
|
||||
.EXAMPLE
|
||||
$sheet.Column(3) | Set-Format -HorizontalAlignment Right -NumberFormat "#,###"
|
||||
Selects column 3 from a sheet object (within a workbook object, which is a child of the ExcelPackage object) and passes it to Set-Format which formats as an integer with comma seperated groups
|
||||
.EXAMPLE
|
||||
Set-Format -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NumberFormat "#,###"
|
||||
Instead of piping the address in this version specifies a block of cells and applies similar formatting
|
||||
Function Set-ExcelRange {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Applies number, font, alignment and/or color formatting, values or formulas to a range of Excel cells.
|
||||
.DESCRIPTION
|
||||
Set-ExcelRange was created to set the style elements for a range of cells,
|
||||
this includes auto-sizing and hiding, setting font elements (Name, Size,
|
||||
Bold, Italic, Underline & UnderlineStyle and Subscript & SuperScript),
|
||||
font and background colors, borders, text wrapping, rotation, alignment
|
||||
within cells, and number format.
|
||||
It was orignally named "Set-Format", but it has been extended to set
|
||||
Values, Formulas and ArrayFormulas (sometimes called Ctrl-shift-Enter
|
||||
[CSE] formulas); because of this, the name has become Set-ExcelRange
|
||||
but the old name of Set-Format is preserved as an alias.
|
||||
.EXAMPLE
|
||||
$sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NumberFormat "#,###" -AutoFit
|
||||
|
||||
#>
|
||||
Selects column 3 from a sheet object (within a workbook object, which
|
||||
is a child of the ExcelPackage object) and passes it to Set-ExcelRange
|
||||
which formats numbers as a integers with comma-separated groups,
|
||||
aligns it right, and auto-fits the column to the contents.
|
||||
.EXAMPLE
|
||||
Set-ExcelRange -Range $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NumberFormat "#,###"
|
||||
|
||||
Instead of piping the address, this version specifies a block of cells
|
||||
and applies similar formatting.
|
||||
.EXAMPLE
|
||||
Set-ExcelRange $excel.Workbook.Worksheets[1].Tables["Processes"] -Italic
|
||||
|
||||
This time instead of specifying a range of cells, a table is selected
|
||||
by name and formatted as italic.
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Format")]
|
||||
Param (
|
||||
#One or more row(s), Column(s) and/or block(s) of cells to format
|
||||
[Parameter(ValueFromPipeline = $true,ParameterSetName="Address",Mandatory=$True,Position=0)]
|
||||
$Address ,
|
||||
#The worksheet where the format is to be applied
|
||||
[Parameter(ParameterSetName="SheetAndRange",Mandatory=$True)]
|
||||
#One or more row(s), Column(s) and/or block(s) of cells to format.
|
||||
[Parameter(ValueFromPipeline = $true,Position=0)]
|
||||
[Alias("Address")]
|
||||
$Range ,
|
||||
#The worksheet where the format is to be applied.
|
||||
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
|
||||
#The area of the worksheet where the format is to be applied
|
||||
[Parameter(ParameterSetName="SheetAndRange",Mandatory=$True)]
|
||||
[OfficeOpenXml.ExcelAddress]$Range,
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc.
|
||||
[Alias("NFormat")]
|
||||
$NumberFormat,
|
||||
#Style of border to draw around the range
|
||||
#Style of border to draw around the range.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||
[System.Drawing.Color]$BorderColor=[System.Drawing.Color]::Black,
|
||||
#Color of the border.
|
||||
$BorderColor=[System.Drawing.Color]::Black,
|
||||
#Style for the bottom border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
||||
#Style for the top border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderTop,
|
||||
#Style for the left border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
|
||||
#Style for the right border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||
#Colour for the text - if none specified it will be left as it it is
|
||||
[System.Drawing.Color]$FontColor,
|
||||
#Value for the cell
|
||||
#Colour for the text - if none is specified it will be left as it is.
|
||||
$FontColor,
|
||||
#Value for the cell.
|
||||
$Value,
|
||||
#Formula for the cell
|
||||
#Formula for the cell.
|
||||
$Formula,
|
||||
#Clear Bold, Italic, StrikeThrough and Underline and set colour to black
|
||||
[switch]$ResetFont,
|
||||
#Make text bold; use -Bold:$false to remove bold
|
||||
[switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic
|
||||
[switch]$Italic,
|
||||
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining
|
||||
[switch]$Underline,
|
||||
#Should Underline use single or double, normal or accounting mode : default is single normal
|
||||
#Specifies formula should be an array formula (a.k.a CSE [ctrl-shift-enter] formula).
|
||||
[Switch]$ArrayFormula,
|
||||
#Clear Bold, Italic, StrikeThrough and Underline and set color to Black.
|
||||
[Switch]$ResetFont,
|
||||
#Make text bold; use -Bold:$false to remove bold.
|
||||
[Switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic.
|
||||
[Switch]$Italic,
|
||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||
[Switch]$Underline,
|
||||
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||
#Strike through text; use -Strikethru:$false to remove Strike through
|
||||
[switch]$StrikeThru,
|
||||
#Subscript or superscript (or none)
|
||||
[Switch]$StrikeThru,
|
||||
#Subscript or Superscript (or none).
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||
#Font to use - Excel defaults to Calibri
|
||||
#Font to use - Excel defaults to Calibri.
|
||||
[String]$FontName,
|
||||
#Point size for the text
|
||||
#Point size for the text.
|
||||
[float]$FontSize,
|
||||
#Change background colour
|
||||
[System.Drawing.Color]$BackgroundColor,
|
||||
#Background pattern - solid by default
|
||||
#Change background color.
|
||||
$BackgroundColor,
|
||||
#Background pattern - Solid by default.
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||
#Secondary colour for background pattern
|
||||
#Secondary color for background pattern.
|
||||
[Alias("PatternColour")]
|
||||
[System.Drawing.Color]$PatternColor,
|
||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping
|
||||
[switch]$WrapText,
|
||||
#Position cell contents to left, right, center etc. default is 'General'
|
||||
$PatternColor,
|
||||
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||
[Switch]$WrapText,
|
||||
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||
#Position cell contents to top bottom or center
|
||||
#Position cell contents to Top, Bottom or Center.
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
||||
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise.
|
||||
[ValidateRange(-90, 90)]
|
||||
[int]$TextRotation ,
|
||||
#Autofit cells to width (columns or ranges only)
|
||||
#Autofit cells to width (columns or ranges only).
|
||||
[Alias("AutoFit")]
|
||||
[Switch]$AutoSize,
|
||||
#Set cells to a fixed width (columns or ranges only), ignored if Autosize is specified
|
||||
#Set cells to a fixed width (columns or ranges only), ignored if Autosize is specified.
|
||||
[float]$Width,
|
||||
#Set cells to a fixed hieght (rows or ranges only)
|
||||
#Set cells to a fixed height (rows or ranges only).
|
||||
[float]$Height,
|
||||
#Hide a row or column (not a range); use -Hidden:$false to unhide
|
||||
[switch]$Hidden
|
||||
#Hide a row or column (not a range); use -Hidden:$false to unhide.
|
||||
[Switch]$Hidden
|
||||
)
|
||||
begin {
|
||||
#Allow Set-Format to take Worksheet and range parameters (like Add Contitional formatting) - convert them to an address
|
||||
if ($WorkSheet -and $Range) {$Address = $WorkSheet.Cells[$Range] }
|
||||
}
|
||||
|
||||
process {
|
||||
if ($Address -is [Array]) {
|
||||
[void]$PSBoundParameters.Remove("Address")
|
||||
$Address | Set-Format @PSBoundParameters
|
||||
if ($Range -is [Array]) {
|
||||
[void]$PSBoundParameters.Remove("Range")
|
||||
$Range | Set-ExcelRange @PSBoundParameters
|
||||
}
|
||||
else {
|
||||
#We should accept, a worksheet and a name of a range or a cell address; a table; the address of a table; a named range; a row, a column or .Cells[ ]
|
||||
if ($Range -is [OfficeOpenXml.Table.ExcelTable]) {$Range = $Range.Address}
|
||||
elseif ($WorkSheet -and ($Range -is [string] -or $Range -is [OfficeOpenXml.ExcelAddress])) {
|
||||
$Range = $WorkSheet.Cells[$Range]
|
||||
}
|
||||
elseif ($Range -is [string]) {Write-Warning -Message "The range pararameter you have specified also needs a worksheet parameter."}
|
||||
|
||||
if ($ResetFont) {
|
||||
$Address.Style.Font.Color.SetColor("Black")
|
||||
$Address.Style.Font.Bold = $false
|
||||
$Address.Style.Font.Italic = $false
|
||||
$Address.Style.Font.UnderLine = $false
|
||||
$Address.Style.Font.Strike = $false
|
||||
$Range.Style.Font.Color.SetColor( ([System.Drawing.Color]::Black))
|
||||
$Range.Style.Font.Bold = $false
|
||||
$Range.Style.Font.Italic = $false
|
||||
$Range.Style.Font.UnderLine = $false
|
||||
$Range.Style.Font.Strike = $false
|
||||
$Range.Style.Font.VerticalAlign = [OfficeOpenXml.Style.ExcelVerticalAlignmentFont]::None
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Underline')) {
|
||||
$Address.Style.Font.UnderLine = [boolean]$Underline
|
||||
$Address.Style.Font.UnderLineType = $UnderLineType
|
||||
$Range.Style.Font.UnderLine = [boolean]$Underline
|
||||
$Range.Style.Font.UnderLineType = $UnderLineType
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Bold')) {
|
||||
$Address.Style.Font.Bold = [boolean]$bold
|
||||
$Range.Style.Font.Bold = [boolean]$bold
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Italic')) {
|
||||
$Address.Style.Font.Italic = [boolean]$italic
|
||||
$Range.Style.Font.Italic = [boolean]$italic
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('StrikeThru')) {
|
||||
$Address.Style.Font.Strike = [boolean]$StrikeThru
|
||||
$Range.Style.Font.Strike = [boolean]$StrikeThru
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('FontSize')){
|
||||
$Address.Style.Font.Size = $FontSize
|
||||
$Range.Style.Font.Size = $FontSize
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('FontName')){
|
||||
$Range.Style.Font.Name = $FontName
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('FontShift')){
|
||||
$Address.Style.Font.VerticalAlign = $FontShift
|
||||
$Range.Style.Font.VerticalAlign = $FontShift
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('FontColor')){
|
||||
$Address.Style.Font.Color.SetColor( $FontColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('NumberFormat')) {
|
||||
$Address.Style.Numberformat.Format = $NumberFormat
|
||||
if ($FontColor -is [string]) {$FontColor = [System.Drawing.Color]::$FontColor }
|
||||
$Range.Style.Font.Color.SetColor( $FontColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('TextRotation')) {
|
||||
$Address.Style.TextRotation = $TextRotation
|
||||
$Range.Style.TextRotation = $TextRotation
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('WrapText')) {
|
||||
$Address.Style.WrapText = [boolean]$WrapText
|
||||
$Range.Style.WrapText = [boolean]$WrapText
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('HorizontalAlignment')) {
|
||||
$Address.Style.HorizontalAlignment = $HorizontalAlignment
|
||||
$Range.Style.HorizontalAlignment = $HorizontalAlignment
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('VerticalAlignment')) {
|
||||
$Address.Style.VerticalAlignment = $VerticalAlignment
|
||||
$Range.Style.VerticalAlignment = $VerticalAlignment
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Value')) {
|
||||
$Address.Value = $Value
|
||||
if ($Value -match '^=') {$PSBoundParameters["Formula"] = $Value -replace '^=','' }
|
||||
else {
|
||||
$Range.Value = $Value
|
||||
if ($Value -is [datetime]) { $Range.Style.Numberformat.Format = 'm/d/yy h:mm' }# This is not a custom format, but a preset recognized as date and localized. It might be overwritten in a moment
|
||||
if ($Value -is [timespan]) { $Range.Style.Numberformat.Format = '[h]:mm:ss' }
|
||||
}
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Formula')) {
|
||||
$Address.Formula = $Formula
|
||||
if ($ArrayFormula) {$Range.CreateArrayFormula(($Formula -replace '^=','')) }
|
||||
else {$Range.Formula = ($Formula -replace '^=','') }
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('NumberFormat')) {
|
||||
$Range.Style.Numberformat.Format = (Expand-NumberFormat $NumberFormat)
|
||||
}
|
||||
if ($BorderColor -is [string]) {$BorderColor = [System.Drawing.Color]::$BorderColor }
|
||||
if ($PSBoundParameters.ContainsKey('BorderAround')) {
|
||||
$Address.Style.Border.BorderAround($BorderAround, $BorderColor)
|
||||
$Range.Style.Border.BorderAround($BorderAround, $BorderColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('BorderBottom')) {
|
||||
$Address.Style.Border.Bottom.Style=$BorderBottom
|
||||
$Address.Style.Border.Bottom.Color.SetColor($BorderColor)
|
||||
$Range.Style.Border.Bottom.Style=$BorderBottom
|
||||
$Range.Style.Border.Bottom.Color.SetColor($BorderColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('BorderTop')) {
|
||||
$Address.Style.Border.Top.Style=$BorderTop
|
||||
$Address.Style.Border.Top.Color.SetColor($BorderColor)
|
||||
$Range.Style.Border.Top.Style=$BorderTop
|
||||
$Range.Style.Border.Top.Color.SetColor($BorderColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('BorderLeft')) {
|
||||
$Address.Style.Border.Left.Style=$BorderLeft
|
||||
$Address.Style.Border.Left.Color.SetColor($BorderColor)
|
||||
$Range.Style.Border.Left.Style=$BorderLeft
|
||||
$Range.Style.Border.Left.Color.SetColor($BorderColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('BorderRight')) {
|
||||
$Address.Style.Border.Right.Style=$BorderRight
|
||||
$Address.Style.Border.Right.Color.SetColor($BorderColor)
|
||||
$Range.Style.Border.Right.Style=$BorderRight
|
||||
$Range.Style.Border.Right.Color.SetColor($BorderColor)
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('BackgroundColor')) {
|
||||
$Address.Style.Fill.PatternType = $BackgroundPattern
|
||||
$Address.Style.Fill.BackgroundColor.SetColor($BackgroundColor)
|
||||
$Range.Style.Fill.PatternType = $BackgroundPattern
|
||||
if ($BackgroundColor -is [string]) {$BackgroundColor = [System.Drawing.Color]::$BackgroundColor }
|
||||
$Range.Style.Fill.BackgroundColor.SetColor($BackgroundColor)
|
||||
if ($PatternColor) {
|
||||
$Address.Style.Fill.PatternColor.SetColor( $PatternColor)
|
||||
if ($PatternColor -is [string]) {$PatternColor = [System.Drawing.Color]::$PatternColor }
|
||||
$Range.Style.Fill.PatternColor.SetColor( $PatternColor)
|
||||
}
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Height')) {
|
||||
if ($Address -is [OfficeOpenXml.ExcelRow] ) {$Address.Height = $Height }
|
||||
elseif ($Address -is [OfficeOpenXml.ExcelRange] ) {
|
||||
($Address.Start.Row)..($Address.Start.Row + $Address.Rows) |
|
||||
ForEach-Object {$Address.WorkSheet.Row($_).Height = $Height }
|
||||
if ($Range -is [OfficeOpenXml.ExcelRow] ) {$Range.Height = $Height }
|
||||
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
|
||||
($Range.Start.Row)..($Range.Start.Row + $Range.Rows) |
|
||||
ForEach-Object {$Range.WorkSheet.Row($_).Height = $Height }
|
||||
}
|
||||
else {Write-Warning -Message ("Can set the height of a row or a range but not a {0} object" -f ($Address.GetType().name)) }
|
||||
else {Write-Warning -Message ("Can set the height of a row or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
}
|
||||
if ($Autosize) {
|
||||
if ($Address -is [OfficeOpenXml.ExcelColumn]) {$Address.AutoFit() }
|
||||
elseif ($Address -is [OfficeOpenXml.ExcelRange] ) {
|
||||
$Address.AutoFitColumns()
|
||||
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.AutoFit() }
|
||||
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
|
||||
$Range.AutoFitColumns()
|
||||
}
|
||||
else {Write-Warning -Message ("Can autofit a column or a range but not a {0} object" -f ($Address.GetType().name)) }
|
||||
else {Write-Warning -Message ("Can autofit a column or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
|
||||
}
|
||||
elseif ($PSBoundParameters.ContainsKey('Width')) {
|
||||
if ($Address -is [OfficeOpenXml.ExcelColumn]) {$Address.Width = $Width}
|
||||
elseif ($Address -is [OfficeOpenXml.ExcelRange] ) {
|
||||
($Address.Start.Column)..($Address.Start.Column + $Address.Columns - 1) |
|
||||
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.Width = $Width}
|
||||
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
|
||||
($Range.Start.Column)..($Range.Start.Column + $Range.Columns - 1) |
|
||||
ForEach-Object {
|
||||
#$ws.Column($_).Width = $Width
|
||||
$Address.Worksheet.Column($_).Width = $Width
|
||||
$Range.Worksheet.Column($_).Width = $Width
|
||||
}
|
||||
}
|
||||
else {Write-Warning -Message ("Can set the width of a column or a range but not a {0} object" -f ($Address.GetType().name)) }
|
||||
else {Write-Warning -Message ("Can set the width of a column or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('$Hidden')) {
|
||||
if ($Address -is [OfficeOpenXml.ExcelRow] -or
|
||||
$Address -is [OfficeOpenXml.ExcelColumn] ) {$Address.Hidden = [boolean]$Hidden}
|
||||
else {Write-Warning -Message ("Can hide a row or a column but not a {0} object" -f ($Address.GetType().name)) }
|
||||
if ($PSBoundParameters.ContainsKey('Hidden')) {
|
||||
if ($Range -is [OfficeOpenXml.ExcelRow] -or
|
||||
$Range -is [OfficeOpenXml.ExcelColumn] ) {$Range.Hidden = [boolean]$Hidden}
|
||||
else {Write-Warning -Message ("Can hide a row or a column but not a {0} object" -f ($Range.GetType().name)) }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function NumberFormatCompletion {
|
||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||
$numformats = [ordered]@{
|
||||
"General" = "General" # format ID 0
|
||||
"Number" = "0.00" # format ID 2
|
||||
"Percentage" = "0.00%" # format ID 10
|
||||
"Scientific" = "0.00E+00" # format ID 11
|
||||
"Fraction" = "# ?/?" # format ID 12
|
||||
"Short Date" = "Localized" # format ID 14 - will be translated to "mm-dd-yy" which is localized on load by Excel.
|
||||
"Short Time" = "Localized" # format ID 20 - will be translated to "h:mm" which is localized on load by Excel.
|
||||
"Long Time" = "Localized" # format ID 21 - will be translated to "h:mm:ss" which is localized on load by Excel.
|
||||
"Date-Time" = "Localized" # format ID 22 - will be translated to "m/d/yy h:mm" which is localized on load by Excel.
|
||||
"Currency" = [cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol + "#,##0.00"
|
||||
"Text" = "@" # format ID 49
|
||||
"h:mm AM/PM" = "h:mm AM/PM" # format ID 18
|
||||
"h:mm:ss AM/PM" = "h:mm:ss AM/PM" # format ID 19
|
||||
"mm:ss" = "mm:ss" # format ID 45
|
||||
"[h]:mm:ss" = "Elapsed hours" # format ID 46
|
||||
"mm:ss.0" = "mm:ss.0" # format ID 47
|
||||
"d-mmm-yy" = "Localized" # format ID 15 which is localized on load by Excel.
|
||||
"d-mmm" = "Localized" # format ID 16 which is localized on load by Excel.
|
||||
"mmm-yy" = "mmm-yy" # format ID 17 which is localized on load by Excel.
|
||||
"0" = "Whole number" # format ID 1
|
||||
"0.00" = "Number, 2 decimals" # format ID 2 or "number"
|
||||
"#,##0" = "Thousand separators" # format ID 3
|
||||
"#,##0.00" = "Thousand separators and 2 decimals" # format ID 4
|
||||
"#," = "Whole thousands"
|
||||
"#.0,," = "Millions, 1 Decimal"
|
||||
"0%" = "Nearest whole percentage" # format ID 9
|
||||
"0.00%" = "Percentage with decimals" # format ID 10 or "Percentage"
|
||||
"00E+00" = "Scientific" # format ID 11 or "Scientific"
|
||||
"# ?/?" = "One Digit fraction" # format ID 12 or "Fraction"
|
||||
"# ??/??" = "Two Digit fraction" # format ID 13
|
||||
"@" = "Text" # format ID 49 or "Text"
|
||||
}
|
||||
$numformats.keys.where({$_ -like "$wordToComplete*"} ) | ForEach-Object {
|
||||
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'" , $_ ,
|
||||
([System.Management.Automation.CompletionResultType]::ParameterValue) , $numformats[$_]
|
||||
}
|
||||
}
|
||||
if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
|
||||
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Export-Excel -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Add-PivotTable -ParameterName PivotNumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName New-PivotTableDefinition -ParameterName PivotNumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelChartDefinition -ParameterName XAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelChartDefinition -ParameterName YAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Add-ExcelChart -ParameterName XAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Add-ExcelChart -ParameterName YAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
|
||||
}
|
||||
|
||||
Function Expand-NumberFormat {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Converts short names for number formats to the formatting strings used in Excel
|
||||
.DESCRIPTION
|
||||
Where you can type a number format you can write, for example, 'Short-Date'
|
||||
and the module will translate it into the format string used by Excel.
|
||||
Some formats, like Short-Date change how they are presented when Excel
|
||||
loads (so date will use the local ordering of year, month and Day). Other
|
||||
formats change how they appear when loaded with different cultures
|
||||
(depending on the country "," or "." or " " may be the thousand seperator
|
||||
although Excel always stores it as ",")
|
||||
.EXAMPLE
|
||||
Expand-NumberFormat percentage
|
||||
|
||||
Returns "0.00%"
|
||||
.EXAMPLE
|
||||
Expand-NumberFormat Currency
|
||||
|
||||
Returns the currency format specified in the local regional settings. This
|
||||
may not be the same as Excel uses. The regional settings set the currency
|
||||
symbol and then whether it is before or after the number and separated with
|
||||
a space or not; for negative numbers the number may be wrapped in parentheses
|
||||
or a - sign might appear before or after the number and symbol.
|
||||
So this returns $#,##0.00;($#,##0.00) for English US, #,##0.00 €;€#,##0.00-
|
||||
for French. (Note some Eurozone countries write €1,23 and others 1,23€ )
|
||||
In French the decimal point will be rendered as a "," and the thousand
|
||||
separator as a space.
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
[OutputType([String])]
|
||||
param (
|
||||
#the format string to Expand
|
||||
$NumberFormat
|
||||
)
|
||||
switch ($NumberFormat) {
|
||||
"Currency" {
|
||||
#https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencynegativepattern(v=vs.110).aspx
|
||||
$sign = [cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol
|
||||
switch ([cultureinfo]::CurrentCulture.NumberFormat.CurrencyPositivePattern) {
|
||||
0 {$pos = "$Sign#,##0.00" ; break }
|
||||
1 {$pos = "#,##0.00$Sign" ; break }
|
||||
2 {$pos = "$Sign #,##0.00" ; break }
|
||||
3 {$pos = "#,##0.00 $Sign" ; break }
|
||||
}
|
||||
switch ([cultureinfo]::CurrentCulture.NumberFormat.CurrencyPositivePattern) {
|
||||
0 {return "$pos;($Sign#,##0.00)" }
|
||||
1 {return "$pos;-$Sign#,##0.00" }
|
||||
2 {return "$pos;$Sign-#,##0.00" }
|
||||
3 {return "$pos;$Sign#,##0.00-" }
|
||||
4 {return "$pos;(#,##0.00$Sign)" }
|
||||
5 {return "$pos;-#,##0.00$Sign" }
|
||||
6 {return "$pos;#,##0.00-$Sign" }
|
||||
7 {return "$pos;#,##0.00$Sign-" }
|
||||
8 {return "$pos;-#,##0.00 $Sign" }
|
||||
9 {return "$pos;-$Sign #,##0.00" }
|
||||
10 {return "$pos;#,##0.00 $Sign-" }
|
||||
11 {return "$pos;$Sign #,##0.00-" }
|
||||
12 {return "$pos;$Sign -#,##0.00" }
|
||||
13 {return "$pos;#,##0.00- $Sign" }
|
||||
14 {return "$pos;($Sign #,##0.00)" }
|
||||
15 {return "$pos;(#,##0.00 $Sign)" }
|
||||
}
|
||||
}
|
||||
"Number" {return "0.00" } # format id 2
|
||||
"Percentage" {return "0.00%" } # format id 10
|
||||
"Scientific" {return "0.00E+00" } # format id 11
|
||||
"Fraction" {return "# ?/?" } # format id 12
|
||||
"Short Date" {return "mm-dd-yy" } # format id 14 localized on load by Excel.
|
||||
"Short Time" {return "h:mm" } # format id 20 localized on load by Excel.
|
||||
"Long Time" {return "h:mm:ss" } # format id 21 localized on load by Excel.
|
||||
"Date-Time" {return "m/d/yy h:mm"} # format id 22 localized on load by Excel.
|
||||
"Text" {return "@" } # format ID 49
|
||||
Default {return $NumberFormat}
|
||||
}
|
||||
}
|
||||
|
||||
11
ToDo.md
11
ToDo.md
@@ -1,11 +0,0 @@
|
||||
- [ ] Create an autocomplete for WorkSheetName param on ImportExcel and for number format ; where number format exists Translate "Date", "DateTime", "Currency"
|
||||
|
||||
- [ ] Add help text for parmaters which don't have it ( PivotDataToColumn , NoClobber and CellStyleSB ) in Export Excel, copy to Send-SQLDataToExcel
|
||||
- [ ] Support "make worksheet active"
|
||||
- [ ] Add checks for valid worksheet names (also check pivot names, range names and table names are valid)
|
||||
- [ ] Investigate regional support for number conversion & possible date conversion
|
||||
- [ ] Add help in ConvertToExcelXLSx.ps1, Get-HTMLTable.ps1, GetRange.PS1, GetExcelTable.Ps1, Import-HTML.PS1, New-ConditionalFormattingIconSet.Ps1, NewConditionalText.PS1, New-Psitem.PS1, Remove-Worksheet.ps1 and Add-ExcelChart - Copy parameter help from function Add-ExcelChart into New-ExcelChart.ps1
|
||||
- [ ] Examples and tests for new "Quick charts" in Export Excel (replace examples) that use Charting.ps1, GetXYRange.ps1, InferData.PS1 (move these to deprecated).
|
||||
- [ ] Test Add PivotTable selecting source sheet by position , UnhideSheet, and Wildcard support for hideSheet
|
||||
- [ ] Test return range support to Set-Row and Set-Column and add examples to examples for set-Row and Set-column set-format, add-Conditional format (e.g. from tests)
|
||||
- [ ] Increase code covereage for import-excel and Set-Format
|
||||
@@ -1,19 +0,0 @@
|
||||
$xlFile = ".\testExport.xlsx"
|
||||
|
||||
Remove-Item -ErrorAction Ignore $xlFile
|
||||
|
||||
$ExportOptions = @{
|
||||
Path = $xlFile
|
||||
Show = $true
|
||||
IncludePivotTable = $true
|
||||
IncludePivotChart = $true
|
||||
PivotRows = echo Company Name
|
||||
PivotData = "PM"
|
||||
ChartType = "BarClustered3D"
|
||||
#Password = "Test"
|
||||
}
|
||||
|
||||
Get-Process |
|
||||
Where Company |
|
||||
Select Company, Name, Handles, PM |
|
||||
Export-Excel @ExportOptions
|
||||
@@ -1,11 +1,12 @@
|
||||
#Requires -Modules Pester
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
if ($PSVersionTable.PSVersion.Major -gt 5) { Write-Warning "Can't test grid view on V6" }
|
||||
else {Add-Type -AssemblyName System.Windows.Forms }
|
||||
Describe "Compare Worksheet" {
|
||||
Context "Simple comparison output" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path "$env:temp\server*.xlsx"
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property *
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name, RequiredServices, CanPauseAndContinue, CanShutdown, CanStop, DisplayName, DependentServices, MachineName
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
@@ -49,8 +50,9 @@ Describe "Compare Worksheet" {
|
||||
|
||||
Context "Setting the background to highlight different rows, use of grid view." {
|
||||
BeforeAll {
|
||||
Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor LightGreen -GridView
|
||||
Start-Sleep -sec 5; [System.Windows.Forms.SendKeys]::Sendwait("%{F4}")
|
||||
$useGrid = ($PSVersionTable.PSVersion.Major -LE 5)
|
||||
$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView:$useGrid
|
||||
if ($useGrid) {Start-Sleep -sec 5; [System.Windows.Forms.SendKeys]::Sendwait("%{F4}") }
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||
@@ -76,7 +78,7 @@ Describe "Compare Worksheet" {
|
||||
|
||||
Context "Setting the forgound to highlight changed properties" {
|
||||
BeforeAll {
|
||||
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -AllDataBackgroundColor white -BackgroundColor LightGreen -FontColor DarkRed
|
||||
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -AllDataBackgroundColor([System.Drawing.Color]::white) -BackgroundColor ([System.Drawing.Color]::LightGreen) -FontColor ([System.Drawing.Color]::DarkRed)
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||
@@ -105,7 +107,8 @@ Describe "Compare Worksheet" {
|
||||
|
||||
Context "More complex comparison: output check and different worksheet names " {
|
||||
BeforeAll {
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property * -ExcludeProperty Name
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property RequiredServices, CanPauseAndContinue, CanShutdown, CanStop,
|
||||
DisplayName, DependentServices, MachineName, ServiceName, ServicesDependedOn, ServiceHandle, Status, ServiceType, StartType -ExcludeProperty Name
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx -WorkSheetname Server1
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
@@ -117,9 +120,10 @@ Describe "Compare Worksheet" {
|
||||
$row6Name = $s[5].ServiceName
|
||||
$s.RemoveAt(5)
|
||||
$s[10].ServiceType = "Changed should not matter"
|
||||
|
||||
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path $env:temp\server2.xlsx -WorkSheetname server2
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -WorkSheetName Server1,Server2 -Key ServiceName -Property DisplayName,StartType -AllDataBackgroundColor AliceBlue -BackgroundColor White -FontColor Red | Sort-Object _row,_file
|
||||
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -WorkSheetName Server1,Server2 -Key ServiceName -Property DisplayName,StartType -AllDataBackgroundColor ([System.Drawing.Color]::AliceBlue) -BackgroundColor ([System.Drawing.Color]::White) -FontColor ([System.Drawing.Color]::Red) | Sort-Object _row,_file
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
|
||||
@@ -168,8 +172,8 @@ Describe "Compare Worksheet" {
|
||||
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | Should beNullOrEmpty
|
||||
}
|
||||
AfterAll {
|
||||
Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
|
||||
Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
|
||||
# Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
|
||||
# Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +239,7 @@ Describe "Merge Worksheet" {
|
||||
}
|
||||
}
|
||||
Context "Wider data set" {
|
||||
it "Copes with more columns beyond Z in the Output sheet " {
|
||||
it "Coped with columns beyond Z in the Output sheet " {
|
||||
{ Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined2.xlsx" } | Should not throw
|
||||
}
|
||||
}
|
||||
@@ -319,19 +323,21 @@ Describe "Merge Multiple sheets" {
|
||||
}
|
||||
it "Creared Conditional formatting rules " {
|
||||
$cf=$ws.ConditionalFormatting
|
||||
$cf.Count | Should be 15
|
||||
$cf[14].Address.Address | Should be 'B2:B1048576'
|
||||
$cf.Count | Should be 17
|
||||
$cf[16].Address.Address | Should be 'B2:B1048576'
|
||||
$cf[16].Type | Should be 'Expression'
|
||||
$cf[16].Formula | Should be 'OR(G2<>"Same",K2<>"Same")'
|
||||
$cf[16].Style.Font.Color.Color.Name | Should be "FFFF0000"
|
||||
$cf[14].Address.Address | Should be 'D2:D1048576'
|
||||
$cf[14].Type | Should be 'Expression'
|
||||
$cf[14].Formula | Should be 'OR(G2<>"Same",K2<>"Same")'
|
||||
$cf[14].Style.Font.Color.Color.Name | Should be "FFFF0000"
|
||||
$cf[13].Address.Address | Should be 'D2:D1048576'
|
||||
$cf[13].Type | Should be 'Expression'
|
||||
$cf[13].Formula | Should be 'OR(G2="Added",K2="Added")'
|
||||
$cf[13].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffb6c1'
|
||||
$cf[14].Formula | Should be 'OR(G2="Added",K2="Added")'
|
||||
$cf[14].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffb6c1'
|
||||
$cf[14].Style.Fill.PatternType.ToString() | Should be 'Solid'
|
||||
$cf[ 0].Address.Address | Should be 'F1:F1048576'
|
||||
$cf[ 0].Type | Should be 'Expression'
|
||||
$cf[ 0].Formula | Should be 'G1="Added"'
|
||||
$cf[ 0].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffa500'
|
||||
$cf[ 0].Style.Fill.PatternType.ToString() | Should be 'Solid'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ Remove-item -Path $path1, $path2 -ErrorAction SilentlyContinue
|
||||
|
||||
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
|
||||
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
|
||||
else {$OtherCurrencySymbol = "£"}
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "<EFBFBD>") {$OtherCurrencySymbol = "$"}
|
||||
else {$OtherCurrencySymbol = "<EFBFBD>"}
|
||||
[PSCustOmobject][Ordered]@{
|
||||
Date = Get-Date
|
||||
Formula1 = '=SUM(F2:G2)'
|
||||
@@ -25,8 +25,8 @@ else {$OtherCurrencySymbol = "
|
||||
StrE164Phone = '+32 (444) 444 4444'
|
||||
StrAltPhone1 = '+32 4 4444 444'
|
||||
StrAltPhone2 = '+3244444444'
|
||||
StrLeadSpace = ' 123'
|
||||
StrTrailSpace = '123 '
|
||||
StrLeadSpace = ' 123'
|
||||
StrTrailSpace = '123 '
|
||||
Link1 = [uri]"https://github.com/dfinke/ImportExcel"
|
||||
Link2 = "https://github.com/dfinke/ImportExcel" # Links are not copied correctly, hopefully this will be fixed at some future date
|
||||
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -WorkSheetname MixedTypes -Path $path2
|
||||
@@ -37,7 +37,7 @@ Describe "Copy-Worksheet" {
|
||||
$excel = Open-ExcelPackage -Path $path2
|
||||
$ws = $excel.Workbook.Worksheets["Processes"]
|
||||
}
|
||||
it "inserted a worksheet " {
|
||||
it "Inserted a worksheet " {
|
||||
$Excel.Workbook.Worksheets.count | Should be 2
|
||||
$ws | Should not benullorEmpty
|
||||
$ws.Dimension.Address | should be $ProcRange
|
||||
@@ -50,14 +50,16 @@ Describe "Copy-Worksheet" {
|
||||
$excel = Open-ExcelPackage -Path $path2
|
||||
$ws = $Excel.Workbook.Worksheets[3]
|
||||
}
|
||||
it "inserted a worksheet with the expected name, number of rows and number of columns " {
|
||||
it "Copied a worksheet, giving the expected name, number of rows and number of columns " {
|
||||
$Excel.Workbook.Worksheets.count | Should be 3
|
||||
$ws | Should not benullorEmpty
|
||||
$ws.Name | Should be "CopyOfMixedTypes"
|
||||
$ws.Dimension.Columns | Should be 22
|
||||
$ws.Dimension.Rows | Should be 2
|
||||
}
|
||||
it "Copied the expected data into the worksheet " {
|
||||
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
|
||||
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
|
||||
$ws.Cells[2, 2].Formula | Should be 'SUM(F2:G2)'
|
||||
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#Requires -Modules Pester
|
||||
|
||||
# $here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
# Import-Module $here -Force -Verbose
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
if (Get-process -Name Excel,xlim -ErrorAction SilentlyContinue) { Write-Warning -Message "You need to close Excel before running the tests." ; return}
|
||||
Describe ExportExcel {
|
||||
@@ -10,7 +8,8 @@ Describe ExportExcel {
|
||||
Context "#Example 1 # Creates and opens a file with the right number of rows and columns" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
$processes = Get-Process
|
||||
#Test with a maximum of 100 processes for speed; export all properties, then export smaller subsets.
|
||||
$processes = Get-Process | select-object -first 100 -Property * -excludeProperty Parent
|
||||
$propertyNames = $Processes[0].psobject.properties.name
|
||||
$rowcount = $Processes.Count
|
||||
$Processes | Export-Excel $path #-show
|
||||
@@ -20,7 +19,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
# it "Started Excel to display the file " {
|
||||
# Get-process -Name Excel, xlim -ErrorAction SilentlyContinue | Should not benullorempty
|
||||
# Get-process -Name Excel, xlim -ErrorAction SilentlyContinue | Should not beNullOrEmpty
|
||||
# }
|
||||
#Start-Sleep -Seconds 5 ;
|
||||
|
||||
@@ -29,11 +28,16 @@ Describe ExportExcel {
|
||||
#TODO Need to test opening pre-existing file with no -create switch (and graceful failure when file does not exist) somewhere else
|
||||
$Excel = Open-ExcelPackage -Path $path -KillExcel
|
||||
it "Killed Excel when Open-Excelpackage was told to " {
|
||||
Get-process -Name Excel, xlim -ErrorAction SilentlyContinue | Should benullorempty
|
||||
Get-process -Name Excel, xlim -ErrorAction SilentlyContinue | Should beNullOrEmpty
|
||||
}
|
||||
|
||||
it "Created 1 worksheet " {
|
||||
it "Created 1 worksheet, named 'Sheet1' " {
|
||||
$Excel.Workbook.Worksheets.count | Should be 1
|
||||
$Excel.Workbook.Worksheets["Sheet1"] | Should not beNullOrEmpty
|
||||
}
|
||||
|
||||
it "Added a 'Sheet1' property to the Package object " {
|
||||
$Excel.Sheet1 | Should not beNullOrEmpty
|
||||
}
|
||||
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
@@ -50,7 +54,7 @@ Describe ExportExcel {
|
||||
}
|
||||
}
|
||||
|
||||
it "Formatted the process StartTime field as 'local short date' " {
|
||||
it "Formatted the process StartTime field as 'localized Date-Time' " {
|
||||
$STHeader = $ws.cells["1:1"].where( {$_.Value -eq "StartTime"})[0]
|
||||
$STCell = $STHeader.Address -replace '1$', '2'
|
||||
$ws.cells[$stcell].Style.Numberformat.NumFmtID | Should be 22
|
||||
@@ -66,16 +70,16 @@ Describe ExportExcel {
|
||||
Context " # NoAliasOrScriptPropeties -ExcludeProperty and -DisplayPropertySet work" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
$processes = Get-Process
|
||||
$processes = Get-Process | Select-Object -First 100
|
||||
$propertyNames = $Processes[0].psobject.properties.where( {$_.MemberType -eq 'Property'}).name
|
||||
$rowcount = $Processes.Count
|
||||
#TestCreating a range with a name which needs illegal chars removing
|
||||
#Test -NoAliasOrScriptPropeties option and creating a range with a name which needs illegal chars removing - check this sends back a warning
|
||||
$warnVar = $null
|
||||
$Processes | Export-Excel $path -NoAliasOrScriptPropeties -RangeName "No Spaces" -WarningVariable warnvar -WarningAction SilentlyContinue
|
||||
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
it "Created a new file with alias & Script Properties removed. " {
|
||||
it "Created a new file with Alias & Script Properties removed. " {
|
||||
$ws.Name | Should be "sheet1"
|
||||
$ws.Dimension.Columns | Should be $propertyNames.Count
|
||||
$ws.Dimension.Rows | Should be ($rowcount + 1 ) # +1 for the header.
|
||||
@@ -86,19 +90,20 @@ Describe ExportExcel {
|
||||
$ws.names["No_spaces"].End.Row | Should be ($rowcount + 1 ) # +1 for the header.
|
||||
$warnVar.Count | Should be 1
|
||||
}
|
||||
#This time use clearsheet instead of deleting the file
|
||||
$Processes | Export-Excel $path -NoAliasOrScriptPropeties -ExcludeProperty SafeHandle, modules, MainModule, StartTime, Threads -ClearSheet
|
||||
#This time use clearsheet instead of deleting the file test -Exclude properties, including wildcards.
|
||||
$Processes | Export-Excel $path -ClearSheet -NoAliasOrScriptPropeties -ExcludeProperty SafeHandle, threads, modules, MainModule, StartInfo, MachineName, MainWindow*, M*workingSet
|
||||
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
it "Created a new file with a further 5 properties excluded and cleared the old sheet " {
|
||||
it "Created a new file with further properties excluded and cleared the old sheet " {
|
||||
$ws.Name | Should be "sheet1"
|
||||
$ws.Dimension.Columns | Should be ($propertyNames.Count - 5)
|
||||
$ws.Dimension.Columns | Should be ($propertyNames.Count - 10)
|
||||
$ws.Dimension.Rows | Should be ($rowcount + 1) # +1 for the header
|
||||
}
|
||||
|
||||
$propertyNames = $Processes[0].psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test -DisplayPropertySet
|
||||
$Processes | Export-Excel $path -DisplayPropertySet
|
||||
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
@@ -114,11 +119,11 @@ Describe ExportExcel {
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#testing -ReturnRange switch
|
||||
$returnedRange = Write-Output -1 668 34 777 860 -0.5 119 -0.1 234 788,"=A9+A10" | Export-Excel -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00' -Path $path -ReturnRange
|
||||
#testing -ReturnRange switch and applying number format to Formulas as well as values.
|
||||
$returnedRange = @($null, -1, 0, 34, 777, "", -0.5, 119, -0.1, 234, 788,"=A9+A10") | Export-Excel -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00' -Path $path -ReturnRange
|
||||
it "Created a new file and returned the expected range " {
|
||||
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
|
||||
$returnedRange | Should be "A1:A11"
|
||||
$returnedRange | Should be "A1:A12"
|
||||
}
|
||||
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
@@ -130,16 +135,43 @@ Describe ExportExcel {
|
||||
it "Created the worksheet with the expected name, number of rows and number of columns " {
|
||||
$ws.Name | Should be "sheet1"
|
||||
$ws.Dimension.Columns | Should be 1
|
||||
$ws.Dimension.Rows | Should be 11
|
||||
$ws.Dimension.Rows | Should be 12
|
||||
}
|
||||
|
||||
it "Set the default style for the sheet as expected " {
|
||||
$ws.cells.Style.Numberformat.Format | Should be '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||
}
|
||||
|
||||
it "Set the default style and value for Cell A1 as expected " {
|
||||
it "Set the default style and set values for Cells as expected, handling null,0 and '' " {
|
||||
$ws.cells[1, 1].Style.Numberformat.Format | Should be '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||
$ws.cells[1, 1].Value | Should be -1
|
||||
$ws.cells[1, 1].Value | Should beNullorEmpty
|
||||
$ws.cells[2, 1].Value | Should be -1
|
||||
$ws.cells[3, 1].Value | Should be 0
|
||||
$ws.cells[5, 1].Value | Should be 777
|
||||
$ws.cells[6, 1].Value | Should be ""
|
||||
$ws.cells[4, 1].Style.Numberformat.Format | Should be '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Context " # Number format parameter" {
|
||||
BeforeAll {
|
||||
$path = "$env:temp\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
1..10 | Export-Excel -Path $path -Numberformat 'Number'
|
||||
1..10 | Export-Excel -Path $path -Numberformat 'Percentage' -Append
|
||||
21..30 | Export-Excel -Path $path -Numberformat 'Currency' -StartColumn 3
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
}
|
||||
it "Set the worksheet default number format correctly " {
|
||||
$ws.Cells.Style.Numberformat.Format | Should be "0.00"
|
||||
}
|
||||
it "Set number formats on specific blocks of cells " {
|
||||
$ws.Cells["A2" ].Style.Numberformat.Format | Should be "0.00"
|
||||
$ws.Cells["c19"].Style.Numberformat.Format | Should be "0.00"
|
||||
$ws.Cells["A20"].Style.Numberformat.Format | Should be "0.00%"
|
||||
$ws.Cells["C6" ].Style.Numberformat.Format | Should be (Expand-NumberFormat "currency")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,10 +180,12 @@ Describe ExportExcel {
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
|
||||
else {$OtherCurrencySymbol = "£"}
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$warnVar = $null
|
||||
#Test correct export of different data types and number formats; test hyperlinks, test -NoNumberConversion test object is converted to a string with no warnings, test calcuation of formula
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
[PSCustOmobject][Ordered]@{
|
||||
Date = Get-Date
|
||||
Formula1 = '=SUM(F2:G2)'
|
||||
Formula1 = '=SUM(S2:T2)'
|
||||
String1 = 'My String'
|
||||
Float = [math]::pi
|
||||
IPAddress = '10.10.25.5'
|
||||
@@ -163,8 +197,8 @@ Describe ExportExcel {
|
||||
StrNegInt = '-31'
|
||||
StrTrailingNeg = '31-'
|
||||
StrParens = '(123)'
|
||||
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
|
||||
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
|
||||
strLocalCurrency = ('{0}123{1}45' -f (Get-Culture).NumberFormat.CurrencySymbol,(Get-Culture).NumberFormat.CurrencyDecimalSeparator)
|
||||
strOtherCurrency = ('{0}123{1}45' -f $OtherCurrencySymbol ,(Get-Culture).NumberFormat.CurrencyDecimalSeparator)
|
||||
StrE164Phone = '+32 (444) 444 4444'
|
||||
StrAltPhone1 = '+32 4 4444 444'
|
||||
StrAltPhone2 = '+3244444444'
|
||||
@@ -174,30 +208,37 @@ Describe ExportExcel {
|
||||
Link2 = "https://github.com/dfinke/ImportExcel"
|
||||
Link3 = "xl://internal/sheet1!A1"
|
||||
Link4 = "xl://internal/sheet1!C5"
|
||||
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -Path $path
|
||||
Link5 = (New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList "Sheet1!E2" , "Display Text")
|
||||
Process = (Get-Process -Id $PID)
|
||||
TimeSpan = [datetime]::Now.Subtract([datetime]::Today)
|
||||
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -Path $path -Calculate -WarningVariable $warnVar
|
||||
it "Created a new file " {
|
||||
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
|
||||
}
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
it "Created 1 worksheet " {
|
||||
it "Created 1 worksheet with no warnings " {
|
||||
$Excel.Workbook.Worksheets.count | Should be 1
|
||||
$warnVar | Should beNullorEmpty
|
||||
}
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
it "Created the worksheet with the expected name, number of rows and number of columns " {
|
||||
$ws.Name | Should be "sheet1"
|
||||
$ws.Dimension.Columns | Should be 24
|
||||
$ws.Dimension.Columns | Should be 27
|
||||
$ws.Dimension.Rows | Should be 2
|
||||
}
|
||||
it "Set a date in Cell A2 " {
|
||||
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
|
||||
}
|
||||
it "Set a formula in Cell B2 " {
|
||||
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
|
||||
$ws.Cells[2, 2].Formula | Should be 'SUM(S2:T2)'
|
||||
}
|
||||
it "Forced a successful calculation of the Value in Cell B2 " {
|
||||
$ws.Cells[2, 2].Value | Should be 246
|
||||
}
|
||||
it "Set strings in Cells E2, F2 and R2 (no number conversion) " {
|
||||
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
|
||||
}
|
||||
it "Set numbers in Cells K2,L2,M2 (diferent Negative integer formats) " {
|
||||
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
|
||||
@@ -218,6 +259,8 @@ Describe ExportExcel {
|
||||
$ws.Cells[2, 24].Hyperlink.Scheme | Should be "xl"
|
||||
$ws.Cells[2, 24].Hyperlink.ReferenceAddress | Should be "sheet1!c5"
|
||||
$ws.Cells[2, 24].Hyperlink.Display | Should be "sheet1!c5"
|
||||
$ws.Cells[2, 25].Hyperlink.ReferenceAddress | Should be "sheet1!E2"
|
||||
$ws.Cells[2, 25].Hyperlink.Display | Should be "Display Text"
|
||||
}
|
||||
it "Processed thousands according to local settings (Cells H2 and I2) " {
|
||||
if ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ",") {
|
||||
@@ -241,12 +284,21 @@ Describe ExportExcel {
|
||||
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
|
||||
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
|
||||
}
|
||||
it "Converted a nested object to a string (Y2) " {
|
||||
$ws.Cells[2, 26].Value | Should match '^System\.Diagnostics\.Process\s+\(.*\)$'
|
||||
}
|
||||
it "Processed a timespan object (Z2) " {
|
||||
$ws.cells[2, 27].Value.ToOADate() | Should beGreaterThan 0
|
||||
$ws.cells[2, 27].Value.ToOADate() | Should beLessThan 1
|
||||
$ws.cells[2, 27].Style.Numberformat.Format | Should be '[h]:mm:ss'
|
||||
}
|
||||
}
|
||||
|
||||
Context "# # Setting cells for different data types with -noHeader" {
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test -NoHeader & -NoNumberConversion
|
||||
[PSCustOmobject][Ordered]@{
|
||||
Date = Get-Date
|
||||
Formula1 = '=SUM(F1:G1)'
|
||||
@@ -280,11 +332,11 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
it "Set a date in Cell A1 " {
|
||||
$ws.Cells[1, 1].Value.Gettype().name | Should be 'DateTime'
|
||||
$ws.Cells[1, 1].Value.Gettype().name | Should be 'DateTime'
|
||||
}
|
||||
|
||||
it "Set a formula in Cell B1 " {
|
||||
$ws.Cells[1, 2].Formula | Should be '=SUM(F1:G1)'
|
||||
$ws.Cells[1, 2].Formula | Should be 'SUM(F1:G1)'
|
||||
}
|
||||
|
||||
it "Set strings in Cells E1 and F1 " {
|
||||
@@ -302,23 +354,19 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context "#Example 5 # Adding a single conditional format " {
|
||||
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor DarkRed -BackgroundColor LightPink
|
||||
it "Created a Conditional format description " {
|
||||
$ct.BackgroundColor -is [System.Drawing.Color] | Should be $true
|
||||
$ct.ConditionalTextColor -is [System.Drawing.Color] | Should be $true
|
||||
$ct.ConditionalType -in [enum]::GetNames( [OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType] ) |
|
||||
Should be $true
|
||||
}
|
||||
#Test New-ConditionalText builds correctly
|
||||
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor ([System.Drawing.Color]::DarkRed) -BackgroundColor ([System.Drawing.Color]::LightPink)
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test -ConditionalText with a single conditional spec.
|
||||
Write-Output 489 668 299 777 860 151 119 497 234 788 | Export-Excel -Path $path -ConditionalText $ct
|
||||
|
||||
it "Created a new file " {
|
||||
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
|
||||
}
|
||||
|
||||
#ToDo need to test applying conitional formatting to a pre-existing worksheet
|
||||
#ToDo need to test applying conitional formatting to a pre-existing worksheet and removing = from formula
|
||||
$Excel = Open-ExcelPackage -Path $path
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
|
||||
@@ -333,21 +381,19 @@ Describe ExportExcel {
|
||||
$cf.Type.ToString() | Should be $ct.ConditionalType
|
||||
#$cf.Style.Fill.BackgroundColor | Should be $ct.BackgroundColor
|
||||
# $cf.Style.Font.Color | Should be $ct.ConditionalTextColor - have to compare r.g.b
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Context "#Example 6 # Adding multiple conditional formats using short form syntax. " {
|
||||
#this is a test of adding more than one conditional block and using the minimal syntax for new-ConditionalText =
|
||||
#Test adding mutliple conditional blocks and using the minimal syntax for new-ConditionalText
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
|
||||
#Testing -Passthrough
|
||||
$Excel = Get-Service | Select-Object Name, Status, DisplayName, ServiceName |
|
||||
Export-Excel $path -PassThru -ConditionalText $(
|
||||
New-ConditionalText Stop DarkRed LightPink
|
||||
New-ConditionalText Running Blue Cyan
|
||||
New-ConditionalText Stop ([System.Drawing.Color]::DarkRed) ([System.Drawing.Color]::LightPink)
|
||||
New-ConditionalText Running ([System.Drawing.Color]::Blue) ([System.Drawing.Color]::Cyan)
|
||||
)
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
it "Added two blocks of conditional formating for the data range " {
|
||||
@@ -387,6 +433,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
$Array = $Obj1, $Obj2, $Obj3
|
||||
#test Update-FirstObjectProperties
|
||||
$newarray = $Array | Update-FirstObjectProperties
|
||||
it "Outputs as many objects as it input " {
|
||||
$newarray.Count | Should be $Array.Count
|
||||
@@ -402,20 +449,22 @@ Describe ExportExcel {
|
||||
|
||||
Context "#Examples 8 & 9 # Adding Pivot tables and charts from parameters" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
#This time we are not deleting the XLSX file so this Should create a new, named, sheet.
|
||||
$Excel = Get-Process | Select-Object -first 50 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -PassThru
|
||||
#Testing -passthru and adding the Pivot as a second step. Want to save and re-open it ...
|
||||
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -NoTotalsInPivot
|
||||
#Test -passthru and -worksheetName creating a new, named, sheet in an existing file.
|
||||
$Excel = Get-Process | Select-Object -first 20 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -PassThru
|
||||
#Testing -Excel Pacakage and adding a Pivot-table as a second step. Want to save and re-open it ...
|
||||
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -NoTotalsInPivot -PivotDataToColumn -Activate
|
||||
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$PTws = $Excel.Workbook.Worksheets["ProcessesPivotTable"]
|
||||
$wCount = $Excel.Workbook.Worksheets.Count
|
||||
it "Added the named sheet and pivot table to the workbook " {
|
||||
$excel.ProcessesPivotTable | Should not beNullOrEmpty
|
||||
$PTws | Should not beNullOrEmpty
|
||||
$PTws.PivotTables.Count | Should be 1
|
||||
$PTws.View.TabSelected | Should be $true
|
||||
$Excel.Workbook.Worksheets["Processes"] | Should not beNullOrEmpty
|
||||
$Excel.Workbook.Worksheets.Count | Should beGreaterThan 2
|
||||
# $excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 51 #50 data + 1 header
|
||||
$excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 21 #20 data + 1 header
|
||||
}
|
||||
$pt = $PTws.PivotTables[0]
|
||||
it "Built the expected Pivot table " {
|
||||
@@ -426,9 +475,9 @@ Describe ExportExcel {
|
||||
$pt.DataFields[0].Field.Name | Should be "PM"
|
||||
$PTws.Drawings.Count | Should be 0
|
||||
}
|
||||
#using the already open sheet add the pivot chart
|
||||
#test adding pivot chart using the already open sheet
|
||||
$warnvar = $null
|
||||
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -ShowCategory -NoLegend -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
Export-Excel -ExcelPackage $Excel -WorkSheetname Processes -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -ShowCategory -ShowPercent -NoLegend -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
$Excel = Open-ExcelPackage $path
|
||||
it "Added a chart to the pivot table without rebuilding " {
|
||||
$ws = $Excel.Workbook.Worksheets["ProcessesPivotTable"]
|
||||
@@ -439,15 +488,16 @@ Describe ExportExcel {
|
||||
it "Generated a message on re-processing the Pivot table " {
|
||||
$warnVar | Should not beNullOrEmpty
|
||||
}
|
||||
#Test appending data extends pivot chart (with a warning) .
|
||||
$warnVar = $null
|
||||
Get-Process | Select-Object -Last 50 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -Append -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
Get-Process | Select-Object -Last 20 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -Append -IncludePivotTable -PivotRows Company -PivotData PM -IncludePivotChart -ChartType PieExploded3D -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$pt = $Excel.Workbook.Worksheets["ProcessesPivotTable"].PivotTables[0]
|
||||
it "Appended to the Worksheet and Extended the Pivot table " {
|
||||
$Excel.Workbook.Worksheets.Count | Should be $wCount
|
||||
# $excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 101 #appended 50 rows to the previous total
|
||||
# $pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
# Should be "A1:E101"
|
||||
$excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 41 #appended 20 rows to the previous total
|
||||
$pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be "A1:E41"
|
||||
}
|
||||
it "Generated a message on extending the Pivot table " {
|
||||
$warnVar | Should not beNullOrEmpty
|
||||
@@ -456,14 +506,15 @@ Describe ExportExcel {
|
||||
|
||||
Context " # Add-Worksheet inserted sheets, moved them correctly, and copied a sheet" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
|
||||
#Test the -CopySource and -Movexxxx parameters for Add-WorkSheet
|
||||
$Excel = Open-ExcelPackage $path
|
||||
#At this point Sheets Should be in the order Sheet1, Processes, ProcessesPivotTable
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Processes" -MoveToEnd # order now Sheet1, ProcessesPivotTable, Processes
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "NewSheet" -MoveAfter "*" -CopySource ($excel.Workbook.Worksheets["Sheet1"]) # Now its NewSheet, Sheet1, ProcessesPivotTable, Processes
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Sheet1" -MoveAfter "Processes" # Now its NewSheet, ProcessesPivotTable, Processes, Sheet1
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "Another" -MoveToStart # Now its Another, NewSheet, ProcessesPivotTable, Processes, Sheet1
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "OneLast" -MoveBefore "ProcessesPivotTable" # Now its Another, NewSheet, Onelast, ProcessesPivotTable, Processes, Sheet1
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "NearDone" -MoveBefore 5 # Now its Another, NewSheet, ProcessesPivotTable, Processes, NearDone ,Sheet1
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname "OneLast" -MoveBefore "ProcessesPivotTable" # Now its Another, NewSheet, Onelast, ProcessesPivotTable, Processes,NearDone ,Sheet1
|
||||
Close-ExcelPackage $Excel
|
||||
|
||||
$Excel = Open-ExcelPackage $path
|
||||
@@ -474,7 +525,8 @@ Describe ExportExcel {
|
||||
$excel.Workbook.Worksheets[3].Name | Should be "Onelast"
|
||||
$excel.Workbook.Worksheets[4].Name | Should be "ProcessesPivotTable"
|
||||
$excel.Workbook.Worksheets[5].Name | Should be "Processes"
|
||||
$excel.Workbook.Worksheets[6].Name | Should be "Sheet1"
|
||||
$excel.Workbook.Worksheets[6].Name | Should be "NearDone"
|
||||
$excel.Workbook.Worksheets[7].Name | Should be "Sheet1"
|
||||
}
|
||||
|
||||
it "Cloned 'Sheet1' to 'NewSheet' " {
|
||||
@@ -489,11 +541,12 @@ Describe ExportExcel {
|
||||
|
||||
Context " # Create and append with Start row and Start Column, inc ranges and Pivot table. " {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Catch warning
|
||||
$warnVar = $null
|
||||
#Test Append with no existing sheet. Test adding a named pivot table from a command line parameter
|
||||
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -AutoFilter -AutoNameRange -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -PivotFilter Name -NoTotalsInPivot
|
||||
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -AutoFilter -AutoNameRange -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
#Test -Append with no existing sheet. Test adding a named pivot table from command line parameters and extending ranges when they're not specified explictly
|
||||
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -PivotFilter Name -NoTotalsInPivot -RangeName procs -AutoFilter -AutoNameRange
|
||||
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -StartRow 3 -StartColumn 3 -BoldTopRow -IncludePivotTable -PivotRows Company -PivotData PM -PivotTableName 'PTOffset' -Path $path -WorkSheetname withOffset -Append -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$dataWs = $Excel.Workbook.Worksheets["withOffset"]
|
||||
$pt = $Excel.Workbook.Worksheets["PTOffset"].PivotTables[0]
|
||||
@@ -503,23 +556,78 @@ Describe ExportExcel {
|
||||
$dataWs.Cells[3, 3].Value | Should not beNullOrEmpty
|
||||
$dataWs.Cells[3, 3].Style.Font.Bold | Should be $true
|
||||
$dataWs.Dimension.End.Row | Should be 23
|
||||
$dataWs.names[0].end.row | Should be 23
|
||||
$dataWs.names[0].name | Should be 'Name'
|
||||
$dataWs.names.Count | Should be 6
|
||||
$dataWs.names[0].Start.row | Should be 4 # StartRow + 1
|
||||
$dataWs.names[0].End.row | Should be $dataWs.Dimension.End.Row
|
||||
$dataWs.names[0].Name | Should be 'Name'
|
||||
$dataWs.names.Count | Should be 7 # Name, cpu, pm, handles & company + Named Range "Procs" + xl one for autofilter
|
||||
$dataWs.cells[$dataws.Dimension].AutoFilter | Should be true
|
||||
}
|
||||
it "Applied and auto-extended an autofilter " {
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Start.Row | Should be 3 #offset
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Start.Column | Should be 3
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Rows | Should be 21 #2 x 10 data + 1 header
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Columns | Should be 5 #Name, cpu, pm, handles & company
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].AutoFilter | Should be $true
|
||||
}
|
||||
it "Created and auto-extended the named ranges " {
|
||||
$dataWs.names["procs"].rows | Should be 21
|
||||
$dataWs.names["procs"].Columns | Should be 5
|
||||
$dataWs.Names["CPU"].Rows | Should be 20
|
||||
$dataWs.Names["CPU"].Columns | Should be 1
|
||||
}
|
||||
it "Created and extended the pivot table " {
|
||||
$pt.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be "C3:G23"
|
||||
Should be "C3:G23"
|
||||
$pt.ColumGrandTotals | Should be $false
|
||||
$pt.RowGrandTotals | Should be $false
|
||||
$pt.Fields["Company"].IsRowField | Should be $true
|
||||
$pt.Fields["PM"].IsDataField | Should be $true
|
||||
$pt.Fields["Name"].IsPageField | Should be $true
|
||||
}
|
||||
it "Generated a message on extending the Pivot table " {
|
||||
$warnVar | Should not beNullOrEmpty
|
||||
}
|
||||
}
|
||||
|
||||
Context " # Create and append explicit and auto table and range extension" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
#Test -Append automatically extends a table, even when it is not specified in the append command;
|
||||
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -Path $path -TableName ProcTab -AutoNameRange -WorkSheetname NoOffset -ClearSheet
|
||||
#Test number format applying to new data
|
||||
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -Path $path -AutoNameRange -WorkSheetname NoOffset -Append -Numberformat 'Number'
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$dataWs = $Excel.Workbook.Worksheets["NoOffset"]
|
||||
|
||||
it "Created a new sheet and auto-extended a table and explicitly extended named ranges " {
|
||||
$dataWs.Tables["ProcTab"].Address.Address | Should be "A1:E21"
|
||||
$dataWs.Names["CPU"].Rows | Should be 20
|
||||
$dataWs.Names["CPU"].Columns | Should be 1
|
||||
}
|
||||
it "Set the expected number formats " {
|
||||
$dataWs.cells["C2"].Style.Numberformat.Format | Should be "General"
|
||||
$dataWs.cells["C12"].Style.Numberformat.Format | Should be "0.00"
|
||||
}
|
||||
#Test extneding autofilter and range when explicitly specified in the append
|
||||
$excel = Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -ExcelPackage $excel -RangeName procs -AutoFilter -WorkSheetname NoOffset -ClearSheet -PassThru
|
||||
Get-Process | Select-Object -last 10 -Property Name, cpu, pm, handles, company | Export-Excel -ExcelPackage $excel -RangeName procs -AutoFilter -WorkSheetname NoOffset -Append
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$dataWs = $Excel.Workbook.Worksheets["NoOffset"]
|
||||
|
||||
it "Created a new sheet and explicitly extended named range and autofilter " {
|
||||
$dataWs.names["procs"].rows | Should be 21
|
||||
$dataWs.names["procs"].Columns | Should be 5
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Rows | Should be 21 #2 x 10 data + 1 header
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].Columns | Should be 5 #Name, cpu, pm, handles & company
|
||||
$dataWs.Names["_xlnm._FilterDatabase"].AutoFilter | Should be $true
|
||||
}
|
||||
}
|
||||
|
||||
Context "#Example 11 # Create and append with title, inc ranges and Pivot table" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
#Test New-PivotTableDefinition builds definition using -Pivotfilter and -PivotTotals options.
|
||||
$ptDef = [ordered]@{}
|
||||
$ptDef += New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet 'Sheet1' -PivotRows "Status" -PivotData @{'Status' = 'Count'} -PivotFilter "StartType" -IncludePivotChart -ChartType BarClustered3D -ChartTitle "Services by status" -ChartHeight 512 -ChartWidth 768 -ChartRow 10 -ChartColumn 0 -NoLegend
|
||||
$ptDef += New-PivotTableDefinition -PivotTableName "PT2" -SourceWorkSheet 'Sheet2' -PivotRows "Company" -PivotData @{'Company' = 'Count'} -IncludePivotChart -ChartType PieExploded3D -ShowPercent -WarningAction SilentlyContinue
|
||||
$ptDef += New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet 'Sheet1' -PivotRows "Status" -PivotData @{'Status' = 'Count'} -PivotTotals Columns -PivotFilter "StartType" -IncludePivotChart -ChartType BarClustered3D -ChartTitle "Services by status" -ChartHeight 512 -ChartWidth 768 -ChartRow 10 -ChartColumn 0 -NoLegend -PivotColumns CanPauseAndContinue
|
||||
$ptDef += New-PivotTableDefinition -PivotTableName "PT2" -SourceWorkSheet 'Sheet2' -PivotRows "Company" -PivotData @{'Company' = 'Count'} -PivotTotalS Rows -IncludePivotChart -ChartType PieExploded3D -ShowPercent -WarningAction SilentlyContinue
|
||||
|
||||
it "Built a pivot definition using New-PivotTableDefinition " {
|
||||
$ptDef.PT1.SourceWorkSheet | Should be 'Sheet1'
|
||||
@@ -528,12 +636,14 @@ Describe ExportExcel {
|
||||
$ptDef.PT1.PivotFilter | Should be 'StartType'
|
||||
$ptDef.PT1.IncludePivotChart | Should be $true
|
||||
$ptDef.PT1.ChartType.tostring() | Should be 'BarClustered3D'
|
||||
$ptDef.PT1.PivotTotals | Should be 'Columns'
|
||||
}
|
||||
Remove-Item -Path $path
|
||||
#Catch warning
|
||||
$warnvar = $null
|
||||
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
Get-Process | Select-Object -Property Name, Company, Handles, CPU, VM | Export-Excel -Path $path -AutoSize -WorkSheetname 'sheet2' -TableName "Processes" -TableStyle Light1 -Title "Processes" -TitleFillPattern Solid -TitleBackgroundColor AliceBlue -TitleBold -TitleSize 22 -PivotTableDefinition $ptDef
|
||||
#Test create two data pages; as part of adding the second give both their own pivot table, test -autosize switch
|
||||
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType, CanPauseAndContinue | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningAction SilentlyContinue -WarningVariable warnvar
|
||||
Get-Process | Select-Object -Property Name, Company, Handles, CPU, VM | Export-Excel -Path $path -AutoSize -WorkSheetname 'sheet2' -TableName "Processes" -TableStyle Light1 -Title "Processes" -TitleFillPattern Solid -TitleBackgroundColor ([System.Drawing.Color]::AliceBlue) -TitleBold -TitleSize 22 -PivotTableDefinition $ptDef
|
||||
$Excel = Open-ExcelPackage $path
|
||||
$ws1 = $Excel.Workbook.Worksheets["Sheet1"]
|
||||
$ws2 = $Excel.Workbook.Worksheets["Sheet2"]
|
||||
@@ -567,17 +677,21 @@ Describe ExportExcel {
|
||||
$PT2 = $ptsheet2.PivotTables[0]
|
||||
$PC1 = $ptsheet1.Drawings[0]
|
||||
$PC2 = $ptsheet2.Drawings[0]
|
||||
it "Created the correct pivot tables and charts from the definitions. " {
|
||||
|
||||
it "Created the pivot tables linked to the right data. " {
|
||||
$PT1.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be ("A1:" + $ws1.Dimension.End.Address)
|
||||
$PT2.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be ("A2:" + $ws2.Dimension.End.Address) #Title in row 1
|
||||
|
||||
}
|
||||
it "Set the other pivot tables and chart options from the definitions. " {
|
||||
$pt1.PageFields[0].Name | Should be 'StartType'
|
||||
$pt1.RowFields[0].Name | Should be 'Status'
|
||||
$pt1.DataFields[0].Field.name | Should be 'Status'
|
||||
$pt1.DataFields[0].Function | Should be 'Count'
|
||||
$pt1.ColumGrandTotals | Should be $true
|
||||
$pt1.RowGrandTotals | Should be $false
|
||||
$pt2.ColumGrandTotals | Should be $false
|
||||
$pt2.RowGrandTotals | Should be $true
|
||||
$pc1.ChartType | Should be 'BarClustered3D'
|
||||
$pc1.From.Column | Should be 0 #chart 1 at 0,10 chart 2 at 4,0 (default)
|
||||
$pc2.From.Column | Should be 4
|
||||
@@ -593,27 +707,30 @@ Describe ExportExcel {
|
||||
Context "#Example 13 # Formatting and another way to do a pivot. " {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-Item $path
|
||||
#Test freezing top row/first column, adding formats and a pivot table - from Add-Pivot table not a specification variable - after the export
|
||||
$excel = Get-Process | Select-Object -Property Name, Company, Handles, CPU, PM, NPM, WS | Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -FreezeTopRowFirstColumn -PassThru
|
||||
$sheet = $excel.Workbook.Worksheets["Processes"]
|
||||
$sheet.Column(1) | Set-Format -Bold -AutoFit
|
||||
$sheet.Column(2) | Set-Format -Width 29 -WrapText
|
||||
$sheet.Column(3) | Set-Format -HorizontalAlignment Right -NFormat "#,###"
|
||||
Set-Format -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
|
||||
Set-Format -Address $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
|
||||
Set-Format -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
||||
$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit
|
||||
$sheet.Column(2) | Set-ExcelRange -Width 29 -WrapText
|
||||
$sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NFormat "#,###"
|
||||
Set-ExcelRange -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
|
||||
Set-ExcelRange -Address $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
|
||||
Set-ExcelRange -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor ([System.Drawing.Color]::Red)
|
||||
#test Add-ConditionalFormatting -passthru and using a range (and no worksheet)
|
||||
$rule = Add-ConditionalFormatting -passthru -Address $sheet.cells["C:C"] -RuleType TopPercent -ConditionValue 20 -Bold -StrikeThru
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red -Bold -Italic -Underline -BackgroundColor Beige -BackgroundPattern LightUp -PatternColor Gray
|
||||
foreach ($c in 5..9) {Set-Format $sheet.Column($c) -AutoFit }
|
||||
Add-PivotTable -PivotTableName "PT_Procs" -ExcelPackage $excel -SourceWorkSheet "Processes" -PivotRows Company -PivotData @{'Name' = 'Count'} -IncludePivotChart -ChartType ColumnClustered -NoLegend
|
||||
Close-ExcelPackage $excel
|
||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor ([System.Drawing.Color]::Red) -Bold -Italic -Underline -BackgroundColor ([System.Drawing.Color]::Beige) -BackgroundPattern LightUp -PatternColor ([System.Drawing.Color]::Gray)
|
||||
#Test Set-ExcelRange with a column
|
||||
foreach ($c in 5..9) {Set-ExcelRange $sheet.Column($c) -AutoFit }
|
||||
Add-PivotTable -PivotTableName "PT_Procs" -ExcelPackage $excel -SourceWorkSheet 1 -PivotRows Company -PivotData @{'Name' = 'Count'} -IncludePivotChart -ChartType ColumnClustered -NoLegend
|
||||
Export-Excel -ExcelPackage $excel -WorksheetName "Processes" -AutoNameRange #Test adding named ranges seperately from adding data.
|
||||
|
||||
$excel = Open-ExcelPackage $path
|
||||
$sheet = $excel.Workbook.Worksheets["Processes"]
|
||||
it "Returned the rule when calling Add-ConditionalFormatting -passthru " {
|
||||
$rule | should not beNullOrEmpty
|
||||
$rule.getType().fullname | should be "OfficeOpenXml.ConditionalFormatting.ExcelConditionalFormattingTopPercent"
|
||||
$rule.Style.Font.Strike | should be true
|
||||
$rule | Should not beNullOrEmpty
|
||||
$rule.getType().fullname | Should be "OfficeOpenXml.ConditionalFormatting.ExcelConditionalFormattingTopPercent"
|
||||
$rule.Style.Font.Strike | Should be true
|
||||
}
|
||||
it "Applied the formating " {
|
||||
$sheet | Should not beNullOrEmpty
|
||||
@@ -641,6 +758,17 @@ Describe ExportExcel {
|
||||
$sheet.ConditionalFormatting[2].Formula | Should be '104857600'
|
||||
$sheet.ConditionalFormatting[2].Style.Font.Color.Color.Name | Should be 'ffff0000'
|
||||
}
|
||||
it "Created the named ranges " {
|
||||
$sheet.Names.Count | Should be 7
|
||||
$sheet.Names[0].Start.Column | Should be 1
|
||||
$sheet.Names[0].Start.Row | Should be 2
|
||||
$sheet.Names[0].End.Row | Should be $sheet.Dimension.End.Row
|
||||
$sheet.Names[0].Name | Should be $sheet.Cells['A1'].Value
|
||||
$sheet.Names[6].Start.Column | Should be 7
|
||||
$sheet.Names[6].Start.Row | Should be 2
|
||||
$sheet.Names[6].End.Row | Should be $sheet.Dimension.End.Row
|
||||
$sheet.Names[6].Name | Should be $sheet.Cells['G1'].Value
|
||||
}
|
||||
it "Froze the panes " {
|
||||
$sheet.view.Panes.Count | Should be 3
|
||||
}
|
||||
@@ -659,14 +787,27 @@ Describe ExportExcel {
|
||||
Context " # Chart from MultiSeries.ps1 in the Examples\charts Directory" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$data = invoke-sum (Get-Process) Company Handles, PM, VirtualMemorySize
|
||||
it "used Invoke-Sum to create a data set " {
|
||||
#Test we haven't missed any parameters on New-ChartDefinition which are on add chart or vice versa.
|
||||
|
||||
$ParamChk1 = (get-command Add-ExcelChart ).Parameters.Keys.where({-not (get-command New-ExcelChartDefinition).Parameters.ContainsKey($_) }) | Sort-Object
|
||||
$ParamChk2 = (get-command New-ExcelChartDefinition).Parameters.Keys.where({-not (get-command Add-ExcelChart ).Parameters.ContainsKey($_) })
|
||||
it "Found the same parameters for Add-ExcelChart and New-ExcelChartDefinintion " {
|
||||
$ParamChk1.count | Should be 3
|
||||
$ParamChk1[0] | Should be "PassThru"
|
||||
$ParamChk1[1] | Should be "PivotTable"
|
||||
$ParamChk1[2] | Should be "Worksheet"
|
||||
$ParamChk2.count | Should be 1
|
||||
$ParamChk2[0] | Should be "Header"
|
||||
}
|
||||
#Test Invoke-Sum
|
||||
$data = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize
|
||||
it "Used Invoke-Sum to create a data set " {
|
||||
$data | Should not beNullOrEmpty
|
||||
$data.count | Should beGreaterThan 1
|
||||
$data[1].Name | Should not beNullOrEmpty
|
||||
$data[1].Handles | Should not beNullOrEmpty
|
||||
$data[1].PM | Should not beNullOrEmpty
|
||||
$data[1].VirtualMemorySize | Should not beNullOrEmpty
|
||||
$data[1].Name | Should not beNullOrEmpty
|
||||
$data[1].Handles | Should not beNullOrEmpty
|
||||
$data[1].PM | Should not beNullOrEmpty
|
||||
$data[1].VirtualMemorySize | Should not beNullOrEmpty
|
||||
}
|
||||
$c = New-ExcelChartDefinition -Title Stats -ChartType LineMarkersStacked -XRange "Processes[Name]" -YRange "Processes[PM]", "Processes[VirtualMemorySize]" -SeriesHeader 'PM', 'VMSize'
|
||||
|
||||
@@ -684,6 +825,7 @@ Describe ExportExcel {
|
||||
$c.ShowCategory | Should not be $true
|
||||
$c.ShowPercent | Should not be $true
|
||||
}
|
||||
#Test creating a chart using -ExcelChartDefinition.
|
||||
$data | Export-Excel $path -AutoSize -TableName Processes -ExcelChartDefinition $c
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$drawings = $excel.Workbook.Worksheets[1].drawings
|
||||
@@ -702,11 +844,16 @@ Describe ExportExcel {
|
||||
|
||||
Context " # variation of plot.ps1 from Examples Directory using Add chart outside ExportExcel" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
#Test inserting a fomual
|
||||
$excel = 0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path $path -WorkSheetname SinX -ClearSheet -FreezeFirstColumn -PassThru
|
||||
#Test-Add Excel Chart to existing data. Test add Conditional formatting with a formula
|
||||
Add-ExcelChart -Worksheet $excel.Workbook.Worksheets["Sinx"] -ChartType line -XRange "X" -YRange "Sinx" -SeriesHeader "Sin(x)" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
|
||||
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" -XAxisPosition Bottom `
|
||||
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 -YAxisPosition Left -LegendPostion Bottom -LegendSize 8 -legendBold
|
||||
$d = $excel.Workbook.Worksheets["Sinx"].Drawings[0]
|
||||
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
|
||||
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
|
||||
-LegendSize 8 -legendBold -LegendPosition Bottom
|
||||
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets["Sinx"] -Range "B2:B362" -RuleType LessThan -ConditionValue "=B1" -ForeGroundColor ([System.Drawing.Color]::Red)
|
||||
$ws = $Excel.Workbook.Worksheets["Sinx"]
|
||||
$d = $ws.Drawings[0]
|
||||
It "Controled the axes and title and legend of the chart " {
|
||||
$d.XAxis.MaxValue | Should be 361
|
||||
$d.XAxis.MajorUnit | Should be 30
|
||||
@@ -731,8 +878,29 @@ Describe ExportExcel {
|
||||
$d.ChartType.tostring() | Should be "line"
|
||||
$d.From.Column | Should be 2
|
||||
}
|
||||
It "Appplied conditional formatting to the data " {
|
||||
$ws.ConditionalFormatting[0].Formula | Should be "B1"
|
||||
}
|
||||
Close-ExcelPackage -ExcelPackage $excel -nosave
|
||||
}
|
||||
Context " # Quick line chart" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
#test drawing a chart when data doesn't have a string
|
||||
0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path $path -LineChart
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Sheet1
|
||||
$d = $ws.Drawings[0]
|
||||
it "Created the chart " {
|
||||
$d.Title.text | Should beNullOrEmpty
|
||||
$d.ChartType | Should be "line"
|
||||
$d.Series[0].Header | Should be "Sinx"
|
||||
$d.Series[0].xSeries | Should be "'Sheet1'!A2:A362"
|
||||
$d.Series[0].Series | Should be "'Sheet1'!B2:B362"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Context " # Quick Pie chart and three icon conditional formating" {
|
||||
$path = "$Env:TEMP\Pie.xlsx"
|
||||
@@ -742,10 +910,10 @@ Describe ExportExcel {
|
||||
Select-Object -Property Name, @{n="TotalPm";e={($_.group | Measure-Object -sum -Property pm).sum }} |
|
||||
Export-Excel -NoHeader -AutoNameRange -path $path -ReturnRange -PieChart -ShowPercent
|
||||
$Cf = New-ConditionalFormattingIconSet -Range ($range -replace "^.*:","B2:") -ConditionalFormat ThreeIconSet -Reverse -IconType Flags
|
||||
$ct = New-ConditionalText -Text "Microsoft" -ConditionalTextColor red -BackgroundColor AliceBlue -ConditionalType ContainsText
|
||||
$ct = New-ConditionalText -Text "Microsoft" -ConditionalTextColor ([System.Drawing.Color]::Red) -BackgroundColor([System.Drawing.Color]::AliceBlue) -ConditionalType ContainsText
|
||||
it "Created the Conditional formatting rules " {
|
||||
$cf.Formatter | should be "ThreeIconSet"
|
||||
$cf.IconType | should be "Flags"
|
||||
$cf.Formatter | Should be "ThreeIconSet"
|
||||
$cf.IconType | Should be "Flags"
|
||||
$cf.Range | Should be ($range -replace "^.*:","B2:")
|
||||
$cf.Reverse | Should be $true
|
||||
$ct.BackgroundColor.Name | Should be "AliceBlue"
|
||||
@@ -753,20 +921,20 @@ Describe ExportExcel {
|
||||
$ct.ConditionalType | Should be "ContainsText"
|
||||
$ct.Text | Should be "Microsoft"
|
||||
}
|
||||
|
||||
#Test -ConditionalFormat & -ConditionalText
|
||||
Export-Excel -Path $path -ConditionalFormat $cf -ConditionalText $ct
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$rows = $range -replace "^.*?(\d+)$", '$1'
|
||||
$chart = $excel.Workbook.Worksheets["sheet1"].Drawings[0]
|
||||
$cFmt = $excel.Workbook.Worksheets["sheet1"].ConditionalFormatting
|
||||
it "Created the chart with the right series " {
|
||||
$chart.ChartType | should be "PieExploded3D"
|
||||
$chart.series.series | should be "'Sheet1'!B1:B$rows" #would be B2 and A2 if we had a header.
|
||||
$chart.series.Xseries | should be "'Sheet1'!A1:A$rows"
|
||||
$chart.DataLabel.ShowPercent | should be $true
|
||||
$chart.ChartType | Should be "PieExploded3D"
|
||||
$chart.series.series | Should be "'Sheet1'!B1:B$rows" #would be B2 and A2 if we had a header.
|
||||
$chart.series.Xseries | Should be "'Sheet1'!A1:A$rows"
|
||||
$chart.DataLabel.ShowPercent | Should be $true
|
||||
}
|
||||
it "Created two Conditional formatting rules " {
|
||||
$cFmt.Count | should be $true
|
||||
$cFmt.Count | Should be $true
|
||||
$cFmt.Where({$_.type -eq "ContainsText"}) | Should not beNullOrEmpty
|
||||
$cFmt.Where({$_.type -eq "ThreeIconSet"}) | Should not beNullOrEmpty
|
||||
}
|
||||
@@ -774,6 +942,7 @@ Describe ExportExcel {
|
||||
|
||||
Context " # Awkward multiple tables" {
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
#Test creating 3 on overlapping tables on the same page. Create rightmost the left most then middle.
|
||||
remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
$r = Get-ChildItem -path C:\WINDOWS\system32 -File
|
||||
|
||||
@@ -791,17 +960,17 @@ Describe ExportExcel {
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
it "Created 3 tables " {
|
||||
$ws.tables.count | should be 3
|
||||
$ws.tables.count | Should be 3
|
||||
}
|
||||
it "Created the FileSize table in the right place with the right size and style " {
|
||||
$ws.Tables["FileSize"].Address.Address | should be "G2:H16" #Insert at row 2, Column 7, 14 rows x 2 columns of data
|
||||
$ws.Tables["FileSize"].StyleName | should be "TableStyleMedium2"
|
||||
$ws.Tables["FileSize"].Address.Address | Should be "G2:H16" #Insert at row 2, Column 7, 14 rows x 2 columns of data
|
||||
$ws.Tables["FileSize"].StyleName | Should be "TableStyleMedium2"
|
||||
}
|
||||
it "Created the ExtSize table in the right place with the right size " {
|
||||
$ws.Tables["ExtSize"].Address.Address | should be "A2:B14" #tile, then 12 rows x 2 columns of data
|
||||
$ws.Tables["ExtSize"].Address.Address | Should be "A2:B14" #tile, then 12 rows x 2 columns of data
|
||||
}
|
||||
it "Created the ExtCount table in the right place with the right size " {
|
||||
$ws.Tables["ExtCount"].Address.Address | should be "D2:E12" #title, then 10 rows x 2 columns of data
|
||||
$ws.Tables["ExtCount"].Address.Address | Should be "D2:E12" #title, then 10 rows x 2 columns of data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
65
__tests__/ExtraLongCmd.tests.ps1
Normal file
65
__tests__/ExtraLongCmd.tests.ps1
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
remove-item -path $path -ErrorAction SilentlyContinue
|
||||
ConvertFrom-Csv @"
|
||||
Product, City, Gross, Net
|
||||
Apple, London , 300, 250
|
||||
Orange, London , 400, 350
|
||||
Banana, London , 300, 200
|
||||
Orange, Paris, 600, 500
|
||||
Banana, Paris, 300, 200
|
||||
Apple, New York, 1200,700
|
||||
|
||||
"@ | Export-Excel -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"} -ExcelChartDefinition @{ChartType="Doughnut";XRange="A2:B7"; YRange="C2:C7"; width=800; } -PivotTableDefinition @{Sales=@{
|
||||
PivotRows="City"; PivotColumns="Product"; PivotData=@{Gross="Sum";Net="Sum"}; PivotNumberFormat="$#,##0.00"; PivotTotals="Both"; PivotTableStyle="Medium12"; Activate=$true
|
||||
|
||||
PivotChartDefinition=@{Title="Gross and net by city and product"; ChartType="ColumnClustered"; Column=6; Width=600; Height=360; YMajorUnit=500; YMinorUnit=100; YAxisNumberformat="$#,##0"; LegendPosition="Bottom"}}}
|
||||
|
||||
$excel = Open-ExcelPackage $path
|
||||
$ws1 = $excel.Workbook.Worksheets[1]
|
||||
$ws2 = $excel.Workbook.Worksheets[2]
|
||||
Describe "Creating workbook with a single line" {
|
||||
Context "Data Page" {
|
||||
It "Inserted the data and created the table " {
|
||||
$ws1.Tables[0] | Should not beNullOrEmpty
|
||||
$ws1.Tables[0].Address.Address | Should be "A1:D7"
|
||||
$ws1.Tables[0].StyleName | Should be "TableStyleMedium13"
|
||||
}
|
||||
It "Applied conditional formatting " {
|
||||
$ws1.ConditionalFormatting[0] | Should not beNullOrEmpty
|
||||
$ws1.ConditionalFormatting[0].type.ToString() | Should be "DataBar"
|
||||
$ws1.ConditionalFormatting[0].Color.G | Should beGreaterThan 100
|
||||
$ws1.ConditionalFormatting[0].Color.R | Should beLessThan 100
|
||||
$ws1.ConditionalFormatting[0].Address.Address | Should be "C2:C7"
|
||||
}
|
||||
It "Added the chart " {
|
||||
$ws1.Drawings[0] | Should not beNullOrEmpty
|
||||
$ws1.Drawings[0].ChartType.ToString() | Should be "DoughNut"
|
||||
$ws1.Drawings[0].Series[0].Series | Should be "'Sheet1'!C2:C7"
|
||||
}
|
||||
}
|
||||
Context "PivotTable" {
|
||||
it "Created the PivotTable on a new page and made it active " {
|
||||
$ws2 | Should not beNullOrEmpty
|
||||
$ws2.PivotTables[0] | Should not beNullOrEmpty
|
||||
$ws2.PivotTables[0].Fields.Count | Should be 4
|
||||
$ws2.PivotTables[0].DataFields[0].Format | Should be "$#,##0.00"
|
||||
$ws2.PivotTables[0].RowFields[0].Name | Should be "City"
|
||||
$ws2.PivotTables[0].ColumnFields[0].Name | Should be "Product"
|
||||
$ws2.PivotTables[0].RowGrandTotals | Should be $true
|
||||
$ws2.PivotTables[0].ColumGrandTotals | Should be $true #Epplus's mis-spelling of column not mine
|
||||
$ws2.View.TabSelected | Should be $true
|
||||
}
|
||||
it "Created the Pivot Chart " {
|
||||
$ws2.Drawings[0] | Should not beNullOrEmpty
|
||||
$ws2.Drawings[0].ChartType.ToString() | Should be ColumnClustered
|
||||
$ws2.Drawings[0].YAxis.MajorUnit | Should be 500
|
||||
$ws2.Drawings[0].YAxis.MinorUnit | Should be 100
|
||||
$ws2.Drawings[0].YAxis.Format | Should be "$#,##0"
|
||||
$ws2.Drawings[0].Legend.Position.ToString() | Should be "Bottom"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
101
__tests__/First10Races.csv
Normal file
101
__tests__/First10Races.csv
Normal file
@@ -0,0 +1,101 @@
|
||||
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
|
||||
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
|
||||
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
|
||||
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
|
||||
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
|
||||
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
|
||||
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
|
||||
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
|
||||
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
|
||||
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
|
||||
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
|
||||
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
|
||||
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
|
||||
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
|
||||
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
|
||||
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
|
||||
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
|
||||
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
|
||||
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
|
||||
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
|
||||
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
|
||||
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
|
||||
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
|
||||
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
|
||||
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
|
||||
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
|
||||
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
|
||||
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
|
||||
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
|
||||
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
|
||||
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
|
||||
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
|
||||
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
|
||||
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
|
||||
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
|
||||
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
|
||||
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
|
||||
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
|
||||
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
|
||||
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
|
||||
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
|
||||
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
|
||||
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
|
||||
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
|
||||
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
|
||||
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
|
||||
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
|
||||
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
|
||||
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
|
||||
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
|
||||
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
|
||||
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
|
||||
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
|
||||
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
|
||||
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
|
||||
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
|
||||
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
|
||||
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
|
||||
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
|
||||
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
|
||||
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
|
||||
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
|
||||
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
|
||||
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
|
||||
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
|
||||
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
|
||||
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
|
||||
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
|
||||
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
|
||||
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
|
||||
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
|
||||
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
|
||||
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
|
||||
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
|
||||
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
|
||||
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
|
||||
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
|
||||
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
|
||||
French,24/06/2018,8,Carlos Sainz,7,Renault,4
|
||||
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
|
||||
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
|
||||
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
|
||||
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
|
||||
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
|
||||
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
|
||||
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
|
||||
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
|
||||
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
|
||||
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
|
||||
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
|
||||
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
|
||||
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
|
||||
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
|
||||
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
|
||||
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
|
||||
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
|
||||
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
|
||||
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
|
||||
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
|
||||
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
|
||||
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
|
||||
|
101
__tests__/First10Races.tests.ps1
Normal file
101
__tests__/First10Races.tests.ps1
Normal file
@@ -0,0 +1,101 @@
|
||||
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
|
||||
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
|
||||
|
||||
Describe "Creating small named ranges with hyperlinks" {
|
||||
BeforeAll {
|
||||
$path = "$env:TEMP\Results.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
#Read race results, and group by race name : export 1 row to get headers, leaving enough rows aboce to put in a link for each race
|
||||
$results = Import-Csv -Path $dataPath | Group-Object -Property RACE
|
||||
$topRow = $lastDataRow = 1 + $results.Count
|
||||
$excel = $results[0].Group[0] | Export-Excel -Path $path -StartRow $TopRow -BoldTopRow -PassThru
|
||||
|
||||
#export each group (race) below the last one, without headers, and create a range for each using the group name (Race)
|
||||
foreach ($r in $results) {
|
||||
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow +1) -RangeName $R.Name -PassThru -AutoSize
|
||||
$lastDataRow += $R.Group.Count
|
||||
}
|
||||
$worksheet = $excel.Workbook.Worksheets[1]
|
||||
$columns = $worksheet.Dimension.Columns
|
||||
|
||||
1..$columns | ForEach-Object {Add-ExcelName -Range $worksheet.cells[$topRow,$_,$lastDataRow,$_]} #Test Add-Excel Name on its own (outside Export-Excel)
|
||||
|
||||
$scwarnVar = $null
|
||||
Set-ExcelColumn -Worksheet $worksheet -StartRow $topRow -Heading "PlacesGained/Lost" `
|
||||
-Value "=GridPosition-FinishPosition" -AutoNameRange -WarningVariable scWarnVar -WarningAction SilentlyContinue #Test as many set column options as possible.
|
||||
$columns ++
|
||||
|
||||
#create a table which covers all the data. And define a pivot table which uses the same address range.
|
||||
$table = Add-ExcelTable -PassThru -Range $worksheet.cells[$topRow,1,$lastDataRow,$columns] -TableName "AllResults" -TableStyle Light4 `
|
||||
-ShowHeader -ShowFilter -ShowColumnStripes -ShowRowStripes:$false -ShowFirstColumn:$false -ShowLastColumn:$false -ShowTotal:$false #Test Add-ExcelTable outside export-Excel with as many options as possible.
|
||||
$pt = New-PivotTableDefinition -PivotTableName Analysis -SourceWorkSheet $worksheet -SourceRange $table.address.address -PivotRows Driver -PivotData @{Points="SUM"} -PivotTotals None
|
||||
|
||||
$cf = Add-ConditionalFormatting -Address $worksheet.cells[$topRow,$columns,$lastDataRow,$columns] -ThreeIconsSet Arrows -Passthru #Test using cells[r1,c1,r2,c2]
|
||||
$cf.Icon2.Type = $cf.Icon3.Type = "Num"
|
||||
$cf.Icon2.Value = 0
|
||||
$cf.Icon3.Value = 1
|
||||
Add-ConditionalFormatting -Address $worksheet.cells["FinishPosition"] -RuleType Equal -ConditionValue 1 -ForeGroundColor ([System.Drawing.Color]::Purple) -Bold -Priority 1 -StopIfTrue #Test Priority and stopIfTrue and using range name
|
||||
Add-ConditionalFormatting -Address $worksheet.Cells["GridPosition"] -RuleType ThreeColorScale -Reverse #Test Reverse
|
||||
$ct = New-ConditionalText -Text "Ferrari"
|
||||
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalText ([System.Drawing.Color]::Red) -Background ([System.Drawing.Color]::White) #Test new-conditionalText in shortest and longest forms.
|
||||
#Create links for each group name (race) and Export them so they start at Cell A1; create a pivot table with definition just created, save the file and open in Excel
|
||||
$results | ForEach-Object {(New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList "Sheet1!$($_.Name)" , "$($_.name) GP")} | #Test Exporting Hyperlinks with display property.
|
||||
Export-Excel -ExcelPackage $excel -AutoSize -PivotTableDefinition $pt -Calculate -ConditionalFormat $ct,$ct2 #Test conditional text rules in conditional format (orignally icon sets only )
|
||||
|
||||
$excel = Open-ExcelPackage $path
|
||||
$sheet = $excel.Workbook.Worksheets[1]
|
||||
$m = $results | measure -sum -Property count
|
||||
$expectedRows = 1 + $m.count + $m.sum
|
||||
}
|
||||
Context "Creating hyperlinks" {
|
||||
it "Put the data into the sheet and created the expected named ranges " {
|
||||
$sheet.Dimension.Rows | should be $expectedRows
|
||||
$sheet.Dimension.Columns | should be $columns
|
||||
$sheet.Names.Count | should be ($columns + $results.Count)
|
||||
$sheet.Names[$results[0].Name] | should not benullorEmpty
|
||||
$sheet.Names[$results[-1].Name] | should not benullorEmpty
|
||||
}
|
||||
it "Added hyperlinks to the named ranges " {
|
||||
$sheet.cells["a1"].Hyperlink.Display | should match $results[0].Name
|
||||
$sheet.cells["a1"].Hyperlink.ReferenceAddress | should match $results[0].Name
|
||||
}
|
||||
}
|
||||
Context "Adding calculated column" {
|
||||
It "Populated the cells with the right heading and formulas " {
|
||||
$sheet.Cells[( $results.Count),$columns] | Should benullorEmpty
|
||||
$sheet.Cells[(1+$results.Count),$columns].Value | Should be "PlacesGained/Lost"
|
||||
$sheet.Cells[(2+$results.Count),$columns].Formula | should be "GridPosition-FinishPosition"
|
||||
$sheet.Names["PlacesGained_Lost"] | should not benullorEmpty
|
||||
}
|
||||
It "Performed the calculation " {
|
||||
$placesMade = $Sheet.Cells[(2+$results.Count),5].value - $Sheet.Cells[(2+$results.Count),3].value
|
||||
$sheet.Cells[(2+$results.Count),$columns].value | Should be $placesmade
|
||||
}
|
||||
It "Applied ConditionalFormatting, including StopIfTrue, Priority and Reverse " {
|
||||
$sheet.ConditionalFormatting[0].Address.Start.Column | should be $columns
|
||||
$sheet.ConditionalFormatting[0].Address.End.Column | should be $columns
|
||||
$sheet.ConditionalFormatting[0].Address.End.Row | should be $expectedRows
|
||||
$sheet.ConditionalFormatting[0].Address.Start.Row | should be ($results.Count + 1)
|
||||
$sheet.ConditionalFormatting[0].Icon3.Type.ToString() | Should be "Num"
|
||||
$sheet.ConditionalFormatting[0].Icon3.Value | Should be 1
|
||||
$sheet.ConditionalFormatting[1].Priority | Should be 1
|
||||
$sheet.ConditionalFormatting[1].StopIfTrue | Should be $true
|
||||
$sheet.ConditionalFormatting[3].LowValue.Color.R | Should begreaterThan 180
|
||||
$sheet.ConditionalFormatting[3].LowValue.Color.G | Should beLessThan 128
|
||||
$sheet.ConditionalFormatting[3].HighValue.Color.R | Should beLessThan 128
|
||||
$sheet.ConditionalFormatting[3].HighValue.Color.G | Should begreaterThan 180
|
||||
}
|
||||
}
|
||||
Context "Adding a table" {
|
||||
it "Created a table " {
|
||||
$sheet.tables[0] | Should not beNullOrEmpty
|
||||
$sheet.tables[0].Address.Start.Column | should be 1
|
||||
$sheet.tables[0].Address.End.Column | should be $columns
|
||||
$sheet.tables[0].Address.Start.row | should be ($results.Count + 1)
|
||||
$sheet.Tables[0].Address.End.Row | should be $expectedRows
|
||||
$sheet.Tables[0].StyleName | should be "TableStyleLight4"
|
||||
$sheet.Tables[0].ShowColumnStripes | should be $true
|
||||
$sheet.Tables[0].ShowRowStripes | should not be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
28
__tests__/FunctionAlias.tests.ps1
Normal file
28
__tests__/FunctionAlias.tests.ps1
Normal file
@@ -0,0 +1,28 @@
|
||||
#Requires -Modules Pester
|
||||
remove-module importExcel -erroraction silentlyContinue
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
|
||||
Describe "Check if Function aliases exist" {
|
||||
|
||||
It "Set-Column should exist" {
|
||||
${Alias:Set-Column} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
It "Set-Row should exist" {
|
||||
${Alias:Set-Row} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
It "Set-Format should exist" {
|
||||
${Alias:Set-Format} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
<#It "Merge-MulipleSheets should exist" {
|
||||
Get-Command Merge-MulipleSheets | Should Not Be $null
|
||||
}
|
||||
#>
|
||||
It "New-ExcelChart should exist" {
|
||||
${Alias:New-ExcelChart} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
}
|
||||
10
__tests__/ImportExcelFileList.tests.ps1
Normal file
10
__tests__/ImportExcelFileList.tests.ps1
Normal file
@@ -0,0 +1,10 @@
|
||||
Describe "ImportExcel File List" {
|
||||
It "All files should exist" {
|
||||
$fileList = Get-Content "$PSScriptRoot\..\filelist.txt"
|
||||
|
||||
foreach ($file in $fileList) {
|
||||
$targetFile = "$PSScriptRoot\..\$file"
|
||||
Test-Path $targetFile | Should Be $true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
$data1 = ConvertFrom-Csv -InputObject @"
|
||||
$data1 = ConvertFrom-Csv -InputObject @"
|
||||
ID,Product,Quantity,Price,Total
|
||||
12001,Nails,37,3.99,147.63
|
||||
12002,Hammer,5,12.10,60.5
|
||||
@@ -22,52 +22,77 @@ ID,Product,Quantity,Price,Total
|
||||
12012,Pliers,3,14.99,44.97
|
||||
"@
|
||||
|
||||
Describe "Join Worksheet" {
|
||||
Describe "Join Worksheet part 1" {
|
||||
BeforeAll {
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$data1 | Export-Excel -Path $path -WorkSheetname Oxford
|
||||
$data2 | Export-Excel -Path $path -WorkSheetname Abingdon
|
||||
$data3 | Export-Excel -Path $path -WorkSheetname Banbury
|
||||
$ptdef = New-PivotTableDefinition -PivotTableName "Summary" -PivotRows "Store" -PivotColumns "Product" -PivotData @{"Total"="SUM"} -IncludePivotChart -ChartTitle "Sales Breakdown" -ChartType ColumnStacked -ChartColumn 10
|
||||
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Summary" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ptdef = New-PivotTableDefinition -PivotTableName "SummaryPivot" -PivotRows "Store" -PivotColumns "Product" -PivotData @{"Total"="SUM"} -IncludePivotChart -ChartTitle "Sales Breakdown" -ChartType ColumnStacked -ChartColumn 10
|
||||
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "SummaryTable" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -TitleBackgroundColor ([System.Drawing.Color]::AliceBlue) -PivotTableDefinition $ptdef
|
||||
|
||||
$excel = Export-Excel -path $path -WorkSheetname SummaryPivot -Activate -NoTotalsInPivot -PivotDataToColumn -HideSheet * -UnHideSheet "Total","SummaryPivot" -PassThru
|
||||
# Open-ExcelPackage -Path $path
|
||||
|
||||
$ws = $excel.Workbook.Worksheets["Total"]
|
||||
$pt = $excel.Workbook.Worksheets["Summary"].pivottables[0]
|
||||
$pc = $excel.Workbook.Worksheets["Summary"].Drawings[0]
|
||||
$pt = $excel.Workbook.Worksheets["SummaryPivot"].pivottables[0]
|
||||
$pc = $excel.Workbook.Worksheets["SummaryPivot"].Drawings[0]
|
||||
}
|
||||
Context "Merge 3 blocks" {
|
||||
Context "Export-Excel setting spreadsheet visibility" {
|
||||
it "Hid the worksheets " {
|
||||
$excel.Workbook.Worksheets["Oxford"].Hidden | Should be 'Hidden'
|
||||
$excel.Workbook.Worksheets["Banbury"].Hidden | Should be 'Hidden'
|
||||
$excel.Workbook.Worksheets["Abingdon"].Hidden | Should be 'Hidden'
|
||||
}
|
||||
it "Un-hid two of the worksheets " {
|
||||
$excel.Workbook.Worksheets["Total"].Hidden | Should be 'Visible'
|
||||
$excel.Workbook.Worksheets["SummaryPivot"].Hidden | Should be 'Visible'
|
||||
}
|
||||
it "Activated the correct worksheet " {
|
||||
$excel.Workbook.worksheets["SummaryPivot"].View.TabSelected | Should be $true
|
||||
$excel.Workbook.worksheets["Total"].View.TabSelected | Should be $false
|
||||
}
|
||||
|
||||
}
|
||||
Context "Merging 3 blocks" {
|
||||
it "Created sheet of the right size with a title and a table " {
|
||||
$ws.Dimension.Address | Should be "A1:F16"
|
||||
$ws.Tables[0].Address.Address | Should be "A2:F16"
|
||||
$ws.cells["A1"].Value | Should be "Store Sales Summary"
|
||||
$ws.cells["A1"].Style.Font.Size | Should be 14
|
||||
$ws.Tables[0].StyleName | Should be "TableStyleLight1"
|
||||
$ws.cells["A2:F2"].Style.Font.Bold | Should be $True
|
||||
$ws.Dimension.Address | Should be "A1:F16"
|
||||
$ws.Tables[0].Address.Address | Should be "A2:F16"
|
||||
$ws.Cells["A1"].Value | Should be "Store Sales Summary"
|
||||
$ws.Cells["A1"].Style.Font.Size | Should be 14
|
||||
$ws.Cells["A1"].Style.Font.Bold | Should be $True
|
||||
$ws.Cells["A1"].Style.Fill.BackgroundColor.Rgb | Should be "FFF0F8FF"
|
||||
$ws.Cells["A1"].Style.Fill.PatternType.ToString() | Should be "Solid"
|
||||
$ws.Tables[0].StyleName | Should be "TableStyleLight1"
|
||||
$ws.Cells["A2:F2"].Style.Font.Bold | Should be $True
|
||||
}
|
||||
it "Added a from column with the right heading " {
|
||||
$ws.cells["F2" ].Value | Should be "Store"
|
||||
$ws.cells["F3" ].Value | Should be "Oxford"
|
||||
$ws.cells["F8" ].Value | Should be "Abingdon"
|
||||
$ws.cells["F13"].Value | Should be "Banbury"
|
||||
$ws.Cells["F2" ].Value | Should be "Store"
|
||||
$ws.Cells["F3" ].Value | Should be "Oxford"
|
||||
$ws.Cells["F8" ].Value | Should be "Abingdon"
|
||||
$ws.Cells["F13"].Value | Should be "Banbury"
|
||||
}
|
||||
it "Filled in the data " {
|
||||
$ws.cells["C3" ].Value | Should be $data1[0].quantity
|
||||
$ws.cells["C8" ].Value | Should be $data2[0].quantity
|
||||
$ws.cells["C13"].Value | Should be $data3[0].quantity
|
||||
$ws.Cells["C3" ].Value | Should be $data1[0].quantity
|
||||
$ws.Cells["C8" ].Value | Should be $data2[0].quantity
|
||||
$ws.Cells["C13"].Value | Should be $data3[0].quantity
|
||||
}
|
||||
it "Created the pivot table " {
|
||||
$pt | Should not beNullOrEmpty
|
||||
$pt.StyleName | Should be "PivotStyleMedium9"
|
||||
$pt.RowFields[0].Name | Should be "Store"
|
||||
$pt.ColumnFields[0].name | Should be "Product"
|
||||
$pt.DataFields[0].name | Should be "Sum of Total"
|
||||
$pc.ChartType | Should be "ColumnStacked"
|
||||
$pc.Title.text | Should be "Sales Breakdown"
|
||||
$pt | Should not beNullOrEmpty
|
||||
$pt.StyleName | Should be "PivotStyleMedium9"
|
||||
$pt.RowFields[0].Name | Should be "Store"
|
||||
$pt.ColumnFields[0].name | Should be "Product"
|
||||
$pt.DataFields[0].name | Should be "Sum of Total"
|
||||
$pc.ChartType | Should be "ColumnStacked"
|
||||
$pc.Title.text | Should be "Sales Breakdown"
|
||||
}
|
||||
}
|
||||
}
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
IF ($PSVersionTable.PSVersion.Major -gt 5) {Write-warning -message "Part 2 Does not run on V6"; return}
|
||||
Describe "Join Worksheet part 2" {
|
||||
Get-WmiObject -Class win32_logicaldisk |
|
||||
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
||||
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
|
||||
@@ -78,26 +103,25 @@ Describe "Join Worksheet" {
|
||||
Join-Worksheet -Path $path -HideSource -WorkSheetName Summary -NoHeader -LabelBlocks -AutoSize -Title "Summary" -TitleBold -TitleSize 22
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Workbook.Worksheets["Summary"]
|
||||
Context "3 Unlinked blocks" {
|
||||
Context "Bringing 3 Unlinked blocks onto one page" {
|
||||
it "Hid the source worksheets " {
|
||||
$excel.Workbook.Worksheets[1].Hidden.tostring() | should be "Hidden"
|
||||
$excel.Workbook.Worksheets[2].Hidden.tostring() | should be "Hidden"
|
||||
$excel.Workbook.Worksheets[1].Hidden.tostring() | Should be "Hidden"
|
||||
$excel.Workbook.Worksheets[2].Hidden.tostring() | Should be "Hidden"
|
||||
}
|
||||
it "Created the Summary sheet with title, and block labels, and copied the correct data " {
|
||||
$ws.Cells["A1"].Value | should be "Summary"
|
||||
$ws.Cells["A2"].Value | should be $excel.Workbook.Worksheets[1].name
|
||||
$ws.Cells["A3"].Value | should be $excel.Workbook.Worksheets[1].Cells["A1"].value
|
||||
$ws.Cells["A4"].Value | should be $excel.Workbook.Worksheets[1].Cells["A2"].value
|
||||
$ws.Cells["B4"].Value | should be $excel.Workbook.Worksheets[1].Cells["B2"].value
|
||||
$ws.Cells["A1"].Value | Should be "Summary"
|
||||
$ws.Cells["A2"].Value | Should be $excel.Workbook.Worksheets[1].name
|
||||
$ws.Cells["A3"].Value | Should be $excel.Workbook.Worksheets[1].Cells["A1"].value
|
||||
$ws.Cells["A4"].Value | Should be $excel.Workbook.Worksheets[1].Cells["A2"].value
|
||||
$ws.Cells["B4"].Value | Should be $excel.Workbook.Worksheets[1].Cells["B2"].value
|
||||
$nextRow = $excel.Workbook.Worksheets[1].Dimension.Rows + 3
|
||||
$ws.Cells["A$NextRow"].Value | should be $excel.Workbook.Worksheets[2].name
|
||||
$ws.Cells["A$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].name
|
||||
$nextRow ++
|
||||
$ws.Cells["A$NextRow"].Value | should be $excel.Workbook.Worksheets[2].Cells["A1"].value
|
||||
$ws.Cells["A$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].Cells["A1"].value
|
||||
$nextRow ++
|
||||
$ws.Cells["A$NextRow"].Value | should be $excel.Workbook.Worksheets[2].Cells["A2"].value
|
||||
$ws.Cells["B$NextRow"].Value | should be $excel.Workbook.Worksheets[2].Cells["B2"].value
|
||||
$ws.Cells["A$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].Cells["A2"].value
|
||||
$ws.Cells["B$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].Cells["B2"].value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
__tests__/PasswordProtection.ps1
Normal file
24
__tests__/PasswordProtection.ps1
Normal file
@@ -0,0 +1,24 @@
|
||||
Describe "Password Support" {
|
||||
Context "Password protected sheet" {
|
||||
BeforeAll {
|
||||
$password = "YouMustRememberThis"
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-Item $path -ErrorAction SilentlyContinue
|
||||
Get-Service | Select-Object -First 10 | Export-excel -password $password -Path $Path -DisplayPropertySet
|
||||
}
|
||||
it "Threw an error when the password was omitted " {
|
||||
{Open-ExcelPackage -Path $path } | should throw
|
||||
}
|
||||
it "Was able to append when the password was included " {
|
||||
{Get-Service | Select-Object -First 10 |
|
||||
Export-excel -password $password -Path $Path -Append } | should not throw
|
||||
}
|
||||
it "Kept the password on the file when it was saved " {
|
||||
{Import-Excel $Path } | should throw
|
||||
}
|
||||
it "Could read the file when the password was included " {
|
||||
(import-excel $path -Password $password).count | should be 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
114
__tests__/RangePassing.ps1
Normal file
114
__tests__/RangePassing.ps1
Normal file
@@ -0,0 +1,114 @@
|
||||
$path = "$env:temp\test.xlsx"
|
||||
describe "Consistent passing of ranges." {
|
||||
Context "Conditional Formatting" {
|
||||
Remove-Item -path $path -ErrorAction SilentlyContinue
|
||||
$excel = Get-Service | Export-Excel -Path $path -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -AutoNameRange -Title "Services on $Env:COMPUTERNAME"
|
||||
it "accepts named ranges, cells['name'], worksheet + Name, worksheet + column " {
|
||||
{Add-ConditionalFormatting $excel.Services.Names["Status"] -StrikeThru -RuleType ContainsText -ConditionValue "Stopped" } | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 1
|
||||
{Add-ConditionalFormatting $excel.Services.Cells["Name"] -Italic -RuleType ContainsText -ConditionValue "SVC" } | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 2
|
||||
$warnvar = $null
|
||||
Add-ConditionalFormatting $excel.Services.Column(3) `
|
||||
-underline -RuleType ContainsText -ConditionValue "Windows" -WarningVariable warnvar -WarningAction SilentlyContinue
|
||||
$warnvar | should not beNullOrEmpty
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 2
|
||||
$warnvar = $null
|
||||
Add-ConditionalFormatting $excel.Services.Column(3) -WorkSheet $excel.Services`
|
||||
-underline -RuleType ContainsText -ConditionValue "Windows" -WarningVariable warnvar -WarningAction SilentlyContinue
|
||||
$warnvar | should beNullOrEmpty
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 3
|
||||
{Add-ConditionalFormatting "Status" -WorkSheet $excel.Services `
|
||||
-ForeGroundColor ([System.Drawing.Color]::Green) -RuleType ContainsText -ConditionValue "Running"} | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 4
|
||||
}
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
$excel = Get-Service | Export-Excel -Path $path -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -TableName servicetable -Title "Services on $Env:COMPUTERNAME"
|
||||
it "accepts table, table.Address and worksheet + 'C:C' " {
|
||||
{Add-ConditionalFormatting $excel.Services.Tables[0] `
|
||||
-Italic -RuleType ContainsText -ConditionValue "Svc" } | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 1
|
||||
{Add-ConditionalFormatting $excel.Services.Tables["ServiceTable"].Address `
|
||||
-Bold -RuleType ContainsText -ConditionValue "windows" } | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 2
|
||||
{Add-ConditionalFormatting -WorkSheet $excel.Services -Address "a:a" `
|
||||
-RuleType ContainsText -ConditionValue "stopped" -ForeGroundColor ([System.Drawing.Color]::Red) } | Should not throw
|
||||
$excel.Services.ConditionalFormatting.Count | Should be 3
|
||||
}
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
}
|
||||
|
||||
Context "Formating (Set-ExcelRange or its alias set-Format) " {
|
||||
it "accepts Named Range, cells['Name'], cells['A1:Z9'], row, Worksheet + 'A1:Z9'" {
|
||||
$excel = Get-Service | Export-Excel -Path test2.xlsx -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -RangeName servicerange -Title "Services on $Env:COMPUTERNAME"
|
||||
{set-format $excel.Services.Names["serviceRange"] -Bold } | Should Not Throw
|
||||
$excel.Services.cells["B2"].Style.Font.Bold | Should be $true
|
||||
{Set-ExcelRange -Range $excel.Services.Cells["serviceRange"] -italic:$true } | Should not throw
|
||||
$excel.Services.cells["C3"].Style.Font.Italic | Should be $true
|
||||
{set-format $excel.Services.Row(4) -underline -Bold:$false } | Should not throw
|
||||
$excel.Services.cells["A4"].Style.Font.UnderLine | Should be $true
|
||||
$excel.Services.cells["A4"].Style.Font.Bold | Should not be $true
|
||||
{Set-ExcelRange $excel.Services.Cells["A3:B3"] -StrikeThru } | Should not throw
|
||||
$excel.Services.cells["B3"].Style.Font.Strike | Should be $true
|
||||
{Set-ExcelRange -WorkSheet $excel.Services -Range "A5:B6" -FontSize 8 } | Should not throw
|
||||
$excel.Services.cells["A5"].Style.Font.Size | Should be 8
|
||||
}
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
it "Accepts Table, Table.Address , worksheet + Name, Column," {
|
||||
$excel = Get-Service | Export-Excel -Path test2.xlsx -WorksheetName Services -PassThru -AutoNameRange -AutoSize -DisplayPropertySet -TableName servicetable -Title "Services on $Env:COMPUTERNAME"
|
||||
{set-ExcelRange $excel.Services.Tables[0] -Italic } | Should not throw
|
||||
$excel.Services.cells["C3"].Style.Font.Italic | Should be $true
|
||||
{set-format $excel.Services.Tables["ServiceTable"].Address -Underline } | Should not throw
|
||||
$excel.Services.cells["C3"].Style.Font.UnderLine | Should be $true
|
||||
{Set-ExcelRange -WorkSheet $excel.Services -Range "Name" -Bold } | Should not throw
|
||||
$excel.Services.cells["B4"].Style.Font.Bold | Should be $true
|
||||
{$excel.Services.Column(3) | Set-ExcelRange -FontColor ([System.Drawing.Color]::Red) } | Should not throw
|
||||
$excel.Services.cells["C4"].Style.Font.Color.Rgb | Should be "FFFF0000"
|
||||
}
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
}
|
||||
|
||||
Context "PivotTables" {
|
||||
it "Accepts Named range, .Cells['Name'], name&Worksheet, cells['A1:Z9'], worksheet&'A1:Z9' "{
|
||||
$excel = Get-Service | Export-Excel -Path $path -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -RangeName servicerange -Title "Services on $Env:COMPUTERNAME"
|
||||
$ws = $excel.Workbook.Worksheets[1] #can get a worksheet by name or index - starting at 1
|
||||
$end = $ws.Dimension.End.Address
|
||||
#can get a named ranged by name or index - starting at zero
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt0 -SourceRange $ws.Names[0]`
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt0"] | Should not beNullOrEmpty
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt1 -SourceRange $ws.Names["servicerange"]`
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt1"] | Should not beNullOrEmpty
|
||||
#Can specify the range for a pivot as NamedRange or Table or TableAddress or Worksheet + "A1:Z10" or worksheet + RangeName, or worksheet.cells["A1:Z10"] or worksheet.cells["RangeName"]
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt2 -SourceRange "servicerange" -SourceWorkSheet $ws `
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt2"] | Should not beNullOrEmpty
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt3 -SourceRange $ws.cells["servicerange"]`
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt3"] | Should not beNullOrEmpty
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt4 -SourceRange $ws.cells["A2:$end"]`
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt4"] | Should not beNullOrEmpty
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt5 -SourceRange "A2:$end" -SourceWorkSheet $ws `
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt5"] | Should not beNullOrEmpty
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
}
|
||||
it "Accepts Table, Table.Addres " {
|
||||
$excel = Get-Service | Export-Excel -Path $path -WorksheetName Services -PassThru -AutoSize -DisplayPropertySet -TableName servicetable -Title "Services on $Env:COMPUTERNAME"
|
||||
$ws = $excel.Workbook.Worksheets["Services"] #can get a worksheet by name or index - starting at 1
|
||||
#Can get a table by name or -stating at zero. Can specify the range for a pivot as or Table or TableAddress
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt1 -SourceRange $ws.tables["servicetable"]`
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt1"] | Should not beNullOrEmpty
|
||||
{Add-PivotTable -ExcelPackage $excel -PivotTableName pt2 -SourceRange $ws.tables[0].Address `
|
||||
-PivotRows Status -PivotData Name } | Should not throw
|
||||
$excel.Workbook.Worksheets["pt2"] | Should not beNullOrEmpty
|
||||
Close-ExcelPackage -NoSave $excel
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv -InputObject @"
|
||||
ID,Product,Quantity,Price
|
||||
@@ -11,75 +10,346 @@ ID,Product,Quantity,Price
|
||||
12011,Crowbar,7,23.48
|
||||
"@
|
||||
|
||||
Describe "Set-Column, Set-Row and Set Format" {
|
||||
$DriverData = convertFrom-CSv @"
|
||||
Name,Wikipage,DateOfBirth
|
||||
Fernando Alonso,/wiki/Fernando_Alonso,1981-07-29
|
||||
Jenson Button,/wiki/Jenson_Button,1980-01-19
|
||||
Kimi Räikkönen,/wiki/Kimi_R%C3%A4ikk%C3%B6nen,1979-10-17
|
||||
Lewis Hamilton,/wiki/Lewis_Hamilton,1985-01-07
|
||||
Nico Rosberg,/wiki/Nico_Rosberg,1985-06-27
|
||||
Sebastian Vettel,/wiki/Sebastian_Vettel,1987-07-03
|
||||
"@ | ForEach-Object {$_.DateOfBirth = [datetime]$_.DateofBirth; $_ }
|
||||
|
||||
|
||||
Describe "Number format expansion and setting" {
|
||||
Context "Argmument Completer for NumberFormat" {
|
||||
it "Returned at least 20 items " {
|
||||
(NumberFormatCompletion ).count | Should beGreaterThan 20
|
||||
}
|
||||
It "Resolved percent to 'percentage' " {
|
||||
$x = (NumberFormatCompletion -wordToComplete Percent)
|
||||
$x.count | Should be 1
|
||||
$x.CompletionText | Should match "^'.*'$"
|
||||
$x.ToolTip | Should be "0.00%"
|
||||
$x.ListItemText | Should be "Percentage"
|
||||
}
|
||||
}
|
||||
Context "Expand-NumberFormat function" {
|
||||
It "Expanded named number formats as expected " {
|
||||
$r = [regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol)
|
||||
Expand-NumberFormat 'Currency' | Should match "^[$r\(\)\[\] RED0#\?\-;,.]+$"
|
||||
Expand-NumberFormat 'Number' | Should be "0.00"
|
||||
Expand-NumberFormat 'Percentage' | Should be "0.00%"
|
||||
Expand-NumberFormat 'Scientific' | Should be "0.00E+00"
|
||||
Expand-NumberFormat 'Fraction' | Should be "# ?/?"
|
||||
Expand-NumberFormat 'Short Date' | Should be "mm-dd-yy"
|
||||
Expand-NumberFormat 'Short Time' | Should be "h:mm"
|
||||
Expand-NumberFormat 'Long Time' | Should be "h:mm:ss"
|
||||
Expand-NumberFormat 'Date-Time' | Should be "m/d/yy h:mm"
|
||||
Expand-NumberFormat 'Text' | Should be "@"
|
||||
}
|
||||
}
|
||||
Context "Apply-NumberFormat" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$n = [datetime]::Now.ToOADate()
|
||||
|
||||
$excel = 1..32 | ForEach-Object {$n} | Export-Excel -Path $path -show -WorksheetName s2 -PassThru
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A1" -numberFormat 'General'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A2" -numberFormat 'Number'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A3" -numberFormat 'Percentage'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A4" -numberFormat 'Scientific'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A5" -numberFormat 'Fraction'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A6" -numberFormat 'Short Date'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A7" -numberFormat 'Short Time'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A8" -numberFormat 'Long Time'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A9" -numberFormat 'Date-Time'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A10" -numberFormat 'Currency'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A11" -numberFormat 'Text'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A12" -numberFormat 'h:mm AM/PM'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A13" -numberFormat 'h:mm:ss AM/PM'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A14" -numberFormat 'mm:ss'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A15" -numberFormat '[h]:mm:ss'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A16" -numberFormat 'mmss.0'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A17" -numberFormat 'd-mmm-yy'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A18" -numberFormat 'd-mmm'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A19" -numberFormat 'mmm-yy'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A20" -numberFormat '0'
|
||||
Set-ExcelRange -WorkSheet $ws -Range "A21" -numberFormat '0.00'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A22"] -NumberFormat '#,##0'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A23"] -NumberFormat '#,##0.00'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A24"] -NumberFormat '#,'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A25"] -NumberFormat '#.0,,'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A26"] -NumberFormat '0%'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A27"] -NumberFormat '0.00%'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A28"] -NumberFormat '0.00E+00'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A29"] -NumberFormat '# ?/?'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A30"] -NumberFormat '# ??/??'
|
||||
Set-ExcelRange -Address $ws.Cells[ "A31"] -NumberFormat '@'
|
||||
|
||||
Close-ExcelPackage -ExcelPackage $excel
|
||||
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
}
|
||||
|
||||
It "Set formats which translate to the correct format ID " {
|
||||
$ws.Cells[ 1,1].Style.Numberformat.NumFmtID | Should be 0 # Set as General
|
||||
$ws.Cells[20,1].Style.Numberformat.NumFmtID | Should be 1 # Set as 0
|
||||
$ws.Cells[ 2,1].Style.Numberformat.NumFmtID | Should be 2 # Set as "Number"
|
||||
$ws.Cells[21,1].Style.Numberformat.NumFmtID | Should be 2 # Set as 0.00
|
||||
$ws.Cells[22,1].Style.Numberformat.NumFmtID | Should be 3 # Set as #,##0
|
||||
$ws.Cells[23,1].Style.Numberformat.NumFmtID | Should be 4 # Set as #,##0.00
|
||||
$ws.Cells[26,1].Style.Numberformat.NumFmtID | Should be 9 # Set as 0%
|
||||
$ws.Cells[27,1].Style.Numberformat.NumFmtID | Should be 10 # Set as 0.00%
|
||||
$ws.Cells[ 3,1].Style.Numberformat.NumFmtID | Should be 10 # Set as "Percentage"
|
||||
$ws.Cells[28,1].Style.Numberformat.NumFmtID | Should be 11 # Set as 0.00E+00
|
||||
$ws.Cells[ 4,1].Style.Numberformat.NumFmtID | Should be 11 # Set as "Scientific"
|
||||
$ws.Cells[ 5,1].Style.Numberformat.NumFmtID | Should be 12 # Set as "Fraction"
|
||||
$ws.Cells[29,1].Style.Numberformat.NumFmtID | Should be 12 # Set as # ?/?
|
||||
$ws.Cells[30,1].Style.Numberformat.NumFmtID | Should be 13 # Set as # ??/?
|
||||
$ws.Cells[ 6,1].Style.Numberformat.NumFmtID | Should be 14 # Set as "Short date"
|
||||
$ws.Cells[17,1].Style.Numberformat.NumFmtID | Should be 15 # Set as d-mmm-yy
|
||||
$ws.Cells[18,1].Style.Numberformat.NumFmtID | Should be 16 # Set as d-mmm
|
||||
$ws.Cells[19,1].Style.Numberformat.NumFmtID | Should be 17 # Set as mmm-yy
|
||||
$ws.Cells[12,1].Style.Numberformat.NumFmtID | Should be 18 # Set as h:mm AM/PM
|
||||
$ws.Cells[13,1].Style.Numberformat.NumFmtID | Should be 19 # Set as h:mm:ss AM/PM
|
||||
$ws.Cells[ 7,1].Style.Numberformat.NumFmtID | Should be 20 # Set as "Short time"
|
||||
$ws.Cells[ 8,1].Style.Numberformat.NumFmtID | Should be 21 # Set as "Long time"
|
||||
$ws.Cells[ 9,1].Style.Numberformat.NumFmtID | Should be 22 # Set as "Date-time"
|
||||
$ws.Cells[14,1].Style.Numberformat.NumFmtID | Should be 45 # Set as mm:ss
|
||||
$ws.Cells[15,1].Style.Numberformat.NumFmtID | Should be 46 # Set as [h]:mm:ss
|
||||
$ws.Cells[16,1].Style.Numberformat.NumFmtID | Should be 47 # Set as mmss.0
|
||||
$ws.Cells[11,1].Style.Numberformat.NumFmtID | Should be 49 # Set as "Text"
|
||||
$ws.Cells[31,1].Style.Numberformat.NumFmtID | Should be 49 # Set as @
|
||||
$ws.Cells[24,1].Style.Numberformat.Format | Should be '#,' # Whole thousands
|
||||
$ws.Cells[25,1].Style.Numberformat.Format | Should be '#.0,,' # Millions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$excel = $data| Export-Excel -Path $path -AutoNameRange -PassThru
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
|
||||
$c = Set-Column -PassThru -Worksheet $ws -Heading "Total" -Value "=Quantity*Price" -NumberFormat "£#,###.00" -FontColor Blue -Bold -HorizontalAlignment Right -VerticalAlignment Top
|
||||
$r = Set-Row -PassThru -Worksheet $ws -StartColumn 3 -BorderAround Thin -Italic -Underline -FontSize 14 -Value {"=sum($columnName`2:$columnName$endrow)" } -VerticalAlignment Bottom
|
||||
Set-Format -Address $excel.Workbook.Worksheets["Sheet1"].cells["b3"] -HorizontalAlignment Right -VerticalAlignment Center -BorderAround Thick -BorderColor Red -StrikeThru
|
||||
Set-Format -Address $excel.Workbook.Worksheets["Sheet1"].cells["c3"] -BorderColor Red -BorderTop DashDot -BorderLeft DashDotDot -BorderBottom Dashed -BorderRight Dotted
|
||||
Set-Format -WorkSheet $ws -Range "E3" -Bold:$false -FontShift Superscript -HorizontalAlignment Left
|
||||
Set-Format -WorkSheet $ws -Range "E1" -ResetFont -HorizontalAlignment General
|
||||
Set-Format -Address $ws.cells["E7"] -ResetFont -WrapText -BackgroundColor AliceBlue -BackgroundPattern DarkTrellis -PatternColor Red -NumberFormat "£#,###.00"
|
||||
Set-Format -Address $ws.Column(1) -Width 0
|
||||
Set-Format -Address $ws.Column(2) -AutoFit
|
||||
Set-Format -Address $ws.Cells["E:E"] -AutoFit
|
||||
Set-Format -Address $ws.row(5) -Height 0
|
||||
Close-ExcelPackage $excel
|
||||
$c = Set-ExcelColumn -PassThru -Worksheet $ws -Heading "Total" -Value "=Quantity*Price" -NumberFormat "£#,###.00" -FontColor ([System.Drawing.Color]::Blue) -Bold -HorizontalAlignment Right -VerticalAlignment Top
|
||||
$r = Set-ExcelRow -PassThru -Worksheet $ws -StartColumn 3 -BorderAround Thin -Italic -Underline -FontSize 14 -Value {"=sum($columnName`2:$columnName$endrow)" } -VerticalAlignment Bottom
|
||||
Set-ExcelRange -Address $excel.Workbook.Worksheets["Sheet1"].Cells["b3"] -HorizontalAlignment Right -VerticalAlignment Center -BorderAround Thick -BorderColor ([System.Drawing.Color]::Red) -StrikeThru
|
||||
Set-ExcelRange -Address $excel.Workbook.Worksheets["Sheet1"].Cells["c3"] -BorderColor ([System.Drawing.Color]::Red) -BorderTop DashDot -BorderLeft DashDotDot -BorderBottom Dashed -BorderRight Dotted
|
||||
Set-ExcelRange -WorkSheet $ws -Range "E3" -Bold:$false -FontShift Superscript -HorizontalAlignment Left
|
||||
Set-ExcelRange -WorkSheet $ws -Range "E1" -ResetFont -HorizontalAlignment General -FontName "Courier New" -fontSize 9
|
||||
Set-ExcelRange -Address $ws.Cells["E7"] -ResetFont -WrapText -BackgroundColor ([System.Drawing.Color]::AliceBlue) -BackgroundPattern DarkTrellis -PatternColor ([System.Drawing.Color]::Red) -NumberFormat "£#,###.00"
|
||||
Set-ExcelRange -Address $ws.Column(1) -Width 0
|
||||
Set-ExcelRange -Address $ws.Column(2) -AutoFit
|
||||
Set-ExcelRange -Address $ws.Cells["E:E"] -AutoFit
|
||||
#Test alias
|
||||
Set-Format -Address $ws.row(5) -Height 0
|
||||
$rr = $r.row
|
||||
Set-ExcelRange -WorkSheet $ws -Range "B$rr" -Value "Total"
|
||||
$BadHideWarnvar = $null
|
||||
Set-ExcelRange -WorkSheet $ws -Range "D$rr" -Formula "=E$rr/C$rr" -Hidden -WarningVariable "BadHideWarnvar" -WarningAction SilentlyContinue
|
||||
$rr ++
|
||||
Set-ExcelRange -WorkSheet $ws -Range "B$rr" -Value ([datetime]::Now)
|
||||
Close-ExcelPackage $excel -Calculate
|
||||
|
||||
|
||||
$excel = Open-ExcelPackage $path
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
}
|
||||
Context "Rows and Columns" {
|
||||
it "Set a row and a column to have zero width/height " {
|
||||
$r | should not beNullorEmpty
|
||||
# $c | should not beNullorEmpty ## can't see why but this test breaks in appveyor
|
||||
$ws.Column(1).width | should be 0
|
||||
$ws.Row(5).height | should be 0
|
||||
Context "Set-ExcelRow and Set-ExcelColumn" {
|
||||
it "Set a row and a column to have zero width/height " {
|
||||
$r | Should not beNullorEmpty
|
||||
# $c | Should not beNullorEmpty ## can't see why but this test breaks in appveyor
|
||||
$ws.Column(1).width | Should be 0
|
||||
$ws.Row(5).height | Should be 0
|
||||
}
|
||||
it "Set a column formula, with numberformat, color, bold face and alignment" {
|
||||
$ws.cells["e2"].Formula | Should be "=Quantity*Price"
|
||||
$ws.cells["e2"].Style.Font.Color.rgb | Should be "FF0000FF"
|
||||
$ws.cells["e2"].Style.Font.Bold | Should be $true
|
||||
$ws.cells["e2"].Style.Font.VerticalAlign | Should be "None"
|
||||
$ws.cells["e2"].Style.Numberformat.format | Should be "£#,###.00"
|
||||
$ws.cells["e2"].Style.HorizontalAlignment | Should be "Right"
|
||||
it "Set a column formula, with numberformat, color, bold face and alignment " {
|
||||
$ws.Cells["e2"].Formula | Should be "Quantity*Price"
|
||||
$ws.Cells["e2"].Value | Should be 147.63
|
||||
$ws.Cells["e2"].Style.Font.Color.rgb | Should be "FF0000FF"
|
||||
$ws.Cells["e2"].Style.Font.Bold | Should be $true
|
||||
$ws.Cells["e2"].Style.Font.VerticalAlign | Should be "None"
|
||||
$ws.Cells["e2"].Style.Numberformat.format | Should be "£#,###.00"
|
||||
$ws.Cells["e2"].Style.HorizontalAlignment | Should be "Right"
|
||||
}
|
||||
}
|
||||
Context "Other formatting" {
|
||||
it "Set a row formula with border font size and underline " {
|
||||
$ws.cells["b7"].style.Border.Top.Style | Should be "None"
|
||||
$ws.cells["F7"].style.Border.Top.Style | Should be "None"
|
||||
$ws.cells["C7"].style.Border.Top.Style | Should be "Thin"
|
||||
$ws.cells["C7"].style.Border.Bottom.Style | Should be "Thin"
|
||||
$ws.cells["C7"].style.Border.Right.Style | Should be "None"
|
||||
$ws.cells["C7"].style.Border.Left.Style | Should be "Thin"
|
||||
$ws.cells["E7"].style.Border.Left.Style | Should be "None"
|
||||
$ws.cells["E7"].style.Border.Right.Style | Should be "Thin"
|
||||
$ws.cells["C7"].style.Font.size | Should be 14
|
||||
$ws.cells["C7"].Formula | Should be "=sum(C2:C6)"
|
||||
$ws.cells["C7"].style.Font.UnderLine | Should be $true
|
||||
$ws.cells["C6"].style.Font.UnderLine | Should be $false
|
||||
it "Trapped an attempt to hide a range instead of a Row/Column " {
|
||||
$BadHideWarnvar | Should not beNullOrEmpty
|
||||
}
|
||||
it "Set and calculated a row formula with border font size and underline " {
|
||||
$ws.Cells["b7"].Style.Border.Top.Style | Should be "None"
|
||||
$ws.Cells["F7"].Style.Border.Top.Style | Should be "None"
|
||||
$ws.Cells["C7"].Style.Border.Top.Style | Should be "Thin"
|
||||
$ws.Cells["C7"].Style.Border.Bottom.Style | Should be "Thin"
|
||||
$ws.Cells["C7"].Style.Border.Right.Style | Should be "None"
|
||||
$ws.Cells["C7"].Style.Border.Left.Style | Should be "Thin"
|
||||
$ws.Cells["E7"].Style.Border.Left.Style | Should be "None"
|
||||
$ws.Cells["E7"].Style.Border.Right.Style | Should be "Thin"
|
||||
$ws.Cells["C7"].Style.Font.size | Should be 14
|
||||
$ws.Cells["C7"].Formula | Should be "sum(C2:C6)"
|
||||
$ws.Cells["C7"].value | Should be 81
|
||||
$ws.Cells["C7"].Style.Font.UnderLine | Should be $true
|
||||
$ws.Cells["C6"].Style.Font.UnderLine | Should be $false
|
||||
}
|
||||
it "Set custom font, size, text-wrapping, alignment, superscript, border and Fill " {
|
||||
$ws.Cells["b3"].Style.Border.Left.Color.Rgb | Should be "FFFF0000"
|
||||
$ws.Cells["b3"].Style.Border.Left.Style | Should be "Thick"
|
||||
$ws.Cells["b3"].Style.Border.Right.Style | Should be "Thick"
|
||||
$ws.Cells["b3"].Style.Border.Top.Style | Should be "Thick"
|
||||
$ws.Cells["b3"].Style.Border.Bottom.Style | Should be "Thick"
|
||||
$ws.Cells["b3"].Style.Font.Strike | Should be $true
|
||||
$ws.Cells["e1"].Style.Font.Color.Rgb | Should be "ff000000"
|
||||
$ws.Cells["e1"].Style.Font.Bold | Should be $false
|
||||
$ws.Cells["e1"].Style.Font.Name | Should be "Courier New"
|
||||
$ws.Cells["e1"].Style.Font.Size | Should be 9
|
||||
$ws.Cells["e3"].Style.Font.VerticalAlign | Should be "Superscript"
|
||||
$ws.Cells["e3"].Style.HorizontalAlignment | Should be "Left"
|
||||
$ws.Cells["C6"].Style.WrapText | Should be $false
|
||||
$ws.Cells["e7"].Style.WrapText | Should be $true
|
||||
$ws.Cells["e7"].Style.Fill.BackgroundColor.Rgb | Should be "FFF0F8FF"
|
||||
$ws.Cells["e7"].Style.Fill.PatternColor.Rgb | Should be "FFFF0000"
|
||||
$ws.Cells["e7"].Style.Fill.PatternType | Should be "DarkTrellis"
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-ExcelRange value setting " {
|
||||
it "Inserted a formula " {
|
||||
$ws.Cells["D7"].Formula | Should be "E7/C7"
|
||||
}
|
||||
it "Inserted a value " {
|
||||
$ws.Cells["B7"].Value | Should be "Total"
|
||||
}
|
||||
it "Inserted a date with localized date-time format " {
|
||||
$ws.Cells["B8"].Style.Numberformat.NumFmtID | Should be 22
|
||||
}
|
||||
}
|
||||
|
||||
Context "Set-ExcelColumn Value Setting" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
|
||||
$excel = $DriverData | Export-Excel -PassThru -Path $path -AutoSize -AutoNameRange
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
|
||||
Set-ExcelColumn -Worksheet $ws -Heading "Link" -AutoSize -Value {"https://en.wikipedia.org" + $worksheet.Cells["B$Row"].value }
|
||||
$c = Set-ExcelColumn -PassThru -Worksheet $ws -Heading "NextBirthday" -Value {
|
||||
$bmonth = $worksheet.Cells["C$Row"].value.month ; $bDay = $worksheet.Cells["C$Row"].value.day
|
||||
$cMonth = [datetime]::Now.Month ; $cday = [datetime]::Now.day ; $cyear = [datetime]::Now.Year
|
||||
if (($cmonth -gt $bmonth) -or (($cMonth -eq $bmonth) -and ($cday -ge $bDay))){
|
||||
[datetime]::new($cyear+1, $bmonth, $bDay)
|
||||
}
|
||||
else {[datetime]::new($cyear, $bmonth, $bday) }
|
||||
}
|
||||
Set-ExcelColumn -Worksheet $ws -Heading "Age" -Value "=INT((NOW()-DateOfBirth)/365)"
|
||||
# Test Piping column Numbers into Set excelColumn
|
||||
3, $c.ColumnMin | Set-ExcelColumn -Worksheet $ws -NumberFormat 'Short Date' -AutoSize
|
||||
|
||||
4..6 | Set-ExcelColumn -Worksheet $ws -AutoNameRange
|
||||
|
||||
Close-ExcelPackage -ExcelPackage $excel -Calculate
|
||||
$excel = Open-ExcelPackage $path
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
}
|
||||
It "Inserted Hyperlinks " {
|
||||
$ws.Cells["D2"].Hyperlink | Should not beNullorEmpty
|
||||
$ws.Cells["D2"].Style.Font.UnderLine | Should be $true
|
||||
}
|
||||
It "Inserted and formatted Dates " {
|
||||
$ws.Cells["C2"].Value.GetType().name | should be "DateTime"
|
||||
$ws.Cells["C2"].Style.Numberformat.NumFmtID | should be 14
|
||||
$ws.Cells["E2"].Value.GetType().name | should be "DateTime"
|
||||
$ws.Cells["E2"].Style.Numberformat.NumFmtID | should be 14
|
||||
}
|
||||
It "Inserted Formulas " {
|
||||
$ws.Cells["F2"].Formula | Should not beNullorEmpty
|
||||
}
|
||||
It "Created Named ranges " {
|
||||
$ws.Names.Count | Should be 6
|
||||
$ws.Names["Age"] | Should not beNullorEmpty
|
||||
$ws.Names["Age"].Start.Column | Should be 6
|
||||
$ws.Names["Age"].Start.Row | Should be 2
|
||||
$ws.Names["Age"].End.Row | Should be 7
|
||||
$ws.names[0].name | Should be "Name"
|
||||
$ws.Names[0].Start.Column | Should be 1
|
||||
$ws.Names[0].Start.Row | Should be 2
|
||||
}
|
||||
|
||||
it "Set custom text wrapping, alignment, superscript, border and Fill " {
|
||||
$ws.cells["e3"].Style.HorizontalAlignment | Should be "Left"
|
||||
$ws.cells["e3"].Style.Font.VerticalAlign | Should be "Superscript"
|
||||
$ws.cells["b3"].style.Border.Left.Color.Rgb | Should be "FFFF0000"
|
||||
$ws.cells["b3"].style.Border.Left.Style | Should be "Thick"
|
||||
$ws.cells["b3"].style.Border.Right.Style | Should be "Thick"
|
||||
$ws.cells["b3"].style.Border.Top.Style | Should be "Thick"
|
||||
$ws.cells["b3"].style.Border.Bottom.Style | Should be "Thick"
|
||||
$ws.cells["b3"].style.Font.Strike | Should be $true
|
||||
$ws.cells["e1"].Style.Font.Color.rgb | Should be "ff000000"
|
||||
$ws.cells["e1"].Style.Font.Bold | Should be $false
|
||||
$ws.cells["C6"].style.WrapText | Should be $false
|
||||
$ws.cells["e7"].style.WrapText | Should be $true
|
||||
$ws.cells["e7"].Style.Fill.BackgroundColor.Rgb| Should be "FFF0F8FF"
|
||||
$ws.cells["e7"].Style.Fill.PatternColor.Rgb | Should be "FFFF0000"
|
||||
$ws.cells["e7"].Style.Fill.PatternType | Should be "DarkTrellis"
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Conditional Formatting" {
|
||||
BeforeAll {
|
||||
Remove-Item $path
|
||||
$data = Get-Process | Where-Object company | Select-Object company,name,pm,handles,*mem*
|
||||
$cfmt = New-ConditionalFormattingIconSet -Range "c:c" -ConditionalFormat ThreeIconSet -IconType Arrows
|
||||
$data | Export-Excel -path $Path -AutoSize -ConditionalFormat $cfmt
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
}
|
||||
Context "Using a pre-prepared 3 Arrows rule" {
|
||||
it "Set the right type, IconSet and range " {
|
||||
$ws.ConditionalFormatting[0].IconSet | Should be "Arrows"
|
||||
$ws.ConditionalFormatting[0].Address.Address | Should be "c:c"
|
||||
$ws.ConditionalFormatting[0].Type.ToString() | Should be "ThreeIconSet"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
$data2 = ConvertFrom-Csv -InputObject @"
|
||||
ID,Product,Quantity,Price,Total
|
||||
12001,Nails,37,3.99,147.63
|
||||
12002,Hammer,5,12.10,60.5
|
||||
12003,Saw,12,15.37,184.44
|
||||
12010,Drill,20,8,160
|
||||
12011,Crowbar,7,23.48,164.36
|
||||
12001,Nails,53,3.99,211.47
|
||||
12002,Hammer,6,12.10,72.60
|
||||
12003,Saw,10,15.37,153.70
|
||||
12010,Drill,10,8,80
|
||||
12012,Pliers,2,14.99,29.98
|
||||
12001,Nails,20,3.99,79.80
|
||||
12002,Hammer,2,12.10,24.20
|
||||
12010,Drill,11,8,88
|
||||
12012,Pliers,3,14.99,44.97
|
||||
"@
|
||||
|
||||
Describe "Table Formatting" {
|
||||
BeforeAll {
|
||||
Remove-Item $path
|
||||
$excel = $data2 | Export-excel -path $path -WorksheetName Hardware -AutoNameRange -AutoSize -BoldTopRow -FreezeTopRow -PassThru
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
#test showfilter & TotalSettings
|
||||
$Table = Add-ExcelTable -PassThru -Range $ws.Cells[$($ws.Dimension.address)] -TableStyle Light1 -TableName HardwareTable -TotalSettings @{"Total"="Sum"} -ShowFirstColumn -ShowFilter:$false
|
||||
#test expnading named number formats
|
||||
Set-ExcelColumn -Worksheet $ws -Column 4 -NumberFormat 'Currency'
|
||||
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
||||
$PtDef =New-PivotTableDefinition -PivotTableName Totals -PivotRows Product -PivotData @{"Total"="Sum"} -PivotNumberFormat Currency -PivotTotals None -PivotTableStyle Dark2
|
||||
Export-excel -ExcelPackage $excel -WorksheetName Hardware -PivotTableDefinition $PtDef
|
||||
$excel= Open-ExcelPackage -Path $path
|
||||
$ws1 = $excel.Workbook.Worksheets["Hardware"]
|
||||
$ws2 = $excel.Workbook.Worksheets["Totals"]
|
||||
}
|
||||
Context "Setting and not clearing when Export-Excel touches the file again."{
|
||||
it "Set the Table Options " {
|
||||
$ws1.Tables[0].Address.Address | should be "A1:E16"
|
||||
$ws1.Tables[0].Name | should be "HardwareTable"
|
||||
$ws1.Tables[0].ShowFirstColumn | should be $true
|
||||
$ws1.Tables[0].ShowLastColumn | should not be $true
|
||||
$ws1.Tables[0].ShowTotal | should be $true
|
||||
$ws1.Tables[0].Columns["Total"].TotalsRowFunction | Should be "Sum"
|
||||
$ws1.Tables[0].StyleName | should be "TableStyleLight1"
|
||||
$ws1.Cells["D4"].Style.Numberformat.Format | Should match ([regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol))
|
||||
$ws1.Cells["E5"].Style.Numberformat.Format | Should match ([regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol))
|
||||
}
|
||||
it "Set the Pivot Options " {
|
||||
$ws2.PivotTables[0].DataFields[0].Format | Should match ([regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol))
|
||||
$ws2.PivotTables[0].ColumGrandTotals | Should be $false
|
||||
$ws2.PivotTables[0].StyleName | Should be "PivotStyleDark2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
appveyor.yml
BIN
appveyor.yml
Binary file not shown.
15
azure-pipelines.yml
Normal file
15
azure-pipelines.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
resources:
|
||||
- repo: self
|
||||
queue:
|
||||
name: Hosted VS2017
|
||||
steps:
|
||||
- powershell: ./ '.\DoTests.ps1'
|
||||
displayName: 'PowerShell Script'
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'Archive $(Build.BinariesDirectory)'
|
||||
|
||||
trigger:
|
||||
paths:
|
||||
exclude:
|
||||
- README.md
|
||||
@@ -1,91 +1,114 @@
|
||||
Function Compare-WorkSheet {
|
||||
Function Compare-WorkSheet {
|
||||
<#
|
||||
.Synopsis
|
||||
Compares two worksheets with the same name in different files.
|
||||
Compares two worksheets and shows the differences.
|
||||
.Description
|
||||
This command takes two file names, a worksheet name and a name for a key column.
|
||||
It reads the worksheet from each file and decides the column names.
|
||||
It builds as hashtable of the key column values and the rows they appear in
|
||||
It then uses PowerShell's compare object command to compare the sheets (explicity checking all column names which have not been excluded)
|
||||
For the difference rows it adds the row number for the key of that row - we have to add the key after doing the comparison,
|
||||
otherwise rows will be considered as different simply because they have different row numbers
|
||||
We also add the name of the file in which the difference occurs.
|
||||
If -BackgroundColor is specified the difference rows will be changed to that background.
|
||||
This command takes two file names, one or two worksheet names and a name
|
||||
for a "key" column. It reads the worksheet from each file and decides the
|
||||
column names and builds a hashtable of the key-column values and the
|
||||
rows in which they appear.
|
||||
It then uses PowerShell's Compare-Object command to compare the sheets
|
||||
(explicitly checkingall the column names which have not been excluded).
|
||||
For the difference rows it adds the row number for the key of that row -
|
||||
we have to add the key after doing the comparison, otherwise identical
|
||||
rows at different positions in the file will not be considered a match.
|
||||
We also add the name of the file and sheet in which the difference occurs.
|
||||
If -BackgroundColor is specified the difference rows will be changed to
|
||||
that background in the orginal file.
|
||||
.Example
|
||||
Compare-WorkSheet -Referencefile 'Server56.xlsx' -Differencefile 'Server57.xlsx' -WorkSheetName Products -key IdentifyingNumber -ExcludeProperty Install* | format-table
|
||||
The two workbooks in this example contain the result of redirecting a subset of properties from Get-WmiObject -Class win32_product to Export-Excel
|
||||
The command compares the "products" pages in the two workbooks, but we don't want to register a differnce if if the software was installed on a
|
||||
different date or from a different place, so Excluding Install* removes InstallDate and InstallSource.
|
||||
This data doesn't have a "name" column" so we specify the "IdentifyingNumber" column as the key.
|
||||
Compare-WorkSheet -Referencefile 'Server56.xlsx' -Differencefile 'Server57.xlsx' -WorkSheetName Products -key IdentifyingNumber -ExcludeProperty Install* | Format-Table
|
||||
|
||||
The two workbooks in this example contain the result of redirecting a subset
|
||||
of properties from Get-WmiObject -Class win32_product to Export-Excel.
|
||||
The command compares the "Products" pages in the two workbooks, but we
|
||||
don't want to register a difference if the software was installed on a
|
||||
different date or from a different place, and excluding Install* removes
|
||||
InstallDate and InstallSource. This data doesn't have a "Name" column, so
|
||||
we specify the "IdentifyingNumber" column as the key.
|
||||
The results will be presented as a table.
|
||||
.Example
|
||||
compare-WorkSheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -GridView
|
||||
This time two workbooks contain the result of redirecting Get-WmiObject -Class win32_service to Export-Excel
|
||||
Here the -Differencefile and -Referencefile parameter switches are assumed , and the default setting for -key ("Name") works for services
|
||||
This will display the differences between the "services" sheets using a grid view
|
||||
Compare-WorkSheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName Services -GridView
|
||||
|
||||
This time two workbooks contain the result of redirecting the command
|
||||
Get-WmiObject -Class win32_service to Export-Excel. Here the -Differencefile
|
||||
and -Referencefile parameter switches are assumed and the default setting for
|
||||
-Key ("Name") works for services. This will display the differences between
|
||||
the "Services" sheets using a grid view
|
||||
.Example
|
||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen
|
||||
This version of the command outputs the differences between the "services" pages and also highlights any different rows in the spreadsheet files.
|
||||
|
||||
This version of the command outputs the differences between the "services" pages and highlights any different rows in the spreadsheet files.
|
||||
.Example
|
||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen -FontColor Red -Show
|
||||
This builds on the previous example: this time Where two changed rows have the value in the "name" column (the default value for -key),
|
||||
this version adds highlighting of the changed cells in red; and then opens the Excel file.
|
||||
|
||||
This example builds on the previous one: this time where two changed rows have
|
||||
the value in the "Name" column (the default value for -Key), this version adds
|
||||
highlighting of the changed cells in red; and then opens the Excel file.
|
||||
.Example
|
||||
Compare-WorkSheet 'Pester-tests.xlsx' 'Pester-tests.xlsx' -WorkSheetName 'Server1','Server2' -Property "full Description","Executed","Result" -Key "full Description"
|
||||
This time the reference file and the difference file are the same file and two different sheets are used. Because the tests include the
|
||||
machine name and time the test was run the command specifies a limited set of columns should be used.
|
||||
|
||||
This time the reference file and the difference file are the same file and
|
||||
two different sheets are used. Because the tests include the machine name
|
||||
and time the test was run, the command specifies that a limited set of
|
||||
columns should be used.
|
||||
.Example
|
||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName general -Startrow 2 -Headername Label,value -Key Label -GridView -ExcludeDifferent
|
||||
The "General" page has a title and two unlabelled columns with a row forCPU, Memory, Domain, Disk and so on
|
||||
So the command is instructed to starts at row 2 to skip the title and to name the columns: the first is "label" and the Second "Value";
|
||||
the label acts as the key. This time we interested the rows which are the same in both sheets,
|
||||
and the result is displayed using grid view. Note that grid view works best when the number of columns is small.
|
||||
|
||||
The "General" page in the two workbooks has a title and two unlabelled columns
|
||||
with a row each for CPU, Memory, Domain, Disk and so on. So the command is
|
||||
told to start at row 2 in order to skip the title and given names for the
|
||||
columns: the first is "label" and the second "Value"; the label acts as the key.
|
||||
This time we are interested in those rows which are the same in both sheets,
|
||||
and the result is displayed using grid view.
|
||||
Note that grid view works best when the number of columns is small.
|
||||
.Example
|
||||
Compare-WorkSheet 'Server1.xlsx' 'Server2.xlsx' -WorkSheetName general -Startrow 2 -Headername Label,value -Key Label -BackgroundColor White -Show -AllDataBackgroundColor LightGray
|
||||
This version of the previous command lightlights all the cells in lightgray and then sets the changed rows back to white; only
|
||||
the unchanged rows are highlighted
|
||||
|
||||
This version of the previous command highlights all the cells in LightGray
|
||||
and then sets the changed rows back to white.
|
||||
Only the unchanged rows are highlighted.
|
||||
#>
|
||||
[cmdletbinding(DefaultParameterSetName)]
|
||||
Param(
|
||||
#First file to compare
|
||||
#First file to compare.
|
||||
[parameter(Mandatory=$true,Position=0)]
|
||||
$Referencefile ,
|
||||
#Second file to compare
|
||||
#Second file to compare.
|
||||
[parameter(Mandatory=$true,Position=1)]
|
||||
$Differencefile ,
|
||||
#Name(s) of worksheets to compare.
|
||||
$WorkSheetName = "Sheet1",
|
||||
#Properties to include in the DIFF - supports wildcards, default is "*"
|
||||
#Properties to include in the comparison - supports wildcards, default is "*".
|
||||
$Property = "*" ,
|
||||
#Properties to exclude from the the search - supports wildcards
|
||||
#Properties to exclude from the comparison - supports wildcards.
|
||||
$ExcludeProperty ,
|
||||
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
|
||||
#Specifies custom property names to use, instead of the values defined in the starting row of the sheet.
|
||||
[Parameter(ParameterSetName='B', Mandatory)]
|
||||
[String[]]$Headername,
|
||||
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet
|
||||
#Automatically generate property names (P1, P2, P3 ...) instead of the using the values the starting row of the sheet.
|
||||
[Parameter(ParameterSetName='C', Mandatory)]
|
||||
[switch]$NoHeader,
|
||||
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
|
||||
#The row from where we start to import data: all rows above the start row are disregarded. By default, this is the first row.
|
||||
[int]$Startrow = 1,
|
||||
#If specified, highlights all the cells - so you can make Equal cells one colour, and Diff cells another.
|
||||
[System.Drawing.Color]$AllDataBackgroundColor,
|
||||
#If specified, highlights the DIFF rows
|
||||
[System.Drawing.Color]$BackgroundColor,
|
||||
#If specified identifies the tabs which contain DIFF rows (ignored if -backgroundColor is omitted)
|
||||
[System.Drawing.Color]$TabColor,
|
||||
#Name of a column which is unique and will be used to add a row to the DIFF object, default is "Name"
|
||||
#If specified, highlights all the cells - so you can make Equal cells one color, and Different cells another.
|
||||
$AllDataBackgroundColor,
|
||||
#If specified, highlights the rows with differences.
|
||||
$BackgroundColor,
|
||||
#If specified identifies the tabs which contain difference rows (ignored if -BackgroundColor is omitted).
|
||||
$TabColor,
|
||||
#Name of a column which is unique and will be used to add a row to the DIFF object, defaults to "Name".
|
||||
$Key = "Name" ,
|
||||
#If specified, highlights the DIFF columns in rows which have the same key.
|
||||
[System.Drawing.Color]$FontColor,
|
||||
#If specified opens the Excel workbooks instead of outputting the diff to the console (unless -passthru is also specified)
|
||||
$FontColor,
|
||||
#If specified, opens the Excel workbooks instead of outputting the diff to the console (unless -PassThru is also specified).
|
||||
[Switch]$Show,
|
||||
#If specified, the command tries to the show the DIFF in a Gridview and not on the console. (unless-Passthru is also specified). This Works best with few columns selected, and requires a key
|
||||
#If specified, the command tries to the show the DIFF in a Grid-View and not on the console. (unless-PassThru is also specified). This works best with few columns selected, and requires a key.
|
||||
[switch]$GridView,
|
||||
#If specified -Passthrough full set of diff data is returned without filtering to the specified properties
|
||||
#If specifieda full set of DIFF data is returned without filtering to the specified properties.
|
||||
[Switch]$PassThru,
|
||||
#If specified the result will include equal rows as well. By default only different rows are returned
|
||||
#If specified the result will include equal rows as well. By default only different rows are returned.
|
||||
[Switch]$IncludeEqual,
|
||||
#If Specified the result includes only the rows where both are equal
|
||||
#If specified, the result includes only the rows where both are equal.
|
||||
[Switch]$ExcludeDifferent
|
||||
)
|
||||
|
||||
@@ -93,29 +116,29 @@ Function Compare-WorkSheet {
|
||||
try { $oneFile = ((Resolve-Path -Path $Referencefile -ErrorAction Stop).path -eq (Resolve-Path -Path $Differencefile -ErrorAction Stop).path)}
|
||||
Catch { Write-Warning -Message "Could not Resolve the filenames." ; return }
|
||||
|
||||
#If we have one file , we mush have two different worksheet names. If we have two files we can a single string or two strings.
|
||||
#If we have one file , we must have two different worksheet names. If we have two files we can have a single string or two strings.
|
||||
if ($onefile -and ( ($WorkSheetName.count -ne 2) -or $WorkSheetName[0] -eq $WorkSheetName[1] ) ) {
|
||||
Write-Warning -Message "If both the Reference and difference file are the same then worksheet name must provide 2 different names"
|
||||
return
|
||||
}
|
||||
if ($WorkSheetName.count -eq 2) {$worksheet1 = $WorkSheetName[0] ; $WorkSheet2 = $WorkSheetName[1]}
|
||||
elseif ($WorkSheetName -is [string]) {$worksheet1 = $WorkSheet2 = $WorkSheetName}
|
||||
if ($WorkSheetName.count -eq 2) {$worksheet1 = $WorkSheetName[0] ; $workSheet2 = $WorkSheetName[1]}
|
||||
elseif ($WorkSheetName -is [string]) {$worksheet1 = $workSheet2 = $WorkSheetName}
|
||||
else {Write-Warning -Message "You must provide either a single worksheet name or two names." ; return }
|
||||
|
||||
$params= @{ ErrorAction = [System.Management.Automation.ActionPreference]::Stop }
|
||||
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
||||
try {
|
||||
$Sheet1 = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
|
||||
$Sheet2 = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
|
||||
$sheet1 = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
|
||||
$sheet2 = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
|
||||
}
|
||||
Catch {Write-Warning -Message "Could not read the worksheet from $Referencefile and/or $Differencefile." ; return }
|
||||
|
||||
#Get Column headings and create a hash table of Name to column letter.
|
||||
$headings = $Sheet1[-1].psobject.Properties.name # This preserves the sequence - using get-member would sort them alphabetically!
|
||||
$headings | ForEach-Object -Begin {$columns = @{} ; $i=65 } -Process {$Columns[$_] = [char]($i ++) }
|
||||
$headings | ForEach-Object -Begin {$columns = @{} ; $i= 1 } -Process {$Columns[$_] = [OfficeOpenXml.ExcelAddress]::GetAddress(1,($i ++)) -replace "\d","" }
|
||||
|
||||
#Make a list of property headings using the Property (default "*") and ExcludeProperty parameters
|
||||
if ($Key -eq "Name" -and $NoHeader) {$key = "p1"}
|
||||
if ($Key -eq "Name" -and $NoHeader) {$Key = "p1"}
|
||||
$propList = @()
|
||||
foreach ($p in $Property) {$propList += ($headings.where({$_ -like $p}) )}
|
||||
foreach ($p in $ExcludeProperty) {$propList = $propList.where({$_ -notlike $p}) }
|
||||
@@ -124,12 +147,12 @@ Function Compare-WorkSheet {
|
||||
if ($propList.Count -eq 0) {Write-Warning -Message "No Columns are selected with -Property = '$Property' and -excludeProperty = '$ExcludeProperty'." ; return}
|
||||
|
||||
#Add RowNumber, Sheetname and file name to every row
|
||||
$FirstDataRow = $startRow + 1
|
||||
if ($Headername -or $NoHeader) {$FirstDataRow -- }
|
||||
$i = $FirstDataRow ; foreach ($row in $Sheet1) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
|
||||
$firstDataRow = $startRow + 1
|
||||
if ($Headername -or $NoHeader) {$firstDataRow -- }
|
||||
$i = $firstDataRow ; foreach ($row in $Sheet1) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "_Sheet" -Value $worksheet1
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "_File" -Value $Referencefile}
|
||||
$i = $FirstDataRow ; foreach ($row in $Sheet2) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
|
||||
$i = $firstDataRow ; foreach ($row in $Sheet2) {Add-Member -InputObject $row -MemberType NoteProperty -Name "_Row" -Value ($i ++)
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "_Sheet" -Value $worksheet2
|
||||
Add-Member -InputObject $row -MemberType NoteProperty -Name "_File" -Value $Differencefile}
|
||||
|
||||
@@ -145,7 +168,7 @@ Function Compare-WorkSheet {
|
||||
foreach ($file in $updates) {
|
||||
try {$xl = Open-ExcelPackage -Path $file.name }
|
||||
catch {Write-warning -Message "Can't open $($file.Name) for writing." ; return}
|
||||
if ($AllDataBackgroundColor) {
|
||||
if ($PSBoundParameters.ContainsKey("AllDataBackgroundColor")) {
|
||||
$file.Group._sheet | Sort-Object -Unique | ForEach-Object {
|
||||
$ws = $xl.Workbook.Worksheets[$_]
|
||||
if ($headerName) {$range = "A" + $startrow + ":" + $ws.dimension.end.address}
|
||||
@@ -158,7 +181,8 @@ Function Compare-WorkSheet {
|
||||
$range = $ws.Dimension -replace "\d+",$row._row
|
||||
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $BackgroundColor
|
||||
}
|
||||
if ($TabColor) {
|
||||
if ($PSBoundParameters.ContainsKey("TabColor")) {
|
||||
if ($TabColor -is [string]) {$TabColor = [System.Drawing.Color]::$TabColor }
|
||||
foreach ($tab in ($file.group._sheet | Select-Object -Unique)) {
|
||||
$xl.Workbook.Worksheets[$tab].TabColor = $TabColor
|
||||
}
|
||||
@@ -166,7 +190,7 @@ Function Compare-WorkSheet {
|
||||
$xl.save() ; $xl.Stream.Close() ; $xl.Dispose()
|
||||
}
|
||||
}
|
||||
#if font colour was specified, set it on changed properties where the same key appears in both sheets.
|
||||
#if font color was specified, set it on changed properties where the same key appears in both sheets.
|
||||
if ($diff -and $FontColor -and ($propList -contains $Key) ) {
|
||||
$updates = $diff.where({$_.SideIndicator -ne "=="}) | Group-object -Property $Key | Where-Object {$_.count -eq 2}
|
||||
if ($updates) {
|
||||
@@ -198,7 +222,9 @@ Function Compare-WorkSheet {
|
||||
#if nothing was found write a message which wont be redirected
|
||||
if (-not $diff) {Write-Host "Comparison of $Referencefile::$worksheet1 and $Differencefile::$WorkSheet2 returned no results." }
|
||||
|
||||
if ($show) {
|
||||
|
||||
|
||||
if ($Show) {
|
||||
Start-Process -FilePath $Referencefile
|
||||
if (-not $oneFile) { Start-Process -FilePath $Differencefile }
|
||||
if ($GridView) { Write-Warning -Message "-GridView is ignored when -Show is specified" }
|
||||
|
||||
41
filelist.txt
Normal file
41
filelist.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
*.dll
|
||||
*.psd1
|
||||
*.psm1
|
||||
AddConditionalFormatting.ps1
|
||||
Charting.ps1
|
||||
ColorCompletion.ps1
|
||||
Compare-Worksheet.ps1
|
||||
ConvertExcelToImageFile.ps1
|
||||
ConvertFromExcelData.ps1
|
||||
ConvertFromExcelToSQLInsert.ps1
|
||||
ConvertToExcelXlsx.ps1
|
||||
Copy-ExcelWorkSheet.ps1
|
||||
Export-Charts.ps1
|
||||
Export-Excel.ps1
|
||||
Export-ExcelSheet.ps1
|
||||
Get-ExcelColumnName.ps1
|
||||
Get-ExcelSheetInfo.ps1
|
||||
Get-ExcelWorkbookInfo.ps1
|
||||
Get-HtmlTable.ps1
|
||||
Get-Range.ps1
|
||||
Get-XYRange.ps1
|
||||
Import-Html.ps1
|
||||
InferData.ps1
|
||||
Invoke-Sum.ps1
|
||||
Join-Worksheet.ps1
|
||||
Merge-Worksheet.ps1
|
||||
New-ConditionalFormattingIconSet.ps1
|
||||
New-ConditionalText.ps1
|
||||
New-ExcelChart.ps1
|
||||
New-PSItem.ps1
|
||||
Open-ExcelPackage.ps1
|
||||
Pivot.ps1
|
||||
PivotTable.ps1
|
||||
Plot.ps1
|
||||
Send-SQLDataToExcel.ps1
|
||||
Set-CellStyle.ps1
|
||||
Set-Column.ps1
|
||||
Set-Row.ps1
|
||||
SetFormat.ps1
|
||||
TrackingUtils.ps1
|
||||
Update-FirstObjectProperties.ps1
|
||||
2
plot.ps1
2
plot.ps1
@@ -155,7 +155,7 @@ class PSPlot {
|
||||
$sum=0
|
||||
|
||||
$columnName.ToCharArray() |
|
||||
ForEach {
|
||||
ForEach-Object {
|
||||
$sum*=26
|
||||
$sum+=[char]$_.tostring().toupper()-[char]'A'+1
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ function ConvertFrom-ExcelColumnName {
|
||||
|
||||
$sum=0
|
||||
$columnName.ToCharArray() |
|
||||
ForEach {
|
||||
ForEach-Object {
|
||||
$sum*=26
|
||||
$sum+=[char]$_.tostring().toupper()-[char]'A'+1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user