mirror of
https://github.com/dfinke/ImportExcel.git
synced 2025-12-16 16:24:03 +00:00
Compare commits
182 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f9b308d53 | ||
|
|
847c9a1dc4 | ||
|
|
b488ffc700 | ||
|
|
3ec2481750 | ||
|
|
2d26c854d9 | ||
|
|
a4348ddca7 | ||
|
|
6bfdea6d3e | ||
|
|
cfd3db5803 | ||
|
|
f20a9de3df | ||
|
|
978e8d38b5 | ||
|
|
e7d2b528e5 | ||
|
|
899a8215e5 | ||
|
|
b06e9e35b7 | ||
|
|
6c7f00b031 | ||
|
|
337af82ae2 | ||
|
|
77ef2ebc40 | ||
|
|
92c97b25c3 | ||
|
|
52231254a5 | ||
|
|
494ac51ae5 | ||
|
|
0febb4a3c2 | ||
|
|
62f0faa5c5 | ||
|
|
1055bc41bf | ||
|
|
e100fa7a36 | ||
|
|
83bd387f98 | ||
|
|
caf0059ef5 | ||
|
|
965831ba57 | ||
|
|
a49cab5efc | ||
|
|
17bcea15e8 | ||
|
|
79fb29740d | ||
|
|
2984fe2ef5 | ||
|
|
8734dbd26c | ||
|
|
0211edf008 | ||
|
|
552552b93d | ||
|
|
2229bfb3ed | ||
|
|
25e7962100 | ||
|
|
6071f77218 | ||
|
|
52b9333d7c | ||
|
|
d3d8d76a71 | ||
|
|
f5f97fcd56 | ||
|
|
6665c2952d | ||
|
|
31444320cb | ||
|
|
d5734ff9b2 | ||
|
|
4481637c21 | ||
|
|
6caf247f5b | ||
|
|
65641955ba | ||
|
|
f2c13949a4 | ||
|
|
878ca570fb | ||
|
|
28fd5512bb | ||
|
|
7e465e3729 | ||
|
|
22283604f8 | ||
|
|
0c603afc0e | ||
|
|
a4a989c556 | ||
|
|
d94db666d7 | ||
|
|
438be760f7 | ||
|
|
2949ecc173 | ||
|
|
639ca738f6 | ||
|
|
736dd648f4 | ||
|
|
acdbd4a618 | ||
|
|
ad35d39850 | ||
|
|
e7afe166a4 | ||
|
|
37b076706e | ||
|
|
3303116658 | ||
|
|
89a8cb0469 | ||
|
|
bb9f4c31a6 | ||
|
|
996d1246cf | ||
|
|
0bb08fcb20 | ||
|
|
d004019761 | ||
|
|
a54ca228e9 | ||
|
|
bb6ff474a8 | ||
|
|
86b5c13543 | ||
|
|
c2525b0348 | ||
|
|
9625e4a8ac | ||
|
|
82177da695 | ||
|
|
b3f7a60be8 | ||
|
|
643610c267 | ||
|
|
bd7d70a050 | ||
|
|
d1f41012a1 | ||
|
|
0fbe9dbc9b | ||
|
|
e0b2d15c53 | ||
|
|
34c924ae19 | ||
|
|
9217962306 | ||
|
|
56acf56430 | ||
|
|
ef9be471ab | ||
|
|
9db2bc068e | ||
|
|
9560ea83f9 | ||
|
|
9c79ba573c | ||
|
|
894e645a47 | ||
|
|
f3dc390bfa | ||
|
|
f0f58f84a0 | ||
|
|
7ded24d2f9 | ||
|
|
cf964e3e4f | ||
|
|
8c5b3b2f5f | ||
|
|
8409adeeba | ||
|
|
153d4d8c45 | ||
|
|
69f9ba7d17 | ||
|
|
e4deb5801e | ||
|
|
1a74c0f0d0 | ||
|
|
72e44da219 | ||
|
|
bef2f29651 | ||
|
|
787dda70ee | ||
|
|
285e9e4949 | ||
|
|
01e3ea206d | ||
|
|
6f3420d11e | ||
|
|
2981bf23b1 | ||
|
|
c5cc018eb5 | ||
|
|
268d48ce3d | ||
|
|
eca631670c | ||
|
|
284560e109 | ||
|
|
234615dfdb | ||
|
|
d31cd04781 | ||
|
|
77481f2901 | ||
|
|
54fec69f88 | ||
|
|
1dc9a02d7d | ||
|
|
f86fdbab22 | ||
|
|
66937db040 | ||
|
|
80520299aa | ||
|
|
2753a6876a | ||
|
|
ade442b18c | ||
|
|
45ba112f73 | ||
|
|
e1fe36699b | ||
|
|
b3f4b188da | ||
|
|
0ce75794e6 | ||
|
|
3afe2059e5 | ||
|
|
66b7b64779 | ||
|
|
d90cd6d2d0 | ||
|
|
1d1f266fb6 | ||
|
|
4945b4d6e3 | ||
|
|
21b5a11aca | ||
|
|
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 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -2,6 +2,8 @@
|
|||||||
Thumbs.db
|
Thumbs.db
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
|
|
||||||
|
*.gitignore
|
||||||
|
|
||||||
# Folder config file
|
# Folder config file
|
||||||
Desktop.ini
|
Desktop.ini
|
||||||
|
|
||||||
@@ -14,6 +16,8 @@ $RECYCLE.BIN/
|
|||||||
*.msm
|
*.msm
|
||||||
*.msp
|
*.msp
|
||||||
|
|
||||||
|
*.dll
|
||||||
|
|
||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
@@ -57,4 +61,6 @@ testCCFMT.ps1
|
|||||||
testHide.ps1
|
testHide.ps1
|
||||||
ImportExcel.zip
|
ImportExcel.zip
|
||||||
.vscode/launch.json
|
.vscode/launch.json
|
||||||
|
.vscode/settings.json
|
||||||
|
|
||||||
|
~$*
|
||||||
|
|||||||
3
.vscode/spellright.dict
vendored
3
.vscode/spellright.dict
vendored
@@ -32,3 +32,6 @@ enums
|
|||||||
Numberformat
|
Numberformat
|
||||||
ChartDefiniton
|
ChartDefiniton
|
||||||
hashtables
|
hashtables
|
||||||
|
Agramont
|
||||||
|
AGramont
|
||||||
|
Jhoneill
|
||||||
|
|||||||
@@ -1,46 +1,97 @@
|
|||||||
Function Add-ConditionalFormatting {
|
Function Add-ConditionalFormatting {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Adds conditional formatting to worksheet.
|
Adds conditional formatting to all or part of a worksheet.
|
||||||
.Description
|
.Description
|
||||||
Conditional formatting allows excel to
|
Conditional formatting allows Excel to:
|
||||||
* Mark cells with Icons depending on their value
|
* Mark cells with icons depending on their value
|
||||||
* Show a databar whose length indicates the value or a 2 or 3 color scale where the color indicate the relative 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
|
* Change the color, font, or number format of cells which meet given criteria
|
||||||
Add-ConditionalFormatting allows these to be set; for fine tuning of the rules you can use the -PassThru switch,
|
Add-ConditionalFormatting allows these parameters to be set; for fine tuning of
|
||||||
which will return the rule so that you can modify things which are specific to that type of rule,
|
the rules, the -PassThru switch will return the rule so that you can modify
|
||||||
for example the values which correspond to each icon in an Icon set.
|
things which are specific to that type of rule, example, the values which
|
||||||
|
correspond to each icon in an Icon-Set.
|
||||||
.Example
|
.Example
|
||||||
>
|
>
|
||||||
PS> $excel = $avdata | Export-Excel -Path (Join-path $FilePath "\Machines.XLSX" ) -WorksheetName "Server Anti-Virus" -AutoSize -FreezeTopRow -AutoFilter -PassThru
|
$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 "b2:b1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "2003"
|
||||||
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "i2:i1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "Disabled"
|
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].Cells["D1:G1048576"].Style.Numberformat.Format = [cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
|
||||||
$excel.Workbook.Worksheets[1].Row(1).style.font.bold = $true
|
$excel.Workbook.Worksheets[1].Row(1).style.font.bold = $true
|
||||||
$excel.Save() ; $excel.Dispose()
|
$excel.Save() ; $excel.Dispose()
|
||||||
|
|
||||||
Here Export-Excel is called with the -passThru parameter so the Excel Package object is stored in $Excel
|
Here Export-Excel is called with the -PassThru parameter so the ExcelPackage object
|
||||||
The desired worksheet is selected and the then columns" B" and "I" are conditionally formatted (excluding the top row) to show red text if
|
representing Machines.XLSX is stored in $Excel.The desired worksheet is selected
|
||||||
the columns contain "2003" or "Disabled respectively. A fixed date format is then applied to columns D..G, and the top row is formatted.
|
and then columns" B" and "I" are conditionally formatted (excluding the top row)
|
||||||
Finally the workbook is saved and the Excel object closed.
|
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
|
.Example
|
||||||
>
|
>
|
||||||
>PS $r = Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Range "B1:B100" -ThreeIconsSet Flags -Passthru
|
$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
|
$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
|
Again Export-Excel has been called with -PassThru leaving a package object
|
||||||
This time B1:B100 has been conditionally formatted with 3 icons, using the flags icon set.
|
in $Excel. This time B1:B100 has been conditionally formatted with 3 icons,
|
||||||
Add-ConditionalFormatting does not provide access to every option in the formatting rule, so passthru has been used and the
|
using the "Flags" Icon-Set. Add-ConditionalFormatting does not provide access
|
||||||
rule is modified to apply the flags in reverse order, and boundaries for the number which will set the split are set to 100 and 1000
|
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
|
.Example
|
||||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
||||||
|
|
||||||
This time $sheet holds an ExcelWorkseet object and databars are add to all of column D except for the tip row.
|
This time $sheet holds an ExcelWorkshseet object and databars are added to
|
||||||
|
column D, excluding the top row.
|
||||||
.Example
|
.Example
|
||||||
Add-ConditionalFormatting -Address $worksheet.cells["FinishPosition"] -RuleType Equal -ConditionValue 1 -ForeGroundColor Purple -Bold -Priority 1 -StopIfTrue
|
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.
|
||||||
|
|
||||||
In this example a named range is used to select the cells where the formula should apply. 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.
|
|
||||||
#>
|
#>
|
||||||
Param (
|
Param (
|
||||||
#A block of cells to format - you can use a named range with -Address $ws.names[1] or $ws.cells["RangeName"]
|
#A block of cells to format - you can use a named range with -Address $ws.names[1] or $ws.cells["RangeName"]
|
||||||
@@ -52,14 +103,14 @@
|
|||||||
#A standard named-rule - Top / Bottom / Less than / Greater than / Contains etc.
|
#A standard named-rule - Top / Bottom / Less than / Greater than / Contains etc.
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 1)]
|
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 1)]
|
||||||
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
|
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
|
||||||
#Text colour for matching objects
|
#Text color for matching objects
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
[Alias("ForeGroundColour")]
|
[Alias("ForegroundColour")]
|
||||||
[System.Drawing.Color]$ForeGroundColor,
|
$ForegroundColor,
|
||||||
#Colour for databar type charts
|
#Color for databar type charts
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
||||||
[Alias("DataBarColour")]
|
[Alias("DataBarColour")]
|
||||||
[System.Drawing.Color]$DataBarColor,
|
$DataBarColor,
|
||||||
#One of the three-icon set types (e.g. Traffic Lights)
|
#One of the three-icon set types (e.g. Traffic Lights)
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
|
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
|
||||||
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting3IconsSetType]$ThreeIconsSet,
|
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting3IconsSetType]$ThreeIconsSet,
|
||||||
@@ -69,27 +120,27 @@
|
|||||||
#A five-icon set name
|
#A five-icon set name
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
|
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
|
||||||
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
|
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
|
||||||
#Use the icon set in reverse order, or reverse the orders of Two- & Three-Color Scales
|
#Use the Icon-Set in reverse order, or reverse the orders of Two- & Three-Color Scales
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
[Parameter(ParameterSetName = "ThreeIconSet")]
|
[Parameter(ParameterSetName = "ThreeIconSet")]
|
||||||
[Parameter(ParameterSetName = "FourIconSet")]
|
[Parameter(ParameterSetName = "FourIconSet")]
|
||||||
[Parameter(ParameterSetName = "FiveIconSet")]
|
[Parameter(ParameterSetName = "FiveIconSet")]
|
||||||
[switch]$Reverse,
|
[switch]$Reverse,
|
||||||
#A value for the condition (for example 2000 if the test is 'lessthan 2000'; Formulas should begin with "=" )
|
#A value for the condition (for example 2000 if the test is 'lessthan 2000'; Formulas should begin with "=" )
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule",Position = 2)]
|
||||||
$ConditionValue,
|
$ConditionValue,
|
||||||
#A second value for the conditions like "between x and Y"
|
#A second value for the conditions like "Between X and Y"
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule",Position = 3)]
|
||||||
$ConditionValue2,
|
$ConditionValue2,
|
||||||
#Background colour for matching items
|
#Background color for matching items
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
[System.Drawing.Color]$BackgroundColor,
|
$BackgroundColor,
|
||||||
#Background pattern for matching items
|
#Background pattern for matching items
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::None ,
|
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::None ,
|
||||||
#Secondary colour when a background pattern requires it
|
#Secondary color when a background pattern requires it
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
[System.Drawing.Color]$PatternColor,
|
$PatternColor,
|
||||||
#Sets the numeric format for matching items
|
#Sets the numeric format for matching items
|
||||||
[Parameter(ParameterSetName = "NamedRule")]
|
[Parameter(ParameterSetName = "NamedRule")]
|
||||||
$NumberFormat,
|
$NumberFormat,
|
||||||
@@ -111,7 +162,7 @@
|
|||||||
#Set the sequence for rule processing
|
#Set the sequence for rule processing
|
||||||
[int]$Priority,
|
[int]$Priority,
|
||||||
#If specified pass the rule back to the caller to allow additional customization.
|
#If specified pass the rule back to the caller to allow additional customization.
|
||||||
[switch]$Passthru
|
[switch]$PassThru
|
||||||
)
|
)
|
||||||
|
|
||||||
#Allow conditional formatting to work like Set-ExcelRange (with single ADDRESS parameter), split it to get worksheet and range of cells.
|
#Allow conditional formatting to work like Set-ExcelRange (with single ADDRESS parameter), split it to get worksheet and range of cells.
|
||||||
@@ -134,18 +185,20 @@
|
|||||||
$Address = "$($Address.Row):$($Address.Row)"
|
$Address = "$($Address.Row):$($Address.Row)"
|
||||||
}
|
}
|
||||||
elseif ($Address -is [OfficeOpenXml.ExcelColumn]) {
|
elseif ($Address -is [OfficeOpenXml.ExcelColumn]) {
|
||||||
$Address = [OfficeOpenXml.ExcelAddress]::new(1,$address.ColumnMin,1,$address.ColumnMax).Address -replace '1',''
|
$Address = (New-Object 'OfficeOpenXml.ExcelAddress' @(1, $address.ColumnMin, 1, $address.ColumnMax).Address) -replace '1',''
|
||||||
if ($Address -notmatch ':') {$Address = "$Address`:$Address"}
|
if ($Address -notmatch ':') {$Address = "$Address`:$Address"}
|
||||||
}
|
}
|
||||||
if ( $Address -is [string] -and $Address -match "!") {$Address = $Address -replace '^.*!',''}
|
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.
|
#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}
|
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
|
#region create a rule of the right type
|
||||||
if ($RuleType -match 'IconSet$') {Write-warning -Message "You cannot configure a IconSet rule in this way; please use -$RuleType <SetName>." ; return}
|
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("ThreeIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Address , $ThreeIconsSet)}
|
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("FourIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Address , $FourIconsSet )}
|
||||||
elseif ($PSBoundParameters.ContainsKey("FiveIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Address , $FiveIconsSet )}
|
elseif ($PSBoundParameters.ContainsKey("FiveIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Address , $FiveIconsSet )}
|
||||||
elseif ($PSBoundParameters.ContainsKey("DataBarColor" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Address , $DataBarColor )}
|
|
||||||
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Address ) }
|
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Address ) }
|
||||||
if ($Reverse) {
|
if ($Reverse) {
|
||||||
if ($rule.type -match 'IconSet$' ) {$rule.reverse = $true}
|
if ($rule.type -match 'IconSet$' ) {$rule.reverse = $true}
|
||||||
@@ -156,7 +209,7 @@
|
|||||||
#region set the rule conditions
|
#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.
|
#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 ($RuleType -match "Than|Equal|Between" ) {
|
||||||
if ($ConditionValue) {
|
if ($PSBoundParameters.ContainsKey("ConditionValue" )) {
|
||||||
$number = $Null
|
$number = $Null
|
||||||
#if the condition type is not a value type, but parses as a number, make it the number
|
#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) ) {
|
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
|
||||||
@@ -166,7 +219,7 @@
|
|||||||
$ConditionValue = '"' + $ConditionValue +'"'
|
$ConditionValue = '"' + $ConditionValue +'"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($ConditionValue2) {
|
if ($PSBoundParameters.ContainsKey("ConditionValue2")) {
|
||||||
$number = $Null
|
$number = $Null
|
||||||
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue2, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
|
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue2, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
|
||||||
$ConditionValue2 = $number
|
$ConditionValue2 = $number
|
||||||
@@ -204,10 +257,13 @@
|
|||||||
if ($PSBoundParameters.ContainsKey("Bold" ) ) {$rule.Style.Font.Bold = [boolean]$Bold }
|
if ($PSBoundParameters.ContainsKey("Bold" ) ) {$rule.Style.Font.Bold = [boolean]$Bold }
|
||||||
if ($PSBoundParameters.ContainsKey("Italic" ) ) {$rule.Style.Font.Italic = [boolean]$Italic }
|
if ($PSBoundParameters.ContainsKey("Italic" ) ) {$rule.Style.Font.Italic = [boolean]$Italic }
|
||||||
if ($PSBoundParameters.ContainsKey("StrikeThru" ) ) {$rule.Style.Font.Strike = [boolean]$StrikeThru }
|
if ($PSBoundParameters.ContainsKey("StrikeThru" ) ) {$rule.Style.Font.Strike = [boolean]$StrikeThru }
|
||||||
if ($PSBoundParameters.ContainsKey("ForeGroundColor" ) ) {$rule.Style.Font.Color.color = $ForeGroundColor }
|
if ($PSBoundParameters.ContainsKey("ForeGroundColor" ) ) {if ($ForeGroundColor -is [string]) {$ForeGroundColor = [System.Drawing.Color]::$ForeGroundColor }
|
||||||
if ($PSBoundParameters.ContainsKey("BackgroundColor" ) ) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
|
$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("BackgroundPattern") ) {$rule.Style.Fill.PatternType = $BackgroundPattern }
|
||||||
if ($PSBoundParameters.ContainsKey("PatternColor" ) ) {$rule.Style.Fill.PatternColor.color = $PatternColor }
|
if ($PSBoundParameters.ContainsKey("PatternColor" ) ) {if ($PatternColor -is [string]) {$PatternColor = [System.Drawing.Color]::$PatternColor }
|
||||||
|
$rule.Style.Fill.PatternColor.color = $PatternColor }
|
||||||
#endregion
|
#endregion
|
||||||
#Allow further tweaking by returning the rule, if passthru specified
|
#Allow further tweaking by returning the rule, if passthru specified
|
||||||
if ($Passthru) {$rule}
|
if ($Passthru) {$rule}
|
||||||
|
|||||||
99
AddDataValidation.ps1
Normal file
99
AddDataValidation.ps1
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
Function Add-ExcelDataValidationRule {
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Adds data validation to a range of cells
|
||||||
|
.Example
|
||||||
|
>
|
||||||
|
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'E2:E1001' -ValidationType Integer -Operator between -Value 0 -Value2 100 `
|
||||||
|
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody 'Percentage must be a whole number between 0 and 100'
|
||||||
|
|
||||||
|
This defines a validation rule on cells E2-E1001; it is an integer rule and requires a number between 0 and 100
|
||||||
|
If a value is input with a fraction, negative number, or positive number > 100 a stop dialog box appears.
|
||||||
|
.Example
|
||||||
|
>
|
||||||
|
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'B2:B1001' -ValidationType List -Formula 'values!$a$2:$a$1000'
|
||||||
|
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody 'You must select an item from the list'
|
||||||
|
This defines a list rule on Cells B2:1001, and the posible values are in a sheet named "values" at cells A2 to A1000
|
||||||
|
Blank cells in this range are ignored. If $ signs are left out of the fomrmula B2 would be checked against A2-A1000
|
||||||
|
B3, against A3-A1001, B4 against A4-A1002 up to B1001 beng checked against A1001-A1999
|
||||||
|
.Example
|
||||||
|
>
|
||||||
|
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'I2:N1001' -ValidationType List -ValueSet @('yes','YES','Yes')
|
||||||
|
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody "Select Yes or leave blank for no"
|
||||||
|
Similar to the previous example but this time provides a value set; Excel comparisons are case sesnsitive, hence 3 versions of Yes.
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
#The range of cells to be validate, e.g. "B2:C100"
|
||||||
|
[Parameter(ValueFromPipeline = $true,Position=0)]
|
||||||
|
[Alias("Address")]
|
||||||
|
$Range ,
|
||||||
|
#The worksheet where the cells should be validated
|
||||||
|
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
|
||||||
|
#An option corresponding to a choice from the 'Allow' pull down on the settings page in the Excel dialog. Any means "any allowed" i.e. no Validation
|
||||||
|
[ValidateSet('Any','Custom','DateTime','Decimal','Integer','List','TextLength','Time')]
|
||||||
|
$ValidationType,
|
||||||
|
#The operator to apply to Decimal, Integer, TextLength, DateTime and time fields, e.g. equal, between
|
||||||
|
[OfficeOpenXml.DataValidation.ExcelDataValidationOperator]$Operator = [OfficeOpenXml.DataValidation.ExcelDataValidationOperator]::equal ,
|
||||||
|
#For Decimal, Integer, TextLength, DateTime the [first] data value
|
||||||
|
$Value,
|
||||||
|
#When using the between operator, the second data value
|
||||||
|
$Value2,
|
||||||
|
#The [first] data value as a formula. Use absolute formulas $A$1 if (e.g.) you want all cells to check against the same list
|
||||||
|
$Formula,
|
||||||
|
#When using the between operator, the second data value as a formula
|
||||||
|
$Formula2,
|
||||||
|
#When using the list validation type, a set of values (rather than refering to Sheet!B$2:B$100 )
|
||||||
|
$ValueSet,
|
||||||
|
#Corresponds to the the 'Show Error alert ...' check box on error alert page in the Excel dialog
|
||||||
|
[switch]$ShowErrorMessage,
|
||||||
|
#Stop, Warning, or Infomation, corresponding to to the style setting in the Excel dialog
|
||||||
|
[OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle]$ErrorStyle,
|
||||||
|
#The title for the message box corresponding to to the title setting in the Excel dialog
|
||||||
|
[String]$ErrorTitle,
|
||||||
|
#The error message corresponding to to the Error message setting in the Excel dialog
|
||||||
|
[String]$ErrorBody,
|
||||||
|
#Corresponds to the the 'Show Input message ...' check box on input message page in the Excel dialog
|
||||||
|
[switch]$ShowPromptMessage,
|
||||||
|
#The prompt message corresponding to to the Input message setting in the Excel dialog
|
||||||
|
[String]$PromptBody,
|
||||||
|
#The title for the message box corresponding to to the title setting in the Excel dialog
|
||||||
|
[String]$PromptTitle,
|
||||||
|
#By default the 'Ignore blank' option will be selected, unless NoBlank is sepcified.
|
||||||
|
[String]$NoBlank
|
||||||
|
)
|
||||||
|
if ($Range -is [Array]) {
|
||||||
|
$null = $PSBoundParameters.Remove("Range")
|
||||||
|
$Range | Add-ExcelDataValidationRule @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 (-not $WorkSheet -and $Range.worksheet) {$WorkSheet = $Range.worksheet}
|
||||||
|
if ($Range.Address) {$Range = $Range.Address}
|
||||||
|
|
||||||
|
if ($Range -isnot [string] -or -not $WorkSheet) {Write-Warning -Message "You need to provide a worksheet and range of cells." ;return}
|
||||||
|
#else we assume Range is a range.
|
||||||
|
|
||||||
|
$validation = $WorkSheet.DataValidations."Add$ValidationType`Validation"($Range)
|
||||||
|
if ($validation.AllowsOperator) {$validation.Operator = $Operator}
|
||||||
|
if ($PSBoundParameters.ContainsKey('value')) {
|
||||||
|
$validation.Formula.Value = $Value
|
||||||
|
}
|
||||||
|
elseif ($Formula) {$validation.Formula.ExcelFormula = $Formula}
|
||||||
|
elseif ($ValueSet) {Foreach ($v in $ValueSet) {$validation.Formula.Values.Add($V)}}
|
||||||
|
if ($PSBoundParameters.ContainsKey('Value2')) {
|
||||||
|
$validation.Formula2.Value = $Value2
|
||||||
|
}
|
||||||
|
elseif ($Formula2) {$validation.Formula2.ExcelFormula = $Formula}
|
||||||
|
$validation.ShowErrorMessage = [bool]$ShowErrorMessage
|
||||||
|
$validation.ShowInputMessage = [bool]$ShowPromptMessage
|
||||||
|
$validation.AllowBlank = -not $NoBlank
|
||||||
|
|
||||||
|
if ($PromptTitle) {$validation.PromptTitle = $PromptTitle}
|
||||||
|
if ($ErrorTitle) {$validation.ErrorTitle = $ErrorTitle}
|
||||||
|
if ($PromptBody) {$validation.Prompt = $PromptBody}
|
||||||
|
if ($ErrorBody) {$validation.Error = $ErrorBody}
|
||||||
|
if ($ErrorStyle) {$validation.ErrorStyle = $ErrorStyle}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,15 +35,15 @@
|
|||||||
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Opening Workbook and copying data"
|
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Opening Workbook and copying data"
|
||||||
$xlWbk = $xlApp.Workbooks.Open($Path)
|
$xlWbk = $xlApp.Workbooks.Open($Path)
|
||||||
$xlWbk.Worksheets($workSheetname).Select()
|
$xlWbk.Worksheets($workSheetname).Select()
|
||||||
$xlWbk.ActiveSheet.Range($range).Select() | Out-Null
|
$null = $xlWbk.ActiveSheet.Range($range).Select()
|
||||||
$xlApp.Selection.Copy() | Out-Null
|
$null = $xlApp.Selection.Copy()
|
||||||
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Saving copied data"
|
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Saving copied data"
|
||||||
# Get-Clipboard came in with PS5. Older versions can use [System.Windows.Clipboard] but it is ugly.
|
# Get-Clipboard came in with PS5. Older versions can use [System.Windows.Clipboard] but it is ugly.
|
||||||
$image = Get-Clipboard -Format Image
|
$image = Get-Clipboard -Format Image
|
||||||
$image.Save($destination, $Format)
|
$image.Save($destination, $Format)
|
||||||
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Closing Excel"
|
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Closing Excel"
|
||||||
$xlWbk.ActiveSheet.Range("a1").Select() | Out-Null
|
$null = $xlWbk.ActiveSheet.Range("a1").Select()
|
||||||
$xlApp.Selection.Copy() | Out-Null
|
$null = $xlApp.Selection.Copy()
|
||||||
$xlApp.Quit()
|
$xlApp.Quit()
|
||||||
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Completed
|
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Completed
|
||||||
if ($show) {Start-Process -FilePath $destination}
|
if ($show) {Start-Process -FilePath $destination}
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
Function ConvertTo-ExcelXlsx {
|
Function ConvertTo-ExcelXlsx {
|
||||||
[CmdletBinding()]
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Converts an Excel xls to a xlsx using -ComObject
|
||||||
|
#>
|
||||||
|
[CmdletBinding()]
|
||||||
Param
|
Param
|
||||||
(
|
(
|
||||||
[parameter(Mandatory=$true, ValueFromPipeline)]
|
[parameter(Mandatory = $true, ValueFromPipeline)]
|
||||||
[string]$Path,
|
[string]$Path,
|
||||||
[parameter(Mandatory=$false)]
|
[parameter(Mandatory = $false)]
|
||||||
[switch]$Force
|
[switch]$Force
|
||||||
)
|
)
|
||||||
Process
|
Process {
|
||||||
{
|
if (-Not ($Path | Test-Path) ) {
|
||||||
if(-Not ($Path | Test-Path) ){
|
|
||||||
throw "File not found"
|
throw "File not found"
|
||||||
}
|
}
|
||||||
if(-Not ($Path | Test-Path -PathType Leaf) ){
|
if (-Not ($Path | Test-Path -PathType Leaf) ) {
|
||||||
throw "Folder paths are not allowed"
|
throw "Folder paths are not allowed"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,31 +23,34 @@ Function ConvertTo-ExcelXlsx {
|
|||||||
$xlsFile = Get-Item -Path $Path
|
$xlsFile = Get-Item -Path $Path
|
||||||
$xlsxPath = "{0}x" -f $xlsFile.FullName
|
$xlsxPath = "{0}x" -f $xlsFile.FullName
|
||||||
|
|
||||||
if($xlsFile.Extension -ne ".xls"){
|
if ($xlsFile.Extension -ne ".xls") {
|
||||||
throw "Expected .xls extension"
|
throw "Expected .xls extension"
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Test-Path -Path $xlsxPath){
|
if (Test-Path -Path $xlsxPath) {
|
||||||
if($Force){
|
if ($Force) {
|
||||||
try {
|
try {
|
||||||
Remove-Item $xlsxPath -Force
|
Remove-Item $xlsxPath -Force
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
throw "{0} already exists and cannot be removed. The file may be locked by another application." -f $xlsxPath
|
throw "{0} already exists and cannot be removed. The file may be locked by another application." -f $xlsxPath
|
||||||
}
|
}
|
||||||
Write-Verbose $("Removed {0}" -f $xlsxPath)
|
Write-Verbose $("Removed {0}" -f $xlsxPath)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw "{0} already exists!" -f $xlsxPath
|
throw "{0} already exists!" -f $xlsxPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
try {
|
||||||
$Excel = New-Object -ComObject "Excel.Application"
|
$Excel = New-Object -ComObject "Excel.Application"
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
throw "Could not create Excel.Application ComObject. Please verify that Excel is installed."
|
throw "Could not create Excel.Application ComObject. Please verify that Excel is installed."
|
||||||
}
|
}
|
||||||
|
|
||||||
$Excel.Visible = $false
|
$Excel.Visible = $false
|
||||||
$Excel.Workbooks.Open($xlsFile.FullName) | Out-Null
|
$null = $Excel.Workbooks.Open($xlsFile.FullName)
|
||||||
$Excel.ActiveWorkbook.SaveAs($xlsxPath, $xlFixedFormat)
|
$Excel.ActiveWorkbook.SaveAs($xlsxPath, $xlFixedFormat)
|
||||||
$Excel.ActiveWorkbook.Close()
|
$Excel.ActiveWorkbook.Close()
|
||||||
$Excel.Quit()
|
$Excel.Quit()
|
||||||
|
|||||||
@@ -29,12 +29,12 @@
|
|||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
|
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory = $true)]
|
||||||
$SourceWorkbook,
|
$SourceWorkbook,
|
||||||
#Name or number (starting from 1) of the worksheet in the source workbook (defaults to 1).
|
#Name or number (starting from 1) of the worksheet in the source workbook (defaults to 1).
|
||||||
$SourceWorkSheet = 1 ,
|
$SourceWorkSheet = 1 ,
|
||||||
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data should be copied.
|
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data should be copied.
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory = $true)]
|
||||||
$DestinationWorkbook,
|
$DestinationWorkbook,
|
||||||
#Name of the worksheet in the destination workbook; by default the same as the source worksheet's name. If the sheet exists it will be deleted and re-copied.
|
#Name of the worksheet in the destination workbook; by default the same as the source worksheet's name. If the sheet exists it will be deleted and re-copied.
|
||||||
$DestinationWorkSheet,
|
$DestinationWorkSheet,
|
||||||
@@ -65,46 +65,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($SourceWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {$sourcews=$SourceWorkbook.Worksheets[$SourceWorkSheet]}
|
if ($SourceWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {$sourcews = $SourceWorkbook.Worksheets[$SourceWorkSheet]}
|
||||||
elseif ($SourceWorkbook -is [OfficeOpenXml.ExcelPackage] ) {$sourcews=$SourceWorkbook.Workbook.Worksheets[$SourceWorkSheet]}
|
elseif ($SourceWorkbook -is [OfficeOpenXml.ExcelPackage] ) {$sourcews = $SourceWorkbook.Workbook.Worksheets[$SourceWorkSheet]}
|
||||||
else {
|
else {
|
||||||
$SourceWorkbook = (Resolve-Path $SourceWorkbook).ProviderPath
|
$SourceWorkbook = (Resolve-Path $SourceWorkbook).ProviderPath
|
||||||
try {
|
try {
|
||||||
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceWorkbook'."
|
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceWorkbook'."
|
||||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceWorkbook, 'Open', 'Read' ,'ReadWrite'
|
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceWorkbook, 'Open', 'Read' , 'ReadWrite'
|
||||||
$Package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
$Package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
||||||
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
|
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Could not open $SourceWorkbook" ; return}
|
catch {Write-Warning -Message "Could not open $SourceWorkbook" ; return}
|
||||||
}
|
}
|
||||||
if (-not $sourceWs) {Write-Warning -Message "Could not find worksheet '$Sourceworksheet' in the source workbook." ; return}
|
if (-not $sourceWs) {Write-Warning -Message "Could not find worksheet '$Sourceworksheet' in the source workbook." ; return}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
|
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
|
||||||
$wb = $DestinationWorkbook
|
$wb = $DestinationWorkbook
|
||||||
}
|
|
||||||
elseif ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
|
|
||||||
$wb = $DestinationWorkbook.workbook
|
|
||||||
if ($show) {$package2 =$DestinationWorkbook}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
|
|
||||||
$wb = $package2.Workbook
|
|
||||||
}
|
|
||||||
if (-not $DestinationWorkSheet) {$DestinationWorkSheet = $SourceWs.Name}
|
|
||||||
if ($wb.Worksheets[$DestinationWorkSheet]) {
|
|
||||||
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorkSheet', deleting it."
|
|
||||||
$wb.Worksheets.Delete($DestinationWorkSheet)
|
|
||||||
}
|
|
||||||
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
|
|
||||||
$null = Add-WorkSheet -ExcelWorkbook $wb -WorkSheetname $DestinationWorkSheet -CopySource $sourceWs
|
|
||||||
if ($package1) {Close-ExcelPackage -ExcelPackage $Package1 -NoSave }
|
|
||||||
if ($package2) {Close-ExcelPackage -ExcelPackage $Package2 -Show:$show }
|
|
||||||
if ($show -and $DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
|
|
||||||
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorkSheet' in the destination workbook" ; return}
|
elseif ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
|
||||||
|
$wb = $DestinationWorkbook.workbook
|
||||||
|
if ($show) {$package2 = $DestinationWorkbook}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
|
||||||
|
$wb = $package2.Workbook
|
||||||
|
}
|
||||||
|
if (-not $DestinationWorkSheet) {$DestinationWorkSheet = $SourceWs.Name}
|
||||||
|
if ($wb.Worksheets[$DestinationWorkSheet]) {
|
||||||
|
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorkSheet', deleting it."
|
||||||
|
$wb.Worksheets.Delete($DestinationWorkSheet)
|
||||||
|
}
|
||||||
|
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
|
||||||
|
$null = Add-WorkSheet -ExcelWorkbook $wb -WorkSheetname $DestinationWorkSheet -CopySource $sourceWs
|
||||||
|
if ($Stream) {$Stream.Close() }
|
||||||
|
if ($package1) {Close-ExcelPackage -ExcelPackage $Package1 -NoSave }
|
||||||
|
if ($package2) {Close-ExcelPackage -ExcelPackage $Package2 -Show:$show }
|
||||||
|
if ($show -and $DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
|
||||||
|
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorkSheet' in the destination workbook" ; return}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
DoTests.ps1
14
DoTests.ps1
@@ -1,3 +1,7 @@
|
|||||||
|
param(
|
||||||
|
[Switch]$DontCreateZip
|
||||||
|
)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Used in Appveyor.yml
|
# Used in Appveyor.yml
|
||||||
##
|
##
|
||||||
@@ -6,12 +10,14 @@ $PSVersionTable.PSVersion
|
|||||||
|
|
||||||
## Create the zip before the tests run
|
## Create the zip before the tests run
|
||||||
## Otherwise the EPPlus.dll is in use after the Pester run
|
## Otherwise the EPPlus.dll is in use after the Pester run
|
||||||
$ModuleVersion = (Get-Content -Raw .\ImportExcel.psd1) | Invoke-Expression | ForEach-Object ModuleVersion
|
$ModuleVersion = (Invoke-Command -ScriptBlock ([scriptblock]::Create((Get-Content -Raw .\ImportExcel.psd1)))).moduleVersion
|
||||||
|
|
||||||
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
|
if (!$DontCreateZip) {
|
||||||
Compress-Archive -Path . -DestinationPath .\$dest
|
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
|
||||||
|
Compress-Archive -Path . -DestinationPath .\$dest
|
||||||
|
}
|
||||||
|
|
||||||
if ((Get-Module -ListAvailable pester) -eq $null) {
|
if ($null -eq (Get-Module -ListAvailable pester)) {
|
||||||
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
|
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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
|
||||||
@@ -51,7 +51,7 @@ Set-Format -Address $sheet1.Cells["E2:G2"] -BorderBottom $BorderBottom -BorderCo
|
|||||||
Set-Format -Address $sheet1.Cells["I2:K2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
|
Set-Format -Address $sheet1.Cells["I2:K2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
|
||||||
Set-Format -Address $sheet1.Cells["M2:O2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
|
Set-Format -Address $sheet1.Cells["M2:O2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
|
||||||
|
|
||||||
Set-Format -Address $sheet1.Cells["A2:C8"] -FontColor GrayText
|
Set-Format -Address $sheet1.Cells["A2:C8"] -FontColor Gray
|
||||||
|
|
||||||
$HorizontalAlignment = "Center"
|
$HorizontalAlignment = "Center"
|
||||||
Set-Format -Address $sheet1.Cells["F1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Revenue
|
Set-Format -Address $sheet1.Cells["F1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Revenue
|
||||||
|
|||||||
85
Examples/ExcelDataValidation/MutipleValidations.ps1
Normal file
85
Examples/ExcelDataValidation/MutipleValidations.ps1
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#region Setup
|
||||||
|
<#
|
||||||
|
This examples demos three types of validation:
|
||||||
|
* Creating a list using a PowerShell array
|
||||||
|
* Creating a list data from another Excel Worksheet
|
||||||
|
* Creating a rule for numbers to be between 0 an 10000
|
||||||
|
|
||||||
|
Run the script then try"
|
||||||
|
* Add random data in Column B
|
||||||
|
* Then choose from the drop down list
|
||||||
|
* Add random data in Column C
|
||||||
|
* Then choose from the drop down list
|
||||||
|
* Add .01 in column F
|
||||||
|
#>
|
||||||
|
|
||||||
|
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||||
|
|
||||||
|
$path = "$Env:TEMP\DataValidation.xlsx"
|
||||||
|
Remove-Item $path -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$data = ConvertFrom-Csv -InputObject @"
|
||||||
|
ID,Region,Product,Quantity,Price
|
||||||
|
12001,North,Nails,37,3.99
|
||||||
|
12002,South,Hammer,5,12.10
|
||||||
|
12003,East,Saw,12,15.37
|
||||||
|
12010,West,Drill,20,8
|
||||||
|
12011,North,Crowbar,7,23.48
|
||||||
|
"@
|
||||||
|
|
||||||
|
# Export the raw data
|
||||||
|
$excelPackage = $Data |
|
||||||
|
Export-Excel -WorksheetName "Sales" -Path $path -PassThru
|
||||||
|
|
||||||
|
# Creates a sheet with data that will be used in a validation rule
|
||||||
|
$excelPackage = @('Chisel', 'Crowbar', 'Drill', 'Hammer', 'Nails', 'Saw', 'Screwdriver', 'Wrench') |
|
||||||
|
Export-excel -ExcelPackage $excelPackage -WorksheetName Values -PassThru
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Creating a list using a PowerShell array
|
||||||
|
$ValidationParams = @{
|
||||||
|
WorkSheet = $excelPackage.sales
|
||||||
|
ShowErrorMessage = $true
|
||||||
|
ErrorStyle = 'stop'
|
||||||
|
ErrorTitle = 'Invalid Data'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$MoreValidationParams = @{
|
||||||
|
Range = 'B2:B1001'
|
||||||
|
ValidationType = 'List'
|
||||||
|
ValueSet = @('North', 'South', 'East', 'West')
|
||||||
|
ErrorBody = "You must select an item from the list."
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Creating a list data from another Excel Worksheet
|
||||||
|
$MoreValidationParams = @{
|
||||||
|
Range = 'C2:C1001'
|
||||||
|
ValidationType = 'List'
|
||||||
|
Formula = 'values!$a$1:$a$10'
|
||||||
|
ErrorBody = "You must select an item from the list.`r`nYou can add to the list on the values page" #Bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Creating a rule for numbers to be between 0 an 10000
|
||||||
|
$MoreValidationParams = @{
|
||||||
|
Range = 'F2:F1001'
|
||||||
|
ValidationType = 'Integer'
|
||||||
|
Operator = 'between'
|
||||||
|
Value = 0
|
||||||
|
Value2 = 10000
|
||||||
|
ErrorBody = 'Quantity must be a whole number between 0 and 10000'
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Close Package
|
||||||
|
Close-ExcelPackage -ExcelPackage $excelPackage -Show
|
||||||
|
#endregion
|
||||||
24
Examples/FormatCellStyles/ApplyStyle.ps1
Normal file
24
Examples/FormatCellStyles/ApplyStyle.ps1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
$data = ConvertFrom-Csv @'
|
||||||
|
Item,Quantity,Price,Total Cost
|
||||||
|
Footballs,9,21.95,197.55
|
||||||
|
Cones,36,7.99,287.64
|
||||||
|
Shin Guards,14,10.95,153.3
|
||||||
|
Turf Shoes,22,79.95,1758.9
|
||||||
|
Baseballs,68,7.99,543.32
|
||||||
|
Baseball Gloves,31,65.00,2015.00
|
||||||
|
Baseball Bats,38,159.00,6042.00
|
||||||
|
'@
|
||||||
|
|
||||||
|
$f = "$env:TEMP\styles.xlsx"
|
||||||
|
Remove-Item $f -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$pkg = $data | Export-Excel -Path $f -AutoSize -PassThru
|
||||||
|
|
||||||
|
$ws = $pkg.Workbook.Worksheets["Sheet1"]
|
||||||
|
|
||||||
|
Set-ExcelRange -WorkSheet $ws -Range "A2:C6" -BackgroundColor PeachPuff -FontColor Purple -FontSize 12 -Width 12
|
||||||
|
Set-ExcelRange -WorkSheet $ws -Range "D2:D6" -BackgroundColor WhiteSmoke -FontColor Orange -Bold -FontSize 12 -Width 12
|
||||||
|
Set-ExcelRange -WorkSheet $ws -Range "A1:D1" -BackgroundColor BlueViolet -FontColor Wheat -FontSize 12 -Width 12
|
||||||
|
Set-ExcelRange -WorkSheet $ws -Range "A:A" -Width 15
|
||||||
|
|
||||||
|
Close-ExcelPackage -ExcelPackage $pkg -Show
|
||||||
101
Examples/Grouping/First10Races.csv
Normal file
101
Examples/Grouping/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
|
||||||
|
10
Examples/Grouping/GroupDate.ps1
Normal file
10
Examples/Grouping/GroupDate.ps1
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
$xlfile = "$env:TEMP\Points.xlsx"
|
||||||
|
|
||||||
|
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Points `
|
||||||
|
-PivotRows Driver, Date -PivotData @{Points = "SUM"} -GroupDateRow Date -GroupDatePart Years, Months
|
||||||
|
|
||||||
|
Import-Csv "$PSScriptRoot\First10Races.csv" |
|
||||||
|
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
|
||||||
|
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition
|
||||||
10
Examples/Grouping/GroupNumeric.ps1
Normal file
10
Examples/Grouping/GroupNumeric.ps1
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
$xlfile = "$env:TEMP\Places.xlsx"
|
||||||
|
|
||||||
|
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Places `
|
||||||
|
-PivotRows Driver, FinishPosition -PivotData @{Date = "Count"} -GroupNumericRow FinishPosition -GroupNumericMin 1 -GroupNumericMax 25 -GroupNumericInterval 3
|
||||||
|
|
||||||
|
Import-Csv "$PSScriptRoot\First10Races.csv" |
|
||||||
|
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
|
||||||
|
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition
|
||||||
39
Examples/Grouping/TimestampBucket.ps1
Normal file
39
Examples/Grouping/TimestampBucket.ps1
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
$data = ConvertFrom-Csv @"
|
||||||
|
Timestamp,Tenant
|
||||||
|
10/29/2018 3:00:00.123,1
|
||||||
|
10/29/2018 3:00:10.456,1
|
||||||
|
10/29/2018 3:01:20.389,1
|
||||||
|
10/29/2018 3:00:30.222,1
|
||||||
|
10/29/2018 3:00:40.143,1
|
||||||
|
10/29/2018 3:00:50.809,1
|
||||||
|
10/29/2018 3:01:00.193,1
|
||||||
|
10/29/2018 3:01:10.555,1
|
||||||
|
10/29/2018 3:01:20.739,1
|
||||||
|
10/29/2018 3:01:30.912,1
|
||||||
|
10/29/2018 3:01:40.989,1
|
||||||
|
10/29/2018 3:01:50.545,1
|
||||||
|
10/29/2018 3:02:00.999,1
|
||||||
|
"@ | Select-Object @{n = 'Timestamp'; e = {get-date $_.timestamp}}, tenant, @{n = 'Bucket'; e = { - (get-date $_.timestamp).Second % 30}}
|
||||||
|
|
||||||
|
$f = "$env:temp\pivottest.xlsx"
|
||||||
|
Remove-Item $f -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$pivotDefParams = @{
|
||||||
|
PivotTableName = 'Timestamp Buckets'
|
||||||
|
PivotRows = @('Timestamp', 'Tenant')
|
||||||
|
PivotData = @{'Bucket' = 'count'}
|
||||||
|
GroupDateRow = 'TimeStamp'
|
||||||
|
GroupDatePart = @('Hours', 'Minutes')
|
||||||
|
Activate = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
$excelParams = @{
|
||||||
|
PivotTableDefinition = New-PivotTableDefinition @pivotDefParams
|
||||||
|
Path = $f
|
||||||
|
WorkSheetname = "Log Data"
|
||||||
|
AutoSize = $true
|
||||||
|
AutoFilter = $true
|
||||||
|
Show = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
$data | Export-Excel @excelParams
|
||||||
26
Examples/InteractWithOtherModules/Pester/Analyze_that.ps1
Normal file
26
Examples/InteractWithOtherModules/Pester/Analyze_that.ps1
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
param(
|
||||||
|
$PesterTestsPath = "$PSScriptRoot\..\..\..\__tests__\"
|
||||||
|
)
|
||||||
|
|
||||||
|
$xlfile = "$env:Temp\testResults.xlsx"
|
||||||
|
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$xlparams = @{
|
||||||
|
Path = $xlfile
|
||||||
|
InputObject = (Invoke-Pester -Script $PesterTestsPath -PassThru).TestResult | Sort-Object describe
|
||||||
|
WorksheetName = 'FullResults'
|
||||||
|
|
||||||
|
IncludePivotTable = $true
|
||||||
|
PivotRows = 'Describe'
|
||||||
|
PivotColumns = 'Passed'
|
||||||
|
PivotData = @{'Passed' = 'Count' }
|
||||||
|
|
||||||
|
IncludePivotChart = $true
|
||||||
|
ChartType = 'BarClustered'
|
||||||
|
|
||||||
|
AutoSize = $true
|
||||||
|
AutoFilter = $true
|
||||||
|
Activate = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
Export-Excel -Show @xlparams
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Runs PsScriptAnalyzer against one or more folders and pivots the results to form a report.
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Analyze_this.ps1
|
||||||
|
Invokes script analyzer on the current directory; creates a file in $env:temp and opens it in Excel
|
||||||
|
.Example
|
||||||
|
Analyze_this.ps1 -xlfile ..\mymodule.xlsx -quiet
|
||||||
|
Invokes script analyzer on the current directory; creates a file in the parent directory but does not open it
|
||||||
|
.Example
|
||||||
|
"." , (dir 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel\') | .\examples\ScriptAnalyzer\Analyze_this.ps1
|
||||||
|
run from a developemnt directory for importExcel it will produce a report for that directory compared against installed versions
|
||||||
|
this creates the file in the default location and opens it
|
||||||
|
#>
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[parameter(ValueFromPipeline = $true)]
|
||||||
|
$Path = $PWD,
|
||||||
|
$xlfile = "$env:TEMP\ScriptAnalyzer.xlsx",
|
||||||
|
$ChartType = 'BarClustered' ,
|
||||||
|
$PivotColumns = 'Location',
|
||||||
|
[switch]$Quiet
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
Remove-Item -Path $xlfile -ErrorAction SilentlyContinue
|
||||||
|
$xlparams = @{
|
||||||
|
Path = $xlfile
|
||||||
|
WorksheetName = 'FullResults'
|
||||||
|
AutoSize = $true
|
||||||
|
AutoFilter = $true
|
||||||
|
Activate = $true
|
||||||
|
Show = (-not $Quiet)
|
||||||
|
}
|
||||||
|
$pivotParams = @{
|
||||||
|
PivotTableName = 'BreakDown'
|
||||||
|
PivotData = @{RuleName = 'Count' }
|
||||||
|
PivotRows = 'Severity', 'RuleName'
|
||||||
|
PivotColumns = 'Location'
|
||||||
|
PivotTotals = 'Rows'
|
||||||
|
}
|
||||||
|
$dirsToProcess = @()
|
||||||
|
}
|
||||||
|
process {
|
||||||
|
if ($path.fullName) {$dirsToProcess += $path.fullName}
|
||||||
|
elseif ($path.path) {$dirsToProcess += $path.Path}
|
||||||
|
else {$dirsToProcess += $path}
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
$pivotParams['-PivotChartDefinition'] = New-ExcelChartDefinition -ChartType $chartType -Column (1 + $dirsToProcess.Count) -Title "Script analysis" -LegendBold
|
||||||
|
$xlparams['PivotTableDefinition'] = New-PivotTableDefinition @pivotParams
|
||||||
|
|
||||||
|
$dirsToProcess | ForEach-Object {
|
||||||
|
$dirName = (Resolve-Path -Path $_) -replace "^.*\\(.*?)\\(.*?)$", '$1-$2'
|
||||||
|
Write-Progress -Activity "Running Script Analyzer" -CurrentOperation $dirName
|
||||||
|
Invoke-ScriptAnalyzer -Path $_ -ErrorAction SilentlyContinue |
|
||||||
|
Add-Member -MemberType NoteProperty -Name Location -Value $dirName -PassThru
|
||||||
|
} | Export-Excel @xlparams
|
||||||
|
Write-Progress -Activity "Running Script Analyzer" -Completed
|
||||||
|
}
|
||||||
55
Examples/MortgageCalculator/MortgageCalculator.ps1
Normal file
55
Examples/MortgageCalculator/MortgageCalculator.ps1
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<#
|
||||||
|
Fixed Rate Loan/Mortgage Calculator in Excel
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
$Amount = 400000,
|
||||||
|
$InterestRate = .065,
|
||||||
|
$Term = 30
|
||||||
|
)
|
||||||
|
|
||||||
|
function New-CellData {
|
||||||
|
param(
|
||||||
|
$Range,
|
||||||
|
$Value,
|
||||||
|
$Format
|
||||||
|
)
|
||||||
|
|
||||||
|
$setFormatParams = @{
|
||||||
|
WorkSheet = $ws
|
||||||
|
Range = $Range
|
||||||
|
NumberFormat = $Format
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Value -is [string] -and $Value.StartsWith('=')) {
|
||||||
|
$setFormatParams.Formula = $Value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$setFormatParams.Value = $Value
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-Format @setFormatParams
|
||||||
|
}
|
||||||
|
|
||||||
|
$f = "$PSScriptRoot\mortgage.xlsx"
|
||||||
|
Remove-Item $f -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$pkg = "" | Export-Excel $f -Title 'Fixed Rate Loan Payments' -PassThru -AutoSize
|
||||||
|
$ws = $pkg.Workbook.Worksheets["Sheet1"]
|
||||||
|
|
||||||
|
New-CellData A3 'Amount'
|
||||||
|
New-CellData B3 $Amount '$#,##0'
|
||||||
|
|
||||||
|
New-CellData A4 "Interest Rate"
|
||||||
|
New-CellData B4 $InterestRate 'Percentage'
|
||||||
|
|
||||||
|
New-CellData A5 "Term (Years)"
|
||||||
|
New-CellData B5 $Term
|
||||||
|
|
||||||
|
New-CellData D3 "Monthly Payment"
|
||||||
|
New-CellData F3 "=-PMT(F4, B5*12, B3)" '$#,##0.#0'
|
||||||
|
|
||||||
|
New-CellData D4 "Monthly Rate"
|
||||||
|
New-CellData F4 "=((1+B4)^(1/12))-1" 'Percentage'
|
||||||
|
|
||||||
|
Close-ExcelPackage $pkg -Show
|
||||||
23
Examples/OutTabulator/demo.txt
Normal file
23
Examples/OutTabulator/demo.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# ConvertFrom-Excel
|
||||||
|
''
|
||||||
|
|
||||||
|
.\test.xlsx
|
||||||
|
|
||||||
|
Import-Excel .\test.xlsx | ft
|
||||||
|
|
||||||
|
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html
|
||||||
|
|
||||||
|
# Create a column definition
|
||||||
|
$columnOptions = @()
|
||||||
|
|
||||||
|
$columnOptions += New-ColumnOption -ColumnName Progress -formatter progress
|
||||||
|
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
|
||||||
|
|
||||||
|
$columnOptions += New-ColumnOption Activity -formatter lineFormatter
|
||||||
|
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
|
||||||
|
|
||||||
|
$columnOptions += New-ColumnOption -ColumnName Rating -formatter star
|
||||||
|
$columnOptions += New-ColumnOption Driver -formatter tickCross
|
||||||
|
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
|
||||||
|
|
||||||
|
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions -groupBy Gender
|
||||||
216
Examples/OutTabulator/start-demo.ps1
Normal file
216
Examples/OutTabulator/start-demo.ps1
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
## Start-Demo.ps1
|
||||||
|
##################################################################################################
|
||||||
|
## This is an overhaul of Jeffrey Snover's original Start-Demo script by Joel "Jaykul" Bennett
|
||||||
|
##
|
||||||
|
## I've switched it to using ReadKey instead of ReadLine (you don't have to hit Enter each time)
|
||||||
|
## As a result, I've changed the names and keys for a lot of the operations, so that they make
|
||||||
|
## sense with only a single letter to tell them apart (sorry if you had them memorized).
|
||||||
|
##
|
||||||
|
## I've also been adding features as I come across needs for them, and you'll contribute your
|
||||||
|
## improvements back to the PowerShell Script repository as well.
|
||||||
|
##################################################################################################
|
||||||
|
## Revision History (version 3.3)
|
||||||
|
## 3.3.3 Fixed: Script no longer says "unrecognized key" when you hit shift or ctrl, etc.
|
||||||
|
## Fixed: Blank lines in script were showing as errors (now printed like comments)
|
||||||
|
## 3.3.2 Fixed: Changed the "x" to match the "a" in the help text
|
||||||
|
## 3.3.1 Fixed: Added a missing bracket in the script
|
||||||
|
## 3.3 - Added: Added a "Clear Screen" option
|
||||||
|
## - Added: Added a "Rewind" function (which I'm not using much)
|
||||||
|
## 3.2 - Fixed: Put back the trap { continue; }
|
||||||
|
## 3.1 - Fixed: No Output when invoking Get-Member (and other cmdlets like it???)
|
||||||
|
## 3.0 - Fixed: Commands which set a variable, like: $files = ls
|
||||||
|
## - Fixed: Default action doesn't continue
|
||||||
|
## - Changed: Use ReadKey instead of ReadLine
|
||||||
|
## - Changed: Modified the option prompts (sorry if you had them memorized)
|
||||||
|
## - Changed: Various time and duration strings have better formatting
|
||||||
|
## - Enhance: Colors are settable: prompt, command, comment
|
||||||
|
## - Added: NoPauseAfterExecute switch removes the extra pause
|
||||||
|
## If you set this, the next command will be displayed immediately
|
||||||
|
## - Added: Auto Execute mode (FullAuto switch) runs the rest of the script
|
||||||
|
## at an automatic speed set by the AutoSpeed parameter (or manually)
|
||||||
|
## - Added: Automatically append an empty line to the end of the demo script
|
||||||
|
## so you have a chance to "go back" after the last line of you demo
|
||||||
|
##################################################################################################
|
||||||
|
##
|
||||||
|
param(
|
||||||
|
$file=".\demo.txt",
|
||||||
|
[int]$command=0,
|
||||||
|
[System.ConsoleColor]$promptColor="Yellow",
|
||||||
|
[System.ConsoleColor]$commandColor="White",
|
||||||
|
[System.ConsoleColor]$commentColor="Green",
|
||||||
|
[switch]$FullAuto,
|
||||||
|
[int]$AutoSpeed = 3,
|
||||||
|
[switch]$NoPauseAfterExecute
|
||||||
|
)
|
||||||
|
|
||||||
|
$RawUI = $Host.UI.RawUI
|
||||||
|
$hostWidth = $RawUI.BufferSize.Width
|
||||||
|
|
||||||
|
# A function for reading in a character
|
||||||
|
function Read-Char() {
|
||||||
|
$_OldColor = $RawUI.ForeGroundColor
|
||||||
|
$RawUI.ForeGroundColor = "Red"
|
||||||
|
$inChar=$RawUI.ReadKey("IncludeKeyUp")
|
||||||
|
# loop until they press a character, so Shift or Ctrl, etc don't terminate us
|
||||||
|
while($inChar.Character -eq 0){
|
||||||
|
$inChar=$RawUI.ReadKey("IncludeKeyUp")
|
||||||
|
}
|
||||||
|
$RawUI.ForeGroundColor = $_OldColor
|
||||||
|
return $inChar.Character
|
||||||
|
}
|
||||||
|
|
||||||
|
function Rewind($lines, $index, $steps = 1) {
|
||||||
|
$started = $index;
|
||||||
|
$index -= $steps;
|
||||||
|
while(($index -ge 0) -and ($lines[$index].Trim(" `t").StartsWith("#"))){
|
||||||
|
$index--
|
||||||
|
}
|
||||||
|
if( $index -lt 0 ) { $index = $started }
|
||||||
|
return $index
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = Resolve-Path $file
|
||||||
|
while(-not(Test-Path $file)) {
|
||||||
|
$file = Read-Host "Please enter the path of your demo script (Crtl+C to cancel)"
|
||||||
|
$file = Resolve-Path $file
|
||||||
|
}
|
||||||
|
|
||||||
|
Clear-Host
|
||||||
|
|
||||||
|
$_lines = Get-Content $file
|
||||||
|
# Append an extra (do nothing) line on the end so we can still go back after the last line.
|
||||||
|
$_lines += "Write-Host 'The End'"
|
||||||
|
$_starttime = [DateTime]::now
|
||||||
|
$FullAuto = $false
|
||||||
|
|
||||||
|
Write-Host -nonew -back black -fore $promptColor $(" " * $hostWidth)
|
||||||
|
Write-Host -nonew -back black -fore $promptColor @"
|
||||||
|
<Demo Started :: $(split-path $file -leaf)>$(' ' * ($hostWidth -(18 + $(split-path $file -leaf).Length)))
|
||||||
|
"@
|
||||||
|
Write-Host -nonew -back black -fore $promptColor "Press"
|
||||||
|
Write-Host -nonew -back black -fore Red " ? "
|
||||||
|
Write-Host -nonew -back black -fore $promptColor "for help.$(' ' * ($hostWidth -17))"
|
||||||
|
Write-Host -nonew -back black -fore $promptColor $(" " * $hostWidth)
|
||||||
|
|
||||||
|
# We use a FOR and an INDEX ($_i) instead of a FOREACH because
|
||||||
|
# it is possible to start at a different location and/or jump
|
||||||
|
# around in the order.
|
||||||
|
for ($_i = $Command; $_i -lt $_lines.count; $_i++)
|
||||||
|
{
|
||||||
|
# Put the current command in the Window Title along with the demo duration
|
||||||
|
$Dur = [DateTime]::Now - $_StartTime
|
||||||
|
$RawUI.WindowTitle = "$(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s {3}" -f
|
||||||
|
$dur.Hours, $dur.Minutes, $dur.Seconds, $($_Lines[$_i])
|
||||||
|
|
||||||
|
# Echo out the commmand to the console with a prompt as though it were real
|
||||||
|
Write-Host -nonew -fore $promptColor "[$_i]$([char]0x2265) "
|
||||||
|
if ($_lines[$_i].Trim(" ").StartsWith("#") -or $_lines[$_i].Trim(" ").Length -le 0) {
|
||||||
|
Write-Host -fore $commentColor "$($_Lines[$_i]) "
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
Write-Host -nonew -fore $commandColor "$($_Lines[$_i]) "
|
||||||
|
}
|
||||||
|
|
||||||
|
if( $FullAuto ) { Start-Sleep $autoSpeed; $ch = [char]13 } else { $ch = Read-Char }
|
||||||
|
switch($ch)
|
||||||
|
{
|
||||||
|
"?" {
|
||||||
|
Write-Host -Fore $promptColor @"
|
||||||
|
|
||||||
|
Running demo: $file
|
||||||
|
(n) Next (p) Previous
|
||||||
|
(q) Quit (s) Suspend
|
||||||
|
(t) Timecheck (v) View $(split-path $file -leaf)
|
||||||
|
(g) Go to line by number
|
||||||
|
(f) Find lines by string
|
||||||
|
(a) Auto Execute mode
|
||||||
|
(c) Clear Screen
|
||||||
|
"@
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"n" { # Next (do nothing)
|
||||||
|
Write-Host -Fore $promptColor "<Skipping Line>"
|
||||||
|
}
|
||||||
|
"p" { # Previous
|
||||||
|
Write-Host -Fore $promptColor "<Back one Line>"
|
||||||
|
while ($_lines[--$_i].Trim(" ").StartsWith("#")){}
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"a" { # EXECUTE (Go Faster)
|
||||||
|
$AutoSpeed = [int](Read-Host "Pause (seconds)")
|
||||||
|
$FullAuto = $true;
|
||||||
|
Write-Host -Fore $promptColor "<eXecute Remaining Lines>"
|
||||||
|
$_i-- # Repeat this line, and then just blow through the rest
|
||||||
|
}
|
||||||
|
"q" { # Quit
|
||||||
|
Write-Host -Fore $promptColor "<Quiting demo>"
|
||||||
|
$_i = $_lines.count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
"v" { # View Source
|
||||||
|
$lines[0..($_i-1)] | Write-Host -Fore Yellow
|
||||||
|
$lines[$_i] | Write-Host -Fore Green
|
||||||
|
$lines[($_i+1)..$lines.Count] | Write-Host -Fore Yellow
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"t" { # Time Check
|
||||||
|
$dur = [DateTime]::Now - $_StartTime
|
||||||
|
Write-Host -Fore $promptColor $(
|
||||||
|
"{3} -- $(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s" -f
|
||||||
|
$dur.Hours, $dur.Minutes, $dur.Seconds, ([DateTime]::Now.ToShortTimeString()))
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"s" { # Suspend (Enter Nested Prompt)
|
||||||
|
Write-Host -Fore $promptColor "<Suspending demo - type 'Exit' to resume>"
|
||||||
|
$Host.EnterNestedPrompt()
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"g" { # GoTo Line Number
|
||||||
|
$i = [int](Read-Host "line number")
|
||||||
|
if($i -le $_lines.Count) {
|
||||||
|
if($i -gt 0) {
|
||||||
|
# extra line back because we're gonna step forward when we loop
|
||||||
|
$_i = Rewind $_lines $_i (($_i-$i)+1)
|
||||||
|
} else {
|
||||||
|
$_i = -1 # Start negative, because we step forward when we loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"f" { # Find by pattern
|
||||||
|
$match = $_lines | Select-String (Read-Host "search string")
|
||||||
|
if($match -eq $null) {
|
||||||
|
Write-Host -Fore Red "Can't find a matching line"
|
||||||
|
} else {
|
||||||
|
$match | % { Write-Host -Fore $promptColor $("[{0,2}] {1}" -f ($_.LineNumber - 1), $_.Line) }
|
||||||
|
if($match.Count -lt 1) {
|
||||||
|
$_i = $match.lineNumber - 2 # back a line, we're gonna step forward when we loop
|
||||||
|
} else {
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"c" {
|
||||||
|
Clear-Host
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
"$([char]13)" { # on enter
|
||||||
|
Write-Host
|
||||||
|
trap [System.Exception] {Write-Error $_; continue;}
|
||||||
|
Invoke-Expression ($_lines[$_i]) | out-default
|
||||||
|
if(-not $NoPauseAfterExecute -and -not $FullAuto) {
|
||||||
|
$null = $RawUI.ReadKey("NoEcho,IncludeKeyUp") # Pause after output for no apparent reason... ;)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default
|
||||||
|
{
|
||||||
|
Write-Host -Fore Green "`nKey not recognized. Press ? for help, or ENTER to execute the command."
|
||||||
|
$_i-- # back a line, we're gonna step forward when we loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dur = [DateTime]::Now - $_StartTime
|
||||||
|
Write-Host -Fore $promptColor $(
|
||||||
|
"<Demo Complete -- $(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s>" -f
|
||||||
|
$dur.Hours, $dur.Minutes, $dur.Seconds, [DateTime]::Now.ToLongTimeString())
|
||||||
|
Write-Host -Fore $promptColor $([DateTime]::now)
|
||||||
|
Write-Host
|
||||||
80
Examples/OutTabulator/targetout.html
Normal file
80
Examples/OutTabulator/targetout.html
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Out-TabulatorView</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery-3.3.1.min.js"></script>
|
||||||
|
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery-ui.min.js"></script>
|
||||||
|
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\tabulator.min.js"></script>
|
||||||
|
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery.sparkline.min.js"></script>
|
||||||
|
|
||||||
|
<link href="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\css\tabulator.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
|
<div id="example-table"></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var lineFormatter = function(cell, formatterParams){
|
||||||
|
setTimeout(function(){ //give cell enough time to be added to the DOM before calling sparkline formatter
|
||||||
|
cell.getElement().sparkline(cell.getValue(), {width:"100%", type:"line", disableTooltips:true});
|
||||||
|
}, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tabledata = [{"Name":"Alan Francis","Progress":90,"Activity":[4,17,11,7,6,12,14,13,11,10,9,6,11,12,0,5,12,14,18,11],"Gender":"male","Rating":3,"Color":"blue","dob":"07/08/1972","Driver":"true"},{"Name":"Brendon Philips","Progress":100,"Activity":[3,7,9,1,4,8,2,6,4,2,1,3,1,3,3,1,1,3,1,3],"Gender":"male","Rating":1,"Color":"orange","dob":"01/08/1980","Driver":""},{"Name":"Christine Lobowski","Progress":42,"Activity":[1,2,5,4,1,16,4,2,1,3,3,7,9,1,4,8,2,6,4,2],"Gender":"female","Rating":0,"Color":"green","dob":"22/05/1982","Driver":"true"},{"Name":"Ed White","Progress":70,"Activity":[20,17,15,11,16,9,4,17,11,12,0,5,12,14,18,11,12,14,20,12],"Gender":"male","Rating":0,"Color":"yellow","dob":"19/06/1976","Driver":""},{"Name":"Emily Sykes","Progress":42,"Activity":[11,15,19,20,17,16,16,5,3,2,1,2,3,4,5,4,2,5,9,8],"Gender":"female","Rating":1,"Color":"maroon","dob":"11/11/1970","Driver":""},{"Name":"Emma Netwon","Progress":40,"Activity":[3,7,9,1,4,8,3,7,9,1,4,8,2,6,4,2,2,6,4,2],"Gender":"female","Rating":4,"Color":"brown","dob":"07/10/1963","Driver":"true"},{"Name":"Frank Harbours","Progress":38,"Activity":[20,17,15,11,16,9,12,14,20,12,11,7,6,12,14,13,11,10,9,6],"Gender":"male","Rating":4,"Color":"red","dob":"12/05/1966","Driver":1},{"Name":"Gemma Jane","Progress":60,"Activity":[4,17,11,12,0,5,12,14,18,11,11,15,19,20,17,16,16,5,3,2],"Gender":"female","Rating":0,"Color":"red","dob":"22/05/1982","Driver":"true"},{"Name":"Hannah Farnsworth","Progress":30,"Activity":[1,2,5,4,1,16,10,12,14,16,13,9,7,11,10,13,4,2,1,3],"Gender":"female","Rating":1,"Color":"pink","dob":"11/02/1991","Driver":""},{"Name":"James Newman","Progress":73,"Activity":[1,20,5,3,10,13,17,15,9,11,1,2,3,4,5,4,2,5,9,8],"Gender":"male","Rating":5,"Color":"red","dob":"22/03/1998","Driver":""},{"Name":"Jamie Newhart","Progress":23,"Activity":[11,7,6,12,14,13,11,10,9,6,4,17,11,12,0,5,12,14,18,11],"Gender":"male","Rating":3,"Color":"green","dob":"14/05/1985","Driver":"true"},{"Name":"Jenny Green","Progress":56,"Activity":[11,15,19,20,17,15,11,16,9,12,14,20,12,20,17,16,16,5,3,2],"Gender":"female","Rating":4,"Color":"indigo","dob":"12/11/1998","Driver":"true"},{"Name":"John Phillips","Progress":80,"Activity":[11,7,6,12,14,1,20,5,3,10,13,17,15,9,1,13,11,10,9,6],"Gender":"male","Rating":1,"Color":"green","dob":"24/09/1950","Driver":"true"},{"Name":"Margret Marmajuke","Progress":16,"Activity":[1,3,1,3,3,1,1,3,1,3,20,17,15,11,16,9,12,14,20,12],"Gender":"female","Rating":5,"Color":"yellow","dob":"31/01/1999","Driver":""},{"Name":"Martin Barryman","Progress":20,"Activity":[1,2,3,4,5,4,11,7,6,12,14,13,11,10,9,6,2,5,9,8],"Gender":"male","Rating":5,"Color":"violet","dob":"04/04/2001","Driver":""},{"Name":"Mary May","Progress":1,"Activity":[10,12,14,16,13,9,7,11,10,13,1,2,5,4,1,16,4,2,1,3],"Gender":"female","Rating":2,"Color":"blue","dob":"14/05/1982","Driver":"true"},{"Name":"Oli Bob","Progress":12,"Activity":[1,20,5,3,10,13,17,15,9,11,10,12,14,16,13,9,7,11,10,13],"Gender":"male","Rating":1,"Color":"red","dob":"19/02/1984","Driver":1},{"Name":"Paul Branderson","Progress":60,"Activity":[1,3,1,3,3,1,11,15,19,20,17,16,16,5,3,2,1,3,1,3],"Gender":"male","Rating":5,"Color":"orange","dob":"01/01/1982","Driver":""},{"Name":"Victoria Bath","Progress":20,"Activity":[10,12,14,16,13,9,7,1,2,3,4,5,4,2,5,9,8,11,10,13],"Gender":"female","Rating":2,"Color":"purple","dob":"22/03/1986","Driver":null}]
|
||||||
|
|
||||||
|
$("#example-table").tabulator(
|
||||||
|
{
|
||||||
|
"outFile": ".\\targetout.html",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"field": "Name",
|
||||||
|
"title": "Name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Progress",
|
||||||
|
"title": "Progress",
|
||||||
|
"formatter": "progress"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Activity",
|
||||||
|
"title": "Activity",
|
||||||
|
"formatter": lineFormatter
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Gender",
|
||||||
|
"title": "Gender"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Rating",
|
||||||
|
"title": "Rating",
|
||||||
|
"formatter": "star"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Color",
|
||||||
|
"title": "Color"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "dob",
|
||||||
|
"title": "dob"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "Driver",
|
||||||
|
"title": "Driver",
|
||||||
|
"formatter": "tickCross"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"groupBy": "Gender"
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#example-table").tabulator("setData", tabledata);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
Examples/OutTabulator/tryConvertFromExcel.ps1
Normal file
9
Examples/OutTabulator/tryConvertFromExcel.ps1
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
param($outFile = "$PSScriptRoot\targetout.html")
|
||||||
|
|
||||||
|
$columnOptions = @()
|
||||||
|
|
||||||
|
$columnOptions += New-ColumnOption -ColumnName Progress -formatter progress
|
||||||
|
$columnOptions += New-ColumnOption -ColumnName Activity -formatter lineFormatter
|
||||||
|
|
||||||
|
ConvertFrom-Excel -ExcelFile $PSScriptRoot\test.xlsx -outFile $PSScriptRoot\targetout.html -columnOptions $columnOptions
|
||||||
55
Examples/PivotTable/MultiplePivotTables.ps1
Normal file
55
Examples/PivotTable/MultiplePivotTables.ps1
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
$data = ConvertFrom-Csv @"
|
||||||
|
Region,Date,Fruit,Sold
|
||||||
|
North,1/1/2017,Pears,50
|
||||||
|
South,1/1/2017,Pears,150
|
||||||
|
East,4/1/2017,Grapes,100
|
||||||
|
West,7/1/2017,Bananas,150
|
||||||
|
South,10/1/2017,Apples,200
|
||||||
|
North,1/1/2018,Pears,100
|
||||||
|
East,4/1/2018,Grapes,200
|
||||||
|
West,7/1/2018,Bananas,300
|
||||||
|
South,10/1/2018,Apples,400
|
||||||
|
"@ | Select-Object -Property Region, @{n = "Date"; e = {[datetime]::ParseExact($_.Date, "M/d/yyyy", (Get-Culture))}}, Fruit, Sold
|
||||||
|
|
||||||
|
$xlfile = "$env:temp\multiplePivotTables.xlsx"
|
||||||
|
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$excel = $data | Export-Excel $xlfile -PassThru -AutoSize -TableName FruitData
|
||||||
|
|
||||||
|
$pivotTableParams = @{
|
||||||
|
PivotTableName = "ByRegion"
|
||||||
|
Address = $excel.Sheet1.cells["F1"]
|
||||||
|
SourceWorkSheet = $excel.Sheet1
|
||||||
|
PivotRows = echo Region Fruit Date
|
||||||
|
PivotData = @{'sold' = 'sum'}
|
||||||
|
PivotTableStyle = 'Light21'
|
||||||
|
GroupDateRow = "Date"
|
||||||
|
GroupDatePart = echo Years Quarters
|
||||||
|
}
|
||||||
|
|
||||||
|
$pt = Add-PivotTable @pivotTableParams -PassThru
|
||||||
|
#$pt.RowHeaderCaption ="By Region,Fruit,Date"
|
||||||
|
$pt.RowHeaderCaption = "By " + ($pivotTableParams.PivotRows -join ",")
|
||||||
|
|
||||||
|
$pivotTableParams.PivotTableName = "ByFruit"
|
||||||
|
$pivotTableParams.Address = $excel.Sheet1.cells["J1"]
|
||||||
|
$pivotTableParams.PivotRows = echo Fruit Region Date
|
||||||
|
|
||||||
|
$pt = Add-PivotTable @pivotTableParams -PassThru
|
||||||
|
$pt.RowHeaderCaption = "By Fruit,Region"
|
||||||
|
|
||||||
|
$pivotTableParams.PivotTableName = "ByDate"
|
||||||
|
$pivotTableParams.Address = $excel.Sheet1.cells["N1"]
|
||||||
|
$pivotTableParams.PivotRows = echo Date Region Fruit
|
||||||
|
|
||||||
|
$pt = Add-PivotTable @pivotTableParams -PassThru
|
||||||
|
$pt.RowHeaderCaption = "By Date,Region,Fruit"
|
||||||
|
|
||||||
|
$pivotTableParams.PivotTableName = "ByYears"
|
||||||
|
$pivotTableParams.Address = $excel.Sheet1.cells["S1"]
|
||||||
|
$pivotTableParams.GroupDatePart = echo Years
|
||||||
|
|
||||||
|
$pt = Add-PivotTable @pivotTableParams -PassThru
|
||||||
|
$pt.RowHeaderCaption = "By Years,Region"
|
||||||
|
|
||||||
|
Close-ExcelPackage $excel -Show
|
||||||
@@ -15,7 +15,7 @@ Apple, New York, 1200,700
|
|||||||
#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.
|
#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.
|
#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)
|
# 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" -PivotTableSyle "Medium12" -PivotNumberFormat "$#,##0.00" `
|
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 @{
|
-PivotRows "City" -PivotColumns "Product" -PivotData @{Gross="Sum";Net="Sum"}-PivotTotals "Both" -Activate -PivotChartDefinition @{
|
||||||
Title="Gross and net by city and product";
|
Title="Gross and net by city and product";
|
||||||
ChartType="ColumnClustered";
|
ChartType="ColumnClustered";
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
<#
|
|
||||||
Revisit I think yahoo deprecated their service
|
|
||||||
#>
|
|
||||||
|
|
||||||
function Get-StockInfo {
|
function Get-StockInfo {
|
||||||
param(
|
param(
|
||||||
$stock,
|
[Parameter(Mandatory)]
|
||||||
[datetime]$startDate,
|
$symbols,
|
||||||
[datetime]$endDate
|
[ValidateSet('open', 'close', 'high', 'low', 'avgTotalVolume')]
|
||||||
|
$dataPlot = "close"
|
||||||
)
|
)
|
||||||
|
|
||||||
Process {
|
$xlfile = "$env:TEMP\stocks.xlsx"
|
||||||
|
rm $xlfile -ErrorAction Ignore
|
||||||
|
|
||||||
if (!$endDate) { $endDate = $startDate}
|
$result = Invoke-RestMethod "https://api.iextrading.com/1.0/stock/market/batch?symbols=$($symbols)&types=quote&last=1"
|
||||||
|
|
||||||
$baseUrl = "http://query.yahooapis.com/v1/public/yql?q="
|
$symbolCount = $symbols.Split(",").count
|
||||||
$q = @"
|
|
||||||
select * from yahoo.finance.historicaldata where symbol = "$($stock)" and startDate = "$($startDate.ToString('yyyy-MM-dd'))" and endDate = "$($endDate.ToString('yyyy-MM-dd'))"
|
|
||||||
"@
|
|
||||||
$suffix = "&env=store://datatables.org/alltableswithkeys&format=json"
|
|
||||||
$r = Invoke-RestMethod ($baseUrl + $q + $suffix)
|
|
||||||
$r.query.results.quote
|
|
||||||
|
|
||||||
}
|
|
||||||
|
$ecd = New-ExcelChartDefinition -Row 1 -Column 1 -SeriesHeader $dataPlot `
|
||||||
|
-XRange symbol -YRange $dataPlot `
|
||||||
|
-Title "$($dataPlot)`r`n As Of $((Get-Date).ToShortDateString())"
|
||||||
|
|
||||||
|
$(foreach ($name in $result.psobject.Properties.name) {
|
||||||
|
$result.$name.quote
|
||||||
|
}) | Export-Excel $xlfile -AutoNameRange -AutoSize -Show -ExcelChartDefinition $ecd -StartRow 21 -StartColumn 2
|
||||||
}
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<#
|
|
||||||
Revisit I think yahoo deprecated their service
|
|
||||||
#>
|
|
||||||
|
|
||||||
# try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
|
||||||
|
|
||||||
# $Symbol = "MSFT"
|
|
||||||
|
|
||||||
# . .\Get-StockInfo.ps1
|
|
||||||
|
|
||||||
# Remove-Item *.xlsx -ErrorAction Ignore
|
|
||||||
|
|
||||||
# $chart = New-ExcelChart -XRange Date -YRange Volume `
|
|
||||||
# -ChartType ColumnStacked `
|
|
||||||
# -Column 9 -Title "$Symbol Volume"
|
|
||||||
|
|
||||||
# Get-StockInfo $Symbol 11/2 11/30 |
|
|
||||||
# Export-Excel .\stocks.xlsx -Show `
|
|
||||||
# -AutoSize -AutoNameRange `
|
|
||||||
# -ExcelChartDefinition $chart
|
|
||||||
3
Examples/Stocks/GetStocksAvgTotVol.ps1
Normal file
3
Examples/Stocks/GetStocksAvgTotVol.ps1
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
. $PSScriptRoot\Get-StockInfo.ps1
|
||||||
|
|
||||||
|
Get-StockInfo -symbols "msft,ibm,ge,xom,aapl" -dataPlot avgTotalVolume
|
||||||
90
Examples/TestRestAPI/PSExcelPester.psm1
Normal file
90
Examples/TestRestAPI/PSExcelPester.psm1
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
function ConvertTo-PesterTest {
|
||||||
|
param(
|
||||||
|
[parameter(Mandatory)]
|
||||||
|
$XlFilename,
|
||||||
|
$WorksheetName = 'Sheet1'
|
||||||
|
)
|
||||||
|
|
||||||
|
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss")
|
||||||
|
|
||||||
|
$records = Import-Excel $XlFilename
|
||||||
|
|
||||||
|
$params = @{}
|
||||||
|
|
||||||
|
$blocks = $(foreach ($record in $records) {
|
||||||
|
foreach ($propertyName in $record.psobject.properties.name) {
|
||||||
|
if ($propertyName -notmatch 'ExpectedResult|QueryString') {
|
||||||
|
$params.$propertyName = $record.$propertyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($record.QueryString) {
|
||||||
|
$params.Uri += "?{0}" -f $record.QueryString
|
||||||
|
}
|
||||||
|
|
||||||
|
@"
|
||||||
|
|
||||||
|
it "Should have the expected result '$($record.ExpectedResult)'" {
|
||||||
|
`$target = '$($params | ConvertTo-Json -compress)' | ConvertFrom-Json
|
||||||
|
|
||||||
|
`$target.psobject.Properties.name | ForEach-Object {`$p=@{}} {`$p.`$_=`$(`$target.`$_)}
|
||||||
|
|
||||||
|
Invoke-RestMethod @p | Should Be '$($record.ExpectedResult)'
|
||||||
|
}
|
||||||
|
|
||||||
|
"@
|
||||||
|
})
|
||||||
|
|
||||||
|
@"
|
||||||
|
Describe "Tests from $($XlFilename) in $($WorksheetName)" {
|
||||||
|
$($blocks)
|
||||||
|
}
|
||||||
|
"@ | Set-Content -Encoding Ascii $testFileName
|
||||||
|
|
||||||
|
[PSCustomObject]@{
|
||||||
|
TestFileName = (Get-ChildItem $testFileName).FullName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Show-PesterResult {
|
||||||
|
param(
|
||||||
|
[Parameter(ValueFromPipelineByPropertyName, Mandatory)]
|
||||||
|
$TestFileName
|
||||||
|
)
|
||||||
|
|
||||||
|
Begin {
|
||||||
|
$xlfilename = ".\test.xlsx"
|
||||||
|
Remove-Item $xlfilename -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$ConditionalText = @()
|
||||||
|
$ConditionalText += New-ConditionalText -Range "Result" -Text failed -BackgroundColor red -ConditionalTextColor black
|
||||||
|
$ConditionalText += New-ConditionalText -Range "Result" -Text passed -BackgroundColor green -ConditionalTextColor black
|
||||||
|
$ConditionalText += New-ConditionalText -Range "Result" -Text pending -BackgroundColor gray -ConditionalTextColor black
|
||||||
|
|
||||||
|
$xlParams = @{
|
||||||
|
Path = $xlfilename
|
||||||
|
WorkSheetname = 'PesterTests'
|
||||||
|
ConditionalText = $ConditionalText
|
||||||
|
PivotRows = 'Result', 'Name'
|
||||||
|
PivotData = @{'Result' = 'Count'}
|
||||||
|
IncludePivotTable = $true
|
||||||
|
AutoSize = $true
|
||||||
|
AutoNameRange = $true
|
||||||
|
AutoFilter = $true
|
||||||
|
Show = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
End {
|
||||||
|
|
||||||
|
$(foreach ($result in (Invoke-Pester -Script $TestFileName -PassThru -Show None).TestResult) {
|
||||||
|
[PSCustomObject][Ordered]@{
|
||||||
|
Description = $result.Describe
|
||||||
|
Name = $result.Name
|
||||||
|
Result = $result.Result
|
||||||
|
Messge = $result.FailureMessage
|
||||||
|
StackTrace = $result.StackTrace
|
||||||
|
}
|
||||||
|
}) | Export-Excel @xlParams
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
function Show-PesterResults {
|
function Show-PesterResults {
|
||||||
$xlfilename=".\test.xlsx"
|
$xlfilename = ".\test.xlsx"
|
||||||
rm $xlfilename -ErrorAction Ignore
|
Remove-Item $xlfilename -ErrorAction Ignore
|
||||||
|
|
||||||
$ConditionalText = @()
|
$ConditionalText = @()
|
||||||
$ConditionalText += New-ConditionalText -Range "Result" -Text failed -BackgroundColor red -ConditionalTextColor black
|
$ConditionalText += New-ConditionalText -Range "Result" -Text failed -BackgroundColor red -ConditionalTextColor black
|
||||||
@@ -8,33 +8,25 @@
|
|||||||
$ConditionalText += New-ConditionalText -Range "Result" -Text pending -BackgroundColor gray -ConditionalTextColor black
|
$ConditionalText += New-ConditionalText -Range "Result" -Text pending -BackgroundColor gray -ConditionalTextColor black
|
||||||
|
|
||||||
$xlParams = @{
|
$xlParams = @{
|
||||||
Path=$xlfilename
|
Path = $xlfilename
|
||||||
WorkSheetname = 'PesterTests'
|
WorkSheetname = 'PesterTests'
|
||||||
ConditionalText=$ConditionalText
|
ConditionalText = $ConditionalText
|
||||||
PivotRows = 'Description'
|
PivotRows = 'Result', 'Name'
|
||||||
PivotColumns = 'Result'
|
PivotData = @{'Result' = 'Count'}
|
||||||
PivotData = @{'Result'='Count'}
|
IncludePivotTable = $true
|
||||||
IncludePivotTable = $true
|
AutoSize = $true
|
||||||
#IncludePivotChart = $true
|
AutoNameRange = $true
|
||||||
#NoLegend = $true
|
AutoFilter = $true
|
||||||
#ShowPercent = $true
|
Show = $true
|
||||||
#ShowCategory = $true
|
|
||||||
AutoSize = $true
|
|
||||||
AutoNameRange = $true
|
|
||||||
AutoFilter = $true
|
|
||||||
Show = $true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(foreach($result in (Invoke-Pester -PassThru -Show None).TestResult) {
|
$(foreach ($result in (Invoke-Pester -PassThru -Show None).TestResult) {
|
||||||
|
[PSCustomObject]@{
|
||||||
[PSCustomObject]@{
|
Description = $result.Describe
|
||||||
Description = $result.Describe
|
Name = $result.Name
|
||||||
Name = $result.Name
|
Result = $result.Result
|
||||||
#Time = $result.Time
|
Messge = $result.FailureMessage
|
||||||
Result = $result.Result
|
StackTrace = $result.StackTrace
|
||||||
Messge = $result.FailureMessage
|
}
|
||||||
StackTrace = $result.StackTrace
|
}) | Sort-Object Description | Export-Excel @xlParams
|
||||||
}
|
|
||||||
|
|
||||||
}) | Sort Description | Export-Excel @xlParams
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
|
||||||
|
|
||||||
function Test-APIReadXls {
|
function Test-APIReadXls {
|
||||||
param(
|
param(
|
||||||
[parameter(Mandatory)]
|
[parameter(Mandatory)]
|
||||||
@@ -7,6 +5,8 @@ function Test-APIReadXls {
|
|||||||
$WorksheetName = 'Sheet1'
|
$WorksheetName = 'Sheet1'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss")
|
||||||
|
|
||||||
$records = Import-Excel $XlFilename
|
$records = Import-Excel $XlFilename
|
||||||
|
|
||||||
$params = @{}
|
$params = @{}
|
||||||
@@ -35,15 +35,11 @@ function Test-APIReadXls {
|
|||||||
"@
|
"@
|
||||||
})
|
})
|
||||||
|
|
||||||
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss.fff")
|
|
||||||
|
|
||||||
@"
|
@"
|
||||||
Describe "Tests from $($XlFilename) in $($WorksheetName)" {
|
Describe "Tests from $($XlFilename) in $($WorksheetName)" {
|
||||||
$($blocks)
|
$($blocks)
|
||||||
}
|
}
|
||||||
"@ | Set-Content -Encoding Ascii $testFileName
|
"@ | Set-Content -Encoding Ascii $testFileName
|
||||||
|
|
||||||
#Invoke-Pester -Script (Get-ChildItem $testFileName)
|
(Get-ChildItem $testFileName).FullName
|
||||||
Get-ChildItem $testFileName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
569
Export-Excel.ps1
569
Export-Excel.ps1
@@ -1,13 +1,17 @@
|
|||||||
function Export-Excel {
|
function Export-Excel {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Export data to an Excel worksheet.
|
Exports data to an Excel worksheet.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Export data to an Excel file and where possible try to convert numbers so Excel recognizes them as numbers instead of text. After all. Excel is a spreadsheet program used for number manipulation and calculations. In case the number conversion is not desired, use the parameter '-NoNumberConversion *'.
|
Exports data to an Excel file and where possible tries to convert numbers
|
||||||
|
in text fields so Excel recognizes them as numbers instead of text.
|
||||||
|
After all: Excel is a spreadsheet program used for number manipulation
|
||||||
|
and calculations. If number conversion is not desired, use the
|
||||||
|
parameter -NoNumberConversion *.
|
||||||
.PARAMETER Path
|
.PARAMETER Path
|
||||||
Path to a new or existing .XLSX file.
|
Path to a new or existing .XLSX file.
|
||||||
.PARAMETER ExcelPackage
|
.PARAMETER ExcelPackage
|
||||||
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 - usually this is returned by specifying -PassThru allowing multiple commands to work on the same workbook without saving and reloading each time.
|
||||||
.PARAMETER WorksheetName
|
.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 ClearSheet
|
.PARAMETER ClearSheet
|
||||||
@@ -15,7 +19,7 @@
|
|||||||
.PARAMETER Append
|
.PARAMETER Append
|
||||||
If specified data will be added to the end of an existing sheet, using the same column headings.
|
If specified data will be added to the end of an existing sheet, using the same column headings.
|
||||||
.PARAMETER TargetData
|
.PARAMETER TargetData
|
||||||
Data to insert onto the worksheet - this is often provided from the pipeline.
|
Data to insert onto the worksheet - this is usually provided from the pipeline.
|
||||||
.PARAMETER DisplayPropertySet
|
.PARAMETER DisplayPropertySet
|
||||||
Many (but not all) objects have a hidden property named psStandardmembers with a child property DefaultDisplayPropertySet ; this parameter reduces the properties exported to those in this set.
|
Many (but not all) objects have a hidden property named psStandardmembers with a child property DefaultDisplayPropertySet ; this parameter reduces the properties exported to those in this set.
|
||||||
.PARAMETER NoAliasOrScriptPropeties
|
.PARAMETER NoAliasOrScriptPropeties
|
||||||
@@ -37,36 +41,36 @@
|
|||||||
.PARAMETER Password
|
.PARAMETER Password
|
||||||
Sets password protection on the workbook.
|
Sets password protection on the workbook.
|
||||||
.PARAMETER IncludePivotTable
|
.PARAMETER IncludePivotTable
|
||||||
Adds a Pivot table using the data in the worksheet.
|
Adds a PivotTable using the data in the worksheet.
|
||||||
.PARAMETER PivotTableName
|
.PARAMETER PivotTableName
|
||||||
If a Pivot table is created from command line parameters, specifies the name of the new sheet holding the pivot. Defaults to "WorksheetName-PivotTable"
|
If a PivotTable is created from command line parameters, specifies the name of the new sheet holding the pivot. Defaults to "WorksheetName-PivotTable".
|
||||||
.PARAMETER PivotRows
|
.PARAMETER PivotRows
|
||||||
Name(s) columns from the spreadsheet which will provide the Row name(s) in a pivot table created from command line parameters.
|
Name(s) of column(s) from the spreadsheet which will provide the Row name(s) in a PivotTable created from command line parameters.
|
||||||
.PARAMETER PivotColumns
|
.PARAMETER PivotColumns
|
||||||
Name(s) columns from the spreadsheet which will provide the Column name(s) in a pivot table created from command line parameters.
|
Name(s) of columns from the spreadsheet which will provide the Column name(s) in a PivotTable created from command line parameters.
|
||||||
.PARAMETER PivotFilter
|
.PARAMETER PivotFilter
|
||||||
Name(s) columns from the spreadsheet which will provide the Filter name(s) in a pivot table created from command line parameters.
|
Name(s) columns from the spreadsheet which will provide the Filter name(s) in a PivotTable created from command line parameters.
|
||||||
.PARAMETER PivotData
|
.PARAMETER PivotData
|
||||||
In a pivot table created from command line parameters, the fields to use in the table body are given as a Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP.
|
In a PivotTable created from command line parameters, the fields to use in the table body are given as a Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP.
|
||||||
.PARAMETER PivotDataToColumn
|
.PARAMETER PivotDataToColumn
|
||||||
If there are multiple datasets in a PivotTable, by default they are shown as separate rows under the given row heading; this switch makes them separate columns.
|
If there are multiple datasets in a PivotTable, by default they are shown as separate rows under the given row heading; this switch makes them separate columns.
|
||||||
.PARAMETER NoTotalsInPivot
|
.PARAMETER NoTotalsInPivot
|
||||||
In a pivot table created from command line parameters, prevents the addition of totals to rows and columns.
|
In a PivotTable created from command line parameters, prevents the addition of totals to rows and columns.
|
||||||
.PARAMETER PivotTotals
|
.PARAMETER PivotTotals
|
||||||
By default, Pivot tables have totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
|
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.
|
||||||
.PARAMETER PivotTableDefinition
|
.PARAMETER PivotTableDefinition
|
||||||
Instead of describing a single pivot table with multiple commandline parameters; you can use a hashTable in the form PivotTableName = Definition;
|
Instead of describing a single PivotTable with multiple command-line parameters; you can use a HashTable in the form PivotTableName = Definition;
|
||||||
Definition is itself a hashtable with Sheet, PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values.
|
Definition is itself a Hashtable with Sheet, PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values.
|
||||||
.PARAMETER IncludePivotChart
|
.PARAMETER IncludePivotChart
|
||||||
Include a chart with the Pivot table - implies -IncludePivotTable.
|
Include a chart with the PivotTable - implies -IncludePivotTable.
|
||||||
.PARAMETER ChartType
|
.PARAMETER ChartType
|
||||||
The type for Pivot chart (one of Excel's defined chart types)
|
The type for PivotChart (one of Excel's defined chart types).
|
||||||
.PARAMETER NoLegend
|
.PARAMETER NoLegend
|
||||||
Exclude the legend from the pivot chart.
|
Exclude the legend from the PivotChart.
|
||||||
.PARAMETER ShowCategory
|
.PARAMETER ShowCategory
|
||||||
Add category labels to the pivot chart.
|
Add category labels to the PivotChart.
|
||||||
.PARAMETER ShowPercent
|
.PARAMETER ShowPercent
|
||||||
Add Percentage labels to the pivot chart.
|
Add percentage labels to the PivotChart.
|
||||||
.PARAMETER ConditionalFormat
|
.PARAMETER ConditionalFormat
|
||||||
One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
|
One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
|
||||||
.PARAMETER ConditionalText
|
.PARAMETER ConditionalText
|
||||||
@@ -74,15 +78,15 @@
|
|||||||
.PARAMETER NoNumberConversion
|
.PARAMETER NoNumberConversion
|
||||||
By default we convert all values to numbers if possible, but this isn't always desirable. NoNumberConversion allows you to add exceptions for the conversion. Wildcards (like '*') are allowed.
|
By default we convert all values to numbers if possible, but this isn't always desirable. NoNumberConversion allows you to add exceptions for the conversion. Wildcards (like '*') are allowed.
|
||||||
.PARAMETER BoldTopRow
|
.PARAMETER BoldTopRow
|
||||||
Makes the top Row boldface.
|
Makes the top row boldface.
|
||||||
.PARAMETER NoHeader
|
.PARAMETER NoHeader
|
||||||
Does not put field names at the top of columns.
|
Does not put field names at the top of columns.
|
||||||
.PARAMETER RangeName
|
.PARAMETER RangeName
|
||||||
Makes the data in the worksheet a named range.
|
Makes the data in the worksheet a named range.
|
||||||
.PARAMETER TableName
|
.PARAMETER TableName
|
||||||
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. The name must not contain spaces. If a style is specified without a name, table1, table2 etc. will be used.
|
||||||
.PARAMETER TableStyle
|
.PARAMETER TableStyle
|
||||||
Selects the style for the named table - defaults to 'Medium6'.
|
Selects the style for the named table - if a name is specified without a style, 'Medium6' is used as a default.
|
||||||
.PARAMETER BarChart
|
.PARAMETER BarChart
|
||||||
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
|
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
|
||||||
.PARAMETER ColumnChart
|
.PARAMETER ColumnChart
|
||||||
@@ -92,11 +96,11 @@
|
|||||||
.PARAMETER PieChart
|
.PARAMETER PieChart
|
||||||
Creates a "quick" pie chart using the first text column as labels and the first numeric column as values
|
Creates a "quick" pie chart using the first text column as labels and the first numeric column as values
|
||||||
.PARAMETER ExcelChartDefinition
|
.PARAMETER ExcelChartDefinition
|
||||||
A hash table containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
|
A hash table containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-Pivot] charts.
|
||||||
.PARAMETER HideSheet
|
.PARAMETER HideSheet
|
||||||
Name(s) of Sheet(s) to hide in the workbook, supports wildcards. If all sheets would be hidden, the sheet being worked on will be revealed.
|
Name(s) of Sheet(s) to hide in the workbook, supports wildcards. If the selection would cause all sheets to be hidden, the sheet being worked on will be revealed.
|
||||||
.PARAMETER UnHideSheet
|
.PARAMETER UnHideSheet
|
||||||
Name(s) of Sheet(s) to Reveal in the workbook, supports wildcards.
|
Name(s) of Sheet(s) to reveal in the workbook, supports wildcards.
|
||||||
.PARAMETER MoveToStart
|
.PARAMETER MoveToStart
|
||||||
If specified, the worksheet will be moved to the start of the workbook.
|
If specified, the worksheet will be moved to the start of the workbook.
|
||||||
-MoveToStart takes precedence over -MoveToEnd, -Movebefore and -MoveAfter if more than one is specified.
|
-MoveToStart takes precedence over -MoveToEnd, -Movebefore and -MoveAfter if more than one is specified.
|
||||||
@@ -126,13 +130,15 @@
|
|||||||
.PARAMETER FreezePane
|
.PARAMETER FreezePane
|
||||||
Freezes panes at specified coordinates (in the form RowNumber, ColumnNumber).
|
Freezes panes at specified coordinates (in the form RowNumber, ColumnNumber).
|
||||||
.PARAMETER AutoFilter
|
.PARAMETER AutoFilter
|
||||||
Enables the 'Filter' in Excel on the complete header row, so users can easily sort, filter and/or search the data in the selected column from within Excel.
|
Enables the Excel filter on the complete header row, so users can easily sort, filter and/or search the data in the selected column.
|
||||||
.PARAMETER AutoSize
|
.PARAMETER AutoSize
|
||||||
Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
|
Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
|
||||||
|
.PARAMETER MaxAutoSizeRows
|
||||||
|
Autosizing can be time consuming, so this sets a maximum number of rows to look at for the Autosize operation. Default is 1000; If 0 is specified ALL rows will be checked
|
||||||
.PARAMETER Activate
|
.PARAMETER Activate
|
||||||
If there is already content in the workbook, a new sheet will not be active UNLESS Activate is specified; if a Pivot table is included it will be the active sheet
|
If there is already content in the workbook, a new sheet will not be active UNLESS Activate is specified; if a PivotTable is included it will be the active sheet
|
||||||
.PARAMETER Now
|
.PARAMETER Now
|
||||||
The 'Now' switch is a shortcut that creates automatically a temporary file, enables 'AutoSize', 'AutoFiler' and 'Show', and opens the file immediately.
|
The -Now switch is a shortcut that automatically creates a temporary file, enables "AutoSize", "AutoFiler" and "Show", and opens the file immediately.
|
||||||
.PARAMETER NumberFormat
|
.PARAMETER NumberFormat
|
||||||
Formats all values that can be converted to a number to the format specified.
|
Formats all values that can be converted to a number to the format specified.
|
||||||
|
|
||||||
@@ -162,7 +168,7 @@
|
|||||||
'[Blue]$#,##0.00;[Red]-$#,##0.00'
|
'[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||||
|
|
||||||
.PARAMETER ReZip
|
.PARAMETER ReZip
|
||||||
If specified, Export-Excel will expand the contents of the .XLSX file (which is multiple files in a zip archive) and rebuilt it.
|
If specified, Export-Excel will expand the contents of the .XLSX file (which is multiple files in a zip archive) and rebuild it.
|
||||||
.PARAMETER NoClobber
|
.PARAMETER NoClobber
|
||||||
Not used. Left in to avoid problems with older scripts, it may be removed in future versions.
|
Not used. Left in to avoid problems with older scripts, it may be removed in future versions.
|
||||||
.PARAMETER CellStyleSB
|
.PARAMETER CellStyleSB
|
||||||
@@ -171,7 +177,7 @@
|
|||||||
.PARAMETER Show
|
.PARAMETER Show
|
||||||
Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
||||||
.PARAMETER ReturnRange
|
.PARAMETER ReturnRange
|
||||||
If specified, Export-Excel returns the range of added cells in the format "A1:Z100"
|
If specified, Export-Excel returns the range of added cells in the format "A1:Z100".
|
||||||
.PARAMETER PassThru
|
.PARAMETER PassThru
|
||||||
If specified, Export-Excel returns an object representing the Excel package without saving the package first.
|
If specified, Export-Excel returns an object representing the Excel package without saving the package first.
|
||||||
To save, you need to call Close-ExcelPackage or send the object back to Export-Excel, or use its .Save() or SaveAs() method.
|
To save, you need to call Close-ExcelPackage or send the object back to Export-Excel, or use its .Save() or SaveAs() method.
|
||||||
@@ -190,7 +196,9 @@
|
|||||||
Write-Output -1 668 34 777 860 -0.5 119 -0.1 234 788 |
|
Write-Output -1 668 34 777 860 -0.5 119 -0.1 234 788 |
|
||||||
Export-Excel @ExcelParams -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
Export-Excel @ExcelParams -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00'
|
||||||
|
|
||||||
Exports all data to the Excel file 'Excel.xslx' and colors the negative values in 'Red' and the positive values in 'Blue'. It will also add a dollar sign '$' in front of the rounded numbers to two decimal characters behind the comma.
|
Exports all data to the Excel file 'Excel.xslx' and colors the negative values
|
||||||
|
in Red and the positive values in Blue. It will also add a dollar sign in front
|
||||||
|
of the numbers which use a thousand seperator and display to two decimal places.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -216,7 +224,9 @@
|
|||||||
PhoneNr3 = '+3244444444'
|
PhoneNr3 = '+3244444444'
|
||||||
} | Export-Excel @ExcelParams -NoNumberConversion IPAddress, Number1
|
} | Export-Excel @ExcelParams -NoNumberConversion IPAddress, Number1
|
||||||
|
|
||||||
Exports all data to the Excel file 'Excel.xslx' and tries to convert all values to numbers where possible except for 'IPAddress' and 'Number1'. These are stored in the sheet 'as is', without being converted to a number.
|
Exports all data to the Excel file "Excel.xlsx" and tries to convert all values
|
||||||
|
to numbers where possible except for "IPAddress" and "Number1", which are
|
||||||
|
stored in the sheet 'as is', without being converted to a number.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -242,7 +252,9 @@
|
|||||||
PhoneNr3 = '+3244444444'
|
PhoneNr3 = '+3244444444'
|
||||||
} | Export-Excel @ExcelParams -NoNumberConversion *
|
} | Export-Excel @ExcelParams -NoNumberConversion *
|
||||||
|
|
||||||
Exports all data to the Excel file 'Excel.xslx' as is, no number conversion will take place. This means that Excel will show the exact same data that you handed over to the 'Export-Excel' function.
|
Exports all data to the Excel file 'Excel.xslx' as is, no number conversion
|
||||||
|
will take place. This means that Excel will show the exact same data that
|
||||||
|
you handed over to the 'Export-Excel' function.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -257,9 +269,11 @@
|
|||||||
New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor DarkRed -BackgroundColor LightPink
|
New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor DarkRed -BackgroundColor LightPink
|
||||||
)
|
)
|
||||||
|
|
||||||
Exports data that will have a 'Conditional formatting rule' in Excel on these cells that will show the background fill color in
|
Exports data that will have a Conditional Formatting rule in Excel
|
||||||
'LightPink' and the text color in 'DarkRed' when the value is greater than '525'. In case this condition is not met the color will
|
that will show cells with a value is greater than 525, whith a
|
||||||
be the default, black text on a white background.
|
background fill color of "LightPink" and the text in "DarkRed".
|
||||||
|
Where condition is not met the color willbe the default, black
|
||||||
|
text on a white background.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -275,7 +289,12 @@
|
|||||||
New-ConditionalText Running Blue Cyan
|
New-ConditionalText Running Blue Cyan
|
||||||
)
|
)
|
||||||
|
|
||||||
Export all services to an Excel sheet where all cells have a 'Conditional formatting rule' in Excel that will show the background fill color in 'LightPink' and the text color in 'DarkRed' when the value contains the word 'Stop'. If the value contains the word 'Running' it will have a background fill color in 'Cyan' and a text color 'Blue'. In case none of these conditions are met the color will be the default, black text on a white background.
|
Exports all services to an Excel sheet, setting a Conditional formatting rule
|
||||||
|
that will set the background fill color to "LightPink" and the text color
|
||||||
|
to "DarkRed" when the value contains the word "Stop".
|
||||||
|
If the value contains the word "Running" it will have a background fill
|
||||||
|
color of "Cyan" and text colored 'Blue'. If neither condition is met, the
|
||||||
|
color will be the default, black text on a white background.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -310,7 +329,8 @@
|
|||||||
$Array | Out-GridView -Title 'Not showing Member3 and Member4'
|
$Array | Out-GridView -Title 'Not showing Member3 and Member4'
|
||||||
$Array | Update-FirstObjectProperties | Export-Excel @ExcelParams -WorksheetName Numbers
|
$Array | Update-FirstObjectProperties | Export-Excel @ExcelParams -WorksheetName Numbers
|
||||||
|
|
||||||
Updates the first object of the array by adding property 'Member3' and 'Member4'. Afterwards. all objects are exported to an Excel file and all column headers are visible.
|
Updates the first object of the array by adding property 'Member3' and 'Member4'.
|
||||||
|
Afterwards. all objects are exported to an Excel file and all column headers are visible.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Get-Process | Export-Excel .\test.xlsx -WorksheetName Processes -IncludePivotTable -Show -PivotRows Company -PivotData PM
|
Get-Process | Export-Excel .\test.xlsx -WorksheetName Processes -IncludePivotTable -Show -PivotRows Company -PivotData PM
|
||||||
@@ -341,10 +361,10 @@
|
|||||||
Get-Process | Select-Object -Property Name,Company,Handles,CPU,VM | Export-Excel -Path .\test.xlsx -AutoSize -WorksheetName 'sheet2'
|
Get-Process | Select-Object -Property Name,Company,Handles,CPU,VM | Export-Excel -Path .\test.xlsx -AutoSize -WorksheetName 'sheet2'
|
||||||
Export-Excel -Path .\test.xlsx -PivotTableDefinition $pt -Show
|
Export-Excel -Path .\test.xlsx -PivotTableDefinition $pt -Show
|
||||||
|
|
||||||
This example defines two pivot tables. Then it puts Service data on Sheet1 with one call to Export-Excel and Process Data on sheet2 with a second call to Export-Excel.
|
This example defines two PivotTables. Then it puts Service data on Sheet1
|
||||||
The third and final call adds the two pivot tables and opens the spreadsheet in Excel.
|
with one call to Export-Excel and Process Data on sheet2 with a second
|
||||||
|
call to Export-Excel. The third and final call adds the two PivotTables
|
||||||
|
and opens the spreadsheet in Excel.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
PS> Remove-Item -Path .\test.xlsx
|
PS> Remove-Item -Path .\test.xlsx
|
||||||
@@ -356,8 +376,11 @@
|
|||||||
$excel.Dispose()
|
$excel.Dispose()
|
||||||
Start-Process .\test.xlsx
|
Start-Process .\test.xlsx
|
||||||
|
|
||||||
This example uses -passthrough. It puts service information into sheet1 of the workbook and saves the ExcelPackageObject in $Excel.
|
This example uses -PassThru. It puts service information into sheet1 of the
|
||||||
It then uses the package object to apply formatting, and then saves the workbook and disposes of the object before loading the document in Excel.
|
workbook and saves the ExcelPackage object in $Excel. It then uses the package
|
||||||
|
object to apply formatting, and then saves the workbook and disposes of the object
|
||||||
|
before loading the document in Excel. Other commands in the module remove the need
|
||||||
|
to work directly with the package object in this way.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -375,27 +398,39 @@
|
|||||||
foreach ($c in 5..9) {Set-ExcelRange -Address $sheet.Column($c) -AutoFit }
|
foreach ($c in 5..9) {Set-ExcelRange -Address $sheet.Column($c) -AutoFit }
|
||||||
Export-Excel -ExcelPackage $excel -WorksheetName "Processes" -IncludePivotChart -ChartType ColumnClustered -NoLegend -PivotRows company -PivotData @{'Name'='Count'} -Show
|
Export-Excel -ExcelPackage $excel -WorksheetName "Processes" -IncludePivotChart -ChartType ColumnClustered -NoLegend -PivotRows company -PivotData @{'Name'='Count'} -Show
|
||||||
|
|
||||||
This a more sophisticated version of the previous example showing different ways of using Set-ExcelRange, and also adding conditional formatting.
|
This a more sophisticated version of the previous example showing different
|
||||||
In the final command a Pivot chart is added and the workbook is opened in Excel.
|
ways of using Set-ExcelRange, and also adding conditional formatting.
|
||||||
|
In the final command a PivotChart is added and the workbook is opened in Excel.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
0..360 | ForEach-Object {[pscustomobject][ordered]@{X=$_; Sinx="=Sin(Radians(x)) "} } | Export-Excel -now -LineChart -AutoNameRange
|
0..360 | ForEach-Object {[pscustomobject][ordered]@{X=$_; Sinx="=Sin(Radians(x)) "} } | Export-Excel -now -LineChart -AutoNameRange
|
||||||
|
|
||||||
Creates a line chart showing the value of Sine(x) for values of X between 0 and 360 degrees.
|
Creates a line chart showing the value of Sine(x) for values of X between 0 and 360 degrees.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
>
|
||||||
|
PS> Invoke-Sqlcmd -ServerInstance localhost\DEFAULT -Database AdventureWorks2014 -Query "select * from sys.tables" -OutputAs DataRows |
|
||||||
|
Export-Excel -Path .\SysTables_AdventureWorks2014.xlsx -WorksheetName Tables
|
||||||
|
|
||||||
|
Runs a query against a SQL Server database and outputs the resulting rows DataRows using the -OutputAs parameter.
|
||||||
|
The results are then piped to the Export-Excel function.
|
||||||
|
NOTE: You need to install the SqlServer module from the PowerShell Gallery in oder to get the -OutputAs parameter for the Invoke-Sqlcmd cmdlet.
|
||||||
|
|
||||||
.LINK
|
.LINK
|
||||||
https://github.com/dfinke/ImportExcel
|
https://github.com/dfinke/ImportExcel
|
||||||
#>
|
#>
|
||||||
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
[CmdletBinding(DefaultParameterSetName = 'Now')]
|
||||||
[OutputType([OfficeOpenXml.ExcelPackage])]
|
[OutputType([OfficeOpenXml.ExcelPackage])]
|
||||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||||
Param(
|
Param(
|
||||||
[Parameter(ParameterSetName = "Default", Position = 0)]
|
|
||||||
[Parameter(ParameterSetName = "Table" , Position = 0)]
|
[Parameter(Mandatory = $true, ParameterSetName = "Path", Position = 0)]
|
||||||
[String]$Path,
|
[String]$Path,
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageDefault")]
|
[Parameter(Mandatory = $true, ParameterSetName = "Package")]
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
|
|
||||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||||
[Parameter(ValueFromPipeline = $true)]
|
[Parameter(ValueFromPipeline = $true)]
|
||||||
$TargetData,
|
[Alias('TargetData')]
|
||||||
|
$InputObject,
|
||||||
[Switch]$Calculate,
|
[Switch]$Calculate,
|
||||||
[Switch]$Show,
|
[Switch]$Show,
|
||||||
[String]$WorksheetName = 'Sheet1',
|
[String]$WorksheetName = 'Sheet1',
|
||||||
@@ -406,7 +441,7 @@
|
|||||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
|
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
|
||||||
[Switch]$TitleBold,
|
[Switch]$TitleBold,
|
||||||
[Int]$TitleSize = 22,
|
[Int]$TitleSize = 22,
|
||||||
[System.Drawing.Color]$TitleBackgroundColor,
|
$TitleBackgroundColor,
|
||||||
[Switch]$IncludePivotTable,
|
[Switch]$IncludePivotTable,
|
||||||
[String]$PivotTableName,
|
[String]$PivotTableName,
|
||||||
[String[]]$PivotRows,
|
[String[]]$PivotRows,
|
||||||
@@ -421,13 +456,14 @@
|
|||||||
[Switch]$ShowCategory,
|
[Switch]$ShowCategory,
|
||||||
[Switch]$ShowPercent,
|
[Switch]$ShowPercent,
|
||||||
[Switch]$AutoSize,
|
[Switch]$AutoSize,
|
||||||
|
$MaxAutoSizeRows = 1000,
|
||||||
[Switch]$NoClobber,
|
[Switch]$NoClobber,
|
||||||
[Switch]$FreezeTopRow,
|
[Switch]$FreezeTopRow,
|
||||||
[Switch]$FreezeFirstColumn,
|
[Switch]$FreezeFirstColumn,
|
||||||
[Switch]$FreezeTopRowFirstColumn,
|
[Switch]$FreezeTopRowFirstColumn,
|
||||||
[Int[]]$FreezePane,
|
[Int[]]$FreezePane,
|
||||||
[Parameter(ParameterSetName = 'Default')]
|
|
||||||
[Parameter(ParameterSetName = 'PackageDefault')]
|
|
||||||
[Switch]$AutoFilter,
|
[Switch]$AutoFilter,
|
||||||
[Switch]$BoldTopRow,
|
[Switch]$BoldTopRow,
|
||||||
[Switch]$NoHeader,
|
[Switch]$NoHeader,
|
||||||
@@ -442,12 +478,12 @@
|
|||||||
elseif ($_[0] -notmatch '[a-z]') { throw 'Tablename starts with an invalid character.' }
|
elseif ($_[0] -notmatch '[a-z]') { throw 'Tablename starts with an invalid character.' }
|
||||||
else { $true }
|
else { $true }
|
||||||
})]
|
})]
|
||||||
[Parameter(ParameterSetName = 'Table' , Mandatory = $true, ValueFromPipelineByPropertyName)]
|
|
||||||
[Parameter(ParameterSetName = 'PackageTable' , Mandatory = $true, ValueFromPipelineByPropertyName)]
|
|
||||||
[String]$TableName,
|
[String]$TableName,
|
||||||
[Parameter(ParameterSetName = 'Table')]
|
|
||||||
[Parameter(ParameterSetName = 'PackageTable')]
|
|
||||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
[OfficeOpenXml.Table.TableStyles]$TableStyle,
|
||||||
[Switch]$Barchart,
|
[Switch]$Barchart,
|
||||||
[Switch]$PieChart,
|
[Switch]$PieChart,
|
||||||
[Switch]$LineChart ,
|
[Switch]$LineChart ,
|
||||||
@@ -472,12 +508,12 @@
|
|||||||
[Object[]]$ConditionalFormat,
|
[Object[]]$ConditionalFormat,
|
||||||
[Object[]]$ConditionalText,
|
[Object[]]$ConditionalText,
|
||||||
[ScriptBlock]$CellStyleSB,
|
[ScriptBlock]$CellStyleSB,
|
||||||
#If there is already content in the workbook the sheet with the Pivot table will not be active UNLESS Activate is specified
|
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
|
||||||
[switch]$Activate,
|
[switch]$Activate,
|
||||||
[Parameter(ParameterSetName = 'Now')]
|
[Parameter(ParameterSetName = 'Now')]
|
||||||
[Switch]$Now,
|
[Switch]$Now,
|
||||||
[Switch]$ReturnRange,
|
[Switch]$ReturnRange,
|
||||||
#By default Pivot tables have Totals for each Row (on the right) and for each column at the bottom. This allows just one or neither to be selected.
|
#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.
|
||||||
[ValidateSet("Both","Columns","Rows","None")]
|
[ValidateSet("Both","Columns","Rows","None")]
|
||||||
[String]$PivotTotals = "Both",
|
[String]$PivotTotals = "Both",
|
||||||
#Included for compatibility - equivalent to -PivotTotals "None"
|
#Included for compatibility - equivalent to -PivotTotals "None"
|
||||||
@@ -485,109 +521,22 @@
|
|||||||
[Switch]$ReZip
|
[Switch]$ReZip
|
||||||
)
|
)
|
||||||
|
|
||||||
Begin {
|
begin {
|
||||||
$numberRegex = [Regex]'\d'
|
$numberRegex = [Regex]'\d'
|
||||||
function Add-CellValue {
|
$isDataTypeValueType = $false
|
||||||
<#
|
if ($NoClobber) {Write-Warning -Message "-NoClobber parameter is no longer used" }
|
||||||
.SYNOPSIS
|
#Open the file, get the worksheet, and decide where in the sheet we are writing, and if there is a number format to apply.
|
||||||
Save a value in an Excel cell.
|
try {
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
DateTime objects are always converted to a short DateTime format in Excel. When Excel loads the file,
|
|
||||||
it applies the local format for dates. And formulas are always saved as formulas. URIs are set as hyperlinks in the file.
|
|
||||||
|
|
||||||
Numerical values will be converted to numbers as defined in the regional settings of the local
|
|
||||||
system. In case the parameter 'NoNumberConversion' is used, we don't convert to number and leave
|
|
||||||
the value 'as is'. In case of conversion failure, we also leave the value 'as is'.
|
|
||||||
#>
|
|
||||||
|
|
||||||
Param (
|
|
||||||
$TargetCell,
|
|
||||||
$CellValue
|
|
||||||
)
|
|
||||||
#The write-verbose commands have been commented out below - even if verbose is silenced they cause a significiant performance impact and if it's on they will cause a flood of messages.
|
|
||||||
Switch ($CellValue) {
|
|
||||||
{ $_ -is [DateTime]} {
|
|
||||||
# Save a date with one of Excel's built in formats format
|
|
||||||
$TargetCell.Value = $_
|
|
||||||
$TargetCell.Style.Numberformat.Format = 'm/d/yy h:mm' # This is not a custom format, but a preset recognized as date and localized.
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$_' as date"
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
{ $_ -is [TimeSpan]} {
|
|
||||||
#Save a timespans with a built in format for elapsed hours, minutes and seconds
|
|
||||||
$TargetCell.Value = $_
|
|
||||||
$TargetCell.Style.Numberformat.Format = '[h]:mm:ss'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
{ $_ -is [System.ValueType]} {
|
|
||||||
# Save numerics, setting format if need be.
|
|
||||||
$TargetCell.Value = $_
|
|
||||||
if ($setNumformat) {$targetCell.Style.Numberformat.Format = $Numberformat }
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$_' as value"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
{($_ -is [String]) -and ($_[0] -eq '=')} {
|
|
||||||
#region Save an Excel formula - we need = to spot the formula but the EPPLUS won't like it if we include it (Excel doesn't care if is there or not)
|
|
||||||
$TargetCell.Formula = ($_ -replace '^=','')
|
|
||||||
if ($setNumformat) {$targetCell.Style.Numberformat.Format = $Numberformat }
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$_' as formula"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
{ [System.Uri]::IsWellFormedUriString($_ , [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 ($_ -is [uri]) {$targetCell.HyperLink = $_ }
|
|
||||||
elseif ($_ -match "^xl://internal/") {
|
|
||||||
$referenceAddress = $_ -replace "^xl://internal/" , ""
|
|
||||||
$display = $referenceAddress -replace "!A1$" , ""
|
|
||||||
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
|
||||||
$TargetCell.HyperLink = $h
|
|
||||||
}
|
|
||||||
else {$TargetCell.HyperLink = $_ } #$TargetCell.Value = $_.AbsoluteUri
|
|
||||||
$TargetCell.Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
|
||||||
$TargetCell.Style.Font.UnderLine = $true
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$($_.AbsoluteUri)' as Hyperlink"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
{( $NoNumberConversion -and (
|
|
||||||
($NoNumberConversion -contains $Name) -or ($NoNumberConversion -eq '*'))) } {
|
|
||||||
#Save text without it to converting to number
|
|
||||||
$TargetCell.Value = $_
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$($TargetCell.Value)' unconverted"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
Default {
|
|
||||||
#Save a value as a number if possible
|
|
||||||
$number = $null
|
|
||||||
if ($numberRegex.IsMatch($_) -and [Double]::TryParse($_, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number)) {
|
|
||||||
# as simpler version using [Double]::TryParse( $_ , [ref]$number)) was found to cause problems reverted back to the longer version
|
|
||||||
$TargetCell.Value = $number
|
|
||||||
if ($setNumformat) {$targetCell.Style.Numberformat.Format = $Numberformat }
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$($TargetCell.Value)' as number converted from '$_' with format '$Numberformat'"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$TargetCell.Value = $_
|
|
||||||
#Write-Verbose "Cell '$Row`:$ColumnIndex' header '$Name' add value '$($TargetCell.Value)' as string"
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$script:Header = $null
|
$script:Header = $null
|
||||||
if ($Append -and $ClearSheet) {throw "You can't use -Append AND -ClearSheet."}
|
if ($Append -and $ClearSheet) {throw "You can't use -Append AND -ClearSheet."}
|
||||||
|
if ($PSBoundParameters.Keys.Count -eq 0 -Or $Now -or (-not $Path -and -not $ExcelPackage) ) {
|
||||||
if ($PSBoundParameters.Keys.Count -eq 0 -Or $Now) {
|
|
||||||
$Path = [System.IO.Path]::GetTempFileName() -replace '\.tmp', '.xlsx'
|
$Path = [System.IO.Path]::GetTempFileName() -replace '\.tmp', '.xlsx'
|
||||||
$Show = $true
|
$Show = $true
|
||||||
$AutoSize = $true
|
$AutoSize = $true
|
||||||
if (!$TableName) {
|
if (-not $TableName) {
|
||||||
$AutoFilter = $true
|
$AutoFilter = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ExcelPackage) {
|
if ($ExcelPackage) {
|
||||||
$pkg = $ExcelPackage
|
$pkg = $ExcelPackage
|
||||||
$Path = $pkg.File
|
$Path = $pkg.File
|
||||||
@@ -595,8 +544,7 @@
|
|||||||
Else { $pkg = Open-ExcelPackage -Path $Path -Create -KillExcel:$KillExcel -Password:$Password}
|
Else { $pkg = Open-ExcelPackage -Path $Path -Create -KillExcel:$KillExcel -Password:$Password}
|
||||||
}
|
}
|
||||||
catch {throw "Could not open Excel Package $path"}
|
catch {throw "Could not open Excel Package $path"}
|
||||||
if ($NoClobber) {Write-Warning -Message "-NoClobber parameter is no longer used" }
|
try {
|
||||||
try {
|
|
||||||
$params = @{WorksheetName=$WorksheetName}
|
$params = @{WorksheetName=$WorksheetName}
|
||||||
foreach ($p in @("ClearSheet", "MoveToStart", "MoveToEnd", "MoveBefore", "MoveAfter", "Activate")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
foreach ($p in @("ClearSheet", "MoveToStart", "MoveToEnd", "MoveBefore", "MoveAfter", "Activate")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
||||||
$ws = $pkg | Add-WorkSheet @params
|
$ws = $pkg | Add-WorkSheet @params
|
||||||
@@ -606,7 +554,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {throw "Could not get worksheet $worksheetname"}
|
catch {throw "Could not get worksheet $worksheetname"}
|
||||||
try {
|
try {
|
||||||
if ($Append -and $ws.Dimension) {
|
if ($Append -and $ws.Dimension) {
|
||||||
#if there is a title or anything else above the header row, append needs to be combined wih a suitable startrow parameter
|
#if there is a title or anything else above the header row, append needs to be combined wih a suitable startrow parameter
|
||||||
$headerRange = $ws.Dimension.Address -replace "\d+$", $StartRow
|
$headerRange = $ws.Dimension.Address -replace "\d+$", $StartRow
|
||||||
@@ -642,6 +590,7 @@
|
|||||||
|
|
||||||
$row = $ws.Dimension.End.Row
|
$row = $ws.Dimension.End.Row
|
||||||
Write-Debug -Message ("Appending: headers are " + ($script:Header -join ", ") + " Start row is $row")
|
Write-Debug -Message ("Appending: headers are " + ($script:Header -join ", ") + " Start row is $row")
|
||||||
|
if ($Title) {Write-Warning -Message "-Title Parameter is ignored when appending."}
|
||||||
}
|
}
|
||||||
elseif ($Title) {
|
elseif ($Title) {
|
||||||
#Can only add a title if not appending!
|
#Can only add a title if not appending!
|
||||||
@@ -649,12 +598,13 @@
|
|||||||
$ws.Cells[$Row, $StartColumn].Value = $Title
|
$ws.Cells[$Row, $StartColumn].Value = $Title
|
||||||
$ws.Cells[$Row, $StartColumn].Style.Font.Size = $TitleSize
|
$ws.Cells[$Row, $StartColumn].Style.Font.Size = $TitleSize
|
||||||
|
|
||||||
if ($TitleBold) {
|
if ($PSBoundParameters.ContainsKey("TitleBold")) {
|
||||||
#Set title to Bold face font if -TitleBold was specified.
|
#Set title to Bold face font if -TitleBold was specified.
|
||||||
#Otherwise the default will be unbolded.
|
#Otherwise the default will be unbolded.
|
||||||
$ws.Cells[$Row, $StartColumn].Style.Font.Bold = $True
|
$ws.Cells[$Row, $StartColumn].Style.Font.Bold = [boolean]$TitleBold
|
||||||
}
|
}
|
||||||
if ($TitleBackgroundColor ) {
|
if ($TitleBackgroundColor ) {
|
||||||
|
if ($TitleBackgroundColor -is [string]) {$TitleBackgroundColor = [System.Drawing.Color]::$TitleBackgroundColor }
|
||||||
$ws.Cells[$Row, $StartColumn].Style.Fill.PatternType = $TitleFillPattern
|
$ws.Cells[$Row, $StartColumn].Style.Fill.PatternType = $TitleFillPattern
|
||||||
$ws.Cells[$Row, $StartColumn].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
|
$ws.Cells[$Row, $StartColumn].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
|
||||||
}
|
}
|
||||||
@@ -668,81 +618,144 @@
|
|||||||
$setNumformat = $false
|
$setNumformat = $false
|
||||||
}
|
}
|
||||||
else { $setNumformat = ($Numberformat -ne $ws.Cells.Style.Numberformat.Format) }
|
else { $setNumformat = ($Numberformat -ne $ws.Cells.Style.Numberformat.Format) }
|
||||||
|
}
|
||||||
$firstTimeThru = $true
|
catch {throw "Failed preparing to export to worksheet '$WorksheetName' to '$Path': $_"}
|
||||||
$isDataTypeValueType = $false
|
#region Special case -inputobject passed a dataTable object
|
||||||
}
|
<# If inputObject was passed via the pipeline it won't be visible until the process block, we will only see it here if it was passed as a parameter
|
||||||
catch {
|
if it was passed it is a data table don't do foreach on it (slow) put the whole table in and set dates on date columns,
|
||||||
if ($AlreadyExists) {
|
set things up for the end block, and skip the process block #>
|
||||||
#Is this set anywhere ?
|
if ($InputObject -is [System.Data.DataTable]) {
|
||||||
throw "Failed exporting worksheet '$WorksheetName' to '$Path': The worksheet '$WorksheetName' already exists."
|
$null = $ws.Cells[$row,$StartColumn].LoadFromDataTable($InputObject, (-not $noHeader) )
|
||||||
|
foreach ($c in $InputObject.Columns.where({$_.datatype -eq [datetime]})) {
|
||||||
|
Set-ExcelColumn -Worksheet $ws -Column ($c.Ordinal + $StartColumn) -NumberFormat 'Date-Time'
|
||||||
}
|
}
|
||||||
else {
|
foreach ($c in $InputObject.Columns.where({$_.datatype -eq [timespan]})) {
|
||||||
throw "Failed preparing to export to worksheet '$WorksheetName' to '$Path': $_"
|
Set-ExcelColumn -Worksheet $ws -Column ($c.Ordinal + $StartColumn) -NumberFormat '[h]:mm:ss'
|
||||||
}
|
}
|
||||||
}
|
$ColumnIndex += $InputObject.Columns.Count - 1
|
||||||
|
if ($noHeader) {$row += $InputObject.Rows.Count -1 }
|
||||||
|
else {$row += $InputObject.Rows.Count }
|
||||||
|
$null = $PSBoundParameters.Remove('InputObject')
|
||||||
|
$firstTimeThru = $false
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
else {$firstTimeThru = $true}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
process { if ($PSBoundParameters.ContainsKey("InputObject")) {
|
||||||
if ($PSBoundParameters.ContainsKey("TargetData")) {
|
try {
|
||||||
try {
|
if ($null -eq $InputObject) {$row += 1}
|
||||||
|
foreach ($TargetData in $InputObject) {
|
||||||
if ($firstTimeThru) {
|
if ($firstTimeThru) {
|
||||||
$firstTimeThru = $false
|
$firstTimeThru = $false
|
||||||
$isDataTypeValueType = ($null -eq $TargetData) -or ($TargetData.GetType().name -match 'string|timespan|datetime|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ulong|ushort|URI|ExcelHyperLink')
|
$isDataTypeValueType = ($null -eq $TargetData) -or ($TargetData.GetType().name -match 'string|timespan|datetime|bool|byte|char|decimal|double|float|int|long|sbyte|short|uint|ulong|ushort|URI|ExcelHyperLink')
|
||||||
if ($isDataTypeValueType -and -not $Append) {$row -= 1} #row incremented before adding values, so it is set to the number of rows inserted at the end
|
if ($isDataTypeValueType ) {
|
||||||
if ($null -ne $TargetData) {Write-Debug "DataTypeName is '$($TargetData.GetType().name)' isDataTypeValueType '$isDataTypeValueType'" }
|
$script:Header = @(".") # dummy value to make sure we go through the "for each name in $header"
|
||||||
|
if (-not $Append) {$row -= 1} # By default row will be 1, it is incremented before inserting values (so it ends pointing at final row.); si first data row is 2 - move back up 1 if there is no header .
|
||||||
|
}
|
||||||
|
if ($null -ne $TargetData) {Write-Debug "DataTypeName is '$($TargetData.GetType().name)' isDataTypeValueType '$isDataTypeValueType'" }
|
||||||
}
|
}
|
||||||
if ($isDataTypeValueType) {
|
#region Add headers - if we are appending, or we have been through here once already we will have the headers
|
||||||
$ColumnIndex = $StartColumn
|
if (-not $script:Header) {
|
||||||
$Row += 1
|
if ($DisplayPropertySet -and $TargetData.psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames) {
|
||||||
try {Add-CellValue -TargetCell $ws.Cells[$Row, $ColumnIndex] -CellValue $TargetData}
|
$script:Header = $TargetData.psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames.Where( {$_ -notin $ExcludeProperty})
|
||||||
catch {Write-Warning "Could not insert value at Row $Row. "}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
if ($NoAliasOrScriptPropeties) {$propType = "Property"} else {$propType = "*"}
|
||||||
#region Add headers - if we are appending, or we have been through here once already we will have the headers
|
$script:Header = $TargetData.PSObject.Properties.where( {$_.MemberType -like $propType}).Name
|
||||||
if (-not $script:Header) {
|
}
|
||||||
|
foreach ($exclusion in $ExcludeProperty) {$script:Header = $script:Header -notlike $exclusion}
|
||||||
|
if ($NoHeader) {
|
||||||
|
# Don't push the headers to the spreadsheet
|
||||||
|
$Row -= 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
$ColumnIndex = $StartColumn
|
$ColumnIndex = $StartColumn
|
||||||
if ($DisplayPropertySet -and $TargetData.psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames) {
|
foreach ($Name in $script:Header) {
|
||||||
$script:Header = $TargetData.psStandardmembers.DefaultDisplayPropertySet.ReferencedPropertyNames.Where( {$_ -notin $ExcludeProperty})
|
$ws.Cells[$Row, $ColumnIndex].Value = $Name
|
||||||
}
|
Write-Verbose "Cell '$Row`:$ColumnIndex' add header '$Name'"
|
||||||
else {
|
$ColumnIndex += 1
|
||||||
if ($NoAliasOrScriptPropeties) {$propType = "Property"} else {$propType = "*"}
|
|
||||||
$script:Header = $TargetData.PSObject.Properties.where( {$_.MemberType -like $propType}).Name
|
|
||||||
}
|
|
||||||
foreach ($exclusion in $ExcludeProperty) {$script:Header = $script:Header -notlike $exclusion}
|
|
||||||
if ($NoHeader) {
|
|
||||||
# Don't push the headers to the spreadsheet
|
|
||||||
$Row -= 1
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foreach ($Name in $script:Header) {
|
|
||||||
$ws.Cells[$Row, $ColumnIndex].Value = $Name
|
|
||||||
Write-Verbose "Cell '$Row`:$ColumnIndex' add header '$Name'"
|
|
||||||
$ColumnIndex += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
#region Add non header values
|
|
||||||
$Row += 1
|
|
||||||
$ColumnIndex = $StartColumn
|
|
||||||
|
|
||||||
foreach ($Name in $script:Header) {
|
|
||||||
try {Add-CellValue -TargetCell $ws.Cells[$Row, $ColumnIndex] -CellValue $TargetData.$Name}
|
|
||||||
catch {Write-Warning -Message "Could not insert the $Name property at Row $Row, Column $Column"}
|
|
||||||
$ColumnIndex += 1
|
|
||||||
}
|
|
||||||
$ColumnIndex -= 1 # column index will be the last column whether isDataTypeValueType was true or false
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
#endregion
|
||||||
catch {
|
#region Add non header values
|
||||||
throw "Failed exporting data to worksheet '$WorksheetName' to '$Path': $_"
|
$Row += 1
|
||||||
|
$ColumnIndex = $StartColumn
|
||||||
|
<#
|
||||||
|
For each item in the header OR for the Data item if this is a simple Type or data table :
|
||||||
|
If it is a date insert with one of Excel's built in formats - recognized as "Date and time to be localized"
|
||||||
|
if it is a timespan insert with a built in format for elapsed hours, minutes and seconds
|
||||||
|
if its any other numeric insert as is , setting format if need be.
|
||||||
|
Preserve URI, Insert a data table, convert non string objects to string.
|
||||||
|
For strings, check for fomula, URI or Number, before inserting as a string (ignore nulls) #>
|
||||||
|
foreach ($Name in $script:Header) {
|
||||||
|
if ($isDataTypeValueType) {$v = $TargetData}
|
||||||
|
else {$v = $TargetData.$Name}
|
||||||
|
try {
|
||||||
|
if ($v -is [DateTime]) {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Value = $v
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Numberformat.Format = 'm/d/yy h:mm' # This is not a custom format, but a preset recognized as date and localized.
|
||||||
|
}
|
||||||
|
elseif ($v -is [TimeSpan]) {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Value = $v
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Numberformat.Format = '[h]:mm:ss'
|
||||||
|
}
|
||||||
|
elseif ($v -is [System.ValueType]) {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Value = $v
|
||||||
|
if ($setNumformat) {$ws.Cells[$Row, $ColumnIndex].Style.Numberformat.Format = $Numberformat }
|
||||||
|
}
|
||||||
|
elseif ($v -is [uri] ) {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].HyperLink = $v
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Font.UnderLine = $true
|
||||||
|
}
|
||||||
|
elseif ($v -isnot [String] ) { #Other objects or null.
|
||||||
|
if ($null -ne $v) { $ws.Cells[$Row, $ColumnIndex].Value = $v.toString()}
|
||||||
|
}
|
||||||
|
elseif ($v[0] -eq '=') {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Formula = ($v -replace '^=','')
|
||||||
|
if ($setNumformat) {$ws.Cells[$Row, $ColumnIndex].Style.Numberformat.Format = $Numberformat }
|
||||||
|
}
|
||||||
|
elseif ( [System.Uri]::IsWellFormedUriString($v , [System.UriKind]::Absolute) ) {
|
||||||
|
if ($v -match "^xl://internal/") {
|
||||||
|
$referenceAddress = $v -replace "^xl://internal/" , ""
|
||||||
|
$display = $referenceAddress -replace "!A1$" , ""
|
||||||
|
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].HyperLink = $h
|
||||||
|
}
|
||||||
|
else {$ws.Cells[$Row, $ColumnIndex].HyperLink = $v } #$ws.Cells[$Row, $ColumnIndex].Value = $v.AbsoluteUri
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Style.Font.UnderLine = $true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$number = $null
|
||||||
|
if ( $numberRegex.IsMatch($v) -and # if it contains digit(s) - this syntax is quicker than -match for many items and cuts out slow checks for non numbers
|
||||||
|
$NoNumberConversion -ne '*' -and # and NoNumberConversion isn't specified
|
||||||
|
$NoNumberConversion -notcontains $Name -and
|
||||||
|
[Double]::TryParse($v, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number)
|
||||||
|
) {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Value = $number
|
||||||
|
if ($setNumformat) {$ws.Cells[$Row, $ColumnIndex].Style.Numberformat.Format = $Numberformat }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$ws.Cells[$Row, $ColumnIndex].Value = $v
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {Write-Warning -Message "Could not insert the '$Name' property at Row $Row, Column $ColumnIndex"}
|
||||||
|
$ColumnIndex += 1
|
||||||
|
}
|
||||||
|
$ColumnIndex -= 1 # column index will be the last column whether isDataTypeValueType was true or false
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch {throw "Failed exporting data to worksheet '$WorksheetName' to '$Path': $_" }
|
||||||
|
|
||||||
End {
|
}}
|
||||||
|
|
||||||
|
end {
|
||||||
if ($firstTimeThru -and $ws.Dimension) {
|
if ($firstTimeThru -and $ws.Dimension) {
|
||||||
$LastRow = $ws.Dimension.End.Row
|
$LastRow = $ws.Dimension.End.Row
|
||||||
$LastCol = $ws.Dimension.End.Column
|
$LastCol = $ws.Dimension.End.Column
|
||||||
@@ -776,27 +789,34 @@
|
|||||||
# if we have 5 columns from 3 to 8, headers are numbered 0..4, so that is in the for loop and used for getting the name...
|
# if we have 5 columns from 3 to 8, headers are numbered 0..4, so that is in the for loop and used for getting the name...
|
||||||
# but we have to add the start column on when referencing positions
|
# but we have to add the start column on when referencing positions
|
||||||
foreach ($c in 0..($LastCol - $StartColumn)) {
|
foreach ($c in 0..($LastCol - $StartColumn)) {
|
||||||
$targetRangeName = $script:Header[$c] #Let Add-ExcelName fix (and warn about) bad names
|
$targetRangeName = @($script:Header)[$c] #Let Add-ExcelName fix (and warn about) bad names
|
||||||
Add-ExcelName -RangeName $targetRangeName -Range $ws.Cells[$targetRow, ($StartColumn + $c ), $LastRow, ($StartColumn + $c )]
|
Add-ExcelName -RangeName $targetRangeName -Range $ws.Cells[$targetRow, ($StartColumn + $c ), $LastRow, ($StartColumn + $c )]
|
||||||
try {#this test can throw with some names, surpress any error
|
try {#this test can throw with some names, surpress any error
|
||||||
if ([OfficeOpenXml.FormulaParsing.ExcelUtilities.ExcelAddressUtil]::IsValidAddress(($targetRangeName -replace '\W' , '_' ))) {
|
if ([OfficeOpenXml.FormulaParsing.ExcelUtilities.ExcelAddressUtil]::IsValidAddress(($targetRangeName -replace '\W' , '_' ))) {
|
||||||
Write-Warning "AutoNameRange: Property name '$targetRangeName' is also a valid Excel address and may cause issues. Consider renaming the property name."
|
Write-Warning -Message "AutoNameRange: Property name '$targetRangeName' is also a valid Excel address and may cause issues. Consider renaming the property."
|
||||||
}
|
}
|
||||||
} Catch {}
|
}
|
||||||
|
Catch {
|
||||||
|
Write-Warning -Message "AutoNameRange: Testing '$targetRangeName' caused an error. This should be harmless, but a change of property name may be needed.."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Failed adding named ranges to worksheet '$WorksheetName': $_" }
|
catch {Write-Warning -Message "Failed adding named ranges to worksheet '$WorksheetName': $_" }
|
||||||
}
|
}
|
||||||
|
#Empty string is not allowed as a name for ranges or tables.
|
||||||
if ($RangeName) { Add-ExcelName -Range $ws.Cells[$dataRange] -RangeName $RangeName}
|
if ($RangeName) { Add-ExcelName -Range $ws.Cells[$dataRange] -RangeName $RangeName}
|
||||||
|
|
||||||
if ($TableName) {
|
#Allow table to be inserted by specifying Name, or Style or both; only process autoFilter if there is no table (they clash).
|
||||||
|
if ($TableName) {
|
||||||
if ($PSBoundParameters.ContainsKey('TableStyle')) {
|
if ($PSBoundParameters.ContainsKey('TableStyle')) {
|
||||||
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
|
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
|
||||||
}
|
}
|
||||||
else {Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName}
|
else {Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName}
|
||||||
}
|
}
|
||||||
|
elseif ($PSBoundParameters.ContainsKey('TableStyle')) {
|
||||||
if ($AutoFilter) {
|
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName "" -TableStyle $TableStyle
|
||||||
|
}
|
||||||
|
elseif ($AutoFilter) {
|
||||||
try {
|
try {
|
||||||
$ws.Cells[$dataRange].AutoFilter = $true
|
$ws.Cells[$dataRange].AutoFilter = $true
|
||||||
Write-Verbose -Message "Enabled autofilter. "
|
Write-Verbose -Message "Enabled autofilter. "
|
||||||
@@ -823,7 +843,7 @@
|
|||||||
'SourceRange' = $dataRange
|
'SourceRange' = $dataRange
|
||||||
}
|
}
|
||||||
if ($PivotTableName -and ($pkg.workbook.worksheets.tables.name -contains $PivotTableName)) {
|
if ($PivotTableName -and ($pkg.workbook.worksheets.tables.name -contains $PivotTableName)) {
|
||||||
Write-Warning -Message "The selected Pivot table name '$PivotTableName' is already used as a table name. Adding a suffix of 'Pivot'."
|
Write-Warning -Message "The selected PivotTable name '$PivotTableName' is already used as a table name. Adding a suffix of 'Pivot'."
|
||||||
$PivotTableName += 'Pivot'
|
$PivotTableName += 'Pivot'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,22 +881,22 @@
|
|||||||
$ws.View.FreezePanes(1, 2)
|
$ws.View.FreezePanes(1, 2)
|
||||||
Write-Verbose -Message "Froze first column"
|
Write-Verbose -Message "Froze first column"
|
||||||
}
|
}
|
||||||
|
#Must be 1..maxrows or and array of 1..maxRows,1..MaxCols
|
||||||
if ($FreezePane) {
|
if ($FreezePane) {
|
||||||
$freezeRow, $freezeColumn = $FreezePane
|
$freezeRow, $freezeColumn = $FreezePane
|
||||||
if (-not $freezeColumn -or $freezeColumn -eq 0) {
|
if (-not $freezeColumn -or $freezeColumn -eq 0) {
|
||||||
$freezeColumn = 1
|
$freezeColumn = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($freezeRow -gt 1) {
|
if ($freezeRow -ge 1) {
|
||||||
$ws.View.FreezePanes($freezeRow, $freezeColumn)
|
$ws.View.FreezePanes($freezeRow, $freezeColumn)
|
||||||
Write-Verbose -Message "Froze pandes at row $freezeRow and column $FreezeColumn"
|
Write-Verbose -Message "Froze panes at row $freezeRow and column $FreezeColumn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Failed adding Freezing the panes in worksheet '$WorksheetName': $_"}
|
catch {Write-Warning -Message "Failed adding Freezing the panes in worksheet '$WorksheetName': $_"}
|
||||||
|
|
||||||
if ($BoldTopRow) { #it sets bold as far as there are populated cells: for whole row could do $ws.row($x).style.font.bold = $true
|
if ($PSBoundParameters.ContainsKey("BoldTopRow")) { #it sets bold as far as there are populated cells: for whole row could do $ws.row($x).style.font.bold = $true
|
||||||
try {
|
try {
|
||||||
if ($Title) {
|
if ($Title) {
|
||||||
$range = $ws.Dimension.Address -replace '\d+', ($StartRow + 1)
|
$range = $ws.Dimension.Address -replace '\d+', ($StartRow + 1)
|
||||||
@@ -884,14 +904,19 @@
|
|||||||
else {
|
else {
|
||||||
$range = $ws.Dimension.Address -replace '\d+', $StartRow
|
$range = $ws.Dimension.Address -replace '\d+', $StartRow
|
||||||
}
|
}
|
||||||
$ws.Cells[$range].Style.Font.Bold = $true
|
$ws.Cells[$range].Style.Font.Bold = [boolean]$BoldTopRow
|
||||||
Write-Verbose -Message "Set $range font style to bold."
|
Write-Verbose -Message "Set $range font style to bold."
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Failed setting the top row to bold in worksheet '$WorksheetName': $_"}
|
catch {Write-Warning -Message "Failed setting the top row to bold in worksheet '$WorksheetName': $_"}
|
||||||
}
|
}
|
||||||
if ($AutoSize) {
|
if ($AutoSize) {
|
||||||
try {
|
try {
|
||||||
$ws.Cells.AutoFitColumns()
|
#Don't fit the all the columns in the sheet; if we are adding cells beside things with hidden columns, that unhides them
|
||||||
|
if ($MaxAutoSizeRows -and $MaxAutoSizeRows -lt $LastRow ) {
|
||||||
|
$AutosizeRange = [OfficeOpenXml.ExcelAddress]::GetAddress($startRow,$StartColumn, $MaxAutoSizeRows , $LastCol)
|
||||||
|
$ws.Cells[$AutosizeRange].AutoFitColumns()
|
||||||
|
}
|
||||||
|
else {$ws.Cells[$dataRange].AutoFitColumns() }
|
||||||
Write-Verbose -Message "Auto-sized columns"
|
Write-Verbose -Message "Auto-sized columns"
|
||||||
}
|
}
|
||||||
catch { Write-Warning -Message "Failed autosizing columns of worksheet '$WorksheetName': $_"}
|
catch { Write-Warning -Message "Failed autosizing columns of worksheet '$WorksheetName': $_"}
|
||||||
@@ -991,7 +1016,7 @@
|
|||||||
Write-Verbose -Message "Added conditional formatting to range $($c.range)"
|
Write-Verbose -Message "Added conditional formatting to range $($c.range)"
|
||||||
}
|
}
|
||||||
elseif ($c -is [hashtable] -or $c -is[System.Collections.Specialized.OrderedDictionary]) {
|
elseif ($c -is [hashtable] -or $c -is[System.Collections.Specialized.OrderedDictionary]) {
|
||||||
if (-not $c.Range) {$c.Range = $ws.Dimension.Address }
|
if (-not $c.Range -or $c.Address) {$c.Address = $ws.Dimension.Address }
|
||||||
Add-ConditionalFormatting -WorkSheet $ws @c
|
Add-ConditionalFormatting -WorkSheet $ws @c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1007,6 +1032,7 @@
|
|||||||
catch {Write-Warning -Message "Failed processing CellStyleSB in worksheet '$WorksheetName': $_"}
|
catch {Write-Warning -Message "Failed processing CellStyleSB in worksheet '$WorksheetName': $_"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Can only add password, may want to support -password $Null removing password.
|
||||||
if ($Password) {
|
if ($Password) {
|
||||||
try {
|
try {
|
||||||
$ws.Protection.SetPassword($Password)
|
$ws.Protection.SetPassword($Password)
|
||||||
@@ -1034,9 +1060,9 @@
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$TempZipPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
|
$TempZipPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
|
||||||
[io.compression.zipfile]::ExtractToDirectory($pkg.File, $TempZipPath) | Out-Null
|
$null = [io.compression.zipfile]::ExtractToDirectory($pkg.File, $TempZipPath)
|
||||||
Remove-Item $pkg.File -Force
|
Remove-Item $pkg.File -Force
|
||||||
[io.compression.zipfile]::CreateFromDirectory($TempZipPath, $pkg.File) | Out-Null
|
$null = [io.compression.zipfile]::CreateFromDirectory($TempZipPath, $pkg.File)
|
||||||
}
|
}
|
||||||
catch {throw "Error resizipping $path : $_"}
|
catch {throw "Error resizipping $path : $_"}
|
||||||
}
|
}
|
||||||
@@ -1052,7 +1078,7 @@
|
|||||||
function Add-WorkSheet {
|
function Add-WorkSheet {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Adds a workshet to an existing workbook.
|
Adds a worksheet to an existing workbook.
|
||||||
.Description
|
.Description
|
||||||
If the named worksheet already exists, the -Clearsheet parameter decides whether it should be deleted and a new one returned,
|
If the named worksheet already exists, the -Clearsheet parameter decides whether it should be deleted and a new one returned,
|
||||||
or if not specified the existing sheet will be returned. By default the sheet is created at the end of the work book, the
|
or if not specified the existing sheet will be returned. By default the sheet is created at the end of the work book, the
|
||||||
@@ -1173,7 +1199,7 @@ function Select-Worksheet {
|
|||||||
Sets the selected tab in an Excel workbook to be the chosen sheet and unselects all the others.
|
Sets the selected tab in an Excel workbook to be the chosen sheet and unselects all the others.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Sometimes when a sheet is added we want it to be the active sheet, sometimes we want the active sheet to be left as it was.
|
Sometimes when a sheet is added we want it to be the active sheet, sometimes we want the active sheet to be left as it was.
|
||||||
Select-Worksheet exists to change the which sheet is the selected tab when Excel opens the file.
|
Select-Worksheet exists to change which sheet is the selected tab when Excel opens the file.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Select-Worksheet -ExcelWorkbook $ExcelWorkbook -WorksheetName "NewSheet"
|
Select-Worksheet -ExcelWorkbook $ExcelWorkbook -WorksheetName "NewSheet"
|
||||||
$ExcelWorkbook holds a workbook object containing a sheet named "NewSheet";
|
$ExcelWorkbook holds a workbook object containing a sheet named "NewSheet";
|
||||||
@@ -1184,10 +1210,11 @@ function Select-Worksheet {
|
|||||||
This sheet will become the [only] active sheet in the workbook.
|
This sheet will become the [only] active sheet in the workbook.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Select-Worksheet -ExcelWorksheet $ws
|
Select-Worksheet -ExcelWorksheet $ws
|
||||||
$ws holds an Excel worksheet which will become the [only] active sheet in the workbook.
|
$ws holds an Excel worksheet which will become the [only] active sheet
|
||||||
|
in its workbook.
|
||||||
#>
|
#>
|
||||||
param (
|
param (
|
||||||
#An object representing an Excel Package.
|
#An object representing an ExcelPackage.
|
||||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Package', Position = 0)]
|
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Package', Position = 0)]
|
||||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||||
#An Excel workbook to which the Worksheet will be added - a package contains one Workbook so you can use workbook or package as it suits.
|
#An Excel workbook to which the Worksheet will be added - a package contains one Workbook so you can use workbook or package as it suits.
|
||||||
@@ -1195,7 +1222,7 @@ function Select-Worksheet {
|
|||||||
[OfficeOpenXml.ExcelWorkbook]$ExcelWorkbook,
|
[OfficeOpenXml.ExcelWorkbook]$ExcelWorkbook,
|
||||||
[Parameter(ParameterSetName='Package')]
|
[Parameter(ParameterSetName='Package')]
|
||||||
[Parameter(ParameterSetName='Workbook')]
|
[Parameter(ParameterSetName='Workbook')]
|
||||||
#The name of the worksheet 'Sheet1' by default.
|
#The name of the worksheet "Sheet1" by default.
|
||||||
[string]$WorksheetName,
|
[string]$WorksheetName,
|
||||||
#An object representing an Excel worksheet.
|
#An object representing an Excel worksheet.
|
||||||
[Parameter(ParameterSetName='Sheet',Mandatory=$true)]
|
[Parameter(ParameterSetName='Sheet',Mandatory=$true)]
|
||||||
@@ -1214,7 +1241,7 @@ function Select-Worksheet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Add-ExcelName {
|
function Add-ExcelName {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Adds a named-range to an existing Excel worksheet.
|
Adds a named-range to an existing Excel worksheet.
|
||||||
@@ -1249,7 +1276,7 @@ Function Add-ExcelName {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-verbose -Message "Creating Named range '$RangeName' as $($Range.FullAddressAbsolute)."
|
Write-verbose -Message "Creating Named range '$RangeName' as $($Range.FullAddressAbsolute)."
|
||||||
$ws.Names.Add($RangeName, $Range) | Out-Null
|
$null = $ws.Names.Add($RangeName, $Range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Failed adding named range '$RangeName' to worksheet '$($ws.Name)': $_" }
|
catch {Write-Warning -Message "Failed adding named range '$RangeName' to worksheet '$($ws.Name)': $_" }
|
||||||
@@ -1278,9 +1305,8 @@ function Add-ExcelTable {
|
|||||||
#The range of cells to assign to a table.
|
#The range of cells to assign to a table.
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[OfficeOpenXml.ExcelRange]$Range,
|
[OfficeOpenXml.ExcelRange]$Range,
|
||||||
#The name for the Table - this should be unqiue in the Workbook.
|
#The name for the Table - this should be unqiue in the Workbook - auto generated names will be used if this is left empty.
|
||||||
[Parameter(Mandatory=$true)]
|
[String]$TableName = "",
|
||||||
[String]$TableName,
|
|
||||||
#The Style for the table, by default "Medium6" is used
|
#The Style for the table, by default "Medium6" is used
|
||||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
||||||
#By default the header row is shown - it can be turned off with -ShowHeader:$false.
|
#By default the header row is shown - it can be turned off with -ShowHeader:$false.
|
||||||
@@ -1303,24 +1329,37 @@ function Add-ExcelTable {
|
|||||||
[Switch]$PassThru
|
[Switch]$PassThru
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
if ($TableName -match "\W") {
|
if ($TableName -eq "" -or $null -eq $TableName) {
|
||||||
Write-Warning -Message "At least one character in $TableName is illegal in a table name and will be replaced with '_' . "
|
$tbl = $Range.Worksheet.Tables.Add($Range, "")
|
||||||
$TableName = $TableName -replace '\W', '_'
|
|
||||||
}
|
|
||||||
$ws = $Range.Worksheet
|
|
||||||
#if the table exists in this worksheet, update it.
|
|
||||||
if ($ws.Tables[$TableName]) {
|
|
||||||
$tbl =$ws.Tables[$TableName]
|
|
||||||
$tbl.TableXml.table.ref = $Range.Address
|
|
||||||
Write-Verbose -Message "Re-defined table '$TableName', now at $($Range.Address)."
|
|
||||||
}
|
|
||||||
elseif ($ws.Workbook.Worksheets.Tables.Name -contains $TableName) {
|
|
||||||
Write-Warning -Message "The Table name '$TableName' is already used on a different worksheet."
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$tbl = $ws.Tables.Add($Range, $TableName)
|
if ([OfficeOpenXml.FormulaParsing.ExcelUtilities.ExcelAddressUtil]::IsValidAddress($TableName)) {
|
||||||
Write-Verbose -Message "Defined table '$TableName' at $($Range.Address)"
|
Write-Warning -Message "$TableName reads as an Excel address, and so is not allowed as a table name."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ($TableName -notMatch '^[A-Z]') {
|
||||||
|
Write-Warning -Message "$TableName is not allowed as a table name because it does not begin with a letter."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ($TableName -match "\W") {
|
||||||
|
Write-Warning -Message "At least one character in $TableName is illegal in a table name and will be replaced with '_' . "
|
||||||
|
$TableName = $TableName -replace '\W', '_'
|
||||||
|
}
|
||||||
|
$ws = $Range.Worksheet
|
||||||
|
#if the table exists in this worksheet, update it.
|
||||||
|
if ($ws.Tables[$TableName]) {
|
||||||
|
$tbl =$ws.Tables[$TableName]
|
||||||
|
$tbl.TableXml.table.ref = $Range.Address
|
||||||
|
Write-Verbose -Message "Re-defined table '$TableName', now at $($Range.Address)."
|
||||||
|
}
|
||||||
|
elseif ($ws.Workbook.Worksheets.Tables.Name -contains $TableName) {
|
||||||
|
Write-Warning -Message "The Table name '$TableName' is already used on a different worksheet."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tbl = $ws.Tables.Add($Range, $TableName)
|
||||||
|
Write-Verbose -Message "Defined table '$($tbl.Name)' at $($Range.Address)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#it seems that show total changes some of the others, so the sequence matters.
|
#it seems that show total changes some of the others, so the sequence matters.
|
||||||
if ($PSBoundParameters.ContainsKey('ShowHeader')) {$tbl.ShowHeader = [bool]$ShowHeader}
|
if ($PSBoundParameters.ContainsKey('ShowHeader')) {$tbl.ShowHeader = [bool]$ShowHeader}
|
||||||
@@ -1329,7 +1368,7 @@ function Add-ExcelTable {
|
|||||||
foreach ($k in $TotalSettings.keys) {
|
foreach ($k in $TotalSettings.keys) {
|
||||||
if (-not $tbl.Columns[$k]) {Write-Warning -Message "Table does not have a Column '$k'."}
|
if (-not $tbl.Columns[$k]) {Write-Warning -Message "Table does not have a Column '$k'."}
|
||||||
elseif ($TotalSettings[$k] -notin @("Average", "Count", "CountNums", "Max", "Min", "None", "StdDev", "Sum", "Var") ) {
|
elseif ($TotalSettings[$k] -notin @("Average", "Count", "CountNums", "Max", "Min", "None", "StdDev", "Sum", "Var") ) {
|
||||||
Write-wanring "'$($TotalSettings[$k])' is not a valid total function."
|
Write-Warning -Message "'$($TotalSettings[$k])' is not a valid total function."
|
||||||
}
|
}
|
||||||
else {$tbl.Columns[$k].TotalsRowFunction = $TotalSettings[$k]}
|
else {$tbl.Columns[$k].TotalsRowFunction = $TotalSettings[$k]}
|
||||||
}
|
}
|
||||||
@@ -1340,7 +1379,7 @@ function Add-ExcelTable {
|
|||||||
if ($PSBoundParameters.ContainsKey('ShowLastColumn')) {$tbl.ShowLastColumn = [bool]$ShowLastColumn}
|
if ($PSBoundParameters.ContainsKey('ShowLastColumn')) {$tbl.ShowLastColumn = [bool]$ShowLastColumn}
|
||||||
if ($PSBoundParameters.ContainsKey('ShowRowStripes')) {$tbl.ShowRowStripes = [bool]$ShowRowStripes}
|
if ($PSBoundParameters.ContainsKey('ShowRowStripes')) {$tbl.ShowRowStripes = [bool]$ShowRowStripes}
|
||||||
if ($PSBoundParameters.ContainsKey('ShowColumnStripes')) {$tbl.ShowColumnStripes = [bool]$ShowColumnStripes}
|
if ($PSBoundParameters.ContainsKey('ShowColumnStripes')) {$tbl.ShowColumnStripes = [bool]$ShowColumnStripes}
|
||||||
if ($PSBoundParameters.ContainsKey('TableStyle')) {$tbl.TableStyle = $TableStyle}
|
$tbl.TableStyle = $TableStyle
|
||||||
|
|
||||||
if ($PassThru) {return $tbl}
|
if ($PassThru) {return $tbl}
|
||||||
}
|
}
|
||||||
|
|||||||
28
Export-StocksToExcel.ps1
Normal file
28
Export-StocksToExcel.ps1
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
function Export-StocksToExcel {
|
||||||
|
param(
|
||||||
|
[string]$symbols,
|
||||||
|
[ValidateSet("Open", "High", "Low", "Close", "Volume")]
|
||||||
|
$measure = "Open"
|
||||||
|
)
|
||||||
|
|
||||||
|
$xl = "$env:TEMP\Stocks.xlsx"
|
||||||
|
|
||||||
|
Remove-Item $xl -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$r = Invoke-RestMethod "https://azfnstockdata-fn83fffd32.azurewebsites.net/api/GetQuoteChart?symbol=$($symbols)"
|
||||||
|
|
||||||
|
$chartColumn = $symbols.Split(',').count + 2
|
||||||
|
$ptd = New-PivotTableDefinition `
|
||||||
|
-SourceWorkSheet Sheet1 `
|
||||||
|
-PivotTableName result `
|
||||||
|
-PivotData @{$measure = 'sum'} `
|
||||||
|
-PivotRows date `
|
||||||
|
-PivotColumns symbol `
|
||||||
|
-ChartType Line `
|
||||||
|
-ChartTitle "Stock - $measure " `
|
||||||
|
-IncludePivotChart -NoTotalsInPivot -ChartColumn $chartColumn -ChartRow 3 -Activate
|
||||||
|
|
||||||
|
$r | Sort-Object Date, symbol | Export-Excel $xl -PivotTableDefinition $ptd -AutoSize -AutoFilter -Show
|
||||||
|
}
|
||||||
|
|
||||||
|
# Export-StocksToExcel -symbols 'ibm,aapl,msft' -measure High
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# https://www.leeholmes.com/blog/2015/01/05/extracting-tables-from-powershells-invoke-webrequest/
|
||||||
|
# tweaked from the above code
|
||||||
function Get-HtmlTable {
|
function Get-HtmlTable {
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ function ConvertFrom-ExcelColumnName {
|
|||||||
$sum
|
$sum
|
||||||
}
|
}
|
||||||
|
|
||||||
ipmo .\ImportExcel.psd1 -Force
|
Import-Module .\ImportExcel.psd1 -Force
|
||||||
|
|
||||||
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
|
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
|
||||||
Get-ExcelTable .\testTable.xlsx Table3
|
Get-ExcelTable .\testTable.xlsx Table3
|
||||||
@@ -10,7 +10,7 @@ function Import-Html {
|
|||||||
)
|
)
|
||||||
|
|
||||||
$xlFile = [System.IO.Path]::GetTempFileName() -replace "tmp","xlsx"
|
$xlFile = [System.IO.Path]::GetTempFileName() -replace "tmp","xlsx"
|
||||||
rm $xlFile -ErrorAction Ignore
|
Remove-Item $xlFile -ErrorAction Ignore
|
||||||
|
|
||||||
Write-Verbose "Exporting to Excel file $($xlFile)"
|
Write-Verbose "Exporting to Excel file $($xlFile)"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
|||||||
RootModule = 'ImportExcel.psm1'
|
RootModule = 'ImportExcel.psm1'
|
||||||
|
|
||||||
# Version number of this module.
|
# Version number of this module.
|
||||||
ModuleVersion = '5.3.3'
|
ModuleVersion = '6.1.0'
|
||||||
|
|
||||||
# ID used to uniquely identify this module
|
# ID used to uniquely identify this module
|
||||||
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
|
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
|
||||||
@@ -61,16 +61,84 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5
|
|||||||
# NestedModules = @()
|
# NestedModules = @()
|
||||||
|
|
||||||
# Functions to export from this module
|
# Functions to export from this module
|
||||||
FunctionsToExport = '*'
|
FunctionsToExport = @(
|
||||||
|
'Add-ConditionalFormatting',
|
||||||
|
'Add-ExcelChart',
|
||||||
|
'Add-ExcelDataValidationRule',
|
||||||
|
'Add-ExcelName',
|
||||||
|
'Add-ExcelTable',
|
||||||
|
'Add-PivotTable',
|
||||||
|
'Add-WorkSheet',
|
||||||
|
'BarChart',
|
||||||
|
'Close-ExcelPackage',
|
||||||
|
'ColumnChart',
|
||||||
|
'Compare-WorkSheet',
|
||||||
|
'Convert-XlRangeToImage',
|
||||||
|
'ConvertFrom-ExcelData',
|
||||||
|
'ConvertFrom-ExcelSheet',
|
||||||
|
'ConvertFrom-ExcelToSQLInsert',
|
||||||
|
'ConvertTo-ExcelXlsx',
|
||||||
|
'Copy-ExcelWorkSheet',
|
||||||
|
'DoChart',
|
||||||
|
'Expand-NumberFormat',
|
||||||
|
'Export-Excel',
|
||||||
|
'Export-ExcelSheet',
|
||||||
|
'Export-MultipleExcelSheets',
|
||||||
|
'Get-ExcelColumnName',
|
||||||
|
'Get-ExcelSheetInfo',
|
||||||
|
'Get-ExcelWorkbookInfo',
|
||||||
|
'Get-HtmlTable',
|
||||||
|
'Get-Range',
|
||||||
|
'Get-XYRange',
|
||||||
|
'Import-Excel',
|
||||||
|
'Import-Html',
|
||||||
|
'Import-UPS',
|
||||||
|
'Import-USPS',
|
||||||
|
'Invoke-AllTests',
|
||||||
|
'Invoke-Sum',
|
||||||
|
'Join-Worksheet',
|
||||||
|
'LineChart',
|
||||||
|
'Merge-MultipleSheets',
|
||||||
|
'Merge-Worksheet',
|
||||||
|
'New-ConditionalFormattingIconSet',
|
||||||
|
'New-ConditionalText',
|
||||||
|
'New-ExcelChartDefinition',
|
||||||
|
'New-PivotTableDefinition',
|
||||||
|
'New-Plot',
|
||||||
|
'New-PSItem',
|
||||||
|
'NumberFormatCompletion',
|
||||||
|
'Open-ExcelPackage',
|
||||||
|
'PieChart',
|
||||||
|
'Pivot',
|
||||||
|
'Remove-WorkSheet'
|
||||||
|
'Select-Worksheet',
|
||||||
|
'Send-SQLDataToExcel',
|
||||||
|
'Set-CellStyle',
|
||||||
|
'Set-ExcelColumn',
|
||||||
|
'Set-ExcelRange',
|
||||||
|
'Set-ExcelRow',
|
||||||
|
'Test-Boolean',
|
||||||
|
'Test-Date',
|
||||||
|
'Test-Integer',
|
||||||
|
'Test-Number',
|
||||||
|
'Test-String',
|
||||||
|
'Update-FirstObjectProperties'
|
||||||
|
)
|
||||||
|
|
||||||
# Cmdlets to export from this module
|
# Cmdlets to export from this module
|
||||||
CmdletsToExport = '*'
|
#CmdletsToExport = '*'
|
||||||
|
|
||||||
# Variables to export from this module
|
# Variables to export from this module
|
||||||
VariablesToExport = '*'
|
#VariablesToExport = '*'
|
||||||
|
|
||||||
# Aliases to export from this module
|
# Aliases to export from this module
|
||||||
AliasesToExport = '*'
|
AliasesToExport = @(
|
||||||
|
'New-ExcelChart',
|
||||||
|
'Set-Column',
|
||||||
|
'Set-Format',
|
||||||
|
'Set-Row',
|
||||||
|
'Use-ExcelData'
|
||||||
|
)
|
||||||
|
|
||||||
# List of all modules packaged with this module
|
# List of all modules packaged with this module
|
||||||
# ModuleList = @()
|
# ModuleList = @()
|
||||||
|
|||||||
286
ImportExcel.psm1
286
ImportExcel.psm1
@@ -1,75 +1,84 @@
|
|||||||
#region import everything we need
|
#region import everything we need
|
||||||
Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
|
Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
|
||||||
. $PSScriptRoot\AddConditionalFormatting.ps1
|
. $PSScriptRoot\AddConditionalFormatting.ps1
|
||||||
. $PSScriptRoot\Charting.ps1
|
. $PSScriptRoot\AddDataValidation.ps1
|
||||||
. $PSScriptRoot\ColorCompletion.ps1
|
. $PSScriptRoot\Charting.ps1
|
||||||
. $PSScriptRoot\ConvertExcelToImageFile.ps1
|
. $PSScriptRoot\ColorCompletion.ps1
|
||||||
. $PSScriptRoot\Compare-WorkSheet.ps1
|
. $PSScriptRoot\ConvertExcelToImageFile.ps1
|
||||||
. $PSScriptRoot\ConvertFromExcelData.ps1
|
. $PSScriptRoot\compare-workSheet.ps1
|
||||||
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
|
. $PSScriptRoot\ConvertFromExcelData.ps1
|
||||||
. $PSScriptRoot\ConvertToExcelXlsx.ps1
|
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
|
||||||
. $PSScriptRoot\Copy-ExcelWorkSheet.ps1
|
. $PSScriptRoot\ConvertToExcelXlsx.ps1
|
||||||
. $PSScriptRoot\Export-Excel.ps1
|
. $PSScriptRoot\Copy-ExcelWorkSheet.ps1
|
||||||
. $PSScriptRoot\Export-ExcelSheet.ps1
|
. $PSScriptRoot\Export-Excel.ps1
|
||||||
. $PSScriptRoot\Get-ExcelColumnName.ps1
|
. $PSScriptRoot\Export-ExcelSheet.ps1
|
||||||
. $PSScriptRoot\Get-ExcelSheetInfo.ps1
|
. $PSScriptRoot\Export-StocksToExcel.ps1
|
||||||
. $PSScriptRoot\Get-ExcelWorkbookInfo.ps1
|
. $PSScriptRoot\Get-ExcelColumnName.ps1
|
||||||
. $PSScriptRoot\Get-HtmlTable.ps1
|
. $PSScriptRoot\Get-ExcelSheetInfo.ps1
|
||||||
. $PSScriptRoot\Get-Range.ps1
|
. $PSScriptRoot\Get-ExcelWorkbookInfo.ps1
|
||||||
. $PSScriptRoot\Get-XYRange.ps1
|
. $PSScriptRoot\Get-HtmlTable.ps1
|
||||||
. $PSScriptRoot\Import-Html.ps1
|
. $PSScriptRoot\Get-Range.ps1
|
||||||
. $PSScriptRoot\InferData.ps1
|
. $PSScriptRoot\Get-XYRange.ps1
|
||||||
. $PSScriptRoot\Invoke-Sum.ps1
|
. $PSScriptRoot\Import-Html.ps1
|
||||||
. $PSScriptRoot\Join-WorkSheet.ps1
|
. $PSScriptRoot\InferData.ps1
|
||||||
. $PSScriptRoot\Merge-Worksheet.ps1
|
. $PSScriptRoot\Invoke-Sum.ps1
|
||||||
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
|
. $PSScriptRoot\Join-Worksheet.ps1
|
||||||
. $PSScriptRoot\New-ConditionalText.ps1
|
. $PSScriptRoot\Merge-worksheet.ps1
|
||||||
. $PSScriptRoot\New-ExcelChart.ps1
|
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
|
||||||
. $PSScriptRoot\New-PSItem.ps1
|
. $PSScriptRoot\New-ConditionalText.ps1
|
||||||
. $PSScriptRoot\Open-ExcelPackage.ps1
|
. $PSScriptRoot\New-ExcelChart.ps1
|
||||||
. $PSScriptRoot\Pivot.ps1
|
. $PSScriptRoot\New-PSItem.ps1
|
||||||
. $PSScriptRoot\PivotTable.ps1
|
. $PSScriptRoot\Open-ExcelPackage.ps1
|
||||||
. $PSScriptRoot\Send-SQLDataToExcel.ps1
|
. $PSScriptRoot\Pivot.ps1
|
||||||
. $PSScriptRoot\Set-CellStyle.ps1
|
. $PSScriptRoot\PivotTable.ps1
|
||||||
. $PSScriptRoot\Set-Column.ps1
|
. $PSScriptRoot\RemoveWorksheet.ps1
|
||||||
. $PSScriptRoot\Set-Row.ps1
|
. $PSScriptRoot\Send-SqlDataToExcel.ps1
|
||||||
. $PSScriptRoot\SetFormat.ps1
|
. $PSScriptRoot\Set-CellStyle.ps1
|
||||||
. $PSScriptRoot\TrackingUtils.ps1
|
. $PSScriptRoot\Set-Column.ps1
|
||||||
. $PSScriptRoot\Update-FirstObjectProperties.ps1
|
. $PSScriptRoot\Set-Row.ps1
|
||||||
|
. $PSScriptRoot\Set-WorkSheetProtection.ps1
|
||||||
|
. $PSScriptRoot\SetFormat.ps1
|
||||||
|
. $PSScriptRoot\TrackingUtils.ps1
|
||||||
|
. $PSScriptRoot\Update-FirstObjectProperties.ps1
|
||||||
|
|
||||||
|
|
||||||
New-Alias -Name Use-ExcelData -Value "ConvertFrom-ExcelData" -Force
|
New-Alias -Name Use-ExcelData -Value "ConvertFrom-ExcelData" -Force
|
||||||
|
|
||||||
if ($PSVersionTable.PSVersion.Major -ge 5) {
|
if ($PSVersionTable.PSVersion.Major -ge 5) {
|
||||||
. $PSScriptRoot\Plot.ps1
|
. $PSScriptRoot\plot.ps1
|
||||||
|
|
||||||
Function New-Plot {
|
Function New-Plot {
|
||||||
Param()
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification='New-Plot does not change system state')]
|
||||||
|
Param()
|
||||||
[PSPlot]::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[PSPlot]::new()
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Write-Warning 'PowerShell 5 is required for plot.ps1'
|
}
|
||||||
Write-Warning 'PowerShell Excel is ready, except for that functionality'
|
else {
|
||||||
}
|
Write-Warning 'PowerShell 5 is required for plot.ps1'
|
||||||
|
Write-Warning 'PowerShell Excel is ready, except for that functionality'
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
function Import-Excel {
|
function Import-Excel {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Create custom objects from the rows in an Excel worksheet.
|
Create custom objects from the rows in an Excel worksheet.
|
||||||
|
|
||||||
.DESCRIPTION
|
.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’.
|
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’.
|
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’.
|
||||||
|
|
||||||
.PARAMETER Path
|
.PARAMETER Path
|
||||||
Specifies the path to the Excel file.
|
Specifies the path to the Excel file.
|
||||||
|
.PARAMETER ExcelPackage
|
||||||
|
Instead of specifying a path provides an Excel Package object (from Open-ExcelPackage)
|
||||||
|
Using this avoids re-reading the whole file when importing multiple parts of it.
|
||||||
|
To allow multiple read operations Import-Excel does NOT close the package, and you should use
|
||||||
|
Close-ExcelPackage -noSave to close it.
|
||||||
.PARAMETER WorksheetName
|
.PARAMETER WorksheetName
|
||||||
Specifies the name of the worksheet in the Excel workbook to import. By default, if no name is provided, the first worksheet will be imported.
|
Specifies the name of the worksheet in the Excel workbook to import. By default, if no name is provided, the first worksheet will be imported.
|
||||||
|
|
||||||
@@ -78,19 +87,15 @@ function Import-Excel {
|
|||||||
|
|
||||||
.PARAMETER HeaderName
|
.PARAMETER HeaderName
|
||||||
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 TopRow.
|
||||||
|
If you provide fewer header names than there are columns of data in the worksheet, then data will only be imported from that number of columns - the others will be ignored.
|
||||||
In case you provide less header names than there is data in the worksheet, then only the data with a corresponding header name will be imported and the data without header name will be disregarded.
|
If you provide more header names than there are columns of data in the worksheet, it will result in blank properties being added to the objects returned.
|
||||||
|
|
||||||
In case you provide more header names than there is data in the worksheet, then all data will be imported and all objects will have all the property names you defined in the header names. As such, the last properties will be blanc as there is no data for them.
|
|
||||||
|
|
||||||
.PARAMETER NoHeader
|
.PARAMETER NoHeader
|
||||||
Automatically generate property names (P1, P2, P3, ..) instead of the ones defined in the column headers of the TopRow.
|
Automatically generate property names (P1, P2, P3, ..) instead of the ones defined in the column headers of the TopRow.
|
||||||
|
|
||||||
This switch is best used when you want to import the complete worksheet ‘as is’ and are not concerned with the property names.
|
This switch is best used when you want to import the complete worksheet ‘as is’ and are not concerned with the property names.
|
||||||
|
|
||||||
.PARAMETER StartRow
|
.PARAMETER StartRow
|
||||||
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 StartRow are disregarded. By default this is the first row.
|
||||||
|
|
||||||
When the parameters ‘-NoHeader’ and ‘-HeaderName’ are not provided, this row will contain the column headers that will be used as property names. When one of both parameters are provided, the property names are automatically created and this row will be treated as a regular row containing data.
|
When the parameters ‘-NoHeader’ and ‘-HeaderName’ are not provided, this row will contain the column headers that will be used as property names. When one of both parameters are provided, the property names are automatically created and this row will be treated as a regular row containing data.
|
||||||
|
|
||||||
.PARAMETER EndRow
|
.PARAMETER EndRow
|
||||||
@@ -221,7 +226,7 @@ function Import-Excel {
|
|||||||
|
|
||||||
Notice that empty rows and empty columns are not imported.
|
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.
|
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.
|
||||||
|
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
@@ -241,31 +246,49 @@ 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’.
|
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
|
.LINK
|
||||||
https://github.com/dfinke/ImportExcel
|
https://github.com/dfinke/ImportExcel
|
||||||
|
|
||||||
.NOTES
|
.NOTES
|
||||||
#>
|
#>
|
||||||
|
|
||||||
[CmdLetBinding(DefaultParameterSetName)]
|
[CmdLetBinding()]
|
||||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||||
Param (
|
Param (
|
||||||
[Alias('FullName')]
|
[Alias('FullName')]
|
||||||
[Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, Position=0, Mandatory)]
|
[Parameter(ParameterSetName = "PathA", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||||
|
[Parameter(ParameterSetName = "PathB", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||||
|
[Parameter(ParameterSetName = "PathC", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||||
[ValidateScript( {(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '.xls$|.xlsx$|.xlsm$')})]
|
[ValidateScript( {(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '.xls$|.xlsx$|.xlsm$')})]
|
||||||
[String]$Path,
|
[String]$Path,
|
||||||
|
[Parameter(ParameterSetName = "PackageA", Mandatory)]
|
||||||
|
[Parameter(ParameterSetName = "PackageB", Mandatory)]
|
||||||
|
[Parameter(ParameterSetName = "PackageC", Mandatory)]
|
||||||
|
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||||
[Alias('Sheet')]
|
[Alias('Sheet')]
|
||||||
[Parameter(Position=1)]
|
[Parameter(Position = 1)]
|
||||||
[ValidateNotNullOrEmpty()]
|
[ValidateNotNullOrEmpty()]
|
||||||
[String]$WorksheetName,
|
[String]$WorksheetName,
|
||||||
[Parameter(ParameterSetName='B', Mandatory)]
|
[Parameter(ParameterSetName = 'PathB' , Mandatory)]
|
||||||
|
[Parameter(ParameterSetName = 'PackageB', Mandatory)]
|
||||||
[String[]]$HeaderName ,
|
[String[]]$HeaderName ,
|
||||||
[Parameter(ParameterSetName='C', Mandatory)]
|
[Parameter(ParameterSetName = 'PathC' , Mandatory)]
|
||||||
|
[Parameter(ParameterSetName = 'PackageC', Mandatory)]
|
||||||
[Switch]$NoHeader ,
|
[Switch]$NoHeader ,
|
||||||
[Alias('HeaderRow','TopRow')]
|
[Alias('HeaderRow', 'TopRow')]
|
||||||
[ValidateRange(1, 9999)]
|
[ValidateRange(1, 9999)]
|
||||||
[Int]$StartRow = 1,
|
[Int]$StartRow = 1,
|
||||||
[Alias('StopRow','BottomRow')]
|
[Alias('StopRow', 'BottomRow')]
|
||||||
[Int]$EndRow ,
|
[Int]$EndRow ,
|
||||||
[Alias('LeftColumn')]
|
[Alias('LeftColumn')]
|
||||||
[Int]$StartColumn = 1,
|
[Int]$StartColumn = 1,
|
||||||
@@ -275,14 +298,14 @@ function Import-Excel {
|
|||||||
[ValidateNotNullOrEmpty()]
|
[ValidateNotNullOrEmpty()]
|
||||||
[String]$Password
|
[String]$Password
|
||||||
)
|
)
|
||||||
Begin {
|
begin {
|
||||||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||||||
Function Get-PropertyNames {
|
Function Get-PropertyNames {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Create objects containing the column number and the column name for each of the different header types.
|
Create objects containing the column number and the column name for each of the different header types.
|
||||||
#>
|
#>
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification="Name would be incorrect, and command is not exported")]
|
||||||
Param (
|
Param (
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[Int[]]$Columns,
|
[Int[]]$Columns,
|
||||||
@@ -295,72 +318,52 @@ function Import-Excel {
|
|||||||
$i = 0
|
$i = 0
|
||||||
foreach ($C in $Columns) {
|
foreach ($C in $Columns) {
|
||||||
$i++
|
$i++
|
||||||
$C | Select-Object @{N='Column'; E={$_}}, @{N='Value'; E={'P' + $i}}
|
$C | Select-Object @{N = 'Column'; E = {$_}}, @{N = 'Value'; E = {'P' + $i}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ($HeaderName) {
|
elseif ($HeaderName) {
|
||||||
$i = 0
|
$i = 0
|
||||||
foreach ($H in $HeaderName) {
|
foreach ($H in $HeaderName) {
|
||||||
$H | Select-Object @{N='Column'; E={$Columns[$i]}}, @{N='Value'; E={$H}}
|
$H | Select-Object @{N = 'Column'; E = {$Columns[$i]}}, @{N = 'Value'; E = {$H}}
|
||||||
$i++
|
$i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($StartRow -eq 0) {
|
if ($StartRow -lt 1) {
|
||||||
throw 'The top row can never be equal to 0 when we need to retrieve headers from the worksheet.'
|
throw 'The top row can never be less than 1 when we need to retrieve headers from the worksheet.' ; return
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($C in $Columns) {
|
foreach ($C in $Columns) {
|
||||||
$Worksheet.Cells[$StartRow,$C] | Where-Object {$_.Value} | Select-Object @{N='Column'; E={$C}}, Value
|
$Worksheet.Cells[$StartRow, $C] | Where-Object {$_.Value} | Select-Object @{N = 'Column'; E = {$C}}, Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Catch {
|
Catch {
|
||||||
throw "Failed creating property names: $_"
|
throw "Failed creating property names: $_" ; return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
process {
|
||||||
#region Open file
|
if ($Path -and $Password) {$ExcelPackage = Open-ExcelPackage -Path $Path -Password $Password}
|
||||||
|
elseif ($Path) {$ExcelPackage = Open-ExcelPackage -Path $Path}
|
||||||
try {
|
try {
|
||||||
$Path = (Resolve-Path $Path).ProviderPath
|
#Select worksheet
|
||||||
Write-Verbose "Import Excel workbook '$Path' with worksheet '$Worksheetname'"
|
if (-not $WorksheetName) { $Worksheet = $ExcelPackage.Workbook.Worksheets[1] }
|
||||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
|
elseif(-not ($Worksheet = $ExcelPackage.Workbook.Worksheets[$WorkSheetName])) {
|
||||||
}
|
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($ExcelPackage.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter." ; return
|
||||||
Catch {throw "Could not open $Path ; $_ "}
|
}
|
||||||
|
|
||||||
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])) {
|
|
||||||
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($Excel.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$Worksheet = $Excel.Workbook.Worksheets | Select-Object -First 1
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||||
#region Get rows and columns
|
#region Get rows and columns
|
||||||
#If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells.
|
#If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells.
|
||||||
if (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row }
|
if (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row }
|
||||||
if (-not $EndColumn) {$EndColumn = $Worksheet.Dimension.End.Column }
|
if (-not $EndColumn) {$EndColumn = $Worksheet.Dimension.End.Column }
|
||||||
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]",0,0)
|
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]", 0, 0)
|
||||||
if ($DataOnly) {
|
if ($DataOnly) {
|
||||||
#If we are using headers startrow will be the headerrow so examine data from startRow + 1,
|
#If we are using headers startrow will be the header-row so examine data from startRow + 1,
|
||||||
if ($NoHeader) {$range = "A" + ($StartRow ) + ":" + $endAddress }
|
if ($NoHeader) {$range = "A" + ($StartRow ) + ":" + $endAddress }
|
||||||
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
|
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
|
||||||
#We're going to look at every cell and build 2 hash tables holding rows & columns which contain data.
|
#We're going to look at every cell and build 2 hash tables holding rows & columns which contain data.
|
||||||
#Want to Avoid 'select unique' operations & large Sorts, becuse time time taken increases with square
|
#Want to Avoid 'select unique' operations & large Sorts, becuse time time taken increases with square
|
||||||
#of number of items (PS uses heapsort at large size). Instead keep a list of what we have seen,
|
#of number of items (PS uses heapsort at large size). Instead keep a list of what we have seen,
|
||||||
@@ -368,23 +371,23 @@ function Import-Excel {
|
|||||||
$colHash = @{}
|
$colHash = @{}
|
||||||
$rowHash = @{}
|
$rowHash = @{}
|
||||||
foreach ($cell in $Worksheet.Cells[$range]) {
|
foreach ($cell in $Worksheet.Cells[$range]) {
|
||||||
if ($null -ne $cell.Value ) {$colHash[$cell.Start.Column]=1; $rowHash[$cell.Start.row]=1 }
|
if ($null -ne $cell.Value ) {$colHash[$cell.Start.Column] = 1; $rowHash[$cell.Start.row] = 1 }
|
||||||
}
|
}
|
||||||
$rows = ( $StartRow..$EndRow ).Where({$rowHash[$_]})
|
$rows = ( $StartRow..$EndRow ).Where( {$rowHash[$_]})
|
||||||
$columns = ($StartColumn..$EndColumn).Where({$colHash[$_]})
|
$columns = ($StartColumn..$EndColumn).Where( {$colHash[$_]})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$Columns = $StartColumn..$EndColumn ; if ($StartColumn -gt $EndColumn) {Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results."}
|
$Columns = $StartColumn .. $EndColumn ; if ($StartColumn -gt $EndColumn) {Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results."}
|
||||||
if ($NoHeader) {$Rows = ( $StartRow)..$EndRow ; if ($StartRow -gt $EndRow) {Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results."} }
|
if ($NoHeader) {$Rows = $StartRow..$EndRow ; if ($StartRow -gt $EndRow) {Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results."} }
|
||||||
else {$Rows = (1 + $StartRow)..$EndRow ; if ($StartRow -ge $EndRow) {Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results."}}
|
else {$Rows = (1 + $StartRow)..$EndRow ; if ($StartRow -ge $EndRow) {Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results."}}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region Create property names
|
#region Create property names
|
||||||
if ((-not $Columns) -or (-not ($PropertyNames = Get-PropertyNames -Columns $Columns -StartRow $StartRow))) {
|
if ((-not $Columns) -or (-not ($PropertyNames = Get-PropertyNames -Columns $Columns -StartRow $StartRow))) {
|
||||||
throw "No column headers found on top row '$StartRow'. If column headers in the worksheet are not a requirement then please use the '-NoHeader' or '-HeaderName' parameter."
|
throw "No column headers found on top row '$StartRow'. If column headers in the worksheet are not a requirement then please use the '-NoHeader' or '-HeaderName' parameter."; return
|
||||||
}
|
}
|
||||||
if ($Duplicates = $PropertyNames | Group-Object Value | Where-Object Count -GE 2) {
|
if ($Duplicates = $PropertyNames | Group-Object Value | Where-Object Count -GE 2) {
|
||||||
throw "Duplicate column headers found on row '$StartRow' in columns '$($Duplicates.Group.Column)'. Column headers must be unique, if this is not a requirement please use the '-NoHeader' or '-HeaderName' parameter."
|
throw "Duplicate column headers found on row '$StartRow' in columns '$($Duplicates.Group.Column)'. Column headers must be unique, if this is not a requirement please use the '-NoHeader' or '-HeaderName' parameter."; return
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||||
@@ -394,12 +397,13 @@ function Import-Excel {
|
|||||||
else {
|
else {
|
||||||
#region Create one object per row
|
#region Create one object per row
|
||||||
foreach ($R in $Rows) {
|
foreach ($R in $Rows) {
|
||||||
Write-Verbose "Import row '$R'"
|
#Disabled write-verbose for speed
|
||||||
|
# Write-Verbose "Import row '$R'"
|
||||||
$NewRow = [Ordered]@{}
|
$NewRow = [Ordered]@{}
|
||||||
|
|
||||||
foreach ($P in $PropertyNames) {
|
foreach ($P in $PropertyNames) {
|
||||||
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
|
$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
|
[PSCustomObject]$NewRow
|
||||||
@@ -408,14 +412,9 @@ function Import-Excel {
|
|||||||
}
|
}
|
||||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||||
}
|
}
|
||||||
Catch {
|
catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return }
|
||||||
throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"
|
finally {
|
||||||
}
|
if ($Path) {Close-ExcelPackage -ExcelPackage $ExcelPackage -NoSave }
|
||||||
Finally {
|
|
||||||
$Stream.Close()
|
|
||||||
$Stream.Dispose()
|
|
||||||
$Excel.Dispose()
|
|
||||||
$Excel = $null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,11 +443,11 @@ function ConvertFrom-ExcelSheet {
|
|||||||
[String]
|
[String]
|
||||||
$OutputPath = '.\',
|
$OutputPath = '.\',
|
||||||
[String]
|
[String]
|
||||||
$SheetName="*",
|
$SheetName = "*",
|
||||||
[ValidateSet('ASCII', 'BigEndianUniCode','Default','OEM','UniCode','UTF32','UTF7','UTF8')]
|
[ValidateSet('ASCII', 'BigEndianUniCode', 'Default', 'OEM', 'UniCode', 'UTF32', 'UTF7', 'UTF8')]
|
||||||
[string]
|
[string]
|
||||||
$Encoding = 'UTF8',
|
$Encoding = 'UTF8',
|
||||||
[ValidateSet('.txt', '.log','.csv')]
|
[ValidateSet('.txt', '.log', '.csv')]
|
||||||
[string]
|
[string]
|
||||||
$Extension = '.csv',
|
$Extension = '.csv',
|
||||||
[ValidateSet(';', ',')]
|
[ValidateSet(';', ',')]
|
||||||
@@ -457,8 +456,8 @@ function ConvertFrom-ExcelSheet {
|
|||||||
)
|
)
|
||||||
|
|
||||||
$Path = (Resolve-Path $Path).Path
|
$Path = (Resolve-Path $Path).Path
|
||||||
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path,"Open","Read","ReadWrite"
|
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, "Open", "Read", "ReadWrite"
|
||||||
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
||||||
$workbook = $xl.Workbook
|
$workbook = $xl.Workbook
|
||||||
|
|
||||||
$targetSheets = $workbook.Worksheets | Where-Object {$_.Name -like $SheetName}
|
$targetSheets = $workbook.Worksheets | Where-Object {$_.Name -like $SheetName}
|
||||||
@@ -469,8 +468,7 @@ function ConvertFrom-ExcelSheet {
|
|||||||
$params.Remove('Extension')
|
$params.Remove('Extension')
|
||||||
$params.NoTypeInformation = $true
|
$params.NoTypeInformation = $true
|
||||||
|
|
||||||
Foreach ($sheet in $targetSheets)
|
Foreach ($sheet in $targetSheets) {
|
||||||
{
|
|
||||||
Write-Verbose "Exporting sheet: $($sheet.Name)"
|
Write-Verbose "Exporting sheet: $($sheet.Name)"
|
||||||
|
|
||||||
$params.Path = "$OutputPath\$($Sheet.Name)$Extension"
|
$params.Path = "$OutputPath\$($Sheet.Name)$Extension"
|
||||||
@@ -478,24 +476,24 @@ function ConvertFrom-ExcelSheet {
|
|||||||
Import-Excel $Path -Sheet $($sheet.Name) | Export-Csv @params
|
Import-Excel $Path -Sheet $($sheet.Name) | Export-Csv @params
|
||||||
}
|
}
|
||||||
|
|
||||||
$stream.Close()
|
$Stream.Close()
|
||||||
$stream.Dispose()
|
$Stream.Dispose()
|
||||||
$xl.Dispose()
|
$xl.Dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
function Export-MultipleExcelSheets {
|
function Export-MultipleExcelSheets {
|
||||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory = $true)]
|
||||||
$Path,
|
$Path,
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[hashtable]$InfoMap,
|
[hashtable]$InfoMap,
|
||||||
[string]$Password,
|
[string]$Password,
|
||||||
[Switch]$Show,
|
[Switch]$Show,
|
||||||
[Switch]$AutoSize
|
[Switch]$AutoSize
|
||||||
)
|
)
|
||||||
|
|
||||||
$parameters = @{}+$PSBoundParameters
|
$parameters = @{} + $PSBoundParameters
|
||||||
$parameters.Remove("InfoMap")
|
$parameters.Remove("InfoMap")
|
||||||
$parameters.Remove("Show")
|
$parameters.Remove("Show")
|
||||||
|
|
||||||
@@ -503,24 +501,24 @@ function Export-MultipleExcelSheets {
|
|||||||
|
|
||||||
foreach ($entry in $InfoMap.GetEnumerator()) {
|
foreach ($entry in $InfoMap.GetEnumerator()) {
|
||||||
Write-Progress -Activity "Exporting" -Status "$($entry.Key)"
|
Write-Progress -Activity "Exporting" -Status "$($entry.Key)"
|
||||||
$parameters.WorkSheetname=$entry.Key
|
$parameters.WorkSheetname = $entry.Key
|
||||||
|
|
||||||
& $entry.Value | Export-Excel @parameters
|
& $entry.Value | Export-Excel @parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
if($Show) {Invoke-Item $Path}
|
if ($Show) {Invoke-Item $Path}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function WorksheetArgumentCompleter {
|
Function WorksheetArgumentCompleter {
|
||||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||||
$xlPath = $fakeBoundParameter['Path']
|
$xlPath = $fakeBoundParameter['Path']
|
||||||
if (Test-Path -Path $xlPath) {
|
if (Test-Path -Path $xlPath) {
|
||||||
$xlpkg = Open-ExcelPackage -Path $xlPath
|
$xlpkg = Open-ExcelPackage -Path $xlPath
|
||||||
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name
|
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name
|
||||||
Close-ExcelPackage -nosave -ExcelPackage $xlpkg
|
Close-ExcelPackage -nosave -ExcelPackage $xlpkg
|
||||||
$WorksheetNames.where({$_ -like "*$wordToComplete*"}) | foreach-object {
|
$WorksheetNames.where( {$_ -like "*$wordToComplete*"}) | foreach-object {
|
||||||
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'",
|
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'",
|
||||||
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) ,$_
|
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-not (Test-Path $InstallDirectory)) {
|
if (-not (Test-Path $InstallDirectory)) {
|
||||||
New-Item -Path $InstallDirectory -ItemType Directory -EA Stop | Out-Null
|
$null = New-Item -Path $InstallDirectory -ItemType Directory -EA Stop
|
||||||
Write-Verbose "$ModuleName created module folder '$InstallDirectory'"
|
Write-Verbose "$ModuleName created module folder '$InstallDirectory'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Combines data on all the sheets in an Excel worksheet onto a single sheet.
|
Combines data on all the sheets in an Excel worksheet onto a single sheet.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Join worksheet can work in two main ways:
|
Join-Worksheet can work in two main ways, either
|
||||||
Either Combining data which has the same layout from many pages into one, or combining pages which have nothing in common.
|
Combining data which has the same layout from many pages into one, or
|
||||||
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.
|
combining pages which have nothing in common.
|
||||||
In the latter case -NoHeader is specified, and each copied block can have the sheet it came from placed above it as a title.
|
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
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
PS> foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
|
PS> foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
|
||||||
@@ -16,11 +19,15 @@
|
|||||||
PS> $ptDef =New-PivotTableDefinition -PivotTableName "Pivot1" -SourceWorkSheet "Combined" -PivotRows "Status" -PivotFilter "MachineName" -PivotData @{Status='Count'} -IncludePivotChart -ChartType BarClustered3D
|
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
|
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.
|
The foreach command gets the services running on four servers and exports each
|
||||||
$PtDef= creates a defintion for a PivotTable.
|
to its own page in Test.xlsx.
|
||||||
The Join-Worksheet command uses the same file and merges the results onto a sheet named "Combined". It sets a column header of "Machinename",
|
$PtDef= creates a definition for a PivotTable.
|
||||||
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.
|
The Join-Worksheet command uses the same file and merges the results into a sheet
|
||||||
Join-Worksheet finishes by calling Export-Excel to AutoSize cells, freeze the top row and make it bold and add the Pivot table.
|
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
|
.EXAMPLE
|
||||||
>
|
>
|
||||||
@@ -30,10 +37,14 @@
|
|||||||
Export-Excel -Path "$env:COMPUTERNAME.xlsx" -WorkSheetname NetAdapter
|
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
|
PS> Join-Worksheet -Path "$env:COMPUTERNAME.xlsx" -WorkSheetName Summary -Title "Summary" -TitleBold -TitleSize 22 -NoHeader -LabelBlocks -AutoSize -HideSource -show
|
||||||
|
|
||||||
The first two commands get logical disk and network card information; each type is exported to its own sheet in a workbook.
|
The first two commands get logical-disk and network-card information; each type
|
||||||
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.
|
is exported to its own sheet in a workbook.
|
||||||
Specifying -LabelBlocks causes each sheet's name to become a title on the summary page above the copied data.
|
The Join-Worksheet command copies both onto a page named "Summary". Because
|
||||||
The source data is hidden, a title is added in 22 point boldface and the columns are sized to fit the data.
|
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')]
|
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
||||||
param (
|
param (
|
||||||
@@ -41,21 +52,21 @@
|
|||||||
[Parameter(ParameterSetName = "Default", Position = 0)]
|
[Parameter(ParameterSetName = "Default", Position = 0)]
|
||||||
[Parameter(ParameterSetName = "Table" , Position = 0)]
|
[Parameter(ParameterSetName = "Table" , Position = 0)]
|
||||||
[String]$Path ,
|
[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 = "PackageDefault")]
|
||||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
|
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
|
||||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||||
# The name of a sheet within the workbook where the other sheets will be joined together - "Combined" by default.
|
# The name of a sheet within the workbook where the other sheets will be joined together - "Combined" by default.
|
||||||
$WorkSheetName = 'Combined',
|
$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,
|
[switch]$Clearsheet,
|
||||||
#Join-Worksheet assumes each sheet has identical headers and the headers should be copied to the target sheet, unless -NoHeader is specified.
|
#Join-Worksheet assumes each sheet has identical headers and the headers should be copied to the target sheet, unless -NoHeader is specified.
|
||||||
[switch]$NoHeader,
|
[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.
|
#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.
|
||||||
$FromLabel = "From" ,
|
[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.
|
#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,
|
[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,
|
[Switch]$AutoSize,
|
||||||
#Freezes headers etc. in the top row.
|
#Freezes headers etc. in the top row.
|
||||||
[Switch]$FreezeTopRow,
|
[Switch]$FreezeTopRow,
|
||||||
@@ -65,25 +76,25 @@
|
|||||||
[Switch]$FreezeTopRowFirstColumn,
|
[Switch]$FreezeTopRowFirstColumn,
|
||||||
# Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
|
# Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
|
||||||
[Int[]]$FreezePane,
|
[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 = 'Default')]
|
||||||
[Parameter(ParameterSetName = 'PackageDefault')]
|
[Parameter(ParameterSetName = 'PackageDefault')]
|
||||||
[Switch]$AutoFilter,
|
[Switch]$AutoFilter,
|
||||||
#Makes the top Row boldface.
|
#Makes the top row boldface.
|
||||||
[Switch]$BoldTopRow,
|
[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,
|
[switch]$HideSource,
|
||||||
#Text of a title to be placed in Cell A1.
|
#Text of a title to be placed in Cell A1.
|
||||||
[String]$Title,
|
[String]$Title,
|
||||||
#Sets the fill pattern for the title cell.
|
#Sets the fill pattern for the title cell.
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
|
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
|
||||||
#Sets the cell background color for the title cell.
|
#Sets the cell background color for the title cell.
|
||||||
[System.Drawing.Color]$TitleBackgroundColor,
|
$TitleBackgroundColor,
|
||||||
#Sets the title in boldface type.
|
#Sets the title in boldface type.
|
||||||
[Switch]$TitleBold,
|
[Switch]$TitleBold,
|
||||||
#Sets the point size for the title.
|
#Sets the point size for the title.
|
||||||
[Int]$TitleSize = 22,
|
[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,
|
[Hashtable]$PivotTableDefinition,
|
||||||
#A hashtable containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
|
#A hashtable containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
|
||||||
[Object[]]$ExcelChartDefinition,
|
[Object[]]$ExcelChartDefinition,
|
||||||
@@ -107,13 +118,13 @@
|
|||||||
})]
|
})]
|
||||||
[Parameter(ParameterSetName = 'Table' , Mandatory = $true)]
|
[Parameter(ParameterSetName = 'Table' , Mandatory = $true)]
|
||||||
[Parameter(ParameterSetName = 'PackageTable' , 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,
|
[String]$TableName,
|
||||||
[Parameter(ParameterSetName = 'Table')]
|
[Parameter(ParameterSetName = 'Table')]
|
||||||
[Parameter(ParameterSetName = 'PackageTable')]
|
[Parameter(ParameterSetName = 'PackageTable')]
|
||||||
#Selects the style for the named table - defaults to 'Medium6'.
|
#Selects the style for the named table - defaults to "Medium6".
|
||||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = '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,
|
[switch]$ReturnRange,
|
||||||
#Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
#Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
|
||||||
[switch]$Show,
|
[switch]$Show,
|
||||||
@@ -138,6 +149,7 @@
|
|||||||
if ($TitleBold) {$destinationSheet.Cells[1, 1].Style.Font.Bold = $True }
|
if ($TitleBold) {$destinationSheet.Cells[1, 1].Style.Font.Bold = $True }
|
||||||
#Can only set TitleBackgroundColor if TitleFillPattern is something other than None.
|
#Can only set TitleBackgroundColor if TitleFillPattern is something other than None.
|
||||||
if ($TitleBackgroundColor -AND ($TitleFillPattern -ne '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.PatternType = $TitleFillPattern
|
||||||
$destinationSheet.Cells[1, 1].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
|
$destinationSheet.Cells[1, 1].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
|
||||||
}
|
}
|
||||||
@@ -149,6 +161,7 @@
|
|||||||
#Assume every row has titles in row 1, copy row 1 from first sheet to new sheet.
|
#Assume every row has titles in row 1, copy row 1 from first sheet to new sheet.
|
||||||
$destinationSheet.Select("A$row")
|
$destinationSheet.Select("A$row")
|
||||||
$ExcelPackage.Workbook.Worksheets[1].cells["1:1"].Copy($destinationSheet.SelectedRange)
|
$ExcelPackage.Workbook.Worksheets[1].cells["1:1"].Copy($destinationSheet.SelectedRange)
|
||||||
|
#fromlabel can't be an empty string
|
||||||
if ($FromLabel ) {
|
if ($FromLabel ) {
|
||||||
#Add a column which says where the data comes from.
|
#Add a column which says where the data comes from.
|
||||||
$fromColumn = ($destinationSheet.Dimension.Columns + 1)
|
$fromColumn = ($destinationSheet.Dimension.Columns + 1)
|
||||||
@@ -185,7 +198,7 @@
|
|||||||
#We accept a bunch of parameters work to pass on to Export-excel ( Autosize, Autofilter, boldtopRow Freeze ); if we have any of those call export-excel otherwise close the package here.
|
#We accept a bunch of parameters work to pass on to Export-excel ( Autosize, Autofilter, boldtopRow Freeze ); if we have any of those call export-excel otherwise close the package here.
|
||||||
$params = @{} + $PSBoundParameters
|
$params = @{} + $PSBoundParameters
|
||||||
'Path', 'Clearsheet', 'NoHeader', 'FromLabel', 'LabelBlocks', 'HideSource',
|
'Path', 'Clearsheet', 'NoHeader', 'FromLabel', 'LabelBlocks', 'HideSource',
|
||||||
'Title', 'TitleFillPattern', 'TitleBackgroundColor', 'TitleBold', 'TitleSize' | ForEach-Object {[void]$params.Remove($_)}
|
'Title', 'TitleFillPattern', 'TitleBackgroundColor', 'TitleBold', 'TitleSize' | ForEach-Object {$null = $params.Remove($_)}
|
||||||
if ($params.Keys.Count) {
|
if ($params.Keys.Count) {
|
||||||
if ($Title) { $params.StartRow = 2}
|
if ($Title) { $params.StartRow = 2}
|
||||||
$params.WorkSheetName = $WorkSheetName
|
$params.WorkSheetName = $WorkSheetName
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
if((Get-Module -list ImportExcel) -eq $null) {
|
if($null -eq (Get-Module -ListAvailable ImportExcel) ) {
|
||||||
Import-Module $PSScriptRoot\ImportExcel.psd1 -force
|
Import-Module $PSScriptRoot\ImportExcel.psd1 -force
|
||||||
}
|
}
|
||||||
@@ -1,84 +1,103 @@
|
|||||||
Function Merge-Worksheet {
|
Function Merge-Worksheet {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.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
|
.Description
|
||||||
The Compare-Worksheet command takes two worksheets and marks differences in the source document, and optionally outputs a grid showing the changes.
|
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 .
|
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.
|
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
|
.Example
|
||||||
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -show
|
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
|
The workbooks contain audit information for two servers, one sheet contains
|
||||||
in a workbook named services which shows all the services and their differences, and opens it in Excel.
|
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
|
.Example
|
||||||
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
|
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.
|
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
|
.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.
|
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.
|
Because no "Key" property is given, "Name" is assumed to be the key
|
||||||
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.
|
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
|
.Example
|
||||||
merge-worksheet -RefO (dir .\ImportExcel\4.0.7) -DiffO (dir .\ImportExcel\4.0.8) -Pr Length | Out-GridView
|
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 time no file is written and the results - which include all properties,
|
||||||
This version uses aliases to shorten the parameters,
|
not just length, are output and sent to Out-Gridview. This version uses
|
||||||
(OutputFileName can be "outFile" and the sheet "OutSheet" : DifferenceObject & ReferenceObject can be DiffObject & RefObject).
|
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)]
|
[cmdletbinding(SupportsShouldProcess=$true)]
|
||||||
Param(
|
Param(
|
||||||
#First Excel file to compare. You can compare two Excel files or two other objects but not one of each.
|
#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)]
|
[parameter(ParameterSetName='A',Mandatory=$true,Position=0)] #A = Compare two files default headers
|
||||||
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)]
|
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)] #B = Compare two files user supplied headers
|
||||||
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)]
|
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)] #C = Compare two files headers P1, P2, P3 etc
|
||||||
$Referencefile ,
|
$Referencefile ,
|
||||||
|
|
||||||
#Second Excel file to compare.
|
#Second Excel file to compare.
|
||||||
[parameter(ParameterSetName='A',Mandatory=$true,Position=1)]
|
[parameter(ParameterSetName='A',Mandatory=$true,Position=1)]
|
||||||
[parameter(ParameterSetName='B',Mandatory=$true,Position=1)]
|
[parameter(ParameterSetName='B',Mandatory=$true,Position=1)]
|
||||||
[parameter(ParameterSetName='C',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 ,
|
$Differencefile ,
|
||||||
|
|
||||||
#Name(s) of worksheets to compare,
|
#Name(s) of Worksheets to compare.
|
||||||
[parameter(ParameterSetName='A',Position=2)]
|
[parameter(ParameterSetName='A',Position=2)] #Applies to all sets EXCEPT D which is two objects (no sheets)
|
||||||
[parameter(ParameterSetName='B',Position=2)]
|
[parameter(ParameterSetName='B',Position=2)]
|
||||||
[parameter(ParameterSetName='C',Position=2)]
|
[parameter(ParameterSetName='C',Position=2)]
|
||||||
[parameter(ParameterSetName='E',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.
|
#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='B')]
|
||||||
[parameter(ParameterSetName='C')]
|
[parameter(ParameterSetName='C')]
|
||||||
[parameter(ParameterSetName='E')]
|
[parameter(ParameterSetName='E')]
|
||||||
|
[parameter(ParameterSetName='F')]
|
||||||
|
[parameter(ParameterSetName='G')]
|
||||||
[int]$Startrow = 1,
|
[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.
|
||||||
[Parameter(ParameterSetName='B',Mandatory=$true)]
|
[Parameter(ParameterSetName='B',Mandatory=$true)] #Compare object + sheet or 2 sheets with user supplied headers
|
||||||
|
[Parameter(ParameterSetName='F',Mandatory=$true)]
|
||||||
[String[]]$Headername,
|
[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 using the values the top row of the sheet.
|
||||||
[Parameter(ParameterSetName='C',Mandatory=$true)]
|
[Parameter(ParameterSetName='C',Mandatory=$true)] #Compare object + sheet or 2 sheets with headers of P1, P2, P3 ...
|
||||||
|
[Parameter(ParameterSetName='G',Mandatory=$true)]
|
||||||
[switch]$NoHeader,
|
[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='D',Mandatory=$true)]
|
||||||
[parameter(ParameterSetName='E',Mandatory=$true)]
|
[parameter(ParameterSetName='E',Mandatory=$true)]
|
||||||
|
[parameter(ParameterSetName='F',Mandatory=$true)]
|
||||||
|
[parameter(ParameterSetName='G',Mandatory=$true)]
|
||||||
[Alias('RefObject')]
|
[Alias('RefObject')]
|
||||||
$ReferenceObject ,
|
$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)]
|
[parameter(ParameterSetName='D',Mandatory=$true,Position=1)]
|
||||||
[Alias('DiffObject')]
|
[Alias('DiffObject')]
|
||||||
$DifferenceObject ,
|
$DifferenceObject ,
|
||||||
[parameter(ParameterSetName='D',Position=2)]
|
[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 "=>"
|
#If there isn't a filename to use to label data from the "Difference" side, DiffPrefix is used, it defaults to "=>"
|
||||||
$DiffPrefix = "=>" ,
|
$DiffPrefix = "=>" ,
|
||||||
#File to hold merged data.
|
#File to hold merged data.
|
||||||
[parameter(Position=3)]
|
[parameter(Position=3)]
|
||||||
[Alias('OutFile')]
|
[Alias('OutFile')]
|
||||||
$OutputFile ,
|
$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)]
|
[parameter(Position=4)]
|
||||||
[Alias('OutSheet')]
|
[Alias('OutSheet')]
|
||||||
$OutputSheetName = "Sheet1",
|
$OutputSheetName = "Sheet1",
|
||||||
@@ -89,51 +108,54 @@
|
|||||||
#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 refence and difference side, default is "Name".
|
||||||
$Key = "Name" ,
|
$Key = "Name" ,
|
||||||
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
|
#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.
|
#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.
|
#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.
|
#Sets the background color for rows not in the reference but added to the difference sheet.
|
||||||
[System.Drawing.Color]$AddBackgroundColor = "PaleGreen",
|
$AddBackgroundColor = [System.Drawing.Color]::PaleGreen,
|
||||||
#if Specified hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
|
#if specified, hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
|
||||||
[switch]$HideEqual ,
|
[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 ,
|
[switch]$Passthru ,
|
||||||
#If specified, opens the output workbook.
|
#If specified, opens the output workbook.
|
||||||
[Switch]$Show
|
[Switch]$Show
|
||||||
)
|
)
|
||||||
|
|
||||||
#region Read Excel data
|
#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.
|
#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)}
|
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 }
|
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 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] ) ) {
|
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"
|
Write-Warning -Message "If both the Reference and difference file are the same then Worksheet name must provide 2 different names"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ($WorkSheetName.count -eq 2) {$workSheet2 = $DiffPrefix = $WorkSheetName[1] ; $worksheet1 = $WorkSheetName[0] ; }
|
if ($WorksheetName.count -eq 2) {$Worksheet2 = $DiffPrefix = $WorksheetName[1] ; $Worksheet1 = $WorksheetName[0] ; }
|
||||||
elseif ($WorkSheetName -is [string]) {$worksheet2 = $workSheet1 = $WorkSheetName ;
|
elseif ($WorksheetName -is [string]) {$Worksheet2 = $Worksheet1 = $WorksheetName ;
|
||||||
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$","" }
|
$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 }
|
$params= @{ ErrorAction = [System.Management.Automation.ActionPreference]::Stop }
|
||||||
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
|
||||||
try {
|
try {
|
||||||
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
|
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $Worksheet1 @params
|
||||||
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @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}
|
if ($NoHeader) {$firstDataRow = $Startrow } else {$firstDataRow = $Startrow + 1}
|
||||||
}
|
}
|
||||||
elseif ( $Differencefile) {
|
elseif ( $Differencefile) {
|
||||||
if ($WorkSheetName -isnot [string]) {Write-Warning -Message "You must provide a single worksheet name." ; return }
|
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 ;}
|
$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 }
|
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 "=>" ) {
|
if ($DiffPrefix -eq "=>" ) {
|
||||||
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$",""
|
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$",""
|
||||||
}
|
}
|
||||||
@@ -149,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
|
$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 ($NoHeader -and "Name" -eq $Key) {$Key = "p1"}
|
||||||
if ($headings -notcontains $Key -and
|
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 $Property) { $propList += ($headings.where({$_ -like $p}) )}
|
||||||
foreach ($p in $ExcludeProperty) { $propList = $propList.where({$_ -notlike $p}) }
|
foreach ($p in $ExcludeProperty) { $propList = $propList.where({$_ -notlike $p}) }
|
||||||
if (($propList -notcontains $Key) -and
|
if (($propList -notcontains $Key) -and
|
||||||
@@ -199,19 +221,29 @@
|
|||||||
else {$Rowhash[$row.$key] = $rowNo }
|
else {$Rowhash[$row.$key] = $rowNo }
|
||||||
$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"}
|
if ($Key -eq '*') {$key = "_ALL"}
|
||||||
#endregion
|
#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 |
|
$expandedDiff = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $propList -PassThru -IncludeEqual |
|
||||||
Group-Object -Property $key | ForEach-Object {
|
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
|
$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]@{}
|
$hash = [ordered]@{}
|
||||||
foreach ($result in $_.Group) {
|
foreach ($result in $_.Group) {
|
||||||
if ($result.SideIndicator -ne "=>") {$hash["_Row"] = $result._Row }
|
if ($result.SideIndicator -ne "=>") {$hash["_Row"] = $result._Row }
|
||||||
elseif (-not $hash["$DiffPrefix Row"]) {$hash["_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 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) {$hash.Side = "<>"} else {$hash["Side"] = $result.SideIndicator}
|
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) {
|
switch ($hash.side) {
|
||||||
'==' { $hash["$DiffPrefix is"] = 'Same' }
|
'==' { $hash["$DiffPrefix is"] = 'Same' }
|
||||||
'=>' { $hash["$DiffPrefix is"] = 'Added' }
|
'=>' { $hash["$DiffPrefix is"] = 'Added' }
|
||||||
@@ -224,7 +256,7 @@
|
|||||||
}
|
}
|
||||||
'<=' { $hash["$DiffPrefix is"] = 'Removed'}
|
'<=' { $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["$DiffPrefix Row"] = $Rowhash[$keyval]
|
||||||
$hash[$key] = $keyval
|
$hash[$key] = $keyval
|
||||||
#Create FieldName and/or =>FieldName columns
|
#Create FieldName and/or =>FieldName columns
|
||||||
@@ -236,6 +268,8 @@
|
|||||||
elseif ($result.SideIndicator -eq "=>") { $hash[("$DiffPrefix $p")] = $result.$P}
|
elseif ($result.SideIndicator -eq "=>") { $hash[("$DiffPrefix $p")] = $result.$P}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($k in $hash.keys) {$eDiffProps[$k] = $true}
|
||||||
[Pscustomobject]$hash
|
[Pscustomobject]$hash
|
||||||
} | Sort-Object -Property "_row"
|
} | Sort-Object -Property "_row"
|
||||||
|
|
||||||
@@ -246,35 +280,35 @@
|
|||||||
$expandedDiff = $expandedDiff | Sort-Object -Property "$DiffPrefix Row"
|
$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" } }
|
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")) {
|
elseif ($PSCmdlet.ShouldProcess($OutputFile,"Write Output to Excel file")) {
|
||||||
$expandedDiff = $expandedDiff | Sort-Object -Property "_row", "$DiffPrefix Row"
|
$expandedDiff = $expandedDiff | Sort-Object -Property "_row", "$DiffPrefix Row"
|
||||||
$xl = $expandedDiff | Select-Object -Property $OutputProps | Update-FirstObjectProperties |
|
$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]
|
$ws = $xl.Workbook.Worksheets[$OutputSheetName]
|
||||||
for ($i = 0; $i -lt $expandedDiff.Count; $i++ ) {
|
for ($i = 0; $i -lt $expandedDiff.Count; $i++ ) {
|
||||||
if ( $expandedDiff[$i].side -ne "==" ) {
|
if ( $expandedDiff[$i].side -ne "==" ) {
|
||||||
Set-ExcelRange -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 }
|
elseif ( $HideEqual ) {$ws.row($i+2).hidden = $true }
|
||||||
if ( $expandedDiff[$i].side -eq "<>" ) {
|
if ( $expandedDiff[$i].side -eq "<>" ) {
|
||||||
$range = $ws.Dimension -replace "\d+", ($i + 2 )
|
$range = $ws.Dimension -replace "\d+", ($i + 2 )
|
||||||
Set-ExcelRange -WorkSheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
|
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
|
||||||
}
|
}
|
||||||
elseif ( $expandedDiff[$i].side -eq "<=" ) {
|
elseif ( $expandedDiff[$i].side -eq "<=" ) {
|
||||||
$rangeR1C1 = "R[{0}]C[1]:R[{0}]C[{1}]" -f ($i + 2 ) , $lastRefColNo
|
$rangeR1C1 = "R[{0}]C[1]:R[{0}]C[{1}]" -f ($i + 2 ) , $lastRefColNo
|
||||||
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
||||||
Set-ExcelRange -WorkSheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
|
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
|
||||||
}
|
}
|
||||||
elseif ( $expandedDiff[$i].side -eq "=>" ) {
|
elseif ( $expandedDiff[$i].side -eq "=>" ) {
|
||||||
if ($propList.count -gt 1) {
|
if ($propList.count -gt 1) {
|
||||||
$rangeR1C1 = "R[{0}]C[{1}]:R[{0}]C[{2}]" -f ($i + 2 ) , $FirstDiffColNo , $lastDiffColNo
|
$rangeR1C1 = "R[{0}]C[{1}]:R[{0}]C[{2}]" -f ($i + 2 ) , $FirstDiffColNo , $lastDiffColNo
|
||||||
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
|
||||||
Set-ExcelRange -WorkSheet $ws -Range $range -BackgroundColor $AddBackgroundColor
|
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $AddBackgroundColor
|
||||||
}
|
}
|
||||||
Set-ExcelRange -WorkSheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
|
Set-ExcelRange -Worksheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Close-ExcelPackage -ExcelPackage $xl -Show:$Show
|
Close-ExcelPackage -ExcelPackage $xl -Show:$Show
|
||||||
@@ -282,135 +316,158 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
Function Merge-MultipleSheets {
|
Function Merge-MultipleSheets {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Merges worksheets into a single worksheet with differences marked up.
|
Merges Worksheets into a single Worksheet with differences marked up.
|
||||||
.Description
|
.Description
|
||||||
The Merge worksheet command combines 2 sheets. Merge-MultipleSheets is designed to merge more than 2.
|
The Merge Worksheet command combines two sheets. Merge-MultipleSheets is
|
||||||
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
|
designed to merge more than two. So if asked to merge sheets A,B,C which
|
||||||
Merge-MultipleSheets calls Merge-Worksheet to merge Name, Displayname and Start mode, from sheets A and C
|
contain Services, with a Name, Displayname and Start mode, where "Name" is
|
||||||
the result has column headings -Row, Name, DisplayName, Startmode, C-DisplayName, C-StartMode C-Is, C-Row
|
treated as the key, Merge-MultipleSheets calls Merge-Worksheet to merge
|
||||||
Merge-MultipleSheets then calls Merge-Worsheet with this result and sheet B, comparing 'Name', 'Displayname' and 'Start mode' columns on each side
|
"Name", "Displayname" and "Startmode" from sheets A and C; the result has
|
||||||
which outputs _Row, Name, DisplayName, Startmode, B-DisplayName, B-StartMode B-Is, B-Row, C-DisplayName, C-StartMode C-Is, C-Row
|
column headings "_Row", "Name", "DisplayName", "Startmode", "C-DisplayName",
|
||||||
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.
|
"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),
|
The "Is" columns hold "Same", "Added", "Removed" or "Changed" and is used for
|
||||||
and when the data is written to Excel the "reference" columns, in this case "DisplayName" and "Start" are renamed to reflect their source,
|
conditional formatting in the output sheet (these columns are hidden by default),
|
||||||
so become "A-DisplayName" and "A-Start".
|
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,
|
Note: the processing order can affect what is seen as a change. For example
|
||||||
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
|
if there is an extra item in sheet B in the example above, Sheet C will be
|
||||||
the entries from sheet A to show that a values were added in at least one sheet.
|
processed and that row and will not be seen to be missing. When sheet B is
|
||||||
However if Sheet B is the reference sheet, A and C will be seen to have an item removed;
|
processed it is marked as an addition, and the conditional formatting marks
|
||||||
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.
|
the entries from sheet A to show that a values were added in at least one
|
||||||
.Example
|
sheet. However if Sheet B is the reference sheet, A and C will be seen to
|
||||||
dir Server*.xlsx | Merge-MulipleSheets -WorkSheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
|
have an item removed; and if B is processed before C, the extra item is
|
||||||
We are auditing servers and each one has a workbook in the current directory which contains a "Services" worksheet (the result of
|
known when C is processed and so C is considered to be missing that item.
|
||||||
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode
|
.Example
|
||||||
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
|
||||||
.Example
|
Here we are auditing servers and each one has a workbook in the current
|
||||||
dir Serv*.xlsx | Merge-MulipleSheets -WorkSheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
|
directory which contains a "Services" Worksheet (the result of
|
||||||
The server audit files in the previous example also have "Software" worksheet, but no single field on that sheet works as a key.
|
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode)
|
||||||
Specifying "*" for the key produces a compound key using all non-excluded fields (and the installation date and file location are excluded).
|
No key is specified so the key is assumed to be the "Name" column.
|
||||||
.Example
|
The files are merged and the result is opened on completion.
|
||||||
Merge-MulipleSheets -Path hotfixes.xlsx -WorkSheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
|
.Example
|
||||||
This time all the servers have written their hofix information to their own worksheets in a shared Excel workbook named "Hotfixes"
|
dir Serv*.xlsx | Merge-MulipleSheets -WorksheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
|
||||||
(the information was obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
|
The server audit files in the previous example also have "Software" worksheet,
|
||||||
This ignores any sheets which are not named "Serv*", and uses the HotfixID as the key ; in this version the row numbers are hidden.
|
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
|
||||||
[cmdletbinding()]
|
date and file location are excluded).
|
||||||
[Alias("Merge-MulipleSheets")]
|
.Example
|
||||||
param (
|
Merge-MulipleSheets -Path hotfixes.xlsx -WorksheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
|
||||||
#Paths to the files to be merged.
|
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()]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="False positives when initializing variable in begin block")]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification="MultipleSheet would be incorrect")]
|
||||||
|
#[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)]
|
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
|
||||||
[string[]]$Path ,
|
$Path ,
|
||||||
#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,
|
[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,
|
[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,
|
[switch]$NoHeader,
|
||||||
|
|
||||||
#Name(s) of worksheets to compare,
|
#Name(s) of Worksheets to compare.
|
||||||
$WorkSheetName = "Sheet1",
|
$WorksheetName = "Sheet1",
|
||||||
#File to write output to
|
#File to write output to.
|
||||||
[Alias('OutFile')]
|
[Alias('OutFile')]
|
||||||
$OutputFile = ".\temp.xlsx",
|
$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')]
|
[Alias('OutSheet')]
|
||||||
$OutputSheetName = "Sheet1",
|
$OutputSheetName = "Sheet1",
|
||||||
#Properties to include in the DIFF - supports wildcards, default is "*".
|
#Properties to include in the comparison - supports wildcards, default is "*".
|
||||||
$Property = "*" ,
|
$Property = "*" ,
|
||||||
#Properties to exclude from the the search - supports wildcards.
|
#Properties to exclude from the the comparison - supports wildcards.
|
||||||
$ExcludeProperty ,
|
$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" ,
|
$Key = "Name" ,
|
||||||
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
|
#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",
|
$KeyFontColor = [System.Drawing.Color]::Red,
|
||||||
#Sets the background color for changed rows.
|
#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.
|
#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.
|
#Sets the background color for rows not in the reference but added to the difference sheet.
|
||||||
[System.Drawing.Color]$AddBackgroundColor = "Orange",
|
$AddBackgroundColor = [System.Drawing.Color]::Orange,
|
||||||
#if Specified hides the columns in the spreadsheet that contain the row numbers
|
#If specified, hides the columns in the spreadsheet that contain the row numbers.
|
||||||
[switch]$HideRowNumbers ,
|
[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 ,
|
[switch]$Passthru ,
|
||||||
#If specified, opens the output workbook.
|
#If specified, opens the output workbook.
|
||||||
[Switch]$Show
|
[Switch]$Show
|
||||||
)
|
)
|
||||||
begin { $filestoProcess = @() }
|
begin { $filestoProcess = @() }
|
||||||
process { $filestoProcess += $Path}
|
process { $filestoProcess += $Path}
|
||||||
end {
|
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]). "
|
Write-Progress -Activity "Merging sheets" -CurrentOperation "Expanding * to names of sheets in $($filestoProcess[0]). "
|
||||||
$excel = Open-ExcelPackage -Path $filestoProcess
|
$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
|
Close-ExcelPackage -NoSave -ExcelPackage $excel
|
||||||
}
|
}
|
||||||
|
|
||||||
#Merge indentically named sheets in different work books;
|
#Merge identically named sheets in different work books;
|
||||||
if ($filestoProcess.Count -ge 2 -and $WorkSheetName -is "string" ) {
|
if ($filestoProcess.Count -ge 2 -and $WorksheetName -is "string" ) {
|
||||||
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorkSheetName' -ErrorAction SilentlyContinue |
|
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorksheetName' -ErrorAction SilentlyContinue |
|
||||||
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
|
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]
|
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[-1]
|
||||||
$nextFileNo = 2
|
$nextFileNo = 2
|
||||||
while ($nextFileNo -lt $filestoProcess.count -and $merged) {
|
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]
|
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[-$nextFileNo]
|
||||||
$nextFileNo ++
|
$nextFileNo ++
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#Merge different sheets from one workbook
|
#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 |
|
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty' -ErrorAction SilentlyContinue |
|
||||||
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
|
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
|
||||||
|
|
||||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-1]) against $($WorkSheetName[0]). "
|
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]
|
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[0,-1]
|
||||||
$nextSheetNo = 2
|
$nextSheetNo = 2
|
||||||
while ($nextSheetNo -lt $WorkSheetName.count -and $merged) {
|
while ($nextSheetNo -lt $WorksheetName.count -and $merged) {
|
||||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-$nextSheetNo]) against $($WorkSheetName[0]). "
|
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]
|
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[-$nextSheetNo] -DiffPrefix $WorksheetName[-$nextSheetNo]
|
||||||
$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 }
|
else { Write-Warning -Message "Need at least two files to process" ; return }
|
||||||
#if the process didn't return data then abandon now.
|
#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 }
|
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
|
$orderByProperties = $merged[0].psobject.properties.where({$_.name -match "row$"}).name
|
||||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Creating output sheet '$OutputSheetName' in $OutputFile"
|
Write-Progress -Activity "Merging sheets" -CurrentOperation "creating output sheet '$OutputSheetName' in $OutputFile"
|
||||||
$excel = $merged | Sort-Object -Property $orderByProperties | Update-FirstObjectProperties |
|
$excel = $merged | Sort-Object -Property $orderByProperties |
|
||||||
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
|
Export-Excel -Path $OutputFile -Worksheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
|
||||||
$sheet = $excel.Workbook.Worksheets[$OutputSheetName]
|
$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
|
#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
|
||||||
@@ -424,8 +481,8 @@ Function Merge-MultipleSheets {
|
|||||||
if ($filesToProcess.Count -ge 2) {
|
if ($filesToProcess.Count -ge 2) {
|
||||||
$refPrefix = (Split-Path -Path $filestoProcess[0] -Leaf) -replace "\.xlsx$"," "
|
$refPrefix = (Split-Path -Path $filestoProcess[0] -Leaf) -replace "\.xlsx$"," "
|
||||||
}
|
}
|
||||||
else {$refPrefix = $WorkSheetName[0] }
|
else {$refPrefix = $WorksheetName[0] }
|
||||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Applying formatting to sheet '$OutputSheetName' in $OutputFile"
|
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'
|
#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$"}) ) {
|
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
|
#Work leftwards across the headings applying conditional formatting which says
|
||||||
@@ -434,7 +491,7 @@ Function Merge-MultipleSheets {
|
|||||||
$columnNo = $cell.start.Column -1
|
$columnNo = $cell.start.Column -1
|
||||||
$cellAddr = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R1C$columnNo",1,$columnNo)
|
$cellAddr = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R1C$columnNo",1,$columnNo)
|
||||||
while ($sheet.cells[$cellAddr].value -match $prefix) {
|
while ($sheet.cells[$cellAddr].value -match $prefix) {
|
||||||
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='Solid'; 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 + '="Added"' ) -BackgroundColor $AddBackgroundColor
|
||||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Changed"') -BackgroundColor $ChangeBackgroundColor
|
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Changed"') -BackgroundColor $ChangeBackgroundColor
|
||||||
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Removed"') -BackgroundColor $DeleteBackgroundColor
|
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Removed"') -BackgroundColor $DeleteBackgroundColor
|
||||||
@@ -450,15 +507,16 @@ Function Merge-MultipleSheets {
|
|||||||
$nameRegex = $colNames -Join '|'
|
$nameRegex = $colNames -Join '|'
|
||||||
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -Notmatch $nameRegex}) ) {
|
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -Notmatch $nameRegex}) ) {
|
||||||
$cell.Value = $refPrefix + $cell.Value
|
$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)}
|
$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 ("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
|
#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()
|
$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 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 '*') {
|
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)
|
$sheet.view.FreezePanes(2, 3)
|
||||||
}
|
}
|
||||||
else {$sheet.view.FreezePanes(2, 2) }
|
else {$sheet.view.FreezePanes(2, 2) }
|
||||||
@@ -473,8 +531,8 @@ Function Merge-MultipleSheets {
|
|||||||
$sheet.Column($cell.start.Column).HIDDEN = $true
|
$sheet.Column($cell.start.Column).HIDDEN = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($Passthru) {$excel}
|
||||||
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
|
else {Close-ExcelPackage -ExcelPackage $excel -Show:$Show}
|
||||||
Write-Progress -Activity "Merging sheets" -Completed
|
Write-Progress -Activity "Merging sheets" -Completed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
function New-ConditionalFormattingIconSet {
|
function New-ConditionalFormattingIconSet {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Creates an object which describes a conditional formatting rule a for 3,4 or 5 icon set
|
Creates an object which describes a conditional formatting rule a for 3,4 or 5 icon set.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Export-Excel takes a -ConditionalFormat parameter which can hold one or more descriptions for conditional formats;
|
Export-Excel takes a -ConditionalFormat parameter which can hold one or more descriptions for conditional formats;
|
||||||
this command builds the
|
this command builds the defintion of a Conditional formatting rule for an icon set.
|
||||||
.PARAMETER Range
|
.PARAMETER Range
|
||||||
The range of cells that the conditional format applies to
|
The range of cells that the conditional format applies to.
|
||||||
.PARAMETER ConditionalFormat
|
.PARAMETER ConditionalFormat
|
||||||
The type of rule: one of "ThreeIconSet","FourIconSet" or "FiveIconSet"
|
The type of rule: one of "ThreeIconSet","FourIconSet" or "FiveIconSet"
|
||||||
.PARAMETER IconType
|
.PARAMETER IconType
|
||||||
The name of an iconSet - different icons are available depending on whether 3,4 or 5 icon set is selected
|
The name of an iconSet - different icons are available depending on whether 3,4 or 5 icon set is selected.
|
||||||
.PARAMETER Reverse
|
.PARAMETER Reverse
|
||||||
Use the icons in the reverse order.
|
Use the icons in the reverse order.
|
||||||
.Example
|
.Example
|
||||||
@@ -18,10 +18,16 @@ function New-ConditionalFormattingIconSet {
|
|||||||
$cfdef = New-ConditionalFormattingIconSet -Range $cfrange -ConditionalFormat ThreeIconSet -IconType Arrows
|
$cfdef = New-ConditionalFormattingIconSet -Range $cfrange -ConditionalFormat ThreeIconSet -IconType Arrows
|
||||||
Export-Excel -ExcelPackage $excel -ConditionalFormat $cfdef -show
|
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 first line creates a range - one column wide in the column $column, running
|
||||||
The second creates a definition object using this range
|
from $topRow to $lastDataRow.
|
||||||
and the third uses Export-Excel with an open package to apply the format and save and open the file.
|
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
|
||||||
#>
|
#>
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
$Range,
|
$Range,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ function New-ConditionalText {
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Some Conditional formatting rules don't apply styles to a cell (IconSets and Databars).
|
Some Conditional formatting rules don't apply styles to a cell (IconSets and Databars).
|
||||||
Some take two parameters (Between).
|
Some take two parameters (Between).
|
||||||
Some take none (ThisWeek , containsErrors, AboveAverage etc).
|
Some take none (ThisWeek, ContainsErrors, AboveAverage etc).
|
||||||
The others take a single parameter (Top, BottomPercent, GreaterThan, Contains 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.
|
This command creates an object to describe the last two categories, which can then be passed to Export-Excel.
|
||||||
.PARAMETER Range
|
.PARAMETER Range
|
||||||
@@ -13,35 +13,44 @@ function New-ConditionalText {
|
|||||||
.PARAMETER ConditionalType
|
.PARAMETER ConditionalType
|
||||||
One of the supported rules; by default "ContainsText" is selected.
|
One of the supported rules; by default "ContainsText" is selected.
|
||||||
.PARAMETER Text
|
.PARAMETER Text
|
||||||
The text (or other value) to use in the rule. Not that Equals, GreaterThan/LessThan rules require text to wrapped in double quotes.
|
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
|
.PARAMETER ConditionalTextColor
|
||||||
The font color for the cell - by default: Dark red.
|
The font color for the cell - by default: "DarkRed".
|
||||||
.PARAMETER BackgroundColor
|
.PARAMETER BackgroundColor
|
||||||
The fill color for the cell - by default: Light pink.
|
The fill color for the cell - by default: "LightPink".
|
||||||
.PARAMETER PatternType
|
.PARAMETER PatternType
|
||||||
The Background pattern for the cell - by default: Solid
|
The background pattern for the cell - by default: "Solid"
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
|
>
|
||||||
$ct = New-ConditionalText -Text 'Ferrari'
|
$ct = New-ConditionalText -Text 'Ferrari'
|
||||||
Export-Excel -ExcelPackage $excel -ConditionalTest $ct -show
|
Export-Excel -ExcelPackage $excel -ConditionalTest $ct -show
|
||||||
|
|
||||||
The first line creates a definition object which will highlight the word "Ferrari" in any cell.
|
The first line creates a definition object which will highlight the word
|
||||||
and the second uses Export-Excel with an open package to apply the format and save and open the file.
|
"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
|
.EXAMPLE
|
||||||
|
>
|
||||||
$ct = New-ConditionalText -Text "Ferrari"
|
$ct = New-ConditionalText -Text "Ferrari"
|
||||||
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalTextColor Red -BackgroundColor White
|
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalTextColor Red -BackgroundColor White
|
||||||
Export-Excel -ExcelPackage $excel -ConditionalText $ct,$ct2 -show
|
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"
|
This builds on the previous example, and specifies a condition of <=3 with
|
||||||
the range could be written "C:C" to specify a named column, or "C2:C102" to specify certain cells in the column.
|
a format of red text on a white background; this applies to a named range
|
||||||
|
"Finish Position". The range could be written -Range "C:C" to specify a
|
||||||
|
named column, or -Range "C2:C102" to specify certain cells in the column.
|
||||||
|
.Link
|
||||||
|
Add-Add-ConditionalFormatting
|
||||||
|
New-ConditionalFormattingIconSet
|
||||||
#>
|
#>
|
||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||||
param(
|
param(
|
||||||
#[Parameter(Mandatory=$true)]
|
#[Parameter(Mandatory=$true)]
|
||||||
[Alias("ConditionValue")]
|
[Alias("ConditionValue")]
|
||||||
$Text,
|
$Text,
|
||||||
[Alias("ForeGroundColor")]
|
[Alias("ForeGroundColor")]
|
||||||
[System.Drawing.Color]$ConditionalTextColor="DarkRed",
|
$ConditionalTextColor=[System.Drawing.Color]::DarkRed,
|
||||||
[System.Drawing.Color]$BackgroundColor="LightPink",
|
$BackgroundColor=[System.Drawing.Color]::LightPink,
|
||||||
[String]$Range,
|
[String]$Range,
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$PatternType=[OfficeOpenXml.Style.ExcelFillStyle]::Solid,
|
[OfficeOpenXml.Style.ExcelFillStyle]$PatternType=[OfficeOpenXml.Style.ExcelFillStyle]::Solid,
|
||||||
[ValidateSet(
|
[ValidateSet(
|
||||||
|
|||||||
@@ -20,23 +20,23 @@
|
|||||||
.PARAMETER YRange
|
.PARAMETER YRange
|
||||||
The range(s) of cells holding values for the Y-Axis - usually "data".
|
The range(s) of cells holding values for the Y-Axis - usually "data".
|
||||||
.PARAMETER Width
|
.PARAMETER Width
|
||||||
Width of the chart in Pixels. Defaults to 500.
|
Width of the chart in pixels. Defaults to 500.
|
||||||
.PARAMETER Height
|
.PARAMETER Height
|
||||||
Height of the chart in Pixels. Defaults to 350.
|
Height of the chart in pixels. Defaults to 350.
|
||||||
.PARAMETER Row
|
.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.
|
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
|
.PARAMETER RowOffSetPixels
|
||||||
Offset to position the chart by a fraction of of a row.
|
Offset to position the chart by a fraction of a row.
|
||||||
.PARAMETER Column
|
.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.
|
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
|
.PARAMETER ColumnOffSetPixels
|
||||||
Offset to position the chart by a fraction of of a column.
|
Offset to position the chart by a fraction of a column.
|
||||||
.PARAMETER NoLegend
|
.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.
|
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
|
.PARAMETER SeriesHeader
|
||||||
Specify explicit name(s) for the data series, which will appear in the legend/key
|
Specifies explicit name(s) for the data series, which will appear in the legend/key
|
||||||
.PARAMETER LegendPosition
|
.PARAMETER LegendPosition
|
||||||
Location of the key, either left, right, top, bottom or TopRight.
|
Location of the key, either "Left", "Right", "Top", "Bottom" or "TopRight".
|
||||||
.PARAMETER LegendSize
|
.PARAMETER LegendSize
|
||||||
Font size for the key.
|
Font size for the key.
|
||||||
.PARAMETER LegendBold
|
.PARAMETER LegendBold
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
.PARAMETER XMinValue
|
.PARAMETER XMinValue
|
||||||
Minimum value for the scale along the X-axis.
|
Minimum value for the scale along the X-axis.
|
||||||
.PARAMETER xAxisPosition
|
.PARAMETER xAxisPosition
|
||||||
Postion for the X-axis (Top or Bottom).
|
Position for the X-axis ("Top" or" Bottom").
|
||||||
.PARAMETER YAxisTitleText
|
.PARAMETER YAxisTitleText
|
||||||
Specifies a title for the Y-axis.
|
Specifies a title for the Y-axis.
|
||||||
.PARAMETER YAxisTitleBold
|
.PARAMETER YAxisTitleBold
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
.PARAMETER YMinValue
|
.PARAMETER YMinValue
|
||||||
Minimum value on the Y-axis.
|
Minimum value on the Y-axis.
|
||||||
.PARAMETER YAxisPosition
|
.PARAMETER YAxisPosition
|
||||||
Postion for the Y-axis (Left or Right).
|
Position for the Y-axis ("Left" or "Right").
|
||||||
.PARAMETER Header
|
.PARAMETER Header
|
||||||
No longer used. This may be removed in future versions.
|
No longer used. This may be removed in future versions.
|
||||||
.Example
|
.Example
|
||||||
@@ -92,10 +92,12 @@
|
|||||||
|
|
||||||
0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -now -WorkSheetname SinX -ExcelChartDefinition $cDef -Show
|
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 definition is defined and then it is used in a call to Export-Excel.
|
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.
|
[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()]
|
[cmdletbinding()]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||||
param(
|
param(
|
||||||
$Title = "Chart Title",
|
$Title = "Chart Title",
|
||||||
$Header,
|
$Header,
|
||||||
@@ -218,7 +220,7 @@ function Add-ExcelChart {
|
|||||||
.PARAMETER NoLegend
|
.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.
|
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
|
.PARAMETER SeriesHeader
|
||||||
Specify explicit name(s) for the data series, which will appear in the legend/key
|
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
|
.PARAMETER LegendPosition
|
||||||
Location of the key, either left, right, top, bottom or TopRight.
|
Location of the key, either left, right, top, bottom or TopRight.
|
||||||
.PARAMETER LegendSize
|
.PARAMETER LegendSize
|
||||||
@@ -348,7 +350,7 @@ function Add-ExcelChart {
|
|||||||
[Switch]$NoLegend,
|
[Switch]$NoLegend,
|
||||||
[Switch]$ShowCategory,
|
[Switch]$ShowCategory,
|
||||||
[Switch]$ShowPercent,
|
[Switch]$ShowPercent,
|
||||||
$SeriesHeader,
|
[String[]]$SeriesHeader,
|
||||||
[Switch]$TitleBold,
|
[Switch]$TitleBold,
|
||||||
[Int]$TitleSize ,
|
[Int]$TitleSize ,
|
||||||
[String]$XAxisTitleText,
|
[String]$XAxisTitleText,
|
||||||
@@ -387,8 +389,16 @@ function Add-ExcelChart {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
|
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
|
||||||
$Series = $chart.Series.Add($YRange[$idx], $XRange)
|
if ($Yrange.count -eq $xrange.count) {
|
||||||
if ($SeriesHeader.Count -gt 0) { $Series.Header = $SeriesHeader[$idx] }
|
$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)"}
|
else { $Series.Header = "Series $($idx)"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,14 +410,16 @@ function Add-ExcelChart {
|
|||||||
}
|
}
|
||||||
if ($NoLegend) { $chart.Legend.Remove() }
|
if ($NoLegend) { $chart.Legend.Remove() }
|
||||||
else {
|
else {
|
||||||
if ($LegendPosition) {$Chart.Legend.Position = $LegendPosition}
|
if ($PSBoundParameters.ContainsKey('LegendPosition')) {$chart.Legend.Position = $LegendPosition}
|
||||||
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
|
if ($PSBoundParameters.ContainsKey('LegendBold')) {$chart.Legend.Font.Bold = [boolean]$LegendBold}
|
||||||
if ($legendBold) {$chart.Legend.Font.Bold = $true}
|
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($XAxisTitleText) {
|
if ($XAxisTitleText) {
|
||||||
$chart.XAxis.Title.Text = $XAxisTitleText
|
$chart.XAxis.Title.Text = $XAxisTitleText
|
||||||
if ($XAxisTitleBold) {$chart.XAxis.Title.Font.Bold = $true}
|
if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) {
|
||||||
|
$chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold
|
||||||
|
}
|
||||||
if ($XAxisTitleSize) {$chart.XAxis.Title.Font.Size = $XAxisTitleSize}
|
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" }
|
if ($XAxisPosition) {Write-Warning "X-axis position is not being set propertly at the moment, parameter ignored" }
|
||||||
@@ -420,7 +432,9 @@ function Add-ExcelChart {
|
|||||||
|
|
||||||
if ($YAxisTitleText) {
|
if ($YAxisTitleText) {
|
||||||
$chart.YAxis.Title.Text = $YAxisTitleText
|
$chart.YAxis.Title.Text = $YAxisTitleText
|
||||||
if ($YAxisTitleBold) {$chart.YAxis.Title.Font.Bold = $true}
|
if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) {
|
||||||
|
$chart.YAxis.Title.Font.Bold = [boolean]$YAxisTitleBold
|
||||||
|
}
|
||||||
if ($YAxisTitleSize) {$chart.YAxis.Title.Font.Size = $YAxisTitleSize}
|
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" }
|
if ($YAxisPosition) {Write-Warning "Y-axis position is not being set propertly at the moment, parameter ignored" }
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='New*', Justification='Does not change system State')]
|
||||||
|
param()
|
||||||
function New-PSItem {
|
function New-PSItem {
|
||||||
|
|
||||||
$totalArgs = $args.Count
|
$totalArgs = $args.Count
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
#Requires -Modules Pester
|
|
||||||
|
|
||||||
|
|
||||||
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
||||||
|
|
||||||
|
|
||||||
Import-Module $here -Force
|
|
||||||
|
|
||||||
$WarningPreference = 'SilentlyContinue'
|
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
|
||||||
|
|
||||||
Function Test-isNumeric {
|
|
||||||
Param (
|
|
||||||
[Parameter(ValueFromPipeline)]$x
|
|
||||||
)
|
|
||||||
|
|
||||||
Return $x -is [byte] -or $x -is [int16] -or $x -is [int32] -or $x -is [int64] `
|
|
||||||
-or $x -is [sbyte] -or $x -is [uint16] -or $x -is [uint32] -or $x -is [uint64] `
|
|
||||||
-or $x -is [float] -or $x -is [double] -or $x -is [decimal]
|
|
||||||
}
|
|
||||||
|
|
||||||
$fakeData = [PSCustOmobject]@{
|
|
||||||
Property_1_Date = (Get-Date).ToString('d') # US '10/16/2017' BE '16/10/2107'
|
|
||||||
Property_2_Formula = '=SUM(G2:H2)'
|
|
||||||
Property_3_String = 'My String'
|
|
||||||
Property_4_String = 'a'
|
|
||||||
Property_5_IPAddress = '10.10.25.5'
|
|
||||||
Property_6_Number = '0'
|
|
||||||
Property_7_Number = '5'
|
|
||||||
Property_8_Number = '007'
|
|
||||||
Property_9_Number = (33).ToString('F2') # US '33.00' BE '33,00'
|
|
||||||
Property_10_Number = (5/3).ToString('F2') # US '1.67' BE '1,67'
|
|
||||||
Property_11_Number = (15999998/3).ToString('N2') # US '5,333,332.67' BE '5.333.332,67'
|
|
||||||
Property_12_Number = '1.555,83'
|
|
||||||
Property_13_PhoneNr = '+32 44'
|
|
||||||
Property_14_PhoneNr = '+32 4 4444 444'
|
|
||||||
Property_15_PhoneNr = '+3244444444'
|
|
||||||
}
|
|
||||||
|
|
||||||
$Path = 'Test.xlsx'
|
|
||||||
|
|
||||||
Describe 'Export-Excel' {
|
|
||||||
in $TestDrive {
|
|
||||||
Describe 'Number conversion' {
|
|
||||||
Context 'numerical values expected' {
|
|
||||||
#region Create test file
|
|
||||||
$fakeData | Export-Excel -Path $Path
|
|
||||||
|
|
||||||
$Path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
|
|
||||||
$Excel = New-Object OfficeOpenXml.ExcelPackage $Path
|
|
||||||
$Worksheet = $Excel.Workbook.WorkSheets[1]
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
it 'zero' {
|
|
||||||
$fakeData.Property_6_Number | Should -BeExactly '0'
|
|
||||||
$Worksheet.Cells[2, 6].Text | Should -BeExactly $fakeData.Property_6_Number
|
|
||||||
$Worksheet.Cells[2, 6].Value | Test-isNumeric | Should -Be $true
|
|
||||||
}
|
|
||||||
|
|
||||||
It 'regular number' {
|
|
||||||
$fakeData.Property_7_Number | Should -BeExactly '5'
|
|
||||||
$Worksheet.Cells[2, 7].Text | Should -BeExactly $fakeData.Property_7_Number
|
|
||||||
$Worksheet.Cells[2, 7].Value | Test-isNumeric | Should -Be $true
|
|
||||||
}
|
|
||||||
|
|
||||||
It 'number starting with zero' {
|
|
||||||
$fakeData.Property_8_Number | Should -BeExactly '007'
|
|
||||||
$Worksheet.Cells[2, 8].Text | Should -BeExactly '7'
|
|
||||||
$Worksheet.Cells[2, 8].Value | Test-isNumeric | Should -Be $true
|
|
||||||
}
|
|
||||||
|
|
||||||
It 'decimal number' {
|
|
||||||
# US '33.00' BE '33,00'
|
|
||||||
$fakeData.Property_9_Number | Should -BeExactly (33).ToString('F2')
|
|
||||||
$Worksheet.Cells[2, 9].Text | Should -BeExactly '33'
|
|
||||||
$Worksheet.Cells[2, 9].Value | Test-isNumeric | Should -Be $true
|
|
||||||
|
|
||||||
# US '1.67' BE '1,67'
|
|
||||||
$fakeData.Property_10_Number | Should -BeExactly (5/3).ToString('F2')
|
|
||||||
$Worksheet.Cells[2, 10].Text | Should -BeExactly $fakeData.Property_10_Number
|
|
||||||
$Worksheet.Cells[2, 10].Value | Test-isNumeric | Should -Be $true
|
|
||||||
}
|
|
||||||
|
|
||||||
It 'thousand seperator and decimal number' {
|
|
||||||
# US '5,333,332.67' BE '5.333.332,67'
|
|
||||||
# Excel BE '5333332,67'
|
|
||||||
$fakeData.Property_11_Number | Should -BeExactly (15999998/3).ToString('N2')
|
|
||||||
$Worksheet.Cells[2, 11].Text | Should -BeExactly $fakeData.Property_11_Number
|
|
||||||
$Worksheet.Cells[2, 11].Value | Test-isNumeric | Should -Be $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,22 @@
|
|||||||
Function Open-ExcelPackage {
|
Function Open-ExcelPackage {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Returns an Excel Package Object for the specified XLSX file
|
Returns an ExcelPackage object for the specified XLSX fil.e
|
||||||
.Description
|
.Description
|
||||||
Import-Excel and Export-Excel open an Excel file, carry out their tasks and close it again.
|
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-Excel package allows the file to be opened for these tasks.
|
Sometimes it is necessary to open a file and do other work on it.
|
||||||
It takes a KillExcel switch to make sure Excel is not holding the file open; a password parameter for existing protected files,
|
Open-ExcelPackage allows the file to be opened for these tasks.
|
||||||
and a create switch to set-up a new file if no file already exists.
|
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
|
.Example
|
||||||
>
|
>
|
||||||
PS> $excel = Open-ExcelPackage -Path "$env:TEMP\test99.xlsx" -Create
|
PS> $excel = Open-ExcelPackage -Path "$env:TEMP\test99.xlsx" -Create
|
||||||
$ws = Add-WorkSheet -ExcelPackage $excel
|
$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 -
|
This will create a new file in the temp folder if it doesn't already exist.
|
||||||
because no name is specified it will use the default name of "Sheet1"
|
It then adds a worksheet - because no name is specified it will use the
|
||||||
|
default name of "Sheet1"
|
||||||
.Example
|
.Example
|
||||||
>
|
>
|
||||||
PS> $excel = Open-ExcelPackage -path "$xlPath" -Password $password
|
PS> $excel = Open-ExcelPackage -path "$xlPath" -Password $password
|
||||||
@@ -21,20 +24,21 @@
|
|||||||
Set-ExcelRange -Range $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
|
Close-ExcelPackage $excel -Show
|
||||||
|
|
||||||
This will open the password protected file at $xlPath using the password stored in $Password.
|
This will open the password protected file at $xlPath using the password stored
|
||||||
Sheet1 is selected and formatting applied to two blocks of the sheet; then the file is and saved and loaded into Excel.
|
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()]
|
[CmdLetBinding()]
|
||||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
||||||
[OutputType([OfficeOpenXml.ExcelPackage])]
|
[OutputType([OfficeOpenXml.ExcelPackage])]
|
||||||
Param (
|
Param (
|
||||||
#The Path to the file to open
|
#The path to the file to open.
|
||||||
[Parameter(Mandatory=$true)]$Path,
|
[Parameter(Mandatory=$true)]$Path,
|
||||||
#If specified, any running instances of Excel will be terminated before opening the file.
|
#If specified, any running instances of Excel will be terminated before opening the file.
|
||||||
[switch]$KillExcel,
|
[switch]$KillExcel,
|
||||||
#The password for a protected worksheet, as a [normal] string (not a secure string.)
|
#The password for a protected worksheet, as a [normal] string (not a secure string).
|
||||||
[String]$Password,
|
[String]$Password,
|
||||||
#By default open only opens an existing file; -Create instructs it to create a new file if required.
|
#By default Open-ExcelPackage will only opens an existing file; -Create instructs it to create a new file if required.
|
||||||
[switch]$Create
|
[switch]$Create
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
193
PivotTable.ps1
193
PivotTable.ps1
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
Add-PivotTable -PivotTableName Sales -Address $excel.Workbook.Worksheets[1].Cells["F1"] `
|
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"} `
|
-SourceWorkSheet $excel.Workbook.Worksheets[1] -PivotRows City -PivotColumns Product -PivotData @{Gross="Sum";Net="Sum"} `
|
||||||
-PivotNumberFormat "$#,##0.00" -PivotTotals Both -PivotTableSyle Medium12 -PivotChartDefinition $chartdef
|
-PivotNumberFormat "$#,##0.00" -PivotTotals Both -PivotTableStyle Medium12 -PivotChartDefinition $chartdef
|
||||||
Close-ExcelPackage -show $excel
|
Close-ExcelPackage -show $excel
|
||||||
|
|
||||||
|
|
||||||
@@ -38,9 +38,53 @@
|
|||||||
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
|
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;
|
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.
|
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.
|
Note that in the chart definition the number format for the axis does not include any fraction part.
|
||||||
|
.Example
|
||||||
|
>
|
||||||
|
$excel = Convertfrom-csv @"
|
||||||
|
Location,OrderDate,quantity
|
||||||
|
Boston,1/1/2017,100
|
||||||
|
New York,1/21/2017,200
|
||||||
|
Boston,1/11/2017,300
|
||||||
|
New York,1/9/2017,400
|
||||||
|
Boston,1/18/2017,500
|
||||||
|
Boston,2/1/2017,600
|
||||||
|
New York,2/21/2017,700
|
||||||
|
New York,2/11/2017,800
|
||||||
|
Boston,2/9/2017,900
|
||||||
|
Boston,2/18/2017,1000
|
||||||
|
New York,1/1/2018,100
|
||||||
|
Boston,1/21/2018,200
|
||||||
|
New York,1/11/2018,300
|
||||||
|
Boston,1/9/2018,400
|
||||||
|
New York,1/18/2018,500
|
||||||
|
Boston,2/1/2018,600
|
||||||
|
Boston,2/21/2018,700
|
||||||
|
New York,2/11/2018,800
|
||||||
|
New York,2/9/2018,900
|
||||||
|
Boston,2/18/2018,1000
|
||||||
|
"@ | Select-Object -Property @{n="OrderDate";e={[datetime]::ParseExact($_.OrderDate,"M/d/yyyy",(Get-Culture))}},
|
||||||
|
Location, Quantity | Export-Excel "test2.xlsx" -PassThru -AutoSize
|
||||||
|
|
||||||
|
Set-ExcelColumn -Worksheet $excel.sheet1 -Column 1 -NumberFormat 'Short Date'
|
||||||
|
|
||||||
|
$pt = Add-PivotTable -PassThru -PivotTableName "ByDate" -Address $excel.Sheet1.cells["F1"] -SourceWorkSheet $excel.Sheet1 -PivotRows location,orderdate -PivotData @{'quantity'='sum'} -GroupDateRow orderdate -GroupDatePart 'Months,Years' -PivotTotals None
|
||||||
|
$pt.RowFields[0].SubtotalTop=$false
|
||||||
|
$pt.RowFields[0].Compact=$false
|
||||||
|
Close-ExcelPackage $excel -Show
|
||||||
|
|
||||||
|
Here the data contains dates formatted as strings using US format. These
|
||||||
|
are converted to DateTime objects before being exported to Excel; the
|
||||||
|
"OrderDate" column is formatted with the local short-date style. Then
|
||||||
|
the PivotTable is added; it groups information by date and location, the
|
||||||
|
date is split into years and then months. No grand totals are displayed.
|
||||||
|
The Pivot table object is caught in a variable, and the "Location"
|
||||||
|
column has its subtotal moved from the top to the bottom of each location
|
||||||
|
section, and the "Compact" option is disabled to prevent "Year" moving
|
||||||
|
into the same column as location.
|
||||||
|
Finally the workbook is saved and shown in Excel.
|
||||||
#>
|
#>
|
||||||
[cmdletbinding(defaultParameterSetName='ChartbyParams')]
|
[cmdletbinding(defaultParameterSetName = 'ChartbyParams')]
|
||||||
[OutputType([OfficeOpenXml.Table.PivotTable.ExcelPivotTable])]
|
[OutputType([OfficeOpenXml.Table.PivotTable.ExcelPivotTable])]
|
||||||
param (
|
param (
|
||||||
#Name for the new PivotTable - this will be the name of a sheet in the Workbook.
|
#Name for the new PivotTable - this will be the name of a sheet in the Workbook.
|
||||||
@@ -67,52 +111,64 @@
|
|||||||
#If there are multiple data items in a PivotTable, by default they are shown on separate rows; this switch makes them separate columns.
|
#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,
|
[Switch]$PivotDataToColumn,
|
||||||
#Define whether totals should be added to rows, columns neither, or both (the default is both).
|
#Define whether totals should be added to rows, columns neither, or both (the default is both).
|
||||||
[ValidateSet("Both","Columns","Rows","None")]
|
[ValidateSet("Both", "Columns", "Rows", "None")]
|
||||||
[String]$PivotTotals = "Both",
|
[String]$PivotTotals = "Both",
|
||||||
#Included for compatibility - equivalent to -PivotTotals "None".
|
#Included for compatibility - equivalent to -PivotTotals "None".
|
||||||
[Switch]$NoTotalsInPivot,
|
[Switch]$NoTotalsInPivot,
|
||||||
|
#The name of a row field which should be grouped by parts of the date/time (ignored if GroupDateRow is not specified)
|
||||||
|
[String]$GroupDateRow,
|
||||||
|
#The Part(s) of the date to use in the grouping (ignored if GroupDateRow is not specified)
|
||||||
|
[OfficeOpenXml.Table.PivotTable.eDateGroupBy[]]$GroupDatePart,
|
||||||
|
#The name of a row field which should be grouped by Number (e.g 0-99, 100-199, 200-299 )
|
||||||
|
[String]$GroupNumericRow,
|
||||||
|
#The starting point for grouping
|
||||||
|
[double]$GroupNumericMin = 0 ,
|
||||||
|
#The endpoint for grouping
|
||||||
|
[double]$GroupNumericMax = [Double]::MaxValue ,
|
||||||
|
#The interval for grouping
|
||||||
|
[double]$GroupNumericInterval = 100 ,
|
||||||
#Number format to apply to the data cells in the PivotTable.
|
#Number format to apply to the data cells in the PivotTable.
|
||||||
[string]$PivotNumberFormat,
|
[string]$PivotNumberFormat,
|
||||||
#Apply a table style to the PivotTable.
|
#Apply a table style to the PivotTable.
|
||||||
[OfficeOpenXml.Table.TableStyles]$PivotTableSyle,
|
[OfficeOpenXml.Table.TableStyles]$PivotTableStyle,
|
||||||
#Use a chart definition instead of specifying chart settings one by one.
|
#Use a chart definition instead of specifying chart settings one by one.
|
||||||
[Parameter(ParameterSetName='ChartbyDef', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
|
[Parameter(ParameterSetName = 'ChartbyDef', Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
|
||||||
$PivotChartDefinition,
|
$PivotChartDefinition,
|
||||||
#If specified, a chart will be included.
|
#If specified, a chart will be included.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$IncludePivotChart,
|
[Switch]$IncludePivotChart,
|
||||||
#Optional title for the pivot chart, by default the title omitted.
|
#Optional title for the pivot chart, by default the title omitted.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[String]$ChartTitle = "",
|
[String]$ChartTitle = "",
|
||||||
#Height of the chart in Pixels (400 by default).
|
#Height of the chart in Pixels (400 by default).
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[int]$ChartHeight = 400 ,
|
[int]$ChartHeight = 400 ,
|
||||||
#Width of the chart in Pixels (600 by default).
|
#Width of the chart in Pixels (600 by default).
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[int]$ChartWidth = 600,
|
[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).
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartRow = 0 ,
|
[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).
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartColumn = 4,
|
[Int]$ChartColumn = 4,
|
||||||
#Vertical offset of the chart from the cell corner.
|
#Vertical offset of the chart from the cell corner.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartRowOffSetPixels = 0 ,
|
[Int]$ChartRowOffSetPixels = 0 ,
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
#Horizontal offset of the chart from the cell corner.
|
#Horizontal offset of the chart from the cell corner.
|
||||||
[Int]$ChartColumnOffSetPixels = 0,
|
[Int]$ChartColumnOffSetPixels = 0,
|
||||||
#Type of chart; defaults to "Pie".
|
#Type of chart; defaults to "Pie".
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
||||||
#If specified hides the chart legend.
|
#If specified hides the chart legend.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$NoLegend,
|
[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.
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$ShowCategory,
|
[Switch]$ShowCategory,
|
||||||
#If specified attaches percentages to slices in a pie chart.
|
#If specified attaches percentages to slices in a pie chart.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$ShowPercent,
|
[Switch]$ShowPercent,
|
||||||
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified.
|
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified.
|
||||||
[switch]$Activate,
|
[switch]$Activate,
|
||||||
@@ -121,7 +177,7 @@
|
|||||||
)
|
)
|
||||||
if ($PivotTableName.length -gt 250) {
|
if ($PivotTableName.length -gt 250) {
|
||||||
Write-warning -Message "PivotTable name will be truncated"
|
Write-warning -Message "PivotTable name will be truncated"
|
||||||
$PivotTableName = $PivotTableName.Substring(0,250)
|
$PivotTableName = $PivotTableName.Substring(0, 250)
|
||||||
}
|
}
|
||||||
if ($Address) {
|
if ($Address) {
|
||||||
[OfficeOpenXml.ExcelWorksheet]$wsPivot = $address.Worksheet
|
[OfficeOpenXml.ExcelWorksheet]$wsPivot = $address.Worksheet
|
||||||
@@ -131,7 +187,7 @@
|
|||||||
if (-not $ExcelPackage) {Write-Warning -message "This combination of Parameters needs to include the ExcelPackage." ; return }
|
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
|
[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 ($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"]}
|
if ($PivotFilter) {$Address = $wsPivot.Cells["A3"]} else { $Address = $wsPivot.Cells["A1"]}
|
||||||
}
|
}
|
||||||
catch {throw "Could not create the sheet for the PivotTable. $_" }
|
catch {throw "Could not create the sheet for the PivotTable. $_" }
|
||||||
}
|
}
|
||||||
@@ -140,25 +196,25 @@
|
|||||||
if (-not $wsPivot.PivotTables[$pivotTableName] ) {
|
if (-not $wsPivot.PivotTables[$pivotTableName] ) {
|
||||||
try {
|
try {
|
||||||
#Accept a string or a worksheet object as $SourceWorksheet - we don't need a worksheet if we have a Rangebase .
|
#Accept a string or a worksheet object as $SourceWorksheet - we don't need a worksheet if we have a Rangebase .
|
||||||
if ( $SourceWorkSheet -is [string]) {
|
if ( $SourceWorkSheet -is [string]) {
|
||||||
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets.where( {$_.name -Like $SourceWorkSheet})[0]
|
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets.where( {$_.name -Like $SourceWorkSheet})[0]
|
||||||
}
|
}
|
||||||
elseif ( $SourceWorkSheet -is [int] ) {
|
elseif ( $SourceWorkSheet -is [int] ) {
|
||||||
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets[$SourceWorkSheet]
|
$SourceWorkSheet = $ExcelPackage.Workbook.Worksheets[$SourceWorkSheet]
|
||||||
}
|
}
|
||||||
if ( $SourceRange -is [OfficeOpenXml.Table.ExcelTable]) {$SourceRange = $SourceRange.Address }
|
if ( $SourceRange -is [OfficeOpenXml.Table.ExcelTable]) {$SourceRange = $SourceRange.Address }
|
||||||
if ( $sourceRange -is [OfficeOpenXml.ExcelRange] -or
|
if ( $sourceRange -is [OfficeOpenXml.ExcelRange] -or
|
||||||
$SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
$SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
||||||
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceRange, $pivotTableName)
|
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceRange, $pivotTableName)
|
||||||
}
|
}
|
||||||
elseif (-not $SourceRange) {
|
elseif (-not $SourceRange) {
|
||||||
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceWorkSheet.cells[$SourceWorkSheet.Dimension.Address], $pivotTableName)
|
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceWorkSheet.cells[$SourceWorkSheet.Dimension.Address], $pivotTableName)
|
||||||
}
|
}
|
||||||
elseif ($SourceWorkSheet -isnot [OfficeOpenXml.ExcelWorksheet] ) {
|
elseif ($SourceWorkSheet -isnot [OfficeOpenXml.ExcelWorksheet] ) {
|
||||||
Write-Warning -Message "Could not find source Worksheet for pivot-table '$pivotTableName'." ; return
|
Write-Warning -Message "Could not find source Worksheet for pivot-table '$pivotTableName'." ; return
|
||||||
}
|
}
|
||||||
elseif ( $SourceRange -is [String] -or $SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
elseif ( $SourceRange -is [String] -or $SourceRange -is [OfficeOpenXml.ExcelAddress]) {
|
||||||
$pivotTable = $wsPivot.PivotTables.Add($Address,$SourceWorkSheet.Cells[$SourceRange], $pivotTableName)
|
$pivotTable = $wsPivot.PivotTables.Add($Address, $SourceWorkSheet.Cells[$SourceRange], $pivotTableName)
|
||||||
}
|
}
|
||||||
else {Write-warning "Could not create a PivotTable with the Source Range provided."; return}
|
else {Write-warning "Could not create a PivotTable with the Source Range provided."; return}
|
||||||
foreach ($Row in $PivotRows) {
|
foreach ($Row in $PivotRows) {
|
||||||
@@ -192,13 +248,23 @@
|
|||||||
try { $null = $pivotTable.PageFields.Add($pivotTable.Fields[$pFilter])}
|
try { $null = $pivotTable.PageFields.Add($pivotTable.Fields[$pFilter])}
|
||||||
catch {Write-Warning -message "Could not add '$pFilter' to Filter/Page fields in PivotTable $pivotTableName." }
|
catch {Write-Warning -message "Could not add '$pFilter' to Filter/Page fields in PivotTable $pivotTableName." }
|
||||||
}
|
}
|
||||||
if ($NoTotalsInPivot) {$PivotTotals = "None" }
|
if ($NoTotalsInPivot) {$PivotTotals = "None" }
|
||||||
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Columns") { $pivotTable.RowGrandTotals = $false }
|
if ($PivotTotals -eq "None" -or $PivotTotals -eq "Columns") { $pivotTable.RowGrandTotals = $false }
|
||||||
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Rows") { $pivotTable.RowGrandTotals = $true }
|
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!
|
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 }
|
elseif ($PivotTotals -eq "Both" -or $PivotTotals -eq "Columns") { $pivotTable.ColumGrandTotals = $true }
|
||||||
if ($PivotDataToColumn ) { $pivotTable.DataOnRows = $false }
|
if ($PivotDataToColumn ) { $pivotTable.DataOnRows = $false }
|
||||||
if ($PivotTableSyle) { $pivotTable.TableStyle = $PivotTableSyle}
|
if ($PivotTableStyle) { $pivotTable.TableStyle = $PivotTableStyle}
|
||||||
|
if ($GroupNumericRow) {
|
||||||
|
$r = $pivotTable.RowFields.Where( {$_.name -eq $GroupNumericRow })
|
||||||
|
if (-not $r ) {Write-Warning -Message "Could not find a Row field named '$GroupNumericRow'; no numeric grouping will be done."}
|
||||||
|
else {$r.AddNumericGrouping($GroupNumericMin, $GroupNumericMax, $GroupNumericInterval)}
|
||||||
|
}
|
||||||
|
if ($GroupDateRow -and $PSBoundParameters.ContainsKey("GroupDatePart")) {
|
||||||
|
$r = $pivotTable.RowFields.Where( {$_.name -eq $GroupDateRow })
|
||||||
|
if (-not $r ) {Write-Warning -Message "Could not find a Row field named '$GroupDateRow'; no date grouping will be done."}
|
||||||
|
else {$r.AddDateGrouping($GroupDatePart)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch {Write-Warning -Message "Failed adding PivotTable '$pivotTableName': $_"}
|
catch {Write-Warning -Message "Failed adding PivotTable '$pivotTableName': $_"}
|
||||||
}
|
}
|
||||||
@@ -211,16 +277,16 @@
|
|||||||
|
|
||||||
#Create the chart if it doesn't exist, leave alone if it does.
|
#Create the chart if it doesn't exist, leave alone if it does.
|
||||||
if ($IncludePivotChart -and -not $wsPivot.Drawings["Chart$pivotTableName"] ) {
|
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 }
|
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': $_"}
|
catch {Write-Warning -Message "Failed adding chart for pivotable '$pivotTableName': $_"}
|
||||||
}
|
}
|
||||||
elseif ($PivotChartDefinition -and -not $wsPivot.Drawings["Chart$pivotTableName"]) {
|
elseif ($PivotChartDefinition -and -not $wsPivot.Drawings["Chart$pivotTableName"]) {
|
||||||
if ($PivotChartDefinition -is [System.Management.Automation.PSCustomObject]) {
|
if ($PivotChartDefinition -is [System.Management.Automation.PSCustomObject]) {
|
||||||
$params = @{PivotTable= $pivotTable }
|
$params = @{PivotTable = $pivotTable }
|
||||||
$PivotChartDefinition.PSObject.Properties | ForEach-Object {if ( $null -ne $_.value) {$params[$_.name] = $_.value}}
|
$PivotChartDefinition.PSObject.Properties | ForEach-Object {if ( $null -ne $_.value) {$params[$_.name] = $_.value}}
|
||||||
Add-ExcelChart @params
|
Add-ExcelChart @params
|
||||||
}
|
}
|
||||||
elseif ($PivotChartDefinition -is [hashtable] -or $PivotChartDefinition -is[System.Collections.Specialized.OrderedDictionary]) {
|
elseif ($PivotChartDefinition -is [hashtable] -or $PivotChartDefinition -is [System.Collections.Specialized.OrderedDictionary]) {
|
||||||
Add-ExcelChart -PivotTable $pivotTable @PivotChartDefinition
|
Add-ExcelChart -PivotTable $pivotTable @PivotChartDefinition
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,6 +312,7 @@ function New-PivotTableDefinition {
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
#>
|
#>
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[Alias("PivtoTableName")]#Previous typo - use alias to avoid breaking scripts
|
[Alias("PivtoTableName")]#Previous typo - use alias to avoid breaking scripts
|
||||||
@@ -267,59 +334,71 @@ function New-PivotTableDefinition {
|
|||||||
[Switch]$PivotDataToColumn,
|
[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.
|
#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)
|
#Define whther totals should be added to rows, columns neither, or both (the default is both)
|
||||||
[ValidateSet("Both","Columns","Rows","None")]
|
[ValidateSet("Both", "Columns", "Rows", "None")]
|
||||||
[String]$PivotTotals = "Both",
|
[String]$PivotTotals = "Both",
|
||||||
#Included for compatibility - equivalent to -PivotTotals "None"
|
#Included for compatibility - equivalent to -PivotTotals "None"
|
||||||
[Switch]$NoTotalsInPivot,
|
[Switch]$NoTotalsInPivot,
|
||||||
|
#The name of a row field which should be grouped by parts of the date/time (ignored if GroupDateRow is not specified)
|
||||||
|
[String]$GroupDateRow,
|
||||||
|
#The Part(s) of the date to use in the grouping (ignored if GroupDateRow is not specified)
|
||||||
|
[OfficeOpenXml.Table.PivotTable.eDateGroupBy[]]$GroupDatePart,
|
||||||
|
#The name of a row field which should be grouped by Number (e.g 0-99, 100-199, 200-299 )
|
||||||
|
[String]$GroupNumericRow,
|
||||||
|
#The starting point for grouping
|
||||||
|
[double]$GroupNumericMin = 0 ,
|
||||||
|
#The endpoint for grouping
|
||||||
|
[double]$GroupNumericMax = [Double]::MaxValue ,
|
||||||
|
#The interval for grouping
|
||||||
|
[double]$GroupNumericInterval = 100 ,
|
||||||
#Number format to apply to the data cells in the PivotTable
|
#Number format to apply to the data cells in the PivotTable
|
||||||
[string]$PivotNumberFormat,
|
[string]$PivotNumberFormat,
|
||||||
#Apply a table style to the PivotTable
|
#Apply a table style to the PivotTable
|
||||||
[OfficeOpenXml.Table.TableStyles]$PivotTableSyle,
|
[OfficeOpenXml.Table.TableStyles]$PivotTableStyle,
|
||||||
#Use a chart definition instead of specifying chart settings one by one
|
#Use a chart definition instead of specifying chart settings one by one
|
||||||
[Parameter(ParameterSetName='ChartbyDef', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
|
[Parameter(ParameterSetName = 'ChartbyDef', Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
|
||||||
$PivotChartDefinition,
|
$PivotChartDefinition,
|
||||||
#If specified a chart Will be included.
|
#If specified a chart Will be included.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$IncludePivotChart,
|
[Switch]$IncludePivotChart,
|
||||||
#Optional title for the pivot chart, by default the title omitted.
|
#Optional title for the pivot chart, by default the title omitted.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[String]$ChartTitle,
|
[String]$ChartTitle,
|
||||||
#Height of the chart in Pixels (400 by default)
|
#Height of the chart in Pixels (400 by default)
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[int]$ChartHeight = 400 ,
|
[int]$ChartHeight = 400 ,
|
||||||
#Width of the chart in Pixels (600 by default)
|
#Width of the chart in Pixels (600 by default)
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[int]$ChartWidth = 600,
|
[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).
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartRow = 0 ,
|
[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)
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartColumn = 4,
|
[Int]$ChartColumn = 4,
|
||||||
#Vertical offset of the chart from the cell corner.
|
#Vertical offset of the chart from the cell corner.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartRowOffSetPixels = 0 ,
|
[Int]$ChartRowOffSetPixels = 0 ,
|
||||||
#Horizontal offset of the chart from the cell corner.
|
#Horizontal offset of the chart from the cell corner.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Int]$ChartColumnOffSetPixels = 0,
|
[Int]$ChartColumnOffSetPixels = 0,
|
||||||
#Type of chart
|
#Type of chart
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
||||||
#If specified hides the chart legend
|
#If specified hides the chart legend
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$NoLegend,
|
[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.
|
#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')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$ShowCategory,
|
[Switch]$ShowCategory,
|
||||||
#If specified attaches percentages to slices in a pie chart.
|
#If specified attaches percentages to slices in a pie chart.
|
||||||
[Parameter(ParameterSetName='ChartbyParams')]
|
[Parameter(ParameterSetName = 'ChartbyParams')]
|
||||||
[Switch]$ShowPercent,
|
[Switch]$ShowPercent,
|
||||||
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
|
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
|
||||||
[switch]$Activate
|
[switch]$Activate
|
||||||
)
|
)
|
||||||
$validDataFuntions = [system.enum]::GetNames([OfficeOpenXml.Table.PivotTable.DataFieldFunctions])
|
$validDataFuntions = [system.enum]::GetNames([OfficeOpenXml.Table.PivotTable.DataFieldFunctions])
|
||||||
|
|
||||||
if ($PivotData.values.Where({$_ -notin $validDataFuntions}) ) {
|
if ($PivotData.values.Where( {$_ -notin $validDataFuntions}) ) {
|
||||||
Write-Warning -Message ("Pivot data functions might not be valid, they should be one of " + ($validDataFuntions -join ", ") + ".")
|
Write-Warning -Message ("Pivot data functions might not be valid, they should be one of " + ($validDataFuntions -join ", ") + ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,8 +409,8 @@ function New-PivotTableDefinition {
|
|||||||
}
|
}
|
||||||
$parameters.Remove('PivotTableName')
|
$parameters.Remove('PivotTableName')
|
||||||
if ($PivotChartDefinition) {
|
if ($PivotChartDefinition) {
|
||||||
$parameters.PivotChartDefinition.XRange = $null
|
$parameters.PivotChartDefinition.XRange = $null
|
||||||
$parameters.PivotChartDefinition.YRange = $null
|
$parameters.PivotChartDefinition.YRange = $null
|
||||||
$parameters.PivotChartDefinition.SeriesHeader = $null
|
$parameters.PivotChartDefinition.SeriesHeader = $null
|
||||||
}
|
}
|
||||||
@{$PivotTableName = $parameters}
|
@{$PivotTableName = $parameters}
|
||||||
|
|||||||
67
README.md
67
README.md
@@ -53,7 +53,72 @@ Install-Module ImportExcel -scope CurrentUser
|
|||||||
Install-Module ImportExcel
|
Install-Module ImportExcel
|
||||||
```
|
```
|
||||||
|
|
||||||
# What's new 5.3.3
|
# What's new 6.1.0
|
||||||
|
|
||||||
|
Thank you to [James O'Neill](https://github.com/jhoneill)
|
||||||
|
- Instead of specifying a path provides an Excel Package object (from `Open-ExcelPackage`), using this avoids re-reading the whole file when importing multiple parts of it. To allow multiple read operations `Import-Excel` does NOT close the package, and you should use `Close-ExcelPackage -noSave` to close it.
|
||||||
|
|
||||||
|
# What's new 6.0.0
|
||||||
|
|
||||||
|
Thank you to [James O'Neill](https://github.com/jhoneill) for the optimizations, and refactoring leading to a ***~10x*** speed increase. Thanks to [ili101](https://github.com/ili101) for earlier PRs that provided the ground work for this.
|
||||||
|
|
||||||
|
* Performance improvement to `Export-Excel` see [#506](https://github.com/dfinke/ImportExcel/issues/506) and [#555](https://github.com/dfinke/ImportExcel/issues/555). This has meant taking code in Add-CellValue back into process block of `Export-Excel`, as the overhead of calling the function was a lot greater than time executing the code inside it. [Blog post to follow](https://jamesone111.wordpress.com/). Some tests are showing a ***~10x*** speed increase. [#572](https://github.com/dfinke/ImportExcel/issues/572) was about a broken #region tag in this part of the code and that has been cleaned up in the process.
|
||||||
|
|
||||||
|
* `Export-Excel` now has an -InputObject parameter (this was previously -TargetData , which is now an alias for InputObject).
|
||||||
|
If the `inputobject` is an array, each item will be inserted, so you can run `export-excel -inputobject $x` rather than `$x | Export-Excel`, and if it is a `system.data.datatable` object it will be inserted directly rather than cell-by-cell. `Send-SQLDataToExcel` takes advantage of this new functionality. There are simple tests for these new items
|
||||||
|
|
||||||
|
* `Export-Excel` previously assumed `-Now` if there were no other parameters, it will now assume `-Now` if there is no `-Path` or `-ExcelPackage`.
|
||||||
|
The .PSD1 file now itemizes the items exported by the module [#557](https://github.com/dfinke/ImportExcel/issues/557)
|
||||||
|
|
||||||
|
# What's new 5.4.5
|
||||||
|
|
||||||
|
Thank you to [James O'Neill](https://github.com/jhoneill) for the great additions.
|
||||||
|
|
||||||
|
- Modified Send-SQLDataToExcel so it creates tables and ranges itself; previously it relied on export-excel to do this which cause problems when adding data to an existing sheet (#555)
|
||||||
|
- Added new command Add-ExcelDataValidation which will apply different data-validation rules to ranges of cells
|
||||||
|
- Changed the export behavior so that (1) attempts to convert to a number only apply if the the value was a string; (2) Nulls are no longer converted to an empty string (3) there is a specific check for URIs and not just text which is a valid URI. Using UNC names in hyperlinks remains problematic.
|
||||||
|
- Changed the behavior of AutoSize in export excel so it only applies to the exported columns. Previously if something was exported next to pre-existing data, AutoSize would resize the whole sheet, potentially undoing things which had been set on the earlier data. If anyone relied on this behavior they will need to explicitly tell the sheet to auto size with $sheet.cells.autofitColumns. (where $sheet points to the sheet, it might be $ExcelPackage.Workbook.Worksheets['Name'])
|
||||||
|
- In Compare-Worksheet,the Key for comparing the sheets can now be written as a hash table with an expression - it is used with a Group-Object command so if it is valid in Group-Object it should be accepted; this allows the creation of composite keys when data being compared doesn't have a column which uniquely identifies rows.
|
||||||
|
- In Set-ExcelRange , added a 'Locked' option equivalent to the checkbox on the Protection Tab of the format cells dialog box in Excel.
|
||||||
|
- Created a Set-WorksheetProtection function. This gives the same options the protection dialog in Excel but is 0.9 release at the moment.
|
||||||
|
|
||||||
|
## New Example
|
||||||
|
|
||||||
|
- Added [MutipleValidations.ps1](https://github.com/dfinke/ImportExcel/blob/master/Examples/ExcelDataValidation/MutipleValidations.ps1). Culled from the `tests`.
|
||||||
|
|
||||||
|
# What's new 5.4.4
|
||||||
|
|
||||||
|
- Fix issue when only a single property is piped into Export-Excel
|
||||||
|
- Fix issue in `Copy-ExcelWorksheet`, close the `$Stream`
|
||||||
|
|
||||||
|
# What's new 5.4.3
|
||||||
|
|
||||||
|
- Added Remove-Worksheet: Removes one or more worksheets from one or more workbooks
|
||||||
|
|
||||||
|
# What's new 5.4.2
|
||||||
|
|
||||||
|
- Added parameters -GroupDateRow and -GroupDatePart & -GroupNumericRow, -GroupNumericMin, -GroupNumericMax and -GroupNumericInterval
|
||||||
|
to Add-PivotTable and New-PivotTableDefinition. The date ones gather dates of the same year and/or quarter and/or month and/or day etc.
|
||||||
|
the number ones group numbers into bands, starting at Min, and going up steps specified by Interval. Added tests and help for these.
|
||||||
|
- Set-ExcelRow and Set-ExcelColumn now check that the worksheet name they passed exists in the workbook.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# What's new 5.4.0
|
||||||
|
|
||||||
|
- 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 PivotTableStyle 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
|
- 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 where -AutoNameRange on pre-existing data included the header in the range.
|
||||||
|
|||||||
@@ -1,34 +1,45 @@
|
|||||||
Function Remove-WorkSheet {
|
Function Remove-WorkSheet {
|
||||||
Param (
|
<#
|
||||||
$Path,
|
.SYNOPSIS
|
||||||
$WorksheetName
|
Removes one or more worksheets from one or more workbooks
|
||||||
|
.EXAMPLE
|
||||||
|
C:\> Remove-WorkSheet -Path Test1.xlsx -WorksheetName Sheet1
|
||||||
|
Removes the worksheet named 'Sheet1' from 'Test1.xlsx'
|
||||||
|
|
||||||
|
C:\> Remove-WorkSheet -Path Test1.xlsx -WorksheetName Sheet1,Target1
|
||||||
|
Removes the worksheet named 'Sheet1' and 'Target1' from 'Test1.xlsx'
|
||||||
|
|
||||||
|
C:\> Remove-WorkSheet -Path Test1.xlsx -WorksheetName Sheet1,Target1 -Show
|
||||||
|
Removes the worksheets and then launches the xlsx in Excel
|
||||||
|
|
||||||
|
C:\> dir c:\reports\*.xlsx | Remove-WorkSheet
|
||||||
|
Removes 'Sheet1' from all the xlsx files in the c:\reports directory
|
||||||
|
|
||||||
|
#>
|
||||||
|
[cmdletbinding(SupportsShouldProcess=$true)]
|
||||||
|
param(
|
||||||
|
# [Parameter(ValueFromPipelineByPropertyName)]
|
||||||
|
[Parameter(ValueFromPipelineByPropertyName)]
|
||||||
|
[Alias('Path')]
|
||||||
|
$FullName,
|
||||||
|
[String[]]$WorksheetName = "Sheet1",
|
||||||
|
[Switch]$Show
|
||||||
)
|
)
|
||||||
|
|
||||||
$Path = (Resolve-Path $Path).ProviderPath
|
Process {
|
||||||
|
if (!$FullName) {
|
||||||
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage $Path
|
throw "Remove-WorkSheet requires the and Excel file"
|
||||||
|
|
||||||
$workSheet = $Excel.Workbook.Worksheets[$WorkSheetName]
|
|
||||||
|
|
||||||
if($workSheet) {
|
|
||||||
if($Excel.Workbook.Worksheets.Count -gt 1) {
|
|
||||||
$Excel.Workbook.Worksheets.Delete($workSheet)
|
|
||||||
} else {
|
|
||||||
throw "Cannot delete $WorksheetName. A workbook must contain at least one visible worksheet"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
$pkg = Open-ExcelPackage -Path $FullName
|
||||||
throw "$WorksheetName not found"
|
|
||||||
|
if ($pkg) {
|
||||||
|
foreach ($wsn in $WorksheetName) {
|
||||||
|
if ($PSCmdlet.ShouldProcess($FullName,"Remove Sheet $wsn")) {
|
||||||
|
$pkg.Workbook.Worksheets.Delete($wsn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Close-ExcelPackage -ExcelPackage $pkg -Show:$Show
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$Excel.Save()
|
|
||||||
$Excel.Dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Import-Module .\ImportExcel.psd1 -Force
|
|
||||||
|
|
||||||
$names = Get-ExcelSheetInfo C:\Temp\testDelete.xlsx
|
|
||||||
$names | Foreach-Object { Remove-WorkSheet C:\Temp\testDelete.xlsx $_.Name}
|
|
||||||
|
|
||||||
##Remove-WorkSheet C:\Temp\testDelete.xlsx sheet6
|
|
||||||
@@ -1,286 +1,175 @@
|
|||||||
Function Send-SQLDataToExcel {
|
Function Send-SQLDataToExcel {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Inserts a DataTable - returned by SQL query into an ExcelSheet, more efficiently than sending it via Export-Excel
|
Inserts a DataTable - returned by a SQL query - into an ExcelSheet
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This command can accept a data table object or take a SQL statement and run it against a database connection.
|
This command takes a SQL statement and run it against a database connection; for the connection it accepts either
|
||||||
If running a SQL statement, the accepts either
|
* an object representing a session with a SQL server or ODBC database, or
|
||||||
* an object representing a session with a SQL server or ODBC database, or
|
* a connection string to make a session (if -MSSQLServer is specified it uses the SQL Native client,
|
||||||
* a connection String to make a session.
|
and -Connection can be a server name instead of a detailed connection string. Without this switch it uses ODBC)
|
||||||
The command takes most of the parameters of Export-Excel, and after inserting the table into the worksheet it
|
The command takes all the parameters of Export-Excel, except for -InputObject (alias TargetData); after
|
||||||
calls Export-Excel to carry out other tasks on the sheet. It is more efficient to do this than to get data-rows
|
fetching the data it calls Export-Excel with the data as the value of InputParameter and whichever of
|
||||||
and pipe them into Export-Excel, stripped off the database 'housekeeping' properties.
|
Export-Excel's parameters it was passed; for details of these parameters see the help for Export-Excel.
|
||||||
.PARAMETER DataTable
|
.PARAMETER Session
|
||||||
A System.Data.DataTable object containing the data to be inserted into the spreadsheet without running a query.
|
An active ODBC Connection or SQL connection object representing a session with a database which will be queried to get the data .
|
||||||
.PARAMETER Session
|
.PARAMETER Connection
|
||||||
An active ODBC Connection or SQL connection object representing a session with a database which will be queried to get the data .
|
A database connection string to be used to create a database session; either
|
||||||
.PARAMETER Connection
|
* A Data source name written in the form DSN=ODBC_Data_Source_Name, or
|
||||||
A database connection string to be used to create a database session; either
|
* A full ODBC or SQL Native Client Connection string, or
|
||||||
* A Data source name written in the form DSN=ODBC_Data_Source_Name, or
|
* The name of a SQL server.
|
||||||
* A full odbc or SQL Connection string, or
|
.PARAMETER MSSQLServer
|
||||||
* The name of a SQL server.
|
Specifies the connection string is for SQL server, not ODBC.
|
||||||
.PARAMETER MSSQLServer
|
.PARAMETER SQL
|
||||||
Specifies the connection string is for SQL server, not ODBC.
|
The SQL query to run against the session which was passed in -Session or set up from -Connection.
|
||||||
.PARAMETER SQL
|
.PARAMETER Database
|
||||||
The SQL query to run against the session which was passed in -Session or set up from -Connection.
|
Switches to a specific database on a SQL server.
|
||||||
.PARAMETER Database
|
.PARAMETER QueryTimeout
|
||||||
Switches to a specific database on a SQL server.
|
Override the default query time of 30 seconds.
|
||||||
.PARAMETER QueryTimeout
|
.PARAMETER DataTable
|
||||||
Override the default query time of 30 seconds.
|
A System.Data.DataTable object containing the data to be inserted into the spreadsheet without running a query.
|
||||||
.PARAMETER Path
|
This remains supported to avoid breaking older scripts, but if you have a DataTable object you can pass the it
|
||||||
Path to a new or existing .XLSX file.
|
into Export-Excel using -InputObject.
|
||||||
.PARAMETER WorkSheetName
|
|
||||||
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.
|
|
||||||
.PARAMETER Title
|
|
||||||
Text of a title to be placed in the top left cell.
|
|
||||||
.PARAMETER TitleBold
|
|
||||||
Sets the title in boldface type.
|
|
||||||
.PARAMETER TitleSize
|
|
||||||
Sets the point size for the title.
|
|
||||||
.PARAMETER TitleBackgroundColor
|
|
||||||
Sets the cell background color for the title cell.
|
|
||||||
.PARAMETER TitleFillPattern
|
|
||||||
Sets the fill pattern for the title cell.
|
|
||||||
.PARAMETER Password
|
|
||||||
Sets password protection on the workbook.
|
|
||||||
.PARAMETER IncludePivotTable
|
|
||||||
Adds a Pivot table using the data in the worksheet.
|
|
||||||
.PARAMETER PivotTableName
|
|
||||||
If a Pivot table is created from command line parameters, specificies the name of the new sheet holding the pivot. If Omitted this will be "WorksheetName-PivotTable"
|
|
||||||
.PARAMETER PivotRows
|
|
||||||
Name(s) columns from the spreadhseet which will provide the Row name(s) in a pivot table created from command line parameters.
|
|
||||||
.PARAMETER PivotColumns
|
|
||||||
Name(s) columns from the spreadhseet which will provide the Column name(s) in a pivot table created from command line parameters.
|
|
||||||
.PARAMETER PivotFilter
|
|
||||||
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
|
|
||||||
Include a chart with the Pivot table - implies -IncludePivotTable.
|
|
||||||
.PARAMETER ChartType
|
|
||||||
The type for Pivot chart (one of Excel's defined chart types)
|
|
||||||
.PARAMETER NoLegend
|
|
||||||
Exclude the legend from the pivot chart.
|
|
||||||
.PARAMETER ShowCategory
|
|
||||||
Add category labels to the pivot chart.
|
|
||||||
.PARAMETER ShowPercent
|
|
||||||
Add Percentage labels to the pivot chart.
|
|
||||||
.PARAMETER PivotTableDefinition
|
|
||||||
Instead of describing a single pivot table with mutliple commandline paramters; you can use a HashTable in the form PivotTableName = Definition;
|
|
||||||
Definition is itself a hashtable with Sheet PivotTows, PivotColumns, PivotData, IncludePivotChart and ChartType values.
|
|
||||||
.PARAMETER ConditionalFormat
|
|
||||||
One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
|
|
||||||
.PARAMETER ConditionalText
|
|
||||||
Applies a 'Conditional formatting rule' in Excel on all the cells. When specific conditions are met a rule is triggered.
|
|
||||||
.PARAMETER BoldTopRow
|
|
||||||
Makes the top Row boldface.
|
|
||||||
.PARAMETER NoHeader
|
|
||||||
Does not put field names at the top of columns.
|
|
||||||
.PARAMETER RangeName
|
|
||||||
Makes the data in the worksheet a named range.
|
|
||||||
.PARAMETER AutoNameRange
|
|
||||||
Makes each column a named range.
|
|
||||||
.PARAMETER TableName
|
|
||||||
Makes the data in the worksheet a table with a name applies a style to it. Name must not contain spaces.
|
|
||||||
.PARAMETER TableStyle
|
|
||||||
Selects the style for the named table - defaults to 'Medium6'.
|
|
||||||
.PARAMETER BarChart
|
|
||||||
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
|
|
||||||
.PARAMETER ColumnChart
|
|
||||||
Creates a "quick" column chart using the first text column as labels and the first numeric column as values
|
|
||||||
.PARAMETER LineChart
|
|
||||||
Creates a "quick" line chart using the first text column as labels and the first numeric column as values
|
|
||||||
.PARAMETER PieChart
|
|
||||||
Creates a "quick" pie chart using the first text column as labels and the first numeric column as values
|
|
||||||
.PARAMETER ExcelChartDefinition
|
|
||||||
A hash table containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
|
|
||||||
.PARAMETER StartRow
|
|
||||||
Row to start adding data. 1 by default. Row 1 will contain the title if any. Then headers will appear (Unless -No header is specified) then the data appears.
|
|
||||||
.PARAMETER StartColumn
|
|
||||||
Column to start adding data - 1 by default.
|
|
||||||
.PARAMETER FreezeTopRow
|
|
||||||
Freezes headers etc. in the top row.
|
|
||||||
.PARAMETER FreezeFirstColumn
|
|
||||||
Freezes titles etc. in the left column.
|
|
||||||
.PARAMETER FreezeTopRowFirstColumn
|
|
||||||
Freezes top row and left column (equivalent to Freeze pane 2,2 ).
|
|
||||||
.PARAMETER FreezePane
|
|
||||||
Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
|
|
||||||
.PARAMETER AutoFilter
|
|
||||||
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.
|
|
||||||
.PARAMETER AutoSize
|
|
||||||
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
|
|
||||||
If specified, Export-Excel returns an object representing the Excel package without saving the package first. To save it you need to call the save or Saveas method or send it back to Export-Excel.
|
|
||||||
|
|
||||||
.EXAMPLE
|
.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
|
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 management
|
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
|
.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:\> $dbPath = 'C:\Users\James\Documents\Database1.accdb'
|
||||||
C:\> $Connection = 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DriverId=790;ReadOnly=0;Dbq=C:\users\James\Documents\f1Results.xlsx;'
|
C:\> $Connection = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=$dbPath;"
|
||||||
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange
|
C:\> $SQL="SELECT top 25 Name,Length From TestData ORDER BY Length DESC"
|
||||||
|
|
||||||
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.
|
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Sizes" -AutoSize
|
||||||
|
|
||||||
|
This creates an ODBC connection string to read from an Access file and a SQL Statement to extracts data from it,
|
||||||
|
and sends the resulting data to a new worksheet
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
C:\> $dbPath = 'C:\users\James\Documents\f1Results.xlsx'
|
||||||
|
C:\> $Connection = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=$dbPath;"
|
||||||
|
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:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo2.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange -ConditionalFormat @{DataBarColor="Blue"; Range="Wins"}
|
||||||
|
|
||||||
|
Similar to the previous example this creates a connection string, this time for an Excel file, and runs
|
||||||
|
a SQL statement to get a list of motor-racing results, outputting 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 )
|
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
|
||||||
.EXAMPLE
|
.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:\> $dbPath = 'C:\users\James\Documents\f1Results.xlsx'
|
||||||
C:\> Get-SQL -Session F1 -excel -Connection "C:\Users\mcp\OneDrive\public\f1\f1Results.xlsx" -sql $sql -OutputVariable Table | out-null
|
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:\> $null = Get-SQL -Session F1 -excel -Connection $dbPath -sql $sql -OutputVariable Table
|
||||||
|
|
||||||
C:\> Send-SQLDataToExcel -DataTable $Table -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -TableName winners -TableStyle Light6 -show
|
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 PowerShell gallery with Install-Module -Name GetSQL -
|
||||||
to simplify making database connections and building /submitting SQL statements.
|
note the function is Get-SQL the module is GetSQL without the "-" )
|
||||||
Here it uses the same SQL statement as before; -OutputVariable leaves a System.Data.DataTable object in $table
|
Get-SQL simplify making database connections and building /submitting SQL statements.
|
||||||
|
Here Get-SQL 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.
|
and Send-SQLDataToExcel puts $table into the worksheet and sets it as an Excel table.
|
||||||
|
The command is equivalent to running
|
||||||
|
C:\> Export-Excel -inputObject $Table -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -TableName winners -TableStyle Light6 -show
|
||||||
|
This is quicker than using
|
||||||
|
C:\> Get-SQL <parameters> | export-excel -ExcludeProperty rowerror,rowstate,table,itemarray,haserrors <parameters>
|
||||||
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
|
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
C:\> $SQL = "SELECT top 25 DriverName, Count(Win) as Wins FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
|
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
|
C:\> Send-SQLDataToExcel -Session $DbSessions["f1"] -SQL $sql -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -ClearSheet -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 database session which Get-SQL created, rather than an ODBC connection string.
|
||||||
|
The Session parameter can either be a object (as shown here), or the name used by Get-SQL ("F1" in this case).
|
||||||
Here the data is presented as a quick chart.
|
Here the data is presented as a quick chart.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
C:\> Send-SQLDataToExcel -path .\demo3.xlsx -WorkSheetname "LR" -Connection "DSN=LR" -sql "SELECT name AS CollectionName FROM AgLibraryCollection Collection ORDER BY CollectionName"
|
C:\> Send-SQLDataToExcel -path .\demo4.xlsx -WorkSheetname "LR" -Connection "DSN=LR" -sql "SELECT name AS CollectionName FROM AgLibraryCollection Collection ORDER BY CollectionName"
|
||||||
|
|
||||||
This example uses an Existing ODBC datasource name "LR" which maps to an adobe lightroom database and gets a list of collection names into a worksheet
|
This example uses an Existing ODBC datasource name "LR" which maps to an adobe lightroom database and gets a list of collection names into a worksheet
|
||||||
|
|
||||||
|
.Link
|
||||||
|
Export-Excel
|
||||||
#>
|
#>
|
||||||
[CmdletBinding()]
|
[CmdletBinding(DefaultParameterSetName="none")]
|
||||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Justification="Allowed to use DBSessions Global variable from GETSQL Module")]
|
||||||
param (
|
|
||||||
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
param (
|
||||||
[Parameter(ParameterSetName="ODBCConnection",Mandatory=$true)]
|
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
||||||
|
[Parameter(ParameterSetName="ODBCConnection", Mandatory=$true)]
|
||||||
$Connection,
|
$Connection,
|
||||||
[Parameter(ParameterSetName="ExistingSession",Mandatory=$true)]
|
[Parameter(ParameterSetName="ExistingSession", Mandatory=$true)]
|
||||||
[System.Data.Common.DbConnection]$Session,
|
$Session,
|
||||||
[Parameter(ParameterSetName="SQLConnection",Mandatory=$true)]
|
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
||||||
[switch]$MsSQLserver,
|
[switch]$MsSQLserver,
|
||||||
[Parameter(ParameterSetName="SQLConnection")]
|
[Parameter(ParameterSetName="SQLConnection")]
|
||||||
[String]$DataBase,
|
[String]$DataBase,
|
||||||
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
||||||
[Parameter(ParameterSetName="ODBCConnection",Mandatory=$true)]
|
[Parameter(ParameterSetName="ODBCConnection", Mandatory=$true)]
|
||||||
[Parameter(ParameterSetName="ExistingSession",Mandatory=$true)]
|
[Parameter(ParameterSetName="ExistingSession", Mandatory=$true)]
|
||||||
[string]$SQL,
|
[string]$SQL,
|
||||||
[int]$QueryTimeout,
|
[int]$QueryTimeout,
|
||||||
[Parameter(ParameterSetName="Pre-FetchedData",Mandatory=$true)]
|
[Parameter(ParameterSetName="Pre-FetchedData", Mandatory=$true)]
|
||||||
[System.Data.DataTable]$DataTable,
|
[System.Data.DataTable]$DataTable
|
||||||
$Path,
|
|
||||||
[String]$WorkSheetname = 'Sheet1',
|
|
||||||
[Switch]$KillExcel,
|
|
||||||
[Switch]$Show,
|
|
||||||
[String]$Title,
|
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
|
|
||||||
[Switch]$TitleBold,
|
|
||||||
[Int]$TitleSize = 22,
|
|
||||||
[System.Drawing.Color]$TitleBackgroundColor,
|
|
||||||
[String]$Password,
|
|
||||||
[Hashtable]$PivotTableDefinition,
|
|
||||||
[Switch]$IncludePivotTable,
|
|
||||||
[String[]]$PivotRows,
|
|
||||||
[String[]]$PivotColumns,
|
|
||||||
$PivotData,
|
|
||||||
[String[]]$PivotFilter,
|
|
||||||
[Switch]$PivotDataToColumn,
|
|
||||||
[Switch]$NoTotalsInPivot,
|
|
||||||
[Switch]$IncludePivotChart,
|
|
||||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
|
|
||||||
[Switch]$NoLegend,
|
|
||||||
[Switch]$ShowCategory,
|
|
||||||
[Switch]$ShowPercent,
|
|
||||||
[Switch]$AutoSize,
|
|
||||||
[Switch]$FreezeTopRow,
|
|
||||||
[Switch]$FreezeFirstColumn,
|
|
||||||
[Switch]$FreezeTopRowFirstColumn,
|
|
||||||
[Int[]]$FreezePane,
|
|
||||||
[Switch]$AutoFilter,
|
|
||||||
[Switch]$BoldTopRow,
|
|
||||||
[Switch]$NoHeader,
|
|
||||||
[String]$RangeName,
|
|
||||||
[String]$TableName,
|
|
||||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
|
||||||
[Switch]$Barchart,
|
|
||||||
[Switch]$PieChart,
|
|
||||||
[Switch]$LineChart ,
|
|
||||||
[Switch]$ColumnChart ,
|
|
||||||
[Object[]]$ExcelChartDefinition,
|
|
||||||
[Switch]$AutoNameRange,
|
|
||||||
[Object[]]$ConditionalFormat,
|
|
||||||
[Object[]]$ConditionalText,
|
|
||||||
[ScriptBlock]$CellStyleSB,
|
|
||||||
[Int]$StartRow = 1,
|
|
||||||
[Int]$StartColumn = 1,
|
|
||||||
[Switch]$ReturnRange,
|
|
||||||
[Switch]$Passthru
|
|
||||||
)
|
)
|
||||||
|
#Import the parameters from Export-Excel, we will pass InputObject, and we have the common parameters so exclude those,
|
||||||
if ($KillExcel) {
|
#and re-write the [Parmameter] attribute on each one to avoid parameterSetName here competing with the settings in Export excel.
|
||||||
Get-Process excel -ErrorAction Ignore | Stop-Process
|
#The down side of this that impossible parameter combinations won't be filtered out and need to be caught later.
|
||||||
while (Get-Process excel -ErrorAction Ignore) {Start-Sleep -Milliseconds 250}
|
DynamicParam {
|
||||||
}
|
$ParameterAttribute = "System.Management.Automation.ParameterAttribute"
|
||||||
|
$RuntimeDefinedParam = "System.Management.Automation.RuntimeDefinedParameter"
|
||||||
#We were either given a session object or a connection string (with, optionally a MSSQLServer parameter)
|
$paramDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
|
||||||
# If we got -MSSQLServer, create a SQL connection, if we didn't but we got -Connection create an ODBC connection
|
$attributeCollection = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute]
|
||||||
if ($MsSQLserver -and $Connection) {
|
$attributeCollection.Add((New-Object -TypeName $ParameterAttribute -Property @{ ParameterSetName = "__AllParameterSets" ;Mandatory = $false}))
|
||||||
if ($Connection -notmatch "=") {$Connection = "server=$Connection;trusted_connection=true;timeout=60"}
|
foreach ($P in (Get-Command -Name Export-Excel).Parameters.values.where({$_.name -notmatch 'Verbose|Debug|Action$|Variable$|Buffer$|TargetData$|InputObject$'})) {
|
||||||
$Session = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $Connection
|
$paramDictionary.Add($p.Name, (New-Object -TypeName $RuntimeDefinedParam -ArgumentList $p.name, $p.ParameterType, $attributeCollection ) )
|
||||||
if ($Session.State -ne 'Open') {$Session.Open()}
|
|
||||||
if ($DataBase) {$Session.ChangeDatabase($DataBase) }
|
|
||||||
}
|
|
||||||
elseif ($Connection) {
|
|
||||||
$Session = New-Object -TypeName System.Data.Odbc.OdbcConnection -ArgumentList $Connection ; $Session.ConnectionTimeout = 30
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($session) {
|
|
||||||
#A session was either passed in or just created. If it's a SQL one make a SQL DataAdapter, otherwise make an ODBC one
|
|
||||||
if ($Session.GetType().name -match "SqlConnection") {
|
|
||||||
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
|
|
||||||
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
|
|
||||||
}
|
}
|
||||||
else {
|
return $paramDictionary
|
||||||
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
|
|
||||||
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
|
|
||||||
}
|
|
||||||
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $ServerTimeout}
|
|
||||||
|
|
||||||
#Both adapter types output the same kind of table, create one and fill it from the adapter
|
|
||||||
$DataTable = New-Object -TypeName System.Data.DataTable
|
|
||||||
$rowCount = $dataAdapter.fill($dataTable)
|
|
||||||
Write-Verbose -Message "Query returned $rowCount row(s)"
|
|
||||||
}
|
}
|
||||||
if ($DataTable.Rows.Count) {
|
process {
|
||||||
#ExportExcel user a -NoHeader parameter so that's what we use here, but needs to be the other way around.
|
#Dynamic params mean we can get passed parameter combination Export-Excel will reject, so throw here, rather than get data and then have Export-Excel error.
|
||||||
$printHeaders = -not $NoHeader
|
if ($PSBoundParameters.Path -and $PSBoundParameters.ExcelPackage) {
|
||||||
if ($Title) {$r = $StartRow +1 }
|
throw 'Parameter error: you cannot specify both a path and an Excel Package.'
|
||||||
else {$r = $StartRow}
|
return
|
||||||
#Get our Excel sheet and fill it with the data
|
}
|
||||||
$excelPackage = Export-Excel -Path $Path -WorkSheetname $WorkSheetname -PassThru
|
if ($PSBoundParameters.AutoFilter -and ($PSBoundParameters.TableName -or $PSBoundParameters.TableStyle)) {
|
||||||
$excelPackage.Workbook.Worksheets[$WorkSheetname].Cells[$r,$StartColumn].LoadFromDataTable($dataTable, $printHeaders ) | Out-Null
|
Write-Warning "Tables are automatically auto-filtered, -AutoFilter will be ignored"
|
||||||
|
$null = $PSBoundParameters.Remove('AutoFilter')
|
||||||
#Apply date format
|
}
|
||||||
for ($c=0 ; $c -lt $DataTable.Columns.Count ; $c++) {
|
#We were either given a session object or a connection string (with, optionally a MSSQLServer parameter)
|
||||||
if ($DataTable.Columns[$c].DataType -eq [datetime]) {
|
#If we got -MSSQLServer, create a SQL connection, if we didn't but we got -Connection create an ODBC connection
|
||||||
Set-ExcelColumn -Worksheet $excelPackage.Workbook.Worksheets[$WorkSheetname] -Column ($c +1) -NumberFormat 'Date-Time'
|
if ($MsSQLserver -and $Connection) {
|
||||||
|
if ($Connection -notmatch '=') {$Connection = "server=$Connection;trusted_connection=true;timeout=60"}
|
||||||
|
$Session = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $Connection
|
||||||
|
if ($Session.State -ne 'Open') {$Session.Open()}
|
||||||
|
if ($DataBase) {$Session.ChangeDatabase($DataBase) }
|
||||||
|
}
|
||||||
|
elseif ($Connection) {
|
||||||
|
$Session = New-Object -TypeName System.Data.Odbc.OdbcConnection -ArgumentList $Connection ; $Session.ConnectionTimeout = 30
|
||||||
|
}
|
||||||
|
if ($Session) {
|
||||||
|
#A session was either passed in or just created. If it's a SQL one make a SQL DataAdapter, otherwise make an ODBC one
|
||||||
|
if ($Session -is [String] -and $Global:DbSessions[$Session]) {$Session = $Global:DbSessions[$Session]}
|
||||||
|
if ($Session.GetType().name -match "SqlConnection") {
|
||||||
|
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
|
||||||
|
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
|
||||||
|
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
|
||||||
|
}
|
||||||
|
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $QueryTimeout}
|
||||||
|
|
||||||
#Call export-excel with any parameters which don't relate to the SQL query
|
#Both adapter types output the same kind of table, create one and fill it from the adapter
|
||||||
"Connection", "Database" , "Session", "MsSQLserver", "Destination" , "SQL" , "DataTable", "Path" | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
|
$DataTable = New-Object -TypeName System.Data.DataTable
|
||||||
Export-Excel -ExcelPackage $excelPackage @PSBoundParameters
|
$rowCount = $dataAdapter.fill($dataTable)
|
||||||
|
Write-Verbose -Message "Query returned $rowCount row(s)"
|
||||||
|
}
|
||||||
|
if ($DataTable.Rows.Count) {
|
||||||
|
#Call export-excel removing parameters which relate to the SQL query, and keeping the rest.
|
||||||
|
'Connection' , 'Database' , 'Session' , 'MsSQLserver' , 'SQL' , 'DataTable' , 'QueryTimeout' | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
|
||||||
|
Export-Excel @PSBoundParameters -InputObject $DataTable
|
||||||
|
}
|
||||||
|
else {Write-Warning -Message ' No Data to insert.' }
|
||||||
|
#If we were passed a connection and opened a session, close that session.
|
||||||
|
if ($Connection) {$Session.close() }
|
||||||
}
|
}
|
||||||
else {Write-Warning -Message "No Data to insert."}
|
|
||||||
#If we were passed a connection and opened a session, close that session.
|
|
||||||
if ($Connection) {$Session.close() }
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
function Set-CellStyle {
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='Set*', Justification='Does not change system state')]
|
||||||
|
param()
|
||||||
|
|
||||||
|
function Set-CellStyle {
|
||||||
param(
|
param(
|
||||||
$WorkSheet,
|
$WorkSheet,
|
||||||
$Row,
|
$Row,
|
||||||
$LastColumn,
|
$LastColumn,
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$Pattern,
|
[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=$WorkSheet.Cells["A$($Row):$($LastColumn)$($Row)"]
|
||||||
$t.Style.Fill.PatternType=$Pattern
|
$t.Style.Fill.PatternType=$Pattern
|
||||||
$t.Style.Fill.BackgroundColor.SetColor($Color)
|
$t.Style.Fill.BackgroundColor.SetColor($Color)
|
||||||
|
|||||||
@@ -1,47 +1,59 @@
|
|||||||
Function Set-ExcelColumn {
|
Function Set-ExcelColumn {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Adds or modifies a column in an Excel sheet, filling values, settings formatting and/or creating named ranges.
|
Adds or modifies a column in an Excel worksheet, filling values, setting formatting and/or creating named ranges.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Set-ExcelColumn can take a value which is either a string containing a value or formula or a scriptblock
|
Set-ExcelColumn can take a value which is either a string containing a
|
||||||
which evaluates to a string, and optionally a column number and fills that value down the column.
|
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.
|
A column heading can be specified, and the column can be made a named range.
|
||||||
The column can be formatted in the same operation.
|
The column can be formatted in the same operation.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
||||||
|
|
||||||
$ws contains a worksheet object - and column E is set to use the local currency format.
|
$ws contains a worksheet object - and column "E" is set to use the
|
||||||
Intelisense will complete predefined number formats. You can see how currency is interpreted on the local computer with the command
|
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
|
Expand-NumberFormat currency
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Set-ExcelColumn -Worksheet $ws -Heading "WinsToFastLaps" -Value {"=E$row/C$row"} -Column 7 -AutoSize -AutoNameRange
|
Set-ExcelColumn -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).
|
Here, $WS already contains a worksheet which holds counts of races won
|
||||||
Set-ExcelColumn specifies that Column 7 should have a heading of "WinsToFastLaps" and the data cells should contain =E2/C2 , =E3/C3 etc
|
and fastest laps recorded by racing drivers (in columns C and E).
|
||||||
the new data cells should become a named range, which will also be named "WinsToFastLaps" the column width will be set automatically.
|
Set-ExcelColumn specifies that Column 7 should have a heading of
|
||||||
.EXAMPLE.
|
"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
|
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.
|
In this example, the worksheet in $ws has partial links to Wikipedia
|
||||||
The -Value parameter is is a script block and it outputs a string which begins https... and ends with the value of cell at
|
pages in column B. The -Value parameter is a script block which
|
||||||
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.
|
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
|
.EXAMPLE
|
||||||
4..6 | Set-ExcelColumn -Worksheet $ws -AutoNameRange
|
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
|
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.
|
and the rest of the column becomes the range.
|
||||||
#>
|
#>
|
||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
[Alias("Set-Column")]
|
[Alias("Set-Column")]
|
||||||
[OutputType([OfficeOpenXml.ExcelColumn],[String])]
|
[OutputType([OfficeOpenXml.ExcelColumn],[String])]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system state')]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="Variables created for script block which may be passed as a parameter, but not used in the script")]
|
||||||
Param (
|
Param (
|
||||||
#If specifying the worksheet by name, the ExcelPackage object which contains the Sheet also needs to be passed.
|
#If specifying the worksheet by name, the ExcelPackage object which contains the worksheet also needs to be passed.
|
||||||
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
[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")]
|
[Parameter(ParameterSetName="Package")]
|
||||||
[String]$Worksheetname = "Sheet1",
|
[String]$Worksheetname = "Sheet1",
|
||||||
#This passes the worksheet object instead of passing a sheet name and a package.
|
#This passes the worksheet object instead of passing a sheet name and an Excelpackage object.
|
||||||
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
|
[Parameter(ParameterSetName="sheet",Mandatory=$true)]
|
||||||
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
|
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
|
||||||
#Column to fill down - the first column is 1. 0 will be interpreted as first empty column.
|
#Column to fill down - the first column is 1. 0 will be interpreted as first empty column.
|
||||||
@@ -61,16 +73,16 @@
|
|||||||
#Style of border to draw around the row.
|
#Style of border to draw around the row.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||||
#Colour for the text - if none specified it will be left as it it is.
|
#Colour for the text - if none specified it will be left as it it is.
|
||||||
[System.Drawing.Color]$FontColor,
|
$FontColor,
|
||||||
#Make text bold; use -Bold:$false to remove bold.
|
#Make text bold; use -Bold:$false to remove bold.
|
||||||
[Switch]$Bold,
|
[Switch]$Bold,
|
||||||
#Make text italic; use -Italic:$false to remove italic.
|
#Make text italic; use -Italic:$false to remove italic.
|
||||||
[Switch]$Italic,
|
[Switch]$Italic,
|
||||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||||
[Switch]$Underline,
|
[Switch]$Underline,
|
||||||
#Should Underline use single or double, normal or accounting mode ? the default is single normal.
|
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||||
#Strike through text; use -Strikethru:$false to remove Strike through.
|
#Strike through text; use -StrikeThru:$false to remove strike through.
|
||||||
[Switch]$StrikeThru,
|
[Switch]$StrikeThru,
|
||||||
#Subscript or Superscript (or None).
|
#Subscript or Superscript (or None).
|
||||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||||
@@ -79,39 +91,44 @@
|
|||||||
#Point size for the text.
|
#Point size for the text.
|
||||||
[float]$FontSize,
|
[float]$FontSize,
|
||||||
#Change background color.
|
#Change background color.
|
||||||
[System.Drawing.Color]$BackgroundColor,
|
$BackgroundColor,
|
||||||
#Background pattern - Solid by default.
|
#Background pattern - "Solid" by default.
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||||
#Secondary color for background pattern.
|
#Secondary color for background pattern.
|
||||||
[Alias("PatternColour")]
|
[Alias("PatternColour")]
|
||||||
[System.Drawing.Color]$PatternColor,
|
$PatternColor,
|
||||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping.
|
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||||
[Switch]$WrapText,
|
[Switch]$WrapText,
|
||||||
#Position cell contents to Left, Right, Center etc. Default is 'General'.
|
#Position cell contents to Left, Right, Center etc. Default is "General".
|
||||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||||
#Position cell contents to Top, Bottom or Center.
|
#Position cell contents to Top, Bottom or Center.
|
||||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
[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)]
|
[ValidateRange(-90, 90)]
|
||||||
[int]$TextRotation ,
|
[int]$TextRotation ,
|
||||||
#Autofit cells to width.
|
#Attempt to auto-fit cells to the width their contents.
|
||||||
[Alias("AutoFit")]
|
[Alias("AutoFit")]
|
||||||
[Switch]$AutoSize,
|
[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,
|
[float]$Width,
|
||||||
#Set the inserted data to be a named range.
|
#Set the inserted data to be a named range.
|
||||||
[Switch]$AutoNameRange,
|
[Switch]$AutoNameRange,
|
||||||
#Hide the column.
|
#Hide the column.
|
||||||
[Switch]$Hide,
|
[Switch]$Hide,
|
||||||
#If Sepecified, returns the range of cells which were affected.
|
#If specified, returns the range of cells which were affected.
|
||||||
[Switch]$Specified,
|
[Switch]$Specified,
|
||||||
#If Specified, return the Column to allow further work to be done on it.
|
#If specified, return an object representing the Column, to allow further work to be done on it.
|
||||||
[Switch]$PassThru
|
[Switch]$PassThru
|
||||||
)
|
)
|
||||||
|
|
||||||
begin {
|
begin {
|
||||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
|
if ($ExcelPackage) {
|
||||||
|
if ($ExcelPackage.Workbook.Worksheets.Name -notcontains $Worksheetname) {
|
||||||
|
throw "The Workbook does not contain a sheet named '$Worksheetname'"
|
||||||
|
}
|
||||||
|
else {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
|
||||||
|
}
|
||||||
|
|
||||||
#In a script block to build a formula, we may want any of corners or the column name,
|
#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 Column and Startrow aren't specified, assume first unused column, and first row
|
||||||
@@ -121,8 +138,9 @@
|
|||||||
$endRow = $Worksheet.Dimension.End.Row
|
$endRow = $Worksheet.Dimension.End.Row
|
||||||
}
|
}
|
||||||
process {
|
process {
|
||||||
|
if ($null -eq $workSheet.Dimension) {Write-Warning "Can't format an empty worksheet."; return}
|
||||||
if ($Column -eq 0 ) {$Column = $endColumn + 1 }
|
if ($Column -eq 0 ) {$Column = $endColumn + 1 }
|
||||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
$columnName = (New-Object 'OfficeOpenXml.ExcelCellAddress' @(1, $column)).Address -replace "1",""
|
||||||
Write-Verbose -Message "Updating Column $columnName"
|
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 there is a heading, insert it and use it as the name for a range (if we're creating one)
|
||||||
if ($PSBoundParameters.ContainsKey('Heading')) {
|
if ($PSBoundParameters.ContainsKey('Heading')) {
|
||||||
@@ -136,14 +154,15 @@
|
|||||||
Add-ExcelName -Range $Worksheet.Cells[($StartRow+1), $Column, $endRow, $Column] -RangeName $Worksheet.Cells[$StartRow, $Column].Value
|
Add-ExcelName -Range $Worksheet.Cells[($StartRow+1), $Column, $endRow, $Column] -RangeName $Worksheet.Cells[$StartRow, $Column].Value
|
||||||
}
|
}
|
||||||
|
|
||||||
#Fill in the data
|
#Fill in the data -it can be zero null or and empty string.
|
||||||
if ($PSBoundParameters.ContainsKey('Value')) { foreach ($row in ($StartRow..$endRow)) {
|
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.
|
if ($Value -is [scriptblock]) { #re-create the script block otherwise variables from this function are out of scope.
|
||||||
$cellData = & ([scriptblock]::create( $Value ))
|
$cellData = & ([scriptblock]::create( $Value ))
|
||||||
Write-Verbose -Message $cellData
|
if ($null -eq $cellData) {Write-Verbose -Message "Script block evaluates to null."}
|
||||||
|
else {Write-Verbose -Message "Script block evaluates to '$cellData'"}
|
||||||
}
|
}
|
||||||
else { $cellData = $Value}
|
else { $cellData = $Value}
|
||||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $Column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
|
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)) {
|
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
|
# 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/") {
|
if ($cellData -match "^xl://internal/") {
|
||||||
@@ -152,18 +171,18 @@
|
|||||||
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
$h = New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList $referenceAddress , $display
|
||||||
$Worksheet.Cells[$Row, $Column].HyperLink = $h
|
$Worksheet.Cells[$Row, $Column].HyperLink = $h
|
||||||
}
|
}
|
||||||
else {$Worksheet.Cells[$Row, $Column].HyperLink = $cellData }
|
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
|
$Worksheet.Cells[$Row, $Column].Style.Font.UnderLine = $true
|
||||||
|
$Worksheet.Cells[$Row, $Column].Style.Font.Color.SetColor([System.Drawing.Color]::Blue)
|
||||||
}
|
}
|
||||||
else { $Worksheet.Cells[$Row, $Column].Value = $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.
|
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' }
|
if ($cellData -is [timespan]) { $Worksheet.Cells[$Row, $Column].Style.Numberformat.Format = '[h]:mm:ss' }
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#region Apply formatting
|
#region Apply formatting
|
||||||
$params = @{}
|
$params = @{}
|
||||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru','FontSize','FontShift','NumberFormat','TextRotation',
|
foreach ($p in @('Underline','Bold','Italic','StrikeThru', 'FontName', 'FontSize','FontShift','NumberFormat','TextRotation',
|
||||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Autosize', 'Width', 'FontColor'
|
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Autosize', 'Width', 'FontColor'
|
||||||
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||||
|
|||||||
88
Set-Row.ps1
88
Set-Row.ps1
@@ -1,32 +1,42 @@
|
|||||||
Function Set-ExcelRow {
|
Function Set-ExcelRow {
|
||||||
<#
|
<#
|
||||||
.Synopsis
|
.Synopsis
|
||||||
Fills values into a [new] row in an Excel spreadsheet. And sets row formats.
|
Fills values into a [new] row in an Excel spreadsheet, and sets row formats.
|
||||||
.Description
|
.Description
|
||||||
Set-ExcelRow accepts either a Worksheet object or an Excel Package object returned by Export-Excel and the name of a sheet,
|
Set-ExcelRow accepts either a Worksheet object or an ExcelPackage object
|
||||||
and inserts the chosen contents into a row of the sheet.
|
returned by Export-Excel and the name of a sheet, and inserts the chosen
|
||||||
The contents can be a constant e.g. "42", a formula or a script block which is converted into a constant or a formula.
|
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.
|
The first cell of the row can optionally be given a heading.
|
||||||
.Example
|
.Example
|
||||||
Set-ExcelRow -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-ExcelRow will select the next row after the end
|
$Ws contains a worksheet object, and no Row number is specified so
|
||||||
of the data in the sheet. The first cell in the row will contain "Total", and each other cell will contain
|
Set-ExcelRow will select the next row after the endof the data in
|
||||||
=Sum(xx2:xx99) - where xx is the column name, and 99 is the last row of data.
|
the sheet. The first cell in the row will contain "Total", and
|
||||||
Note the use of `2 to Prevent 2 becoming part of the variable "ColumnName"
|
each of the other cells will contain
|
||||||
The script block can use $Worksheet, $Row, $Column (number), $ColumnName (letter), $StartRow/Column and $EndRow/Column
|
=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
|
.Example
|
||||||
Set-ExcelRow -Worksheet $ws -Heading Total -HeadingBold -Value {"=sum($columnName`2:$columnName$endrow)" } -NumberFormat 'Currency' -StartColumn 2 -Bold -BorderTop Double -BorderBottom Thin
|
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;
|
This builds on the previous example, but this time the label "Total"
|
||||||
the formula and heading are set in bold face, and the formula is formatted for the local currency,
|
appears in column 2 and the formula fills from column 3 onwards.
|
||||||
and given a double line border above and single line border below.
|
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()]
|
[cmdletbinding()]
|
||||||
[Alias("Set-Row")]
|
[Alias("Set-Row")]
|
||||||
[OutputType([OfficeOpenXml.ExcelRow],[String])]
|
[OutputType([OfficeOpenXml.ExcelRow],[String])]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system state')]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="Variables created for script block which may be passed as a parameter, but not used in the script")]
|
||||||
Param (
|
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)]
|
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||||
#The name of the sheet to update in the package.
|
#The name of the sheet to update in the package.
|
||||||
@@ -40,21 +50,21 @@
|
|||||||
$Row = 0 ,
|
$Row = 0 ,
|
||||||
#Position in the row to start from.
|
#Position in the row to start from.
|
||||||
[int]$StartColumn,
|
[int]$StartColumn,
|
||||||
#Value, formula or script block to fill in. Script block can use $worksheet, $row, $Column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn
|
#Value, Formula or ScriptBlock to fill in. A ScriptBlock can use $worksheet, $row, $Column [number], $ColumnName [letter(s)], $startRow, $startColumn, $endRow, $endColumn.
|
||||||
$Value,
|
$Value,
|
||||||
#Optional Row heading.
|
#Optional row-heading.
|
||||||
$Heading ,
|
$Heading ,
|
||||||
#Set the heading in bold type.
|
#Set the heading in bold type.
|
||||||
[Switch]$HeadingBold,
|
[Switch]$HeadingBold,
|
||||||
#Change the size of the heading type.
|
#Change the font-size of the heading.
|
||||||
[Int]$HeadingSize ,
|
[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.
|
#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")]
|
[Alias("NFormat")]
|
||||||
$NumberFormat,
|
$NumberFormat,
|
||||||
#Style of border to draw around the row.
|
#Style of border to draw around the row.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||||
#Color of the border
|
#Color of the border.
|
||||||
[System.Drawing.Color]$BorderColor=[System.Drawing.Color]::Black,
|
$BorderColor=[System.Drawing.Color]::Black,
|
||||||
#Style for the bottom border.
|
#Style for the bottom border.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
||||||
#Style for the top border.
|
#Style for the top border.
|
||||||
@@ -63,17 +73,17 @@
|
|||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
|
||||||
#Style for the right border.
|
#Style for the right border.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||||
#Colour for the text - if none specified it will be left as it it is.
|
#Color for the text - if none specified it will be left as it it is.
|
||||||
[System.Drawing.Color]$FontColor,
|
$FontColor,
|
||||||
#Make text bold; use -Bold:$false to remove bold.
|
#Make text bold; use -Bold:$false to remove bold.
|
||||||
[Switch]$Bold,
|
[Switch]$Bold,
|
||||||
#Make text italic; use -Italic:$false to remove italic.
|
#Make text italic; use -Italic:$false to remove italic.
|
||||||
[Switch]$Italic,
|
[Switch]$Italic,
|
||||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||||
[Switch]$Underline,
|
[Switch]$Underline,
|
||||||
#Should Underline use single or double, normal or accounting mode : default is single normal.
|
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||||
#Strike through text; use -Strikethru:$false to remove Strike through.
|
#Strike through text; use -StrikeThru:$false to remove strike through.
|
||||||
[Switch]$StrikeThru,
|
[Switch]$StrikeThru,
|
||||||
#Subscript or Superscript (or none).
|
#Subscript or Superscript (or none).
|
||||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||||
@@ -82,34 +92,38 @@
|
|||||||
#Point size for the text.
|
#Point size for the text.
|
||||||
[float]$FontSize,
|
[float]$FontSize,
|
||||||
#Change background color.
|
#Change background color.
|
||||||
[System.Drawing.Color]$BackgroundColor,
|
$BackgroundColor,
|
||||||
#Background pattern - solid by default.
|
#Background pattern - solid by default.
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||||
#Secondary color for background pattern.
|
#Secondary color for background pattern.
|
||||||
[Alias("PatternColour")]
|
[Alias("PatternColour")]
|
||||||
[System.Drawing.Color]$PatternColor,
|
$PatternColor,
|
||||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping.
|
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||||
[Switch]$WrapText,
|
[Switch]$WrapText,
|
||||||
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
||||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||||
#Position cell contents to Top Bottom or Center.
|
#Position cell contents to Top, Bottom or Center.
|
||||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
[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)]
|
[ValidateRange(-90, 90)]
|
||||||
[int]$TextRotation ,
|
[int]$TextRotation ,
|
||||||
#Set cells to a fixed hieght.
|
#Set cells to a fixed height.
|
||||||
[float]$Height,
|
[float]$Height,
|
||||||
#Hide the Row.
|
#Hide the row.
|
||||||
[Switch]$Hide,
|
[Switch]$Hide,
|
||||||
#If Sepecified returns the range of cells which were affected.
|
#If sepecified, returns the range of cells which were affected.
|
||||||
[Switch]$ReturnRange,
|
[Switch]$ReturnRange,
|
||||||
#If Specified, return a row object to allow further work to be done.
|
#If Specified, return a row object to allow further work to be done.
|
||||||
[Switch]$PassThru
|
[Switch]$PassThru
|
||||||
)
|
)
|
||||||
begin {
|
begin {
|
||||||
#if we were passed a package object and a worksheet name , get the worksheet.
|
#if we were passed a package object and a worksheet name , get the worksheet.
|
||||||
if ($ExcelPackage) {$Worksheet = $ExcelPackage.Workbook.worksheets[$Worksheetname] }
|
if ($ExcelPackage) {
|
||||||
|
if ($ExcelPackage.Workbook.Worksheets.Name -notcontains $Worksheetname) {
|
||||||
|
throw "The Workbook does not contain a sheet named '$Worksheetname'"
|
||||||
|
}
|
||||||
|
else {$Worksheet = $ExcelPackage.Workbook.Worksheets[$Worksheetname] }
|
||||||
|
}
|
||||||
#In a script block to build a formula, we may want any of corners or the columnname,
|
#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 row and start column aren't specified assume first unused row, and first column
|
||||||
if (-not $StartColumn) {$StartColumn = $Worksheet.Dimension.Start.Column }
|
if (-not $StartColumn) {$StartColumn = $Worksheet.Dimension.Start.Column }
|
||||||
@@ -118,6 +132,7 @@
|
|||||||
$endRow = $Worksheet.Dimension.End.Row
|
$endRow = $Worksheet.Dimension.End.Row
|
||||||
}
|
}
|
||||||
process {
|
process {
|
||||||
|
if ($null -eq $workSheet.Dimension) {Write-Warning "Can't format an empty worksheet."; return}
|
||||||
if ($Row -eq 0 ) {$Row = $endRow + 1 }
|
if ($Row -eq 0 ) {$Row = $endRow + 1 }
|
||||||
Write-Verbose -Message "Updating Row $Row"
|
Write-Verbose -Message "Updating Row $Row"
|
||||||
#Add a row label
|
#Add a row label
|
||||||
@@ -130,11 +145,12 @@
|
|||||||
#Fill in the data
|
#Fill in the data
|
||||||
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) {
|
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) {
|
||||||
#We might want the column name in a script block
|
#We might want the column name in a script block
|
||||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
$columnName = (New-Object -TypeName OfficeOpenXml.ExcelCellAddress @(1,$column)).Address -replace "1",""
|
||||||
if ($Value -is [scriptblock] ) {
|
if ($Value -is [scriptblock] ) {
|
||||||
#re-create the script block otherwise variables from this function are out of scope.
|
#re-create the script block otherwise variables from this function are out of scope.
|
||||||
$cellData = & ([scriptblock]::create( $Value ))
|
$cellData = & ([scriptblock]::create( $Value ))
|
||||||
Write-Verbose -Message $cellData
|
if ($null -eq $cellData) {Write-Verbose -Message "Script block evaluates to null."}
|
||||||
|
else {Write-Verbose -Message "Script block evaluates to '$cellData'"}
|
||||||
}
|
}
|
||||||
else{$cellData = $Value}
|
else{$cellData = $Value}
|
||||||
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
|
if ($cellData -match "^=") { $Worksheet.Cells[$Row, $column].Formula = ($cellData -replace '^=','') } #EPPlus likes formulas with no = sign; Excel doesn't care
|
||||||
@@ -156,14 +172,14 @@
|
|||||||
}}
|
}}
|
||||||
#region Apply formatting
|
#region Apply formatting
|
||||||
$params = @{}
|
$params = @{}
|
||||||
foreach ($p in @('Underline','Bold','Italic','StrikeThru','FontSize', 'FontShift','NumberFormat','TextRotation',
|
foreach ($p in @('Underline','Bold','Italic','StrikeThru', 'FontName', 'FontSize', 'FontShift','NumberFormat','TextRotation',
|
||||||
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Height', 'FontColor'
|
'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Height', 'FontColor'
|
||||||
'BorderAround', 'BorderBottom', 'BorderTop', 'BorderLeft', 'BorderRight', 'BorderColor',
|
'BorderAround', 'BorderBottom', 'BorderTop', 'BorderLeft', 'BorderRight', 'BorderColor',
|
||||||
'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
'BackgroundColor', 'BackgroundPattern', 'PatternColor')) {
|
||||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||||
}
|
}
|
||||||
if ($params.Count) {
|
if ($params.Count) {
|
||||||
$theRange = [OfficeOpenXml.ExcelAddress]::New($Row, $StartColumn, $Row, $endColumn)
|
$theRange = New-Object -TypeName OfficeOpenXml.ExcelAddress @($Row, $StartColumn, $Row, $endColumn)
|
||||||
Set-ExcelRange -WorkSheet $Worksheet -Range $theRange @params
|
Set-ExcelRange -WorkSheet $Worksheet -Range $theRange @params
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
81
Set-WorkSheetProtection.ps1
Normal file
81
Set-WorkSheetProtection.ps1
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
Function Set-WorkSheetProtection {
|
||||||
|
[Cmdletbinding()]
|
||||||
|
<#
|
||||||
|
.Synopsis
|
||||||
|
Sets protection on the worksheet
|
||||||
|
.Description
|
||||||
|
|
||||||
|
.Example
|
||||||
|
Set-WorkSheetProtection -WorkSheet $planSheet -IsProtected -AllowAll -AllowInsertColumns:$false -AllowDeleteColumns:$false -UnLockAddress "A:N"
|
||||||
|
Turns on protection for the worksheet in $planSheet, checks all the allow boxes excel Insert and Delete columns and unlocks columns A-N
|
||||||
|
#>
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system state')]
|
||||||
|
param (
|
||||||
|
#The worksheet where protection is to be applied.
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
|
||||||
|
#Value of the "Protect Worksheet and Contents of locked cells" check box. Initially FALSE. use -IsProtected:$false to turn off it it has been switched on
|
||||||
|
[switch]$IsProtected,
|
||||||
|
#If provided sets all the ALLOW options to true or false and then allows them to be changed individually
|
||||||
|
[switch]$AllowAll,
|
||||||
|
#Opposite of the value in the 'Select locked cells' check box. Set to allow when Protect is first enabled
|
||||||
|
[switch]$BlockSelectLockedCells,
|
||||||
|
#Opposite of the value in the 'Select unlocked cells' check box. Set to allow when Protect is first enabled
|
||||||
|
[switch]$BlockSelectUnlockedCells,
|
||||||
|
#Value of the 'Format Cells' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowFormatCells,
|
||||||
|
#Value of the 'Format Columns' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowFormatColumns,
|
||||||
|
#Value of the 'Format Rows' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowFormatRows,
|
||||||
|
#Value of the 'Insert Columns' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowInsertColumns,
|
||||||
|
#Value of the 'Insert Columns' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowInsertRows,
|
||||||
|
#Value of the 'Insert Hyperlinks' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowInsertHyperlinks,
|
||||||
|
#Value of the 'Delete Columns' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowDeleteColumns,
|
||||||
|
#Value of the 'Delete Rows' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowDeleteRows,
|
||||||
|
#Value of the 'Sort' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowSort,
|
||||||
|
#Value of the 'Use AutoFilter' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowAutoFilter,
|
||||||
|
#Value of the 'Use PivotTable and PivotChart' check box. Set to block when Protect is first enabled
|
||||||
|
[switch]$AllowPivotTables,
|
||||||
|
##Opposite of the value in the 'Edit objects' check box. Set to allow when Protect is first enabled
|
||||||
|
[switch]$BlockEditObject,
|
||||||
|
##Opposite of the value in the 'Edit Scenarios' check box. Set to allow when Protect is first enabled
|
||||||
|
[switch]$BlockEditScenarios,
|
||||||
|
#Address range for cells to lock in the form "A:Z" or "1:10" or "A1:Z10"
|
||||||
|
[string]$LockAddress,
|
||||||
|
#Address range for cells to Unlock in the form "A:Z" or "1:10" or "A1:Z10"
|
||||||
|
[string]$UnLockAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($PSBoundParameters.ContainsKey('isprotected') -and $IsProtected -eq $false) {$worksheet.Protection.IsProtected = $false}
|
||||||
|
elseif ($IsProtected) {
|
||||||
|
$worksheet.Protection.IsProtected = $true
|
||||||
|
foreach ($ParName in @('AllowFormatCells',
|
||||||
|
'AllowFormatColumns', 'AllowFormatRows',
|
||||||
|
'AllowInsertColumns', 'AllowInsertRows', 'AllowInsertHyperlinks',
|
||||||
|
'AllowDeleteColumns', 'AllowDeleteRows',
|
||||||
|
'AllowSort' , 'AllowAutoFilter', 'AllowPivotTables')) {
|
||||||
|
if ($AllowAll -and -not $PSBoundParameters.ContainsKey($Parname)) {$worksheet.Protection.$ParName = $true}
|
||||||
|
elseif ($PSBoundParameters[$ParName] -eq $true ) {$worksheet.Protection.$ParName = $true}
|
||||||
|
}
|
||||||
|
if ($BlockSelectLockedCells) {$worksheet.Protection.AllowSelectLockedCells = $false }
|
||||||
|
if ($BlockSelectUnlockedCells) {$worksheet.Protection.AllowSelectUnLockedCells = $false }
|
||||||
|
if ($BlockEditObject) {$worksheet.Protection.AllowEditObject = $false }
|
||||||
|
if ($BlockEditScenarios) {$worksheet.Protection.AllowEditScenarios = $false }
|
||||||
|
}
|
||||||
|
Else {Write-Warning -Message "You haven't said if you want to turn protection off, or on." }
|
||||||
|
|
||||||
|
if ($UnlockAddress) {
|
||||||
|
Set-ExcelRange -Range $WorkSheet.cells[$UnlockAddress] -Locked:$false
|
||||||
|
}
|
||||||
|
if ($lockAddress) {
|
||||||
|
Set-ExcelRange -Range $WorkSheet.cells[$UnlockAddress] -Locked
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,38 @@
|
|||||||
Function Set-ExcelRange {
|
Function Set-ExcelRange {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Applies Number, font, alignment and color formatting, values or formulas to a range of Excel Cells.
|
Applies number, font, alignment and/or color formatting, values or formulas to a range of Excel cells.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Set-ExcelRange was created to set the style elements for a range of cells, this includes
|
Set-ExcelRange was created to set the style elements for a range of cells,
|
||||||
auto-sizing and hiding, setting font elements (Name, Size, Bold, Italic, Underline & UnderlineStyle and Subscript & SuperScript),
|
this includes auto-sizing and hiding, setting font elements (Name, Size,
|
||||||
font and background colors, borders, text wrapping, rotation, aliginment within cells, and number format.
|
Bold, Italic, Underline & UnderlineStyle and Subscript & SuperScript),
|
||||||
It was orignally named "Set-Format",but it has been extended to set Values, Formulas and
|
font and background colors, borders, text wrapping, rotation, alignment
|
||||||
ArrayFormulas (sometimes called Ctrl-shift-Enter [CSE] formulas); because of this
|
within cells, and number format.
|
||||||
The name has become Set-ExcelRange - but the old name of Set-Format is preserved as an alias name.
|
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
|
.EXAMPLE
|
||||||
$sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NumberFormat "#,###" -AutoFit
|
$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
|
Selects column 3 from a sheet object (within a workbook object, which
|
||||||
which formats as an integer with comma-separated groups, aligns it right, and auto-fits the column to the contents.
|
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
|
.EXAMPLE
|
||||||
Set-ExcelRange -Range $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NumberFormat "#,###"
|
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.
|
Instead of piping the address, this version specifies a block of cells
|
||||||
|
and applies similar formatting.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Set-ExcelRange $excel.Workbook.Worksheets[1].Tables["Processes"] -Italic
|
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.
|
This time instead of specifying a range of cells, a table is selected
|
||||||
|
by name and formatted as italic.
|
||||||
#>
|
#>
|
||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
[Alias("Set-Format")]
|
[Alias("Set-Format")]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system state')]
|
||||||
Param (
|
Param (
|
||||||
#One or more row(s), Column(s) and/or block(s) of cells to format.
|
#One or more row(s), Column(s) and/or block(s) of cells to format.
|
||||||
[Parameter(ValueFromPipeline = $true,Position=0)]
|
[Parameter(ValueFromPipeline = $true,Position=0)]
|
||||||
@@ -38,7 +46,7 @@
|
|||||||
#Style of border to draw around the range.
|
#Style of border to draw around the range.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||||
#Color of the border.
|
#Color of the border.
|
||||||
[System.Drawing.Color]$BorderColor=[System.Drawing.Color]::Black,
|
$BorderColor=[System.Drawing.Color]::Black,
|
||||||
#Style for the bottom border.
|
#Style for the bottom border.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
||||||
#Style for the top border.
|
#Style for the top border.
|
||||||
@@ -48,22 +56,22 @@
|
|||||||
#Style for the right border.
|
#Style for the right border.
|
||||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||||
#Colour for the text - if none is specified it will be left as it is.
|
#Colour for the text - if none is specified it will be left as it is.
|
||||||
[System.Drawing.Color]$FontColor,
|
$FontColor,
|
||||||
#Value for the cell.
|
#Value for the cell.
|
||||||
$Value,
|
$Value,
|
||||||
#Formula for the cell.
|
#Formula for the cell.
|
||||||
$Formula,
|
$Formula,
|
||||||
#Specifies formula should be an array formula (a.k.a CSE [ctrl-shift-enter] formula).
|
#Specifies formula should be an array formula (a.k.a CSE [ctrl-shift-enter] formula).
|
||||||
[Switch]$ArrayFormula,
|
[Switch]$ArrayFormula,
|
||||||
#Clear Bold, Italic, StrikeThrough and Underline and set colour to black.
|
#Clear Bold, Italic, StrikeThrough and Underline and set color to Black.
|
||||||
[Switch]$ResetFont,
|
[Switch]$ResetFont,
|
||||||
#Make text bold; use -Bold:$false to remove bold.
|
#Make text bold; use -Bold:$false to remove bold.
|
||||||
[Switch]$Bold,
|
[Switch]$Bold,
|
||||||
#Make text italic; use -Italic:$false to remove italic.
|
#Make text italic; use -Italic:$false to remove italic.
|
||||||
[Switch]$Italic,
|
[Switch]$Italic,
|
||||||
#Underline the text using the underline style in -underline type; use -Underline:$false to remove underlining.
|
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||||
[Switch]$Underline,
|
[Switch]$Underline,
|
||||||
#Should Underline use single or double, normal or accounting mode: the default is single normal.
|
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||||
#Strike through text; use -Strikethru:$false to remove Strike through
|
#Strike through text; use -Strikethru:$false to remove Strike through
|
||||||
[Switch]$StrikeThru,
|
[Switch]$StrikeThru,
|
||||||
@@ -74,17 +82,17 @@
|
|||||||
#Point size for the text.
|
#Point size for the text.
|
||||||
[float]$FontSize,
|
[float]$FontSize,
|
||||||
#Change background color.
|
#Change background color.
|
||||||
[System.Drawing.Color]$BackgroundColor,
|
$BackgroundColor,
|
||||||
#Background pattern - Solid by default.
|
#Background pattern - Solid by default.
|
||||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||||
#Secondary color for background pattern.
|
#Secondary color for background pattern.
|
||||||
[Alias("PatternColour")]
|
[Alias("PatternColour")]
|
||||||
[System.Drawing.Color]$PatternColor,
|
$PatternColor,
|
||||||
#Turn on text wrapping; use -WrapText:$false to turn off word wrapping.
|
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||||
[Switch]$WrapText,
|
[Switch]$WrapText,
|
||||||
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
||||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||||
#Position cell contents to Top Bottom or Center.
|
#Position cell contents to Top, Bottom or Center.
|
||||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
[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)]
|
[ValidateRange(-90, 90)]
|
||||||
@@ -94,14 +102,16 @@
|
|||||||
[Switch]$AutoSize,
|
[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,
|
[float]$Width,
|
||||||
#Set cells to a fixed hieght (rows or ranges only).
|
#Set cells to a fixed height (rows or ranges only).
|
||||||
[float]$Height,
|
[float]$Height,
|
||||||
#Hide a row or column (not a range); use -Hidden:$false to unhide.
|
#Hide a row or column (not a range); use -Hidden:$false to unhide.
|
||||||
[Switch]$Hidden
|
[Switch]$Hidden,
|
||||||
|
#Locks cells. Cells are locked by default use -locked:$false on the whole sheet and then lock specific ones, and enable protection on the sheet.
|
||||||
|
[Switch]$Locked
|
||||||
)
|
)
|
||||||
process {
|
process {
|
||||||
if ($Range -is [Array]) {
|
if ($Range -is [Array]) {
|
||||||
[void]$PSBoundParameters.Remove("Range")
|
$null = $PSBoundParameters.Remove("Range")
|
||||||
$Range | Set-ExcelRange @PSBoundParameters
|
$Range | Set-ExcelRange @PSBoundParameters
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -110,10 +120,10 @@
|
|||||||
elseif ($WorkSheet -and ($Range -is [string] -or $Range -is [OfficeOpenXml.ExcelAddress])) {
|
elseif ($WorkSheet -and ($Range -is [string] -or $Range -is [OfficeOpenXml.ExcelAddress])) {
|
||||||
$Range = $WorkSheet.Cells[$Range]
|
$Range = $WorkSheet.Cells[$Range]
|
||||||
}
|
}
|
||||||
elseif ($Range -is [string]) {Write-Warning -Message "The range pararameter you have specified also needs a worksheet parameter."}
|
elseif ($Range -is [string]) {Write-Warning -Message "The range pararameter you have specified also needs a worksheet parameter." ;return}
|
||||||
|
#else we assume Range is a range.
|
||||||
if ($ResetFont) {
|
if ($ResetFont) {
|
||||||
$Range.Style.Font.Color.SetColor("Black")
|
$Range.Style.Font.Color.SetColor( ([System.Drawing.Color]::Black))
|
||||||
$Range.Style.Font.Bold = $false
|
$Range.Style.Font.Bold = $false
|
||||||
$Range.Style.Font.Italic = $false
|
$Range.Style.Font.Italic = $false
|
||||||
$Range.Style.Font.UnderLine = $false
|
$Range.Style.Font.UnderLine = $false
|
||||||
@@ -136,10 +146,14 @@
|
|||||||
if ($PSBoundParameters.ContainsKey('FontSize')){
|
if ($PSBoundParameters.ContainsKey('FontSize')){
|
||||||
$Range.Style.Font.Size = $FontSize
|
$Range.Style.Font.Size = $FontSize
|
||||||
}
|
}
|
||||||
|
if ($PSBoundParameters.ContainsKey('FontName')){
|
||||||
|
$Range.Style.Font.Name = $FontName
|
||||||
|
}
|
||||||
if ($PSBoundParameters.ContainsKey('FontShift')){
|
if ($PSBoundParameters.ContainsKey('FontShift')){
|
||||||
$Range.Style.Font.VerticalAlign = $FontShift
|
$Range.Style.Font.VerticalAlign = $FontShift
|
||||||
}
|
}
|
||||||
if ($PSBoundParameters.ContainsKey('FontColor')){
|
if ($PSBoundParameters.ContainsKey('FontColor')){
|
||||||
|
if ($FontColor -is [string]) {$FontColor = [System.Drawing.Color]::$FontColor }
|
||||||
$Range.Style.Font.Color.SetColor( $FontColor)
|
$Range.Style.Font.Color.SetColor( $FontColor)
|
||||||
}
|
}
|
||||||
if ($PSBoundParameters.ContainsKey('TextRotation')) {
|
if ($PSBoundParameters.ContainsKey('TextRotation')) {
|
||||||
@@ -169,6 +183,7 @@
|
|||||||
if ($PSBoundParameters.ContainsKey('NumberFormat')) {
|
if ($PSBoundParameters.ContainsKey('NumberFormat')) {
|
||||||
$Range.Style.Numberformat.Format = (Expand-NumberFormat $NumberFormat)
|
$Range.Style.Numberformat.Format = (Expand-NumberFormat $NumberFormat)
|
||||||
}
|
}
|
||||||
|
if ($BorderColor -is [string]) {$BorderColor = [System.Drawing.Color]::$BorderColor }
|
||||||
if ($PSBoundParameters.ContainsKey('BorderAround')) {
|
if ($PSBoundParameters.ContainsKey('BorderAround')) {
|
||||||
$Range.Style.Border.BorderAround($BorderAround, $BorderColor)
|
$Range.Style.Border.BorderAround($BorderAround, $BorderColor)
|
||||||
}
|
}
|
||||||
@@ -190,8 +205,10 @@
|
|||||||
}
|
}
|
||||||
if ($PSBoundParameters.ContainsKey('BackgroundColor')) {
|
if ($PSBoundParameters.ContainsKey('BackgroundColor')) {
|
||||||
$Range.Style.Fill.PatternType = $BackgroundPattern
|
$Range.Style.Fill.PatternType = $BackgroundPattern
|
||||||
|
if ($BackgroundColor -is [string]) {$BackgroundColor = [System.Drawing.Color]::$BackgroundColor }
|
||||||
$Range.Style.Fill.BackgroundColor.SetColor($BackgroundColor)
|
$Range.Style.Fill.BackgroundColor.SetColor($BackgroundColor)
|
||||||
if ($PatternColor) {
|
if ($PatternColor) {
|
||||||
|
if ($PatternColor -is [string]) {$PatternColor = [System.Drawing.Color]::$PatternColor }
|
||||||
$Range.Style.Fill.PatternColor.SetColor( $PatternColor)
|
$Range.Style.Fill.PatternColor.SetColor( $PatternColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,6 +244,9 @@
|
|||||||
$Range -is [OfficeOpenXml.ExcelColumn] ) {$Range.Hidden = [boolean]$Hidden}
|
$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)) }
|
else {Write-Warning -Message ("Can hide a row or a column but not a {0} object" -f ($Range.GetType().name)) }
|
||||||
}
|
}
|
||||||
|
if ($PSBoundParameters.ContainsKey('Locked')) {
|
||||||
|
$Range.Style.Locked=$Locked
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,12 +308,15 @@ if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter)
|
|||||||
Function Expand-NumberFormat {
|
Function Expand-NumberFormat {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Converts short names for Number formats to the formatting strings used in Excel
|
Converts short names for number formats to the formatting strings used in Excel
|
||||||
.DESCRIPTION
|
.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
|
Where you can type a number format you can write, for example, 'Short-Date'
|
||||||
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)
|
and the module will translate it into the format string used by Excel.
|
||||||
Other formats change how they appear when loaded with different cultures (depending on the country "," or "." or " " may be the thousand seperator
|
Some formats, like Short-Date change how they are presented when Excel
|
||||||
although excel always stores it as ",")
|
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
|
.EXAMPLE
|
||||||
Expand-NumberFormat percentage
|
Expand-NumberFormat percentage
|
||||||
|
|
||||||
@@ -301,11 +324,15 @@ Function Expand-NumberFormat {
|
|||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Expand-NumberFormat Currency
|
Expand-NumberFormat Currency
|
||||||
|
|
||||||
Returns the currency format specified in the local regional settings. This may not be the same as Excel uses
|
Returns the currency format specified in the local regional settings. This
|
||||||
The regional settings set the currency symbol and then whether it is before or after the number and seperated with a space or not;
|
may not be the same as Excel uses. The regional settings set the currency
|
||||||
for negative numbers the number by wrapped in parentheses or a - sign might appear before or after the number and symbol.
|
symbol and then whether it is before or after the number and separated with
|
||||||
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€ )
|
a space or not; for negative numbers the number may be wrapped in parentheses
|
||||||
In French the decimal point will be rendered as a "," and the thousand seperator as a space.
|
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()]
|
[cmdletbinding()]
|
||||||
[OutputType([String])]
|
[OutputType([String])]
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='Update*', Justification='Does not change system state')]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Scope='Function', Target='Update*', Justification='Property would be incorrect')]
|
||||||
|
|
||||||
|
param()
|
||||||
|
|
||||||
Function Update-FirstObjectProperties {
|
Function Update-FirstObjectProperties {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
@@ -79,7 +84,7 @@ Function Update-FirstObjectProperties {
|
|||||||
$Union = @()
|
$Union = @()
|
||||||
$Input | ForEach-Object {
|
$Input | ForEach-Object {
|
||||||
If ($Union.Count) {
|
If ($Union.Count) {
|
||||||
$_ | Get-Member | Where {-not ($Union[0] | Get-Member $_.Name)} | ForEach-Object {
|
$_ | Get-Member | Where-Object {-not ($Union[0] | Get-Member $_.Name)} | ForEach-Object {
|
||||||
$Union[0] | Add-Member -MemberType NoteProperty -Name $_.Name -Value $Null
|
$Union[0] | Add-Member -MemberType NoteProperty -Name $_.Name -Value $Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
#Requires -Modules Pester
|
#Requires -Modules Pester
|
||||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||||
|
if ($PSVersionTable.PSVersion.Major -gt 5) { Write-Warning "Can't test grid view on V6" }
|
||||||
Add-Type -AssemblyName System.Windows.Forms
|
else {Add-Type -AssemblyName System.Windows.Forms }
|
||||||
|
|
||||||
Describe "Compare Worksheet" {
|
Describe "Compare Worksheet" {
|
||||||
Context "Simple comparison output" {
|
Context "Simple comparison output" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Remove-Item -Path "$env:temp\server*.xlsx"
|
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 | 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
|
#$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
|
$row4Displayname = $s[2].DisplayName
|
||||||
@@ -51,8 +50,16 @@ Describe "Compare Worksheet" {
|
|||||||
|
|
||||||
Context "Setting the background to highlight different rows, use of grid view." {
|
Context "Setting the background to highlight different rows, use of grid view." {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor LightGreen -GridView
|
$useGrid = ($PSVersionTable.PSVersion.Major -LE 5)
|
||||||
Start-Sleep -sec 5; [System.Windows.Forms.SendKeys]::Sendwait("%{F4}")
|
if ($useGrid) {
|
||||||
|
$ModulePath = (Get-Command -Name 'Compare-WorkSheet').Module.Path
|
||||||
|
$PowerShellExec = if ($PSEdition -eq 'Core') {'pwsh.exe'} else {'powershell.exe'}
|
||||||
|
$PowerShellPath = Join-Path -Path $PSHOME -ChildPath $PowerShellExec
|
||||||
|
. $PowerShellPath -Command ("Import-Module $ModulePath; " + '$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView; Start-Sleep -sec 5')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView:$useGrid
|
||||||
|
}
|
||||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||||
@@ -78,7 +85,7 @@ Describe "Compare Worksheet" {
|
|||||||
|
|
||||||
Context "Setting the forgound to highlight changed properties" {
|
Context "Setting the forgound to highlight changed properties" {
|
||||||
BeforeAll {
|
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"
|
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||||
@@ -107,7 +114,8 @@ Describe "Compare Worksheet" {
|
|||||||
|
|
||||||
Context "More complex comparison: output check and different worksheet names " {
|
Context "More complex comparison: output check and different worksheet names " {
|
||||||
BeforeAll {
|
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 | 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
|
#$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
|
$row4Displayname = $s[2].DisplayName
|
||||||
@@ -119,9 +127,10 @@ Describe "Compare Worksheet" {
|
|||||||
$row6Name = $s[5].ServiceName
|
$row6Name = $s[5].ServiceName
|
||||||
$s.RemoveAt(5)
|
$s.RemoveAt(5)
|
||||||
$s[10].ServiceType = "Changed should not matter"
|
$s[10].ServiceType = "Changed should not matter"
|
||||||
|
|
||||||
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path $env:temp\server2.xlsx -WorkSheetname server2
|
$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")
|
#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"
|
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||||
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
|
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
|
||||||
@@ -170,8 +179,8 @@ Describe "Compare Worksheet" {
|
|||||||
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | Should beNullOrEmpty
|
$s2Sheet.Cells["F4"].Style.Font.Color.Rgb | Should beNullOrEmpty
|
||||||
}
|
}
|
||||||
AfterAll {
|
AfterAll {
|
||||||
Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
|
# Close-ExcelPackage -ExcelPackage $xl1 -NoSave -Show
|
||||||
Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
|
# Close-ExcelPackage -ExcelPackage $xl2 -NoSave -Show
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,21 +328,23 @@ Describe "Merge Multiple sheets" {
|
|||||||
$ws.Cells[12,9 ].Value | Should be $ws.Cells[12,5].Value
|
$ws.Cells[12,9 ].Value | Should be $ws.Cells[12,5].Value
|
||||||
$ws.Cells[12,10].Value | Should be $ws.Cells[12,6].Value
|
$ws.Cells[12,10].Value | Should be $ws.Cells[12,6].Value
|
||||||
}
|
}
|
||||||
it "Creared Conditional formatting rules " {
|
it "Created Conditional formatting rules " {
|
||||||
$cf=$ws.ConditionalFormatting
|
$cf=$ws.ConditionalFormatting
|
||||||
$cf.Count | Should be 15
|
$cf.Count | Should be 17
|
||||||
$cf[14].Address.Address | Should be 'B2:B1048576'
|
$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].Type | Should be 'Expression'
|
||||||
$cf[14].Formula | Should be 'OR(G2<>"Same",K2<>"Same")'
|
$cf[14].Formula | Should be 'OR(G2="Added",K2="Added")'
|
||||||
$cf[14].Style.Font.Color.Color.Name | Should be "FFFF0000"
|
$cf[14].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffb6c1'
|
||||||
$cf[13].Address.Address | Should be 'D2:D1048576'
|
$cf[14].Style.Fill.PatternType.ToString() | Should be 'Solid'
|
||||||
$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[ 0].Address.Address | Should be 'F1:F1048576'
|
$cf[ 0].Address.Address | Should be 'F1:F1048576'
|
||||||
$cf[ 0].Type | Should be 'Expression'
|
$cf[ 0].Type | Should be 'Expression'
|
||||||
$cf[ 0].Formula | Should be 'G1="Added"'
|
$cf[ 0].Formula | Should be 'G1="Added"'
|
||||||
$cf[ 0].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffa500'
|
$cf[ 0].Style.Fill.BackgroundColor.Color.Name | Should be 'ffffa500'
|
||||||
|
$cf[ 0].Style.Fill.PatternType.ToString() | Should be 'Solid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,10 @@ $path1 = "$env:TEMP\Test1.xlsx"
|
|||||||
$path2 = "$env:TEMP\Test2.xlsx"
|
$path2 = "$env:TEMP\Test2.xlsx"
|
||||||
Remove-item -Path $path1, $path2 -ErrorAction SilentlyContinue
|
Remove-item -Path $path1, $path2 -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
|
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
|
||||||
|
|
||||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "<EFBFBD>") {$OtherCurrencySymbol = "$"}
|
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
|
||||||
else {$OtherCurrencySymbol = "<EFBFBD>"}
|
else {$OtherCurrencySymbol = "£"}
|
||||||
[PSCustOmobject][Ordered]@{
|
[PSCustOmobject][Ordered]@{
|
||||||
Date = Get-Date
|
Date = Get-Date
|
||||||
Formula1 = '=SUM(F2:G2)'
|
Formula1 = '=SUM(F2:G2)'
|
||||||
@@ -31,7 +31,7 @@ else {$OtherCurrencySymbol = "
|
|||||||
Link2 = "https://github.com/dfinke/ImportExcel" # Links are not copied correctly, hopefully this will be fixed at some future date
|
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
|
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -WorkSheetname MixedTypes -Path $path2
|
||||||
Describe "Copy-Worksheet" {
|
Describe "Copy-Worksheet" {
|
||||||
Context "Simplest copy"{
|
Context "Simplest copy" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Copy-ExcelWorkSheet -SourceWorkbook $path1 -DestinationWorkbook $path2
|
Copy-ExcelWorkSheet -SourceWorkbook $path1 -DestinationWorkbook $path2
|
||||||
$excel = Open-ExcelPackage -Path $path2
|
$excel = Open-ExcelPackage -Path $path2
|
||||||
@@ -43,12 +43,12 @@ Describe "Copy-Worksheet" {
|
|||||||
$ws.Dimension.Address | should be $ProcRange
|
$ws.Dimension.Address | should be $ProcRange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Context "Mixed types using a package object"{
|
Context "Mixed types using a package object" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Copy-ExcelWorkSheet -SourceWorkbook $excel -DestinationWorkbook $excel -DestinationWorkSheet "CopyOfMixedTypes"
|
Copy-ExcelWorkSheet -SourceWorkbook $excel -DestinationWorkbook $excel -DestinationWorkSheet "CopyOfMixedTypes"
|
||||||
Close-ExcelPackage -ExcelPackage $excel
|
Close-ExcelPackage -ExcelPackage $excel
|
||||||
$excel = Open-ExcelPackage -Path $path2
|
$excel = Open-ExcelPackage -Path $path2
|
||||||
$ws = $Excel.Workbook.Worksheets[3]
|
$ws = $Excel.Workbook.Worksheets[3]
|
||||||
}
|
}
|
||||||
it "Copied a worksheet, giving 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
|
$Excel.Workbook.Worksheets.count | Should be 3
|
||||||
@@ -60,29 +60,57 @@ Describe "Copy-Worksheet" {
|
|||||||
it "Copied the expected data into the worksheet " {
|
it "Copied the expected data into the worksheet " {
|
||||||
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
|
$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, 5].Value.GetType().name | Should be 'String'
|
||||||
$ws.Cells[2, 6].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, 18].Value.GetType().name | Should be 'String'
|
||||||
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
|
||||||
($ws.Cells[2, 12].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 12].Value -is [valuetype] ) | Should be $true
|
||||||
($ws.Cells[2, 13].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 13].Value -is [valuetype] ) | Should be $true
|
||||||
$ws.Cells[2, 11].Value | Should beLessThan 0
|
$ws.Cells[2, 11].Value | Should beLessThan 0
|
||||||
$ws.Cells[2, 12].Value | Should beLessThan 0
|
$ws.Cells[2, 12].Value | Should beLessThan 0
|
||||||
$ws.Cells[2, 13].Value | Should beLessThan 0
|
$ws.Cells[2, 13].Value | Should beLessThan 0
|
||||||
if ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ",") {
|
if ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ",") {
|
||||||
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
|
||||||
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
|
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
|
||||||
}
|
}
|
||||||
elseif ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ".") {
|
elseif ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ".") {
|
||||||
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
|
||||||
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
|
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
|
||||||
}
|
}
|
||||||
($ws.Cells[2, 14].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 14].Value -is [valuetype] ) | Should be $true
|
||||||
$ws.Cells[2, 15].Value.GetType().name | Should be 'String'
|
$ws.Cells[2, 15].Value.GetType().name | Should be 'String'
|
||||||
$ws.Cells[2, 16].Value.GetType().name | Should be 'String'
|
$ws.Cells[2, 16].Value.GetType().name | Should be 'String'
|
||||||
$ws.Cells[2, 17].Value.GetType().name | Should be 'String'
|
$ws.Cells[2, 17].Value.GetType().name | Should be 'String'
|
||||||
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
|
||||||
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
|
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Context "Copy worksheet should close all files" {
|
||||||
|
BeforeAll {
|
||||||
|
$xlfile = "$env:TEMP\reports.xlsx"
|
||||||
|
$xlfileArchive = "$env:TEMP\reportsArchive.xlsx"
|
||||||
|
|
||||||
|
rm $xlfile -ErrorAction SilentlyContinue
|
||||||
|
rm $xlfileArchive -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$sheets = echo 1.1.2019 1.2.2019 1.3.2019 1.4.2019 1.5.2019
|
||||||
|
|
||||||
|
$sheets | ForEach-Object {
|
||||||
|
"Hello World" | Export-Excel $xlfile -WorksheetName $_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should copy and remove sheets" {
|
||||||
|
$targetSheets = echo 1.1.2019 1.4.2019
|
||||||
|
|
||||||
|
$targetSheets | ForEach-Object {
|
||||||
|
Copy-ExcelWorkSheet -SourceWorkbook $xlfile -DestinationWorkbook $xlfileArchive -SourceWorkSheet $_ -DestinationWorkSheet $_
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetSheets | ForEach-Object { Remove-WorkSheet -FullName $xlfile -WorksheetName $_ }
|
||||||
|
|
||||||
|
(Get-ExcelSheetInfo -Path $xlfile ).Count | Should Be 3
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ Describe ExportExcel {
|
|||||||
$path = "$env:TEMP\Test.xlsx"
|
$path = "$env:TEMP\Test.xlsx"
|
||||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||||
#Test with a maximum of 100 processes for speed; export all properties, then export smaller subsets.
|
#Test with a maximum of 100 processes for speed; export all properties, then export smaller subsets.
|
||||||
$processes = Get-Process | select-object -first 100
|
$processes = Get-Process | where {$_.StartTime} | Select-Object -first 100 -Property * -excludeProperty Parent
|
||||||
$propertyNames = $Processes[0].psobject.properties.name
|
$propertyNames = $Processes[0].psobject.properties.name
|
||||||
$rowcount = $Processes.Count
|
$rowcount = $Processes.Count
|
||||||
$Processes | Export-Excel $path #-show
|
$Processes | Export-Excel $path #-show
|
||||||
@@ -135,7 +135,7 @@ Describe ExportExcel {
|
|||||||
it "Created the worksheet with the expected name, number of rows and number of columns " {
|
it "Created the worksheet with the expected name, number of rows and number of columns " {
|
||||||
$ws.Name | Should be "sheet1"
|
$ws.Name | Should be "sheet1"
|
||||||
$ws.Dimension.Columns | Should be 1
|
$ws.Dimension.Columns | Should be 1
|
||||||
$ws.Dimension.Rows | Should be 12
|
$ws.Dimension.End.Row | Should be 12
|
||||||
}
|
}
|
||||||
|
|
||||||
it "Set the default style for the sheet as expected " {
|
it "Set the default style for the sheet as expected " {
|
||||||
@@ -355,13 +355,7 @@ Describe ExportExcel {
|
|||||||
|
|
||||||
Context "#Example 5 # Adding a single conditional format " {
|
Context "#Example 5 # Adding a single conditional format " {
|
||||||
#Test New-ConditionalText builds correctly
|
#Test New-ConditionalText builds correctly
|
||||||
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor DarkRed -BackgroundColor LightPink
|
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor ([System.Drawing.Color]::DarkRed) -BackgroundColor ([System.Drawing.Color]::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
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = "$env:TEMP\Test.xlsx"
|
$path = "$env:TEMP\Test.xlsx"
|
||||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||||
@@ -398,8 +392,8 @@ Describe ExportExcel {
|
|||||||
#Testing -Passthrough
|
#Testing -Passthrough
|
||||||
$Excel = Get-Service | Select-Object Name, Status, DisplayName, ServiceName |
|
$Excel = Get-Service | Select-Object Name, Status, DisplayName, ServiceName |
|
||||||
Export-Excel $path -PassThru -ConditionalText $(
|
Export-Excel $path -PassThru -ConditionalText $(
|
||||||
New-ConditionalText Stop DarkRed LightPink
|
New-ConditionalText Stop ([System.Drawing.Color]::DarkRed) ([System.Drawing.Color]::LightPink)
|
||||||
New-ConditionalText Running Blue Cyan
|
New-ConditionalText Running ([System.Drawing.Color]::Blue) ([System.Drawing.Color]::Cyan)
|
||||||
)
|
)
|
||||||
$ws = $Excel.Workbook.Worksheets[1]
|
$ws = $Excel.Workbook.Worksheets[1]
|
||||||
it "Added two blocks of conditional formating for the data range " {
|
it "Added two blocks of conditional formating for the data range " {
|
||||||
@@ -649,7 +643,7 @@ Describe ExportExcel {
|
|||||||
$warnvar = $null
|
$warnvar = $null
|
||||||
#Test create two data pages; as part of adding the second give both their own pivot table, test -autosize switch
|
#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-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 AliceBlue -TitleBold -TitleSize 22 -PivotTableDefinition $ptDef
|
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
|
$Excel = Open-ExcelPackage $path
|
||||||
$ws1 = $Excel.Workbook.Worksheets["Sheet1"]
|
$ws1 = $Excel.Workbook.Worksheets["Sheet1"]
|
||||||
$ws2 = $Excel.Workbook.Worksheets["Sheet2"]
|
$ws2 = $Excel.Workbook.Worksheets["Sheet2"]
|
||||||
@@ -722,10 +716,10 @@ Describe ExportExcel {
|
|||||||
Set-ExcelRange -Address $sheet.Cells["E1:H1048576"] -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.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
|
||||||
Set-ExcelRange -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
|
Set-ExcelRange -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
|
||||||
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
|
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor ([System.Drawing.Color]::Red)
|
||||||
#test Add-ConditionalFormatting -passthru and using a range (and no worksheet)
|
#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
|
$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
|
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
|
#Test Set-ExcelRange with a column
|
||||||
foreach ($c in 5..9) {Set-ExcelRange $sheet.Column($c) -AutoFit }
|
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
|
Add-PivotTable -PivotTableName "PT_Procs" -ExcelPackage $excel -SourceWorkSheet 1 -PivotRows Company -PivotData @{'Name' = 'Count'} -IncludePivotChart -ChartType ColumnClustered -NoLegend
|
||||||
@@ -857,7 +851,7 @@ Describe ExportExcel {
|
|||||||
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
|
-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 `
|
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
|
||||||
-LegendSize 8 -legendBold -LegendPosition Bottom
|
-LegendSize 8 -legendBold -LegendPosition Bottom
|
||||||
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets["Sinx"] -Range "B2:B362" -RuleType LessThan -ConditionValue "=B1" -ForeGroundColor Red
|
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets["Sinx"] -Range "B2:B362" -RuleType LessThan -ConditionValue "=B1" -ForeGroundColor ([System.Drawing.Color]::Red)
|
||||||
$ws = $Excel.Workbook.Worksheets["Sinx"]
|
$ws = $Excel.Workbook.Worksheets["Sinx"]
|
||||||
$d = $ws.Drawings[0]
|
$d = $ws.Drawings[0]
|
||||||
It "Controled the axes and title and legend of the chart " {
|
It "Controled the axes and title and legend of the chart " {
|
||||||
@@ -916,7 +910,7 @@ Describe ExportExcel {
|
|||||||
Select-Object -Property Name, @{n="TotalPm";e={($_.group | Measure-Object -sum -Property pm).sum }} |
|
Select-Object -Property Name, @{n="TotalPm";e={($_.group | Measure-Object -sum -Property pm).sum }} |
|
||||||
Export-Excel -NoHeader -AutoNameRange -path $path -ReturnRange -PieChart -ShowPercent
|
Export-Excel -NoHeader -AutoNameRange -path $path -ReturnRange -PieChart -ShowPercent
|
||||||
$Cf = New-ConditionalFormattingIconSet -Range ($range -replace "^.*:","B2:") -ConditionalFormat ThreeIconSet -Reverse -IconType Flags
|
$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 " {
|
it "Created the Conditional formatting rules " {
|
||||||
$cf.Formatter | Should be "ThreeIconSet"
|
$cf.Formatter | Should be "ThreeIconSet"
|
||||||
$cf.IconType | Should be "Flags"
|
$cf.IconType | Should be "Flags"
|
||||||
@@ -972,8 +966,9 @@ Describe ExportExcel {
|
|||||||
$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"].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"].StyleName | Should be "TableStyleMedium2"
|
||||||
}
|
}
|
||||||
it "Created the ExtSize table in the right place with the right size " {
|
it "Created the ExtSize table in the right place with the right size and style " {
|
||||||
$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
|
||||||
|
$ws.Tables["ExtSize"].StyleName | Should be "TableStyleMedium6"
|
||||||
}
|
}
|
||||||
it "Created the ExtCount table in the right place with the right size " {
|
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
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ Banana, London , 300, 200
|
|||||||
Orange, Paris, 600, 500
|
Orange, Paris, 600, 500
|
||||||
Banana, Paris, 300, 200
|
Banana, Paris, 300, 200
|
||||||
Apple, New York, 1200,700
|
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=@{
|
"@ | 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"; PivotTableSyle="Medium12"; Activate=$true
|
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"}}}
|
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
|
$excel = Open-ExcelPackage $path
|
||||||
|
|||||||
@@ -1,50 +1,60 @@
|
|||||||
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
|
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
|
||||||
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
|
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
|
||||||
|
|
||||||
Describe "Creating small named ranges with hyperlinks" {
|
Describe "Creating small named ranges with hyperlinks" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
$path = "$env:TEMP\Results.xlsx"
|
$path = "$env:TEMP\Results.xlsx"
|
||||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
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
|
#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
|
$results = Import-Csv -Path $dataPath |
|
||||||
$topRow = $lastDataRow = 1 + $results.Count
|
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
|
||||||
$excel = $results[0].Group[0] | Export-Excel -Path $path -StartRow $TopRow -BoldTopRow -PassThru
|
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)
|
#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) {
|
foreach ($r in $results) {
|
||||||
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow +1) -RangeName $R.Name -PassThru -AutoSize
|
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow + 1) -RangeName $R.Name -PassThru -AutoSize
|
||||||
$lastDataRow += $R.Group.Count
|
$lastDataRow += $R.Group.Count
|
||||||
}
|
}
|
||||||
$worksheet = $excel.Workbook.Worksheets[1]
|
$worksheet = $excel.Workbook.Worksheets[1]
|
||||||
$columns = $worksheet.Dimension.Columns
|
$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)
|
1..$columns | ForEach-Object {Add-ExcelName -Range $worksheet.cells[$topRow, $_, $lastDataRow, $_]} #Test Add-Excel Name on its own (outside Export-Excel)
|
||||||
|
|
||||||
$scwarnVar = $null
|
$scwarnVar = $null
|
||||||
Set-ExcelColumn -Worksheet $worksheet -StartRow $topRow -Heading "PlacesGained/Lost" `
|
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.
|
-Value "=GridPosition-FinishPosition" -AutoNameRange -WarningVariable scWarnVar -WarningAction SilentlyContinue #Test as many set column options as possible.
|
||||||
$columns ++
|
$columns ++
|
||||||
|
|
||||||
#create a table which covers all the data. And define a pivot table which uses the same address range.
|
#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 `
|
$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.
|
-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
|
$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 = 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.Type = $cf.Icon3.Type = "Num"
|
||||||
$cf.Icon2.Value = 0
|
$cf.Icon2.Value = 0
|
||||||
$cf.Icon3.Value = 1
|
$cf.Icon3.Value = 1
|
||||||
Add-ConditionalFormatting -Address $worksheet.cells["FinishPosition"] -RuleType Equal -ConditionValue 1 -ForeGroundColor Purple -Bold -Priority 1 -StopIfTrue #Test Priority and stopIfTrue and using range name
|
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
|
Add-ConditionalFormatting -Address $worksheet.Cells["GridPosition"] -RuleType ThreeColorScale -Reverse #Test Reverse
|
||||||
$ct = New-ConditionalText -Text "Ferrari"
|
$ct = New-ConditionalText -Text "Ferrari"
|
||||||
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalText Red -Background White #Test new-conditionalText in shortest and longest forms.
|
$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
|
#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.
|
$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 )
|
Export-Excel -ExcelPackage $excel -AutoSize -PivotTableDefinition $pt -Calculate -ConditionalFormat $ct, $ct2 -PassThru #Test conditional text rules in conditional format (orignally icon sets only )
|
||||||
|
|
||||||
|
$null = Add-WorkSheet -ExcelPackage $excel -WorksheetName "Points1"
|
||||||
|
Add-PivotTable -PivotTableName "Points1" -Address $excel.Points1.Cells["A1"] -ExcelPackage $excel -SourceWorkSheet sheet1 -SourceRange $excel.Sheet1.Tables[0].Address.Address -PivotRows Driver, Date -PivotData @{Points = "SUM"} -GroupDateRow Date -GroupDatePart Years, Months
|
||||||
|
|
||||||
|
$null = Add-WorkSheet -ExcelPackage $excel -WorksheetName "Places1"
|
||||||
|
$newpt = Add-PivotTable -PivotTableName "Places1" -Address $excel.Places1.Cells["A1"] -ExcelPackage $excel -SourceWorkSheet sheet1 -SourceRange $excel.Sheet1.Tables[0].Address.Address -PivotRows Driver, FinishPosition -PivotData @{Date = "Count"} -GroupNumericRow FinishPosition -GroupNumericMin 1 -GroupNumericMax 25 -GroupNumericInterval 3 -PassThru
|
||||||
|
$newpt.RowFields[0].SubTotalFunctions = [OfficeOpenXml.Table.PivotTable.eSubTotalFunctions]::None
|
||||||
|
Close-ExcelPackage -ExcelPackage $excel
|
||||||
|
|
||||||
$excel = Open-ExcelPackage $path
|
$excel = Open-ExcelPackage $path
|
||||||
$sheet = $excel.Workbook.Worksheets[1]
|
$sheet = $excel.Workbook.Worksheets[1]
|
||||||
$m = $results | measure -sum -Property count
|
$m = $results | Measure-Object -sum -Property count
|
||||||
$expectedRows = 1 + $m.count + $m.sum
|
$expectedRows = 1 + $m.count + $m.sum
|
||||||
}
|
}
|
||||||
Context "Creating hyperlinks" {
|
Context "Creating hyperlinks" {
|
||||||
@@ -62,14 +72,14 @@ Describe "Creating small named ranges with hyperlinks" {
|
|||||||
}
|
}
|
||||||
Context "Adding calculated column" {
|
Context "Adding calculated column" {
|
||||||
It "Populated the cells with the right heading and formulas " {
|
It "Populated the cells with the right heading and formulas " {
|
||||||
$sheet.Cells[( $results.Count),$columns] | Should benullorEmpty
|
$sheet.Cells[( $results.Count), $columns] | Should benullorEmpty
|
||||||
$sheet.Cells[(1+$results.Count),$columns].Value | Should be "PlacesGained/Lost"
|
$sheet.Cells[(1 + $results.Count), $columns].Value | Should be "PlacesGained/Lost"
|
||||||
$sheet.Cells[(2+$results.Count),$columns].Formula | should be "GridPosition-FinishPosition"
|
$sheet.Cells[(2 + $results.Count), $columns].Formula | should be "GridPosition-FinishPosition"
|
||||||
$sheet.Names["PlacesGained_Lost"] | should not benullorEmpty
|
$sheet.Names["PlacesGained_Lost"] | should not benullorEmpty
|
||||||
}
|
}
|
||||||
It "Performed the calculation " {
|
It "Performed the calculation " {
|
||||||
$placesMade = $Sheet.Cells[(2+$results.Count),5].value - $Sheet.Cells[(2+$results.Count),3].value
|
$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
|
$sheet.Cells[(2 + $results.Count), $columns].value | Should be $placesmade
|
||||||
}
|
}
|
||||||
It "Applied ConditionalFormatting, including StopIfTrue, Priority and Reverse " {
|
It "Applied ConditionalFormatting, including StopIfTrue, Priority and Reverse " {
|
||||||
$sheet.ConditionalFormatting[0].Address.Start.Column | should be $columns
|
$sheet.ConditionalFormatting[0].Address.Start.Column | should be $columns
|
||||||
@@ -98,4 +108,32 @@ Describe "Creating small named ranges with hyperlinks" {
|
|||||||
$sheet.Tables[0].ShowRowStripes | should not be $true
|
$sheet.Tables[0].ShowRowStripes | should not be $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Context "Adding Pivot tables" {
|
||||||
|
it "Added a worksheet with a pivot table grouped by date " {
|
||||||
|
$excel.Points1 | should not beNullOrEmpty
|
||||||
|
$excel.Points1.PivotTables.Count | should be 1
|
||||||
|
$pt = $excel.Points1.PivotTables[0]
|
||||||
|
$pt.RowFields.Count | should be 3
|
||||||
|
$pt.RowFields[0].name | should be "Driver"
|
||||||
|
$pt.RowFields[0].Grouping | should benullorEmpty
|
||||||
|
$pt.RowFields[1].name | should be "years"
|
||||||
|
$pt.RowFields[1].Grouping | should not benullorEmpty
|
||||||
|
$pt.RowFields[2].name | should be "date"
|
||||||
|
$pt.RowFields[2].Grouping | should not benullorEmpty
|
||||||
|
}
|
||||||
|
it "Added a worksheet with a pivot table grouped by Number " {
|
||||||
|
$excel.Places1 | should not beNullOrEmpty
|
||||||
|
$excel.Places1.PivotTables.Count | should be 1
|
||||||
|
$pt = $excel.Places1.PivotTables[0]
|
||||||
|
$pt.RowFields.Count | should be 2
|
||||||
|
$pt.RowFields[0].name | should be "Driver"
|
||||||
|
$pt.RowFields[0].Grouping | should benullorEmpty
|
||||||
|
$pt.RowFields[0].SubTotalFunctions.ToString() | should be "None"
|
||||||
|
$pt.RowFields[1].name | should be "FinishPosition"
|
||||||
|
$pt.RowFields[1].Grouping | should not benullorEmpty
|
||||||
|
$pt.RowFields[1].Grouping.Start | should be 1
|
||||||
|
$pt.RowFields[1].Grouping.End | should be 25
|
||||||
|
$pt.RowFields[1].Grouping.Interval | should be 3
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,26 +1,28 @@
|
|||||||
#Requires -Modules Pester
|
#Requires -Modules Pester
|
||||||
|
remove-module importExcel -erroraction silentlyContinue
|
||||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||||
|
|
||||||
|
|
||||||
Describe "Check if Function aliases exist" {
|
Describe "Check if Function aliases exist" {
|
||||||
|
|
||||||
It "Set-Column should exist" {
|
It "Set-Column should exist" {
|
||||||
Get-Command Set-Column | Should Not Be $null
|
${Alias:Set-Column} | Should Not BeNullOrEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Set-Row should exist" {
|
It "Set-Row should exist" {
|
||||||
Get-Command Set-Row | Should Not Be $null
|
${Alias:Set-Row} | Should Not BeNullOrEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Set-Format should exist" {
|
It "Set-Format should exist" {
|
||||||
Get-Command Set-Format | Should Not Be $null
|
${Alias:Set-Format} | Should Not BeNullOrEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Merge-MulipleSheets should exist" {
|
<#It "Merge-MulipleSheets should exist" {
|
||||||
Get-Command Merge-MulipleSheets | Should Not Be $null
|
Get-Command Merge-MulipleSheets | Should Not Be $null
|
||||||
}
|
}
|
||||||
|
#>
|
||||||
It "New-ExcelChart should exist" {
|
It "New-ExcelChart should exist" {
|
||||||
Get-Command New-ExcelChart | Should Not Be $null
|
${Alias:New-ExcelChart} | Should Not BeNullOrEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -17,8 +17,8 @@ Describe "Tests" {
|
|||||||
$data[1].p1 | Should be "b"
|
$data[1].p1 | Should be "b"
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Should read fast < 2000 milliseconds" {
|
It "Should read fast < 2100 milliseconds" {
|
||||||
$timer.TotalMilliseconds | should BeLessThan 2000
|
$timer.TotalMilliseconds | should BeLessThan 2100
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Should read larger xlsx, 4k rows 1 col < 3000 milliseconds" {
|
It "Should read larger xlsx, 4k rows 1 col < 3000 milliseconds" {
|
||||||
@@ -29,4 +29,14 @@ Describe "Tests" {
|
|||||||
$timer.TotalMilliseconds | should BeLessThan 3000
|
$timer.TotalMilliseconds | should BeLessThan 3000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "Should be able to open, read and close as seperate actions" {
|
||||||
|
$timer = Measure-Command {
|
||||||
|
$excel = Open-ExcelPackage $PSScriptRoot\Simple.xlsx
|
||||||
|
$data = Import-Excel -ExcelPackage $excel
|
||||||
|
Close-ExcelPackage -ExcelPackage $excel -NoSave}
|
||||||
|
$timer.TotalMilliseconds | should BeLessThan 2100
|
||||||
|
$data.count | Should be 2
|
||||||
|
$data[0].p1 | Should be "a"
|
||||||
|
$data[1].p1 | Should be "b"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
79
__tests__/InputItemParameter.tests.ps1
Normal file
79
__tests__/InputItemParameter.tests.ps1
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
Describe "Exporting with -Inputobject" {
|
||||||
|
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 = ((Get-Process) + (Get-Process -id $PID)) | Select-Object -last 10 -Property Name, cpu, pm, handles, StartTime
|
||||||
|
$DataTable = [System.Data.DataTable]::new('Test')
|
||||||
|
$null = $DataTable.Columns.Add('Name')
|
||||||
|
$null = $DataTable.Columns.Add('CPU', [double])
|
||||||
|
$null = $DataTable.Columns.Add('PM', [Long])
|
||||||
|
$null = $DataTable.Columns.Add('Handles', [Int])
|
||||||
|
$null = $DataTable.Columns.Add('StartTime', [DateTime])
|
||||||
|
foreach ($r in $results) {
|
||||||
|
$null = $DataTable.Rows.Add($r.name, $r.CPU, $R.PM, $r.Handles, $r.StartTime)
|
||||||
|
}
|
||||||
|
export-excel -Path $path -InputObject $results -WorksheetName Sheet1 -RangeName "Whole"
|
||||||
|
export-excel -Path $path -InputObject $DataTable -WorksheetName Sheet2 -AutoNameRange
|
||||||
|
Send-SQLDataToExcel -path $path -DataTable $DataTable -WorkSheetname Sheet3 -TableName "Data"
|
||||||
|
$excel = Open-ExcelPackage $path
|
||||||
|
$sheet = $excel.Sheet1
|
||||||
|
}
|
||||||
|
Context "Array of processes" {
|
||||||
|
it "Put the correct rows and columns into the sheet " {
|
||||||
|
$sheet.Dimension.Rows | should be ($results.Count + 1)
|
||||||
|
$sheet.Dimension.Columns | should be 5
|
||||||
|
$sheet.cells["A1"].Value | should be "Name"
|
||||||
|
$sheet.cells["E1"].Value | should be "StartTime"
|
||||||
|
$sheet.cells["A3"].Value | should be $results[1].Name
|
||||||
|
}
|
||||||
|
it "Created a range for the whole sheet " {
|
||||||
|
$sheet.Names[0].Name | should be "Whole"
|
||||||
|
$sheet.Names[0].Start.Address | should be "A1"
|
||||||
|
$sheet.Names[0].End.row | should be ($results.Count + 1)
|
||||||
|
$sheet.Names[0].End.Column | should be 5
|
||||||
|
}
|
||||||
|
it "Formatted date fields with date type " {
|
||||||
|
$sheet.Cells["E11"].Style.Numberformat.NumFmtID | should be 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sheet = $excel.Sheet2
|
||||||
|
Context "Table of processes" {
|
||||||
|
it "Put the correct rows and columns into the sheet " {
|
||||||
|
$sheet.Dimension.Rows | should be ($results.Count + 1)
|
||||||
|
$sheet.Dimension.Columns | should be 5
|
||||||
|
$sheet.cells["A1"].Value | should be "Name"
|
||||||
|
$sheet.cells["E1"].Value | should be "StartTime"
|
||||||
|
$sheet.cells["A3"].Value | should be $results[1].Name
|
||||||
|
}
|
||||||
|
it "Created named ranges for each column " {
|
||||||
|
$sheet.Names.count | should be 5
|
||||||
|
$sheet.Names[0].Name | should be "Name"
|
||||||
|
$sheet.Names[1].Start.Address | should be "B2"
|
||||||
|
$sheet.Names[2].End.row | should be ($results.Count + 1)
|
||||||
|
$sheet.Names[3].End.Column | should be 4
|
||||||
|
$sheet.Names[4].Start.Column | should be 5
|
||||||
|
}
|
||||||
|
it "Formatted date fields with date type " {
|
||||||
|
$sheet.Cells["E11"].Style.Numberformat.NumFmtID | should be 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sheet = $excel.Sheet3
|
||||||
|
Context "Table of processes via Send-SQLDataToExcel" {
|
||||||
|
it "Put the correct rows and columns into the sheet " {
|
||||||
|
$sheet.Dimension.Rows | should be ($results.Count + 1)
|
||||||
|
$sheet.Dimension.Columns | should be 5
|
||||||
|
$sheet.cells["A1"].Value | should be "Name"
|
||||||
|
$sheet.cells["E1"].Value | should be "StartTime"
|
||||||
|
$sheet.cells["A3"].Value | should be $results[1].Name
|
||||||
|
}
|
||||||
|
it "Created a table " {
|
||||||
|
$sheet.Tables.count | should be 1
|
||||||
|
$sheet.Tables[0].Name | should be "Data"
|
||||||
|
$sheet.Tables[0].Columns[4].name | should be "StartTime"
|
||||||
|
}
|
||||||
|
it "Formatted date fields with date type " {
|
||||||
|
$sheet.Cells["E11"].Style.Numberformat.NumFmtID | should be 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ ID,Product,Quantity,Price,Total
|
|||||||
12012,Pliers,3,14.99,44.97
|
12012,Pliers,3,14.99,44.97
|
||||||
"@
|
"@
|
||||||
|
|
||||||
Describe "Join Worksheet" {
|
Describe "Join Worksheet part 1" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
$path = "$Env:TEMP\test.xlsx"
|
$path = "$Env:TEMP\test.xlsx"
|
||||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||||
@@ -30,7 +30,7 @@ Describe "Join Worksheet" {
|
|||||||
$data2 | Export-Excel -Path $path -WorkSheetname Abingdon
|
$data2 | Export-Excel -Path $path -WorkSheetname Abingdon
|
||||||
$data3 | Export-Excel -Path $path -WorkSheetname Banbury
|
$data3 | Export-Excel -Path $path -WorkSheetname Banbury
|
||||||
$ptdef = New-PivotTableDefinition -PivotTableName "SummaryPivot" -PivotRows "Store" -PivotColumns "Product" -PivotData @{"Total"="SUM"} -IncludePivotChart -ChartTitle "Sales Breakdown" -ChartType ColumnStacked -ChartColumn 10
|
$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 AliceBlue -PivotTableDefinition $ptdef
|
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
|
$excel = Export-Excel -path $path -WorkSheetname SummaryPivot -Activate -NoTotalsInPivot -PivotDataToColumn -HideSheet * -UnHideSheet "Total","SummaryPivot" -PassThru
|
||||||
# Open-ExcelPackage -Path $path
|
# Open-ExcelPackage -Path $path
|
||||||
@@ -88,12 +88,15 @@ Describe "Join Worksheet" {
|
|||||||
$pc.Title.text | Should be "Sales Breakdown"
|
$pc.Title.text | Should be "Sales Breakdown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$path = "$env:TEMP\Test.xlsx"
|
$path = "$env:TEMP\Test.xlsx"
|
||||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||||
Get-WmiObject -Class win32_logicaldisk |
|
#switched to CIM objects so test runs on V6
|
||||||
|
Describe "Join Worksheet part 2" {
|
||||||
|
Get-CimInstance -ClassName win32_logicaldisk |
|
||||||
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
||||||
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
|
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
|
||||||
Get-NetAdapter |
|
Get-CimInstance -Namespace root/StandardCimv2 -class MSFT_NetAdapter |
|
||||||
Select-Object -Property Name,InterfaceDescription,MacAddress,LinkSpeed |
|
Select-Object -Property Name,InterfaceDescription,MacAddress,LinkSpeed |
|
||||||
Export-Excel -Path $path -WorkSheetname NetAdapters
|
Export-Excel -Path $path -WorkSheetname NetAdapters
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe "Consistent passing of ranges." {
|
|||||||
$warnvar | should beNullOrEmpty
|
$warnvar | should beNullOrEmpty
|
||||||
$excel.Services.ConditionalFormatting.Count | Should be 3
|
$excel.Services.ConditionalFormatting.Count | Should be 3
|
||||||
{Add-ConditionalFormatting "Status" -WorkSheet $excel.Services `
|
{Add-ConditionalFormatting "Status" -WorkSheet $excel.Services `
|
||||||
-ForeGroundColor Green -RuleType ContainsText -ConditionValue "Running"} | Should not throw
|
-ForeGroundColor ([System.Drawing.Color]::Green) -RuleType ContainsText -ConditionValue "Running"} | Should not throw
|
||||||
$excel.Services.ConditionalFormatting.Count | Should be 4
|
$excel.Services.ConditionalFormatting.Count | Should be 4
|
||||||
}
|
}
|
||||||
Close-ExcelPackage -NoSave $excel
|
Close-ExcelPackage -NoSave $excel
|
||||||
@@ -32,7 +32,7 @@ describe "Consistent passing of ranges." {
|
|||||||
-Bold -RuleType ContainsText -ConditionValue "windows" } | Should not throw
|
-Bold -RuleType ContainsText -ConditionValue "windows" } | Should not throw
|
||||||
$excel.Services.ConditionalFormatting.Count | Should be 2
|
$excel.Services.ConditionalFormatting.Count | Should be 2
|
||||||
{Add-ConditionalFormatting -WorkSheet $excel.Services -Address "a:a" `
|
{Add-ConditionalFormatting -WorkSheet $excel.Services -Address "a:a" `
|
||||||
-RuleType ContainsText -ConditionValue "stopped" -ForeGroundColor Red } | Should not throw
|
-RuleType ContainsText -ConditionValue "stopped" -ForeGroundColor ([System.Drawing.Color]::Red) } | Should not throw
|
||||||
$excel.Services.ConditionalFormatting.Count | Should be 3
|
$excel.Services.ConditionalFormatting.Count | Should be 3
|
||||||
}
|
}
|
||||||
Close-ExcelPackage -NoSave $excel
|
Close-ExcelPackage -NoSave $excel
|
||||||
@@ -62,7 +62,7 @@ describe "Consistent passing of ranges." {
|
|||||||
$excel.Services.cells["C3"].Style.Font.UnderLine | Should be $true
|
$excel.Services.cells["C3"].Style.Font.UnderLine | Should be $true
|
||||||
{Set-ExcelRange -WorkSheet $excel.Services -Range "Name" -Bold } | Should not throw
|
{Set-ExcelRange -WorkSheet $excel.Services -Range "Name" -Bold } | Should not throw
|
||||||
$excel.Services.cells["B4"].Style.Font.Bold | Should be $true
|
$excel.Services.cells["B4"].Style.Font.Bold | Should be $true
|
||||||
{$excel.Services.Column(3) | Set-ExcelRange -FontColor red } | Should not throw
|
{$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"
|
$excel.Services.cells["C4"].Style.Font.Color.Rgb | Should be "FFFF0000"
|
||||||
}
|
}
|
||||||
Close-ExcelPackage -NoSave $excel
|
Close-ExcelPackage -NoSave $excel
|
||||||
|
|||||||
78
__tests__/Remove-WorkSheet.tests.ps1
Normal file
78
__tests__/Remove-WorkSheet.tests.ps1
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#Requires -Modules Pester
|
||||||
|
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||||
|
|
||||||
|
Describe "Remove Worksheet" {
|
||||||
|
Context "Remove a worksheet output" {
|
||||||
|
BeforeEach {
|
||||||
|
# Create three sheets
|
||||||
|
$data = ConvertFrom-Csv @"
|
||||||
|
Name,Age
|
||||||
|
Jane,10
|
||||||
|
John,20
|
||||||
|
"@
|
||||||
|
$xlFile1 = "$env:TEMP\RemoveWorsheet1.xlsx"
|
||||||
|
Remove-Item $xlFile1 -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$data | Export-Excel -Path $xlFile1 -WorksheetName Target1
|
||||||
|
$data | Export-Excel -Path $xlFile1 -WorksheetName Target2
|
||||||
|
$data | Export-Excel -Path $xlFile1 -WorksheetName Target3
|
||||||
|
$data | Export-Excel -Path $xlFile1 -WorksheetName Sheet1
|
||||||
|
|
||||||
|
$xlFile2 = "$env:TEMP\RemoveWorsheet2.xlsx"
|
||||||
|
Remove-Item $xlFile2 -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$data | Export-Excel -Path $xlFile2 -WorksheetName Target1
|
||||||
|
$data | Export-Excel -Path $xlFile2 -WorksheetName Target2
|
||||||
|
$data | Export-Excel -Path $xlFile2 -WorksheetName Target3
|
||||||
|
$data | Export-Excel -Path $xlFile2 -WorksheetName Sheet1
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should throw about the Path" {
|
||||||
|
{Remove-WorkSheet} | Should throw 'Remove-WorkSheet requires the and Excel file'
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should delete Target2" {
|
||||||
|
Remove-WorkSheet -Path $xlFile1 -WorksheetName Target2
|
||||||
|
|
||||||
|
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||||
|
|
||||||
|
$actual.Count | Should Be 3
|
||||||
|
$actual[0].Name | Should Be "Target1"
|
||||||
|
$actual[1].Name | Should Be "Target3"
|
||||||
|
$actual[2].Name | Should Be "Sheet1"
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should delete Sheet1" {
|
||||||
|
Remove-WorkSheet -Path $xlFile1
|
||||||
|
|
||||||
|
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||||
|
|
||||||
|
$actual.Count | Should Be 3
|
||||||
|
$actual[0].Name | Should Be "Target1"
|
||||||
|
$actual[1].Name | Should Be "Target2"
|
||||||
|
$actual[2].Name | Should Be "Target3"
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should delete multiple sheets" {
|
||||||
|
Remove-WorkSheet -Path $xlFile1 -WorksheetName Target1, Sheet1
|
||||||
|
|
||||||
|
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||||
|
|
||||||
|
$actual.Count | Should Be 2
|
||||||
|
$actual[0].Name | Should Be "Target2"
|
||||||
|
$actual[1].Name | Should Be "Target3"
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should delete sheet from multiple workbooks" {
|
||||||
|
|
||||||
|
Get-ChildItem "$env:TEMP\RemoveWorsheet*.xlsx" | Remove-WorkSheet
|
||||||
|
|
||||||
|
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||||
|
|
||||||
|
$actual.Count | Should Be 3
|
||||||
|
$actual[0].Name | Should Be "Target1"
|
||||||
|
$actual[1].Name | Should Be "Target2"
|
||||||
|
$actual[2].Name | Should Be "Target3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ Describe "Number format expansion and setting" {
|
|||||||
$x.ListItemText | Should be "Percentage"
|
$x.ListItemText | Should be "Percentage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Context "Expand-NumberFormat function" {
|
Context "Expand-NumberFormat function" {
|
||||||
It "Expanded named number formats as expected " {
|
It "Expanded named number formats as expected " {
|
||||||
$r = [regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol)
|
$r = [regex]::Escape([cultureinfo]::CurrentCulture.NumberFormat.CurrencySymbol)
|
||||||
Expand-NumberFormat 'Currency' | Should match "^[$r\(\)\[\] RED0#\?\-;,.]+$"
|
Expand-NumberFormat 'Currency' | Should match "^[$r\(\)\[\] RED0#\?\-;,.]+$"
|
||||||
@@ -55,7 +55,7 @@ Describe "Number format expansion and setting" {
|
|||||||
$n = [datetime]::Now.ToOADate()
|
$n = [datetime]::Now.ToOADate()
|
||||||
|
|
||||||
$excel = 1..32 | ForEach-Object {$n} | Export-Excel -Path $path -show -WorksheetName s2 -PassThru
|
$excel = 1..32 | ForEach-Object {$n} | Export-Excel -Path $path -show -WorksheetName s2 -PassThru
|
||||||
$ws = $excel.Workbook.Worksheets[1]
|
$ws = $excel.Workbook.Worksheets[1]
|
||||||
Set-ExcelRange -WorkSheet $ws -Range "A1" -numberFormat 'General'
|
Set-ExcelRange -WorkSheet $ws -Range "A1" -numberFormat 'General'
|
||||||
Set-ExcelRange -WorkSheet $ws -Range "A2" -numberFormat 'Number'
|
Set-ExcelRange -WorkSheet $ws -Range "A2" -numberFormat 'Number'
|
||||||
Set-ExcelRange -WorkSheet $ws -Range "A3" -numberFormat 'Percentage'
|
Set-ExcelRange -WorkSheet $ws -Range "A3" -numberFormat 'Percentage'
|
||||||
@@ -91,40 +91,40 @@ Describe "Number format expansion and setting" {
|
|||||||
Close-ExcelPackage -ExcelPackage $excel
|
Close-ExcelPackage -ExcelPackage $excel
|
||||||
|
|
||||||
$excel = Open-ExcelPackage -Path $path
|
$excel = Open-ExcelPackage -Path $path
|
||||||
$ws = $excel.Workbook.Worksheets[1]
|
$ws = $excel.Workbook.Worksheets[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Set formats which translate to the correct format ID " {
|
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[ 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[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[ 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[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[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[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[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[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[ 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[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[ 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[ 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[29, 1].Style.Numberformat.NumFmtID | Should be 12 # Set as # ?/?
|
||||||
$ws.Cells[30,1].Style.Numberformat.NumFmtID | Should be 13 # 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[ 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[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[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[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[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[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[ 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[ 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[ 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[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[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[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[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[31, 1].Style.Numberformat.NumFmtID | Should be 49 # Set as @
|
||||||
$ws.Cells[24,1].Style.Numberformat.Format | Should be '#,' # Whole thousands
|
$ws.Cells[24, 1].Style.Numberformat.Format | Should be '#,' # Whole thousands
|
||||||
$ws.Cells[25,1].Style.Numberformat.Format | Should be '#.0,,' # Millions
|
$ws.Cells[25, 1].Style.Numberformat.Format | Should be '#.0,,' # Millions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,13 +135,13 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
|||||||
$excel = $data| Export-Excel -Path $path -AutoNameRange -PassThru
|
$excel = $data| Export-Excel -Path $path -AutoNameRange -PassThru
|
||||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||||
|
|
||||||
$c = Set-ExcelColumn -PassThru -Worksheet $ws -Heading "Total" -Value "=Quantity*Price" -NumberFormat "£#,###.00" -FontColor Blue -Bold -HorizontalAlignment Right -VerticalAlignment Top
|
$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
|
$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 Red -StrikeThru
|
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 Red -BorderTop DashDot -BorderLeft DashDotDot -BorderBottom Dashed -BorderRight Dotted
|
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 "E3" -Bold:$false -FontShift Superscript -HorizontalAlignment Left
|
||||||
Set-ExcelRange -WorkSheet $ws -Range "E1" -ResetFont -HorizontalAlignment General
|
Set-ExcelRange -WorkSheet $ws -Range "E1" -ResetFont -HorizontalAlignment General -FontName "Courier New" -fontSize 9
|
||||||
Set-ExcelRange -Address $ws.cells["E7"] -ResetFont -WrapText -BackgroundColor AliceBlue -BackgroundPattern DarkTrellis -PatternColor Red -NumberFormat "£#,###.00"
|
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(1) -Width 0
|
||||||
Set-ExcelRange -Address $ws.Column(2) -AutoFit
|
Set-ExcelRange -Address $ws.Column(2) -AutoFit
|
||||||
Set-ExcelRange -Address $ws.Cells["E:E"] -AutoFit
|
Set-ExcelRange -Address $ws.Cells["E:E"] -AutoFit
|
||||||
@@ -162,55 +162,57 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
|||||||
Context "Set-ExcelRow and Set-ExcelColumn" {
|
Context "Set-ExcelRow and Set-ExcelColumn" {
|
||||||
it "Set a row and a column to have zero width/height " {
|
it "Set a row and a column to have zero width/height " {
|
||||||
$r | Should not beNullorEmpty
|
$r | Should not beNullorEmpty
|
||||||
# $c | Should not beNullorEmpty ## can't see why but this test breaks in appveyor
|
# $c | Should not beNullorEmpty ## can't see why but this test breaks in appveyor
|
||||||
$ws.Column(1).width | Should be 0
|
$ws.Column(1).width | Should be 0
|
||||||
$ws.Row(5).height | Should be 0
|
$ws.Row(5).height | Should be 0
|
||||||
}
|
}
|
||||||
it "Set a column formula, with numberformat, color, bold face and alignment " {
|
it "Set a column formula, with numberformat, color, bold face and alignment " {
|
||||||
$ws.cells["e2"].Formula | Should be "Quantity*Price"
|
$ws.Cells["e2"].Formula | Should be "Quantity*Price"
|
||||||
$ws.cells["e2"].Value | Should be 147.63
|
$ws.Cells["e2"].Value | Should be 147.63
|
||||||
$ws.cells["e2"].Style.Font.Color.rgb | Should be "FF0000FF"
|
$ws.Cells["e2"].Style.Font.Color.rgb | Should be "FF0000FF"
|
||||||
$ws.cells["e2"].Style.Font.Bold | Should be $true
|
$ws.Cells["e2"].Style.Font.Bold | Should be $true
|
||||||
$ws.cells["e2"].Style.Font.VerticalAlign | Should be "None"
|
$ws.Cells["e2"].Style.Font.VerticalAlign | Should be "None"
|
||||||
$ws.cells["e2"].Style.Numberformat.format | Should be "£#,###.00"
|
$ws.Cells["e2"].Style.Numberformat.format | Should be "£#,###.00"
|
||||||
$ws.cells["e2"].Style.HorizontalAlignment | Should be "Right"
|
$ws.Cells["e2"].Style.HorizontalAlignment | Should be "Right"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Context "Other formatting" {
|
Context "Other formatting" {
|
||||||
it "Trapped an attempt to hide a range instead of a Row/Column " {
|
it "Trapped an attempt to hide a range instead of a Row/Column " {
|
||||||
$BadHideWarnvar | Should not beNullOrEmpty
|
$BadHideWarnvar | Should not beNullOrEmpty
|
||||||
}
|
}
|
||||||
it "Set a row formula with border font size and underline " {
|
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["b7"].Style.Border.Top.Style | Should be "None"
|
||||||
$ws.cells["F7"].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.Top.Style | Should be "Thin"
|
||||||
$ws.cells["C7"].style.Border.Bottom.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.Right.Style | Should be "None"
|
||||||
$ws.cells["C7"].style.Border.Left.Style | Should be "Thin"
|
$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.Left.Style | Should be "None"
|
||||||
$ws.cells["E7"].style.Border.Right.Style | Should be "Thin"
|
$ws.Cells["E7"].Style.Border.Right.Style | Should be "Thin"
|
||||||
$ws.cells["C7"].style.Font.size | Should be 14
|
$ws.Cells["C7"].Style.Font.size | Should be 14
|
||||||
$ws.cells["C7"].Formula | Should be "sum(C2:C6)"
|
$ws.Cells["C7"].Formula | Should be "sum(C2:C6)"
|
||||||
$ws.cells["C7"].value | Should be 81
|
$ws.Cells["C7"].value | Should be 81
|
||||||
$ws.cells["C7"].style.Font.UnderLine | Should be $true
|
$ws.Cells["C7"].Style.Font.UnderLine | Should be $true
|
||||||
$ws.cells["C6"].style.Font.UnderLine | Should be $false
|
$ws.Cells["C6"].Style.Font.UnderLine | Should be $false
|
||||||
}
|
}
|
||||||
it "Set custom text wrapping, alignment, superscript, border and Fill " {
|
it "Set custom font, size, text-wrapping, alignment, superscript, border and Fill " {
|
||||||
$ws.cells["e3"].Style.HorizontalAlignment | Should be "Left"
|
$ws.Cells["b3"].Style.Border.Left.Color.Rgb | Should be "FFFF0000"
|
||||||
$ws.cells["e3"].Style.Font.VerticalAlign | Should be "Superscript"
|
$ws.Cells["b3"].Style.Border.Left.Style | Should be "Thick"
|
||||||
$ws.cells["b3"].style.Border.Left.Color.Rgb | Should be "FFFF0000"
|
$ws.Cells["b3"].Style.Border.Right.Style | Should be "Thick"
|
||||||
$ws.cells["b3"].style.Border.Left.Style | Should be "Thick"
|
$ws.Cells["b3"].Style.Border.Top.Style | Should be "Thick"
|
||||||
$ws.cells["b3"].style.Border.Right.Style | Should be "Thick"
|
$ws.Cells["b3"].Style.Border.Bottom.Style | Should be "Thick"
|
||||||
$ws.cells["b3"].style.Border.Top.Style | Should be "Thick"
|
$ws.Cells["b3"].Style.Font.Strike | Should be $true
|
||||||
$ws.cells["b3"].style.Border.Bottom.Style | Should be "Thick"
|
$ws.Cells["e1"].Style.Font.Color.Rgb | Should be "ff000000"
|
||||||
$ws.cells["b3"].style.Font.Strike | Should be $true
|
$ws.Cells["e1"].Style.Font.Bold | Should be $false
|
||||||
$ws.cells["e1"].Style.Font.Color.rgb | Should be "ff000000"
|
$ws.Cells["e1"].Style.Font.Name | Should be "Courier New"
|
||||||
$ws.cells["e1"].Style.Font.Bold | Should be $false
|
$ws.Cells["e1"].Style.Font.Size | Should be 9
|
||||||
$ws.cells["C6"].style.WrapText | Should be $false
|
$ws.Cells["e3"].Style.Font.VerticalAlign | Should be "Superscript"
|
||||||
$ws.cells["e7"].style.WrapText | Should be $true
|
$ws.Cells["e3"].Style.HorizontalAlignment | Should be "Left"
|
||||||
$ws.cells["e7"].Style.Fill.BackgroundColor.Rgb | Should be "FFF0F8FF"
|
$ws.Cells["C6"].Style.WrapText | Should be $false
|
||||||
$ws.cells["e7"].Style.Fill.PatternColor.Rgb | Should be "FFFF0000"
|
$ws.Cells["e7"].Style.WrapText | Should be $true
|
||||||
$ws.cells["e7"].Style.Fill.PatternType | Should be "DarkTrellis"
|
$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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,14 +235,14 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
|||||||
$excel = $DriverData | Export-Excel -PassThru -Path $path -AutoSize -AutoNameRange
|
$excel = $DriverData | Export-Excel -PassThru -Path $path -AutoSize -AutoNameRange
|
||||||
$ws = $excel.Workbook.Worksheets[1]
|
$ws = $excel.Workbook.Worksheets[1]
|
||||||
|
|
||||||
Set-ExcelColumn -Worksheet $ws -Heading "Link" -AutoSize -Value {"https://en.wikipedia.org" + $worksheet.cells["B$Row"].value }
|
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 {
|
$c = Set-ExcelColumn -PassThru -Worksheet $ws -Heading "NextBirthday" -Value {
|
||||||
$bmonth = $worksheet.cells["C$Row"].value.month ; $bDay = $worksheet.cells["C$Row"].value.day
|
$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
|
$cMonth = [datetime]::Now.Month ; $cday = [datetime]::Now.day ; $cyear = [datetime]::Now.Year
|
||||||
if (($cmonth -gt $bmonth) -or (($cMonth -eq $bmonth) -and ($cday -ge $bDay))){
|
if (($cmonth -gt $bmonth) -or (($cMonth -eq $bmonth) -and ($cday -ge $bDay))) {
|
||||||
[datetime]::new($cyear+1, $bmonth, $bDay)
|
[datetime]::new($cyear + 1, $bmonth, $bDay)
|
||||||
}
|
}
|
||||||
else {[datetime]::new($cyear, $bmonth, $bday) }
|
else {[datetime]::new($cyear, $bmonth, $bday) }
|
||||||
}
|
}
|
||||||
Set-ExcelColumn -Worksheet $ws -Heading "Age" -Value "=INT((NOW()-DateOfBirth)/365)"
|
Set-ExcelColumn -Worksheet $ws -Heading "Age" -Value "=INT((NOW()-DateOfBirth)/365)"
|
||||||
# Test Piping column Numbers into Set excelColumn
|
# Test Piping column Numbers into Set excelColumn
|
||||||
@@ -251,7 +253,7 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
|||||||
Close-ExcelPackage -ExcelPackage $excel -Calculate
|
Close-ExcelPackage -ExcelPackage $excel -Calculate
|
||||||
$excel = Open-ExcelPackage $path
|
$excel = Open-ExcelPackage $path
|
||||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||||
}
|
}
|
||||||
It "Inserted Hyperlinks " {
|
It "Inserted Hyperlinks " {
|
||||||
$ws.Cells["D2"].Hyperlink | Should not beNullorEmpty
|
$ws.Cells["D2"].Hyperlink | Should not beNullorEmpty
|
||||||
$ws.Cells["D2"].Style.Font.UnderLine | Should be $true
|
$ws.Cells["D2"].Style.Font.UnderLine | Should be $true
|
||||||
@@ -279,14 +281,14 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Describe "Conditional Formatting" {
|
Describe "Conditional Formatting" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Remove-Item $path
|
Remove-Item $path
|
||||||
$data = Get-Process | Where-Object company | Select-Object company,name,pm,handles,*mem*
|
$data = Get-Process | Where-Object company | Select-Object company, name, pm, handles, *mem*
|
||||||
$cfmt = New-ConditionalFormattingIconSet -Range "c:c" -ConditionalFormat ThreeIconSet -IconType Arrows
|
$cfmt = New-ConditionalFormattingIconSet -Range "c:c" -ConditionalFormat ThreeIconSet -IconType Arrows
|
||||||
$data | Export-Excel -path $Path -AutoSize -ConditionalFormat $cfmt
|
$data | Export-Excel -path $Path -AutoSize -ConditionalFormat $cfmt
|
||||||
$excel = Open-ExcelPackage -Path $path
|
$excel = Open-ExcelPackage -Path $path
|
||||||
$ws = $excel.Workbook.Worksheets[1]
|
$ws = $excel.Workbook.Worksheets[1]
|
||||||
}
|
}
|
||||||
Context "Using a pre-prepared 3 Arrows rule" {
|
Context "Using a pre-prepared 3 Arrows rule" {
|
||||||
it "Set the right type, IconSet and range " {
|
it "Set the right type, IconSet and range " {
|
||||||
@@ -316,23 +318,61 @@ ID,Product,Quantity,Price,Total
|
|||||||
12012,Pliers,3,14.99,44.97
|
12012,Pliers,3,14.99,44.97
|
||||||
"@
|
"@
|
||||||
|
|
||||||
Describe "Table Formatting" {
|
Describe "AutoNameRange data with a single property name" {
|
||||||
|
BeforeEach {
|
||||||
|
$xlfile = "$Env:TEMP\testNamedRange.xlsx"
|
||||||
|
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should have a single item as a named range" {
|
||||||
|
$excel = ConvertFrom-Csv @"
|
||||||
|
Sold
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
|
||||||
|
|
||||||
|
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||||
|
|
||||||
|
$ws.Names.Count | Should Be 1
|
||||||
|
$ws.Names[0].Name | Should Be 'Sold'
|
||||||
|
}
|
||||||
|
|
||||||
|
it "Should have a more than a single item as a named range" {
|
||||||
|
$excel = ConvertFrom-Csv @"
|
||||||
|
Sold,ID
|
||||||
|
1,a
|
||||||
|
2,b
|
||||||
|
3,c
|
||||||
|
4,d
|
||||||
|
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
|
||||||
|
|
||||||
|
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||||
|
|
||||||
|
$ws.Names.Count | Should Be 2
|
||||||
|
$ws.Names[0].Name | Should Be 'Sold'
|
||||||
|
$ws.Names[1].Name | Should Be 'ID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Describe "Table Formatting" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
Remove-Item $path
|
Remove-Item $path
|
||||||
$excel = $data2 | Export-excel -path $path -WorksheetName Hardware -AutoNameRange -AutoSize -BoldTopRow -FreezeTopRow -PassThru
|
$excel = $data2 | Export-excel -path $path -WorksheetName Hardware -AutoNameRange -AutoSize -BoldTopRow -FreezeTopRow -PassThru
|
||||||
$ws = $excel.Workbook.Worksheets[1]
|
$ws = $excel.Workbook.Worksheets[1]
|
||||||
#test showfilter & TotalSettings
|
#test showfilter & TotalSettings
|
||||||
$Table = Add-ExcelTable -PassThru -Range $ws.cells[$($ws.Dimension.address)] -TableStyle Light1 -TableName HardwareTable -TotalSettings @{"Total"="Sum"} -ShowFirstColumn -ShowFilter:$false
|
$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
|
#test expnading named number formats
|
||||||
Set-ExcelColumn -Worksheet $ws -Column 4 -NumberFormat 'Currency'
|
Set-ExcelColumn -Worksheet $ws -Column 4 -NumberFormat 'Currency'
|
||||||
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency'
|
||||||
$PtDef =New-PivotTableDefinition -PivotTableName Totals -PivotRows Product -PivotData @{"Total"="Sum"} -PivotNumberFormat Currency -PivotTotals None -PivotTableSyle Dark2
|
$PtDef = New-PivotTableDefinition -PivotTableName Totals -PivotRows Product -PivotData @{"Total" = "Sum"} -PivotNumberFormat Currency -PivotTotals None -PivotTableStyle Dark2
|
||||||
Export-excel -ExcelPackage $excel -WorksheetName Hardware -PivotTableDefinition $PtDef
|
Export-excel -ExcelPackage $excel -WorksheetName Hardware -PivotTableDefinition $PtDef
|
||||||
$excel= Open-ExcelPackage -Path $path
|
$excel = Open-ExcelPackage -Path $path
|
||||||
$ws1 = $excel.Workbook.Worksheets["Hardware"]
|
$ws1 = $excel.Workbook.Worksheets["Hardware"]
|
||||||
$ws2 = $excel.Workbook.Worksheets["Totals"]
|
$ws2 = $excel.Workbook.Worksheets["Totals"]
|
||||||
}
|
}
|
||||||
Context "Setting and not clearing when Export-Excel touches the file again."{
|
Context "Setting and not clearing when Export-Excel touches the file again." {
|
||||||
it "Set the Table Options " {
|
it "Set the Table Options " {
|
||||||
$ws1.Tables[0].Address.Address | should be "A1:E16"
|
$ws1.Tables[0].Address.Address | should be "A1:E16"
|
||||||
$ws1.Tables[0].Name | should be "HardwareTable"
|
$ws1.Tables[0].Name | should be "HardwareTable"
|
||||||
@@ -351,7 +391,3 @@ Describe "Table Formatting" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
58
__tests__/Validation.tests.ps1
Normal file
58
__tests__/Validation.tests.ps1
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
$data = ConvertFrom-Csv -InputObject @"
|
||||||
|
ID,Product,Quantity,Price
|
||||||
|
12001,Nails,37,3.99
|
||||||
|
12002,Hammer,5,12.10
|
||||||
|
12003,Saw,12,15.37
|
||||||
|
12010,Drill,20,8
|
||||||
|
12011,Crowbar,7,23.48
|
||||||
|
"@
|
||||||
|
|
||||||
|
$path = "$Env:TEMP\DataValidation.xlsx"
|
||||||
|
|
||||||
|
Describe "Data validation and protection" {
|
||||||
|
Context "Data Validation rules" {
|
||||||
|
BeforeAll {
|
||||||
|
Remove-Item $path -ErrorAction SilentlyContinue
|
||||||
|
$excelPackage = $Data | export-excel -WorksheetName "Sales" -path $path -PassThru
|
||||||
|
$excelPackage = @('Chisel','Crowbar','Drill','Hammer','Nails','Saw','Screwdriver','Wrench') |
|
||||||
|
Export-excel -ExcelPackage $excelPackage -WorksheetName Values -PassThru
|
||||||
|
|
||||||
|
$VParams = @{WorkSheet = $excelPackage.sales; ShowErrorMessage=$true; ErrorStyle='stop'; ErrorTitle='Invalid Data' }
|
||||||
|
Add-ExcelDataValidationRule @VParams -Range 'B2:B1001' -ValidationType List -Formula 'values!$a$1:$a$10' -ErrorBody "You must select an item from the list.`r`nYou can add to the list on the values page" #Bucket
|
||||||
|
Add-ExcelDataValidationRule @VParams -Range 'E2:E1001' -ValidationType Integer -Operator between -Value 0 -Value2 10000 -ErrorBody 'Quantity must be a whole number between 0 and 10000'
|
||||||
|
Close-ExcelPackage -ExcelPackage $excelPackage
|
||||||
|
|
||||||
|
$excelPackage = Open-ExcelPackage -Path $path
|
||||||
|
$ws = $excelPackage.Sales
|
||||||
|
}
|
||||||
|
It "Created the expected number of rules " {
|
||||||
|
$ws.DataValidations.count | Should be 2
|
||||||
|
}
|
||||||
|
It "Created a List validation rule against a range of Cells " {
|
||||||
|
$ws.DataValidations[0].ValidationType.Type.tostring() | Should be 'List'
|
||||||
|
$ws.DataValidations[0].Formula.ExcelFormula | Should be 'values!$a$1:$a$10'
|
||||||
|
$ws.DataValidations[0].Formula2 | Should benullorempty
|
||||||
|
$ws.DataValidations[0].Operator.tostring() | should be 'any'
|
||||||
|
}
|
||||||
|
It "Created an integer validation rule for values between X and Y " {
|
||||||
|
$ws.DataValidations[1].ValidationType.Type.tostring() | Should be 'Whole'
|
||||||
|
$ws.DataValidations[1].Formula.Value | Should be 0
|
||||||
|
$ws.DataValidations[1].Formula2.value | Should not benullorempty
|
||||||
|
$ws.DataValidations[1].Operator.tostring() | should be 'between'
|
||||||
|
}
|
||||||
|
It "Set Error behaviors for both rules " {
|
||||||
|
$ws.DataValidations[0].ErrorStyle.tostring() | Should be 'stop'
|
||||||
|
$ws.DataValidations[1].ErrorStyle.tostring() | Should be 'stop'
|
||||||
|
$ws.DataValidations[0].AllowBlank | Should be $true
|
||||||
|
$ws.DataValidations[1].AllowBlank | Should be $true
|
||||||
|
$ws.DataValidations[0].ShowErrorMessage | Should be $true
|
||||||
|
$ws.DataValidations[1].ShowErrorMessage | Should be $true
|
||||||
|
$ws.DataValidations[0].ErrorTitle | Should not benullorempty
|
||||||
|
$ws.DataValidations[1].ErrorTitle | Should not benullorempty
|
||||||
|
$ws.DataValidations[0].Error | Should not benullorempty
|
||||||
|
$ws.DataValidations[1].Error | Should not benullorempty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
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
|
||||||
@@ -3,29 +3,37 @@
|
|||||||
.Synopsis
|
.Synopsis
|
||||||
Compares two worksheets and shows the differences.
|
Compares two worksheets and shows the differences.
|
||||||
.Description
|
.Description
|
||||||
This command takes two file names, one or two worksheet name and a name for a key column.
|
This command takes two file names, one or two worksheet names and a name
|
||||||
It reads the worksheet from each file and decides the column names.
|
for a "key" column. It reads the worksheet from each file and decides the
|
||||||
It builds a hashtable of the key-column values and the rows in which they appear.
|
column names and builds a hashtable of the key-column values and the
|
||||||
It then uses PowerShell's compare object command to compare the sheets (explicity checking
|
rows in which they appear.
|
||||||
all the column names which have not been excluded). For the difference rows it adds the
|
It then uses PowerShell's Compare-Object command to compare the sheets
|
||||||
row number for the key of that row - we have to add the key after doing the comparison,
|
(explicitly checkingall the column names which have not been excluded).
|
||||||
otherwise identical rows at diffeent positions in the file will not will be considered to match.
|
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.
|
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.
|
If -BackgroundColor is specified the difference rows will be changed to
|
||||||
|
that background in the orginal file.
|
||||||
.Example
|
.Example
|
||||||
Compare-WorkSheet -Referencefile 'Server56.xlsx' -Differencefile 'Server57.xlsx' -WorkSheetName Products -key IdentifyingNumber -ExcludeProperty Install* | Format-Table
|
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 two workbooks in this example contain the result of redirecting a subset
|
||||||
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
|
of properties from Get-WmiObject -Class win32_product to Export-Excel.
|
||||||
different date or from a different place, and excluding Install* removes InstallDate and InstallSource.
|
The command compares the "Products" pages in the two workbooks, but we
|
||||||
This data doesn't have a "Name" column" so we specify the "IdentifyingNumber" column as the key.
|
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.
|
The results will be presented as a table.
|
||||||
.Example
|
.Example
|
||||||
compare-WorkSheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName Services -GridView
|
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.
|
This time two workbooks contain the result of redirecting the command
|
||||||
Here the -Differencefile and -Referencefile parameter switches are assumed , and the default setting for -key ("Name") works for services
|
Get-WmiObject -Class win32_service to Export-Excel. Here the -Differencefile
|
||||||
This will display the differences between the "Services" sheets using a grid view
|
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
|
.Example
|
||||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen
|
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen
|
||||||
|
|
||||||
@@ -33,27 +41,36 @@
|
|||||||
.Example
|
.Example
|
||||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen -FontColor Red -Show
|
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName Services -BackgroundColor lightGreen -FontColor Red -Show
|
||||||
|
|
||||||
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 example builds on the previous one: this time where two changed rows have
|
||||||
this version adds highlighting of the changed cells in red; and then opens the Excel file.
|
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
|
.Example
|
||||||
Compare-WorkSheet 'Pester-tests.xlsx' 'Pester-tests.xlsx' -WorkSheetName 'Server1','Server2' -Property "full Description","Executed","Result" -Key "full Description"
|
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
|
This time the reference file and the difference file are the same file and
|
||||||
machine name and time the test was run the command specifies that a limited set of columns should be used.
|
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
|
.Example
|
||||||
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName general -Startrow 2 -Headername Label,value -Key Label -GridView -ExcludeDifferent
|
Compare-WorkSheet 'Server54.xlsx' 'Server55.xlsx' -WorkSheetName general -Startrow 2 -Headername Label,value -Key Label -GridView -ExcludeDifferent
|
||||||
|
|
||||||
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;
|
The "General" page in the two workbooks has a title and two unlabelled columns
|
||||||
so the command is instructed 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";
|
with a row each for CPU, Memory, Domain, Disk and so on. So the command is
|
||||||
the label acts as the key. This time we interested the rows which are the same in both sheets,
|
told to start at row 2 in order to skip the title and given names for the
|
||||||
and the result is displayed using grid view. Note that grid view works best when the number of columns is small.
|
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
|
.Example
|
||||||
Compare-WorkSheet 'Server1.xlsx' 'Server2.xlsx' -WorkSheetName general -Startrow 2 -Headername Label,value -Key Label -BackgroundColor White -Show -AllDataBackgroundColor LightGray
|
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 highlights all the cells in lightgray and then sets the changed rows back to white;
|
This version of the previous command highlights all the cells in LightGray
|
||||||
only the unchanged rows are highlighted
|
and then sets the changed rows back to white.
|
||||||
|
Only the unchanged rows are highlighted.
|
||||||
#>
|
#>
|
||||||
[cmdletbinding(DefaultParameterSetName)]
|
[cmdletbinding(DefaultParameterSetName)]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification="Write host used for sub-warning level message to operator which does not form output")]
|
||||||
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="False positives when initializing variable in begin block")]
|
||||||
Param(
|
Param(
|
||||||
#First file to compare.
|
#First file to compare.
|
||||||
[parameter(Mandatory=$true,Position=0)]
|
[parameter(Mandatory=$true,Position=0)]
|
||||||
@@ -63,9 +80,9 @@
|
|||||||
$Differencefile ,
|
$Differencefile ,
|
||||||
#Name(s) of worksheets to compare.
|
#Name(s) of worksheets to compare.
|
||||||
$WorkSheetName = "Sheet1",
|
$WorkSheetName = "Sheet1",
|
||||||
#Properties to include in the DIFF - supports wildcards, default is "*".
|
#Properties to include in the comparison - supports wildcards, default is "*".
|
||||||
$Property = "*" ,
|
$Property = "*" ,
|
||||||
#Properties to exclude from the search - supports wildcards.
|
#Properties to exclude from the comparison - supports wildcards.
|
||||||
$ExcludeProperty ,
|
$ExcludeProperty ,
|
||||||
#Specifies custom property names to use, instead of the values defined in the starting row of the sheet.
|
#Specifies custom property names to use, instead of the values defined in the starting row of the sheet.
|
||||||
[Parameter(ParameterSetName='B', Mandatory)]
|
[Parameter(ParameterSetName='B', Mandatory)]
|
||||||
@@ -75,25 +92,25 @@
|
|||||||
[switch]$NoHeader,
|
[switch]$NoHeader,
|
||||||
#The row from where we start to import data: all rows above the start row 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,
|
[int]$Startrow = 1,
|
||||||
#If specified, highlights all the cells - so you can make Equal cells one colour, and Diff cells another.
|
#If specified, highlights all the cells - so you can make Equal cells one color, and Different cells another.
|
||||||
[System.Drawing.Color]$AllDataBackgroundColor,
|
$AllDataBackgroundColor,
|
||||||
#If specified, highlights the DIFF rows.
|
#If specified, highlights the rows with differences.
|
||||||
[System.Drawing.Color]$BackgroundColor,
|
$BackgroundColor,
|
||||||
#If specified identifies the tabs which contain DIFF rows (ignored if -BackgroundColor is omitted).
|
#If specified identifies the tabs which contain difference rows (ignored if -BackgroundColor is omitted).
|
||||||
[System.Drawing.Color]$TabColor,
|
$TabColor,
|
||||||
#Name of a column which is unique and will be used to add a row to the DIFF object, defaults to "Name".
|
#Name of a column which is unique and will be used to add a row to the DIFF object, defaults to "Name".
|
||||||
$Key = "Name" ,
|
$Key = "Name" ,
|
||||||
#If specified, highlights the DIFF columns in rows which have the same key.
|
#If specified, highlights the DIFF columns in rows which have the same key.
|
||||||
[System.Drawing.Color]$FontColor,
|
$FontColor,
|
||||||
#If specified opens the Excel workbooks instead of outputting the diff to the console (unless -Passthru is also specified).
|
#If specified, opens the Excel workbooks instead of outputting the diff to the console (unless -PassThru is also specified).
|
||||||
[Switch]$Show,
|
[Switch]$Show,
|
||||||
#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.
|
#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,
|
[switch]$GridView,
|
||||||
#If specified -Passthrough a 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,
|
[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,
|
[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
|
[Switch]$ExcludeDifferent
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -153,7 +170,7 @@
|
|||||||
foreach ($file in $updates) {
|
foreach ($file in $updates) {
|
||||||
try {$xl = Open-ExcelPackage -Path $file.name }
|
try {$xl = Open-ExcelPackage -Path $file.name }
|
||||||
catch {Write-warning -Message "Can't open $($file.Name) for writing." ; return}
|
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 {
|
$file.Group._sheet | Sort-Object -Unique | ForEach-Object {
|
||||||
$ws = $xl.Workbook.Worksheets[$_]
|
$ws = $xl.Workbook.Worksheets[$_]
|
||||||
if ($headerName) {$range = "A" + $startrow + ":" + $ws.dimension.end.address}
|
if ($headerName) {$range = "A" + $startrow + ":" + $ws.dimension.end.address}
|
||||||
@@ -166,7 +183,8 @@
|
|||||||
$range = $ws.Dimension -replace "\d+",$row._row
|
$range = $ws.Dimension -replace "\d+",$row._row
|
||||||
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $BackgroundColor
|
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)) {
|
foreach ($tab in ($file.group._sheet | Select-Object -Unique)) {
|
||||||
$xl.Workbook.Worksheets[$tab].TabColor = $TabColor
|
$xl.Workbook.Worksheets[$tab].TabColor = $TabColor
|
||||||
}
|
}
|
||||||
@@ -174,8 +192,8 @@
|
|||||||
$xl.save() ; $xl.Stream.Close() ; $xl.Dispose()
|
$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) ) {
|
if ($diff -and $FontColor -and (($propList -contains $Key) -or ($key -is [hashtable])) ) {
|
||||||
$updates = $diff.where({$_.SideIndicator -ne "=="}) | Group-object -Property $Key | Where-Object {$_.count -eq 2}
|
$updates = $diff.where({$_.SideIndicator -ne "=="}) | Group-object -Property $Key | Where-Object {$_.count -eq 2}
|
||||||
if ($updates) {
|
if ($updates) {
|
||||||
$XL1 = Open-ExcelPackage -path $Referencefile
|
$XL1 = Open-ExcelPackage -path $Referencefile
|
||||||
@@ -203,11 +221,9 @@
|
|||||||
}
|
}
|
||||||
elseif ($diff -and $FontColor) {Write-Warning -Message "To match rows to set changed cells, you must specify -Key and it must match one of the included properties." }
|
elseif ($diff -and $FontColor) {Write-Warning -Message "To match rows to set changed cells, you must specify -Key and it must match one of the included properties." }
|
||||||
|
|
||||||
#if nothing was found write a message which wont be redirected
|
#if nothing was found write a message which will not be redirected
|
||||||
if (-not $diff) {Write-Host "Comparison of $Referencefile::$worksheet1 and $Differencefile::$WorkSheet2 returned no results." }
|
if (-not $diff) {Write-Host "Comparison of $Referencefile::$worksheet1 and $Differencefile::$WorkSheet2 returned no results." }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ($Show) {
|
if ($Show) {
|
||||||
Start-Process -FilePath $Referencefile
|
Start-Process -FilePath $Referencefile
|
||||||
if (-not $oneFile) { Start-Process -FilePath $Differencefile }
|
if (-not $oneFile) { Start-Process -FilePath $Differencefile }
|
||||||
|
|||||||
BIN
images/GroupingNumeric.png
Normal file
BIN
images/GroupingNumeric.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
BIN
images/exportstockinfo.gif
Normal file
BIN
images/exportstockinfo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 MiB |
Reference in New Issue
Block a user