mirror of
https://github.com/dfinke/ImportExcel.git
synced 2025-12-15 07:43:23 +00:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3f3ae74a4 | ||
|
|
fda61ca10f | ||
|
|
29efd505ed | ||
|
|
600d95199c | ||
|
|
1ad80825ca | ||
|
|
a2b322d45c | ||
|
|
bb9aa9233b | ||
|
|
591b854e2b | ||
|
|
15eb2130b5 | ||
|
|
ea8927394f | ||
|
|
cfd89f5afc | ||
|
|
3a6946466f | ||
|
|
89a59b1eba | ||
|
|
8047631014 | ||
|
|
9458a29a6b | ||
|
|
ab2405edad | ||
|
|
d1592f8739 | ||
|
|
6650ecd5b8 | ||
|
|
b27f6bec3c | ||
|
|
99f742fa8c | ||
|
|
558070bb60 | ||
|
|
1e0dd763ca | ||
|
|
a783b9c8ca | ||
|
|
9abbe2983b | ||
|
|
0556e4947a | ||
|
|
859b1e5467 | ||
|
|
0f4e491076 | ||
|
|
b30a91d64f | ||
|
|
d1f794c933 | ||
|
|
a016f069a5 | ||
|
|
fb16ec4677 | ||
|
|
1a51d38c0f | ||
|
|
554163a911 | ||
|
|
efd8dcd60a | ||
|
|
1c77bd31b5 | ||
|
|
35e013fe1d | ||
|
|
8ac9927cfa | ||
|
|
9c305a1dae | ||
|
|
aa738629f7 | ||
|
|
c1a26f4f4b | ||
|
|
63f41ceaec | ||
|
|
b82888527f | ||
|
|
a3c71de190 | ||
|
|
f3a99f04ce | ||
|
|
f631a20269 | ||
|
|
dbd35721ee | ||
|
|
8759070636 | ||
|
|
6259b8d091 | ||
|
|
7086c3707c | ||
|
|
8b28172616 | ||
|
|
abdd37b09e | ||
|
|
e1e855a823 | ||
|
|
585d9686a6 | ||
|
|
e87a6bdaf5 | ||
|
|
5ded5111b4 | ||
|
|
914c61048b | ||
|
|
25fb76d9b7 | ||
|
|
7faa27a3b3 | ||
|
|
5700be0684 | ||
|
|
6d86108060 | ||
|
|
4581c2b3e9 | ||
|
|
142c31ccc1 | ||
|
|
b99b7ba799 | ||
|
|
17b5d2caec | ||
|
|
6add16aa9f | ||
|
|
9aa0192ee6 | ||
|
|
fa25d1ac06 | ||
|
|
8131eee50f | ||
|
|
3ce485a144 | ||
|
|
bb1b413ada | ||
|
|
08078410dc | ||
|
|
3edcc0bdfb | ||
|
|
25081f84c1 | ||
|
|
668e3c982c | ||
|
|
98cf7e03c1 | ||
|
|
5b5c1c6fce | ||
|
|
4383916090 | ||
|
|
7c2bbf9595 | ||
|
|
48ca35b9ff | ||
|
|
68be3c3483 | ||
|
|
78326b4258 | ||
|
|
94b10b6f51 | ||
|
|
8ac9815e83 | ||
|
|
b3184d36a9 | ||
|
|
e58265075a | ||
|
|
453b2d8963 | ||
|
|
bc816851c9 | ||
|
|
b0a68e3445 | ||
|
|
8a1d0b0cf8 | ||
|
|
26f55251e2 | ||
|
|
0f9b308d53 | ||
|
|
847c9a1dc4 | ||
|
|
b488ffc700 | ||
|
|
3ec2481750 | ||
|
|
2d26c854d9 | ||
|
|
a4348ddca7 | ||
|
|
6bfdea6d3e | ||
|
|
cfd3db5803 | ||
|
|
f20a9de3df | ||
|
|
978e8d38b5 | ||
|
|
e7d2b528e5 | ||
|
|
899a8215e5 | ||
|
|
b06e9e35b7 | ||
|
|
6c7f00b031 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -60,7 +60,6 @@ test.xlsx
|
||||
testCCFMT.ps1
|
||||
testHide.ps1
|
||||
ImportExcel.zip
|
||||
.vscode/launch.json
|
||||
.vscode/settings.json
|
||||
|
||||
~$*
|
||||
|
||||
56
.vscode/launch.json
vendored
Normal file
56
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Pester Tests",
|
||||
"script": "Import-Module -Name '.\\' -Force ; Invoke-Pester", // Change to '.\\ModuleName.psd1' if Git name different
|
||||
"args": [""],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File in Temporary Console",
|
||||
"script": "${file}",
|
||||
"args": [],
|
||||
"cwd": "${file}",
|
||||
"createTemporaryIntegratedConsole": true
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Launch Current File w/Args Prompt",
|
||||
"script": "${file}",
|
||||
"args": [
|
||||
"${command:SpecifyScriptArgs}"
|
||||
],
|
||||
"cwd": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "attach",
|
||||
"name": "PowerShell Attach to Host Process",
|
||||
"processId": "${command:PickPSHostProcess}",
|
||||
"runspaceId": 1
|
||||
},
|
||||
{
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"name": "PowerShell Interactive Session",
|
||||
"cwd": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
Function Add-ConditionalFormatting {
|
||||
try {
|
||||
#ensure that color and font lookups are available
|
||||
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
|
||||
}
|
||||
catch {}
|
||||
Function Add-ConditionalFormatting {
|
||||
<#
|
||||
.Synopsis
|
||||
Adds conditional formatting to all or part of a worksheet.
|
||||
@@ -105,7 +110,7 @@
|
||||
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
|
||||
#Text color for matching objects
|
||||
[Parameter(ParameterSetName = "NamedRule")]
|
||||
[Alias("ForegroundColour")]
|
||||
[Alias("ForegroundColour","FontColor")]
|
||||
$ForegroundColor,
|
||||
#Color for databar type charts
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
|
||||
@@ -185,7 +190,7 @@
|
||||
$Address = "$($Address.Row):$($Address.Row)"
|
||||
}
|
||||
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 -is [string] -and $Address -match "!") {$Address = $Address -replace '^.*!',''}
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
}
|
||||
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 (-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.
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName ConditionalTextColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
|
||||
@@ -37,5 +41,4 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
|
||||
|
||||
}
|
||||
@@ -69,6 +69,8 @@
|
||||
Only the unchanged rows are highlighted.
|
||||
#>
|
||||
[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(
|
||||
#First file to compare.
|
||||
[parameter(Mandatory=$true,Position=0)]
|
||||
@@ -219,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." }
|
||||
|
||||
#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 ($Show) {
|
||||
Start-Process -FilePath $Referencefile
|
||||
if (-not $oneFile) { Start-Process -FilePath $Differencefile }
|
||||
@@ -3,7 +3,7 @@ function ConvertFrom-ExcelData {
|
||||
.SYNOPSIS
|
||||
Reads data from a sheet, and for each row, calls a custom scriptblock with a list of property names and the row of data.
|
||||
|
||||
|
||||
|
||||
.EXAMPLE
|
||||
ConvertFrom-ExcelData .\testSQLGen.xlsx {
|
||||
param($propertyNames, $record)
|
||||
|
||||
@@ -3,24 +3,27 @@
|
||||
.SYNOPSIS
|
||||
Copies a worksheet between workbooks or within the same workbook.
|
||||
.DESCRIPTION
|
||||
Copy-ExcelWorkSheet takes Source and Destination workbook parameters; each can be the path to an XLSx file, an ExcelPackage object or an ExcelWorkbook object.
|
||||
The Source worksheet is specified by name or number (starting from 1), and the destination worksheet can be explicitly named,
|
||||
or will follow the name of the source if no name is specified.
|
||||
Copy-ExcelWorkSheet takes a Source object which is either a worksheet,
|
||||
or a package, Workbook or path, in which case the source worksheet can be specified
|
||||
by name or number (starting from 1).
|
||||
The destination worksheet can be explicitly named, or will follow the name of the source if no name is specified.
|
||||
The Destination workbook can be given as the path to an XLSx file, an ExcelPackage object or an ExcelWorkbook object.
|
||||
|
||||
.EXAMPLE
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook Test1.xlsx -DestinationWorkbook Test2.xlsx
|
||||
This is the simplest version of the command: no source worksheet is specified so Copy-ExcelWorksheet uses the first sheet in the workbook
|
||||
No Destination sheet is specified so the new worksheet will be the same as the one which is being copied.
|
||||
.EXAMPLE
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook Server1.xlsx -sourceWorksheet "Settings" -DestinationWorkbook Settings.xlsx -DestinationWorkSheet "Server1"
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook Server1.xlsx -sourceWorksheet "Settings" -DestinationWorkbook Settings.xlsx -DestinationWorksheet "Server1"
|
||||
Here the Settings page from Server1's workbook is copied to the 'Server1" page of a "Settings" workbook.
|
||||
.EXAMPLE
|
||||
C:\> $excel = Open-ExcelPackage .\test.xlsx
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet "first" -DestinationWorkbook $excel -Show -DestinationWorkSheet Duplicate
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet "first" -DestinationWorkbook $excel -Show -DestinationWorksheet Duplicate
|
||||
This opens the workbook test.xlsx and copies the worksheet named "first" to a new worksheet named "Duplicate",
|
||||
because -Show is specified the file is saved and opened in Excel
|
||||
.EXAMPLE
|
||||
C:\> $excel = Open-ExcelPackage .\test.xlsx
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet 1 -DestinationWorkbook $excel -DestinationWorkSheet Duplicate
|
||||
C:\> Copy-ExcelWorkSheet -SourceWorkbook $excel -SourceWorkSheet 1 -DestinationWorkbook $excel -DestinationWorksheet Duplicate
|
||||
C:\> Close-ExcelPackage $excel
|
||||
This is almost the same as the previous example, except source sheet is specified by position rather than name and
|
||||
because -Show is not specified, so other steps can be carried using the package object, at the end the file is saved by Close-ExcelPackage
|
||||
@@ -29,83 +32,99 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
|
||||
[Parameter(Mandatory = $true)]
|
||||
$SourceWorkbook,
|
||||
[Parameter(Mandatory = $true,ValueFromPipeline=$true)]
|
||||
[Alias('SourceWorkbook')]
|
||||
$SourceObject,
|
||||
#Name or number (starting from 1) of the worksheet in the source workbook (defaults to 1).
|
||||
$SourceWorkSheet = 1 ,
|
||||
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data should be copied.
|
||||
[Parameter(Mandatory = $true)]
|
||||
$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.
|
||||
$DestinationWorkSheet,
|
||||
$DestinationWorksheet,
|
||||
#if the destination is an excel package or a path, launch excel and open the file on completion.
|
||||
[Switch]$Show
|
||||
)
|
||||
#Special case - give the same path for source and destination worksheet
|
||||
if ($SourceWorkbook -is [System.String] -and $SourceWorkbook -eq $DestinationWorkbook) {
|
||||
if (-not $DestinationWorkSheet) {Write-Warning -Message "You must specify a destination worksheet name if copying within the same workbook."; return}
|
||||
else {
|
||||
Write-Verbose -Message "Copying "
|
||||
$excel = Open-ExcelPackage -Path $SourceWorkbook
|
||||
if (-not $excel.Workbook.Worksheets[$Sourceworksheet]) {
|
||||
Write-Warning -Message "Could not find Worksheet $sourceWorksheet in $sourceWorkbook"
|
||||
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
||||
return
|
||||
}
|
||||
elseif ($excel.Workbook.Worksheets[$Sourceworksheet].name -eq $DestinationWorkSheet) {
|
||||
Write-Warning -Message "The destination worksheet name is the same as the source. "
|
||||
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
||||
return
|
||||
}
|
||||
begin {
|
||||
#For the case where we are piped multiple sheets, we want to open the destination in the begin and close it in the end.
|
||||
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
|
||||
if ($Show) {$package2 = $DestinationWorkbook}
|
||||
$DestinationWorkbook = $DestinationWorkbook.Workbook
|
||||
}
|
||||
elseif ($DestinationWorkbook -is [string] -and ($DestinationWorkbook -ne $SourceObject)) {
|
||||
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
|
||||
$DestinationWorkbook = $package2.Workbook
|
||||
}
|
||||
}
|
||||
process {
|
||||
#Special case - given the same path for source and destination worksheet
|
||||
if ($SourceObject -is [System.String] -and $SourceObject -eq $DestinationWorkbook) {
|
||||
if (-not $DestinationWorksheet) {Write-Warning -Message "You must specify a destination worksheet name if copying within the same workbook."; return}
|
||||
else {
|
||||
$null = Add-WorkSheet -ExcelPackage $Excel -WorkSheetname $DestinationWorkSheet -CopySource ($excel.Workbook.Worksheets[$SourceWorkSheet])
|
||||
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
|
||||
return
|
||||
Write-Verbose -Message "Copying "
|
||||
$excel = Open-ExcelPackage -Path $SourceObject
|
||||
if (-not $excel.Workbook.Worksheets[$Sourceworksheet]) {
|
||||
Write-Warning -Message "Could not find Worksheet $sourceWorksheet in $SourceObject"
|
||||
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
||||
return
|
||||
}
|
||||
elseif ($excel.Workbook.Worksheets[$Sourceworksheet].name -eq $DestinationWorksheet) {
|
||||
Write-Warning -Message "The destination worksheet name is the same as the source. "
|
||||
Close-ExcelPackage -ExcelPackage $excel -NoSave
|
||||
return
|
||||
}
|
||||
else {
|
||||
$null = Add-WorkSheet -ExcelPackage $excel -WorkSheetname $DestinationWorksheet -CopySource ($excel.Workbook.Worksheets[$SourceWorkSheet])
|
||||
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($SourceObject -is [OfficeOpenXml.ExcelWorksheet]) {$sourceWs = $SourceObject}
|
||||
elseif ($SourceObject -is [OfficeOpenXml.ExcelWorkbook]) {$sourceWs = $SourceObject.Worksheets[$SourceWorkSheet]}
|
||||
elseif ($SourceObject -is [OfficeOpenXml.ExcelPackage] ) {$sourceWs = $SourceObject.Workbook.Worksheets[$SourceWorkSheet]}
|
||||
else {
|
||||
$SourceObject = (Resolve-Path $SourceObject).ProviderPath
|
||||
try {
|
||||
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceObject'."
|
||||
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceObject, 'Open', 'Read' , 'ReadWrite'
|
||||
$package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
||||
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
|
||||
}
|
||||
catch {Write-Warning -Message "Could not open $SourceObject - the error was '$($_.exception.message)' " ; return}
|
||||
}
|
||||
if (-not $sourceWs) {Write-Warning -Message "Could not find worksheet '$Sourceworksheet' in the source workbook." ; return}
|
||||
else {
|
||||
try {
|
||||
if ($DestinationWorkbook -isnot [OfficeOpenXml.ExcelWorkbook]) {
|
||||
Write-Warning "Not a valid workbook" ; return
|
||||
}
|
||||
#check if we have a destination sheet name and set one if not. Because we might loop round check $psBoundParameters, not the variable.
|
||||
if (-not $PSBoundParameters['DestinationWorksheet']) {
|
||||
#if we are piped files, use the file name without the extension as the destination sheet name, Otherwise use the source sheet name
|
||||
if ($_ -is [System.IO.FileInfo]) {$DestinationWorksheet = $_.name -replace '\.xlsx$', '' }
|
||||
else { $DestinationWorksheet = $sourceWs.Name}
|
||||
}
|
||||
if ($DestinationWorkbook.Worksheets[$DestinationWorksheet]) {
|
||||
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorksheet', deleting it."
|
||||
$DestinationWorkbook.Worksheets.Delete($DestinationWorksheet)
|
||||
}
|
||||
Write-Verbose "Copying '$($sourcews.name)' from $($SourceObject) to '$($DestinationWorksheet)' in $($PSBoundParameters['DestinationWorkbook'])"
|
||||
$null = Add-WorkSheet -ExcelWorkbook $DestinationWorkbook -WorkSheetname $DestinationWorksheet -CopySource $sourceWs
|
||||
#Leave the destination open but close the source - if we're copying more than one sheet we'll re-open it and live with the inefficiency
|
||||
if ($stream) {$stream.Close() }
|
||||
if ($package1) {Close-ExcelPackage -ExcelPackage $package1 -NoSave }
|
||||
}
|
||||
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorksheet' in the destination workbook. Error was '$($_.exception.message)'" ; return}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($SourceWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {$sourcews = $SourceWorkbook.Worksheets[$SourceWorkSheet]}
|
||||
elseif ($SourceWorkbook -is [OfficeOpenXml.ExcelPackage] ) {$sourcews = $SourceWorkbook.Workbook.Worksheets[$SourceWorkSheet]}
|
||||
else {
|
||||
$SourceWorkbook = (Resolve-Path $SourceWorkbook).ProviderPath
|
||||
try {
|
||||
Write-Verbose "Opening worksheet '$Worksheetname' in Excel workbook '$SourceWorkbook'."
|
||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $SourceWorkbook, 'Open', 'Read' , 'ReadWrite'
|
||||
$Package1 = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
||||
$sourceWs = $Package1.Workbook.Worksheets[$SourceWorkSheet]
|
||||
}
|
||||
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}
|
||||
else {
|
||||
try {
|
||||
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
|
||||
$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 ($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}
|
||||
end {
|
||||
#OK Now we can close the destination package
|
||||
if ($package2) {Close-ExcelPackage -ExcelPackage $package2 -Show:$Show }
|
||||
if ($Show -and -not $package2) {
|
||||
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
|
||||
}
|
||||
}
|
||||
}
|
||||
28
DoTests.ps1
28
DoTests.ps1
@@ -1,28 +0,0 @@
|
||||
param(
|
||||
[Switch]$DontCreateZip
|
||||
)
|
||||
|
||||
##
|
||||
# Used in Appveyor.yml
|
||||
##
|
||||
|
||||
$PSVersionTable.PSVersion
|
||||
|
||||
## Create the zip before the tests run
|
||||
## Otherwise the EPPlus.dll is in use after the Pester run
|
||||
$ModuleVersion = (Get-Content -Raw .\ImportExcel.psd1) | Invoke-Expression | ForEach-Object ModuleVersion
|
||||
|
||||
if (!$DontCreateZip) {
|
||||
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
|
||||
Compress-Archive -Path . -DestinationPath .\$dest
|
||||
}
|
||||
|
||||
if ($null -eq (Get-Module -ListAvailable pester)) {
|
||||
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
|
||||
}
|
||||
|
||||
$result = Invoke-Pester -Script $PSScriptRoot\__tests__ -Verbose -PassThru
|
||||
|
||||
if ($result.FailedCount -gt 0) {
|
||||
throw "$($result.FailedCount) tests failed."
|
||||
}
|
||||
BIN
EPPlus.dll
BIN
EPPlus.dll
Binary file not shown.
21
Examples/Charts/ChartAndTrendlines.ps1
Normal file
21
Examples/Charts/ChartAndTrendlines.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
# Creates a worksheet, addes a chart and then a Linear trendline
|
||||
|
||||
$xlfile = "$env:TEMP\trendLine.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv @"
|
||||
Region,Item,TotalSold
|
||||
West,screws,60
|
||||
South,lemon,48
|
||||
South,apple,71
|
||||
East,screwdriver,70
|
||||
East,kiwi,32
|
||||
West,screwdriver,1
|
||||
South,melon,21
|
||||
East,apple,79
|
||||
South,apple,68
|
||||
South,avocado,73
|
||||
"@
|
||||
|
||||
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine Linear
|
||||
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange -Show
|
||||
27
Examples/Charts/NumberOfVisitors.ps1
Normal file
27
Examples/Charts/NumberOfVisitors.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
$xlfile = "$env:TEMP\visitors.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv @"
|
||||
Week, TotalVisitors
|
||||
1,11916
|
||||
2,11665
|
||||
3,13901
|
||||
4,15444
|
||||
5,21592
|
||||
6,15057
|
||||
7,26187
|
||||
8,20662
|
||||
9,28935
|
||||
10,32443
|
||||
"@
|
||||
|
||||
$cd = New-ExcelChartDefinition `
|
||||
-XRange Week `
|
||||
-YRange TotalVisitors `
|
||||
-Title "No. Of Visitors" `
|
||||
-ChartType ColumnClustered `
|
||||
-NoLegend `
|
||||
-ChartTrendLine Linear
|
||||
|
||||
$data | Export-Excel $xlfile -Show -AutoNameRange -AutoSize -TableName Visitors -ExcelChartDefinition $cd
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$f = ".\dashboard.xlsx"
|
||||
$f = "$env:temp\dashboard.xlsx"
|
||||
Remove-Item $f -ErrorAction Ignore
|
||||
|
||||
$data = @"
|
||||
@@ -69,4 +69,4 @@ Set-Format -Address $sheet1.Cells["I10"] -Formula "=Sum(I3:I8)" -Bold
|
||||
Set-Format -Address $sheet1.Cells["M10"] -Formula "=Sum(M3:M8)" -Bold
|
||||
Set-Format -Address $sheet1.Cells["O10"] -Formula "=Sum(O3:O8)" -Bold
|
||||
|
||||
Close-ExcelPackage $excel -Show
|
||||
Close-ExcelPackage $excel -Show
|
||||
|
||||
89
Examples/CustomizeExportExcel/Out-Excel.ps1
Normal file
89
Examples/CustomizeExportExcel/Out-Excel.ps1
Normal file
@@ -0,0 +1,89 @@
|
||||
<#
|
||||
This is an example on how to customize Export-Excel to your liking.
|
||||
First select a name for your function, in ths example its "Out-Excel" you can even set the name to "Export-Excel".
|
||||
You can customize the following things:
|
||||
1. To add parameters to the function define them in "param()", here I added "Preset1" and "Preset2".
|
||||
The parameters need to be removed after use (see comments and code below).
|
||||
2. To remove parameters from the function add them to the list under "$_.Name -notmatch", I removed "Now".
|
||||
3. Add your custom code, here I defined what the Presets do:
|
||||
Preset1 configure the TableStyle, name the table depending on WorksheetName and FreezeTopRow.
|
||||
Preset2 will set AutoFilter and add the Title "Daily Report".
|
||||
(see comments and code below).
|
||||
#>
|
||||
Function Out-Excel {
|
||||
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
param(
|
||||
[switch]
|
||||
${Preset1},
|
||||
[switch]
|
||||
${Preset2}
|
||||
)
|
||||
DynamicParam {
|
||||
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
|
||||
foreach ($P in (Get-Command -Name Export-Excel).Parameters.values.where( { $_.Name -notmatch 'Verbose|Debug|Action$|Variable$|Buffer$|Now' })) {
|
||||
$paramDictionary.Add($P.Name, [System.Management.Automation.RuntimeDefinedParameter]::new( $P.Name, $P.ParameterType, $P.Attributes ) )
|
||||
}
|
||||
return $paramDictionary
|
||||
}
|
||||
|
||||
begin {
|
||||
try {
|
||||
# Run you custom code here if it need to run before calling Export-Excel.
|
||||
$PSBoundParameters['Now'] = $true
|
||||
if ($Preset1) {
|
||||
$PSBoundParameters['TableStyle'] = 'Medium7'
|
||||
$PSBoundParameters['FreezeTopRow'] = $true
|
||||
if ($PSBoundParameters['WorksheetName'] -and -not $PSBoundParameters['TableName']) {
|
||||
$PSBoundParameters['TableName'] = $PSBoundParameters['WorksheetName'] + '_Table'
|
||||
}
|
||||
}
|
||||
elseif ($Preset2) {
|
||||
$PSBoundParameters['Title'] = 'Daily Report'
|
||||
$PSBoundParameters['AutoFilter'] = $true
|
||||
}
|
||||
# Remove the extra params we added as Export-Excel will not know what to do with them:
|
||||
$null = $PSBoundParameters.Remove('Preset1')
|
||||
$null = $PSBoundParameters.Remove('Preset2')
|
||||
|
||||
# The rest of the code was auto generated.
|
||||
$outBuffer = $null
|
||||
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
|
||||
$PSBoundParameters['OutBuffer'] = 1
|
||||
}
|
||||
|
||||
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-Excel', [System.Management.Automation.CommandTypes]::Function)
|
||||
# You can add a pipe after @PSBoundParameters to manipulate the output.
|
||||
$scriptCmd = { & $wrappedCmd @PSBoundParameters }
|
||||
|
||||
$steppablePipeline = $scriptCmd.GetSteppablePipeline()
|
||||
$steppablePipeline.Begin($PSCmdlet)
|
||||
}
|
||||
catch {
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
$steppablePipeline.Process($_)
|
||||
}
|
||||
catch {
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
try {
|
||||
$steppablePipeline.End()
|
||||
}
|
||||
catch {
|
||||
throw
|
||||
}
|
||||
}
|
||||
<#
|
||||
|
||||
.ForwardHelpTargetName Export-Excel
|
||||
.ForwardHelpCategory Function
|
||||
|
||||
#>
|
||||
}
|
||||
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
|
||||
}
|
||||
25
Examples/Sparklines/SalesByQuarter.ps1
Normal file
25
Examples/Sparklines/SalesByQuarter.ps1
Normal file
@@ -0,0 +1,25 @@
|
||||
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
|
||||
|
||||
$xlfile = "$env:TEMP\SalesByQuarter.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv @"
|
||||
Region,Q1,Q2,Q3,Q4,YTDPerformance
|
||||
Asia,1400,7200,5700,6900
|
||||
Europe,3400,2300,9400,7300
|
||||
Midwest,4700,9300,3700,8600
|
||||
Northeast,2300,4300,4600,5600
|
||||
"@
|
||||
|
||||
$excel = $data | Export-Excel $xlfile -Passthru -AutoSize -TableName SalesByQuarter
|
||||
|
||||
$ws = $excel.Sheet1
|
||||
|
||||
Set-Format -WorkSheet $ws -Range "B2:E5" -NumberFormat "$#,##0" -AutoSize
|
||||
$sparkLineType = "line"
|
||||
$null = $ws.SparklineGroups.Add( $sparkLineType, $ws.Cells["F2"], $ws.Cells["B2:E2"] )
|
||||
$null = $ws.SparklineGroups.Add( $sparkLineType, $ws.Cells["F3"], $ws.Cells["B3:E3"] )
|
||||
$null = $ws.SparklineGroups.Add( $sparkLineType, $ws.Cells["F4"], $ws.Cells["B4:E4"] )
|
||||
$null = $ws.SparklineGroups.Add( $sparkLineType, $ws.Cells["F5"], $ws.Cells["B5:E5"] )
|
||||
|
||||
Close-ExcelPackage $excel -Show
|
||||
99
Examples/Sparklines/Sparklines.ps1
Normal file
99
Examples/Sparklines/Sparklines.ps1
Normal file
@@ -0,0 +1,99 @@
|
||||
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
|
||||
|
||||
class data {
|
||||
[datetime]$Date
|
||||
[Double]$AUD
|
||||
[Double]$CAD
|
||||
[Double]$CHF
|
||||
[Double]$DKK
|
||||
[Double]$EUR
|
||||
[Double]$GBP
|
||||
[Double]$HKD
|
||||
[Double]$JPY
|
||||
[Double]$MYR
|
||||
[Double]$NOK
|
||||
[Double]$NZD
|
||||
[Double]$RUB
|
||||
[Double]$SEK
|
||||
[Double]$THB
|
||||
[Double]$TRY
|
||||
[Double]$USD
|
||||
}
|
||||
|
||||
[data[]]$data = ConvertFrom-Csv @"
|
||||
Date,AUD,CAD,CHF,DKK,EUR,GBP,HKD,JPY,MYR,NOK,NZD,RUB,SEK,THB,TRY,USD
|
||||
2016-03-01,6.17350,6.42084,8.64785,1.25668,9.37376,12.01683,1.11067,0.07599,2.06900,0.99522,5.69227,0.11665,1.00000,0.24233,2.93017,8.63185
|
||||
2016-03-02,6.27223,6.42345,8.63480,1.25404,9.35350,12.14970,1.11099,0.07582,2.07401,0.99311,5.73277,0.11757,1.00000,0.24306,2.94083,8.63825
|
||||
2016-03-07,6.33778,6.38403,8.50245,1.24980,9.32373,12.05756,1.09314,0.07478,2.07171,0.99751,5.77539,0.11842,1.00000,0.23973,2.91088,8.48885
|
||||
2016-03-08,6.30268,6.31774,8.54066,1.25471,9.36254,12.03361,1.09046,0.07531,2.05625,0.99225,5.72501,0.11619,1.00000,0.23948,2.91067,8.47020
|
||||
2016-03-09,6.32630,6.33698,8.46118,1.24399,9.28125,11.98879,1.08544,0.07467,2.04128,0.98960,5.71601,0.11863,1.00000,0.23893,2.91349,8.42945
|
||||
2016-03-10,6.24241,6.28817,8.48684,1.25260,9.34350,11.99193,1.07956,0.07392,2.04500,0.98267,5.58145,0.11769,1.00000,0.23780,2.89150,8.38245
|
||||
2016-03-11,6.30180,6.30152,8.48295,1.24848,9.31230,12.01194,1.07545,0.07352,2.04112,0.98934,5.62335,0.11914,1.00000,0.23809,2.90310,8.34510
|
||||
2016-03-15,6.19790,6.21615,8.42931,1.23754,9.22896,11.76418,1.07026,0.07359,2.00929,0.97129,5.49278,0.11694,1.00000,0.23642,2.86487,8.30540
|
||||
2016-03-16,6.18508,6.22493,8.41792,1.23543,9.21149,11.72470,1.07152,0.07318,2.01179,0.96907,5.49138,0.11836,1.00000,0.23724,2.84767,8.31775
|
||||
2016-03-17,6.25214,6.30642,8.45981,1.24327,9.26623,11.86396,1.05571,0.07356,2.01706,0.98159,5.59544,0.12024,1.00000,0.23543,2.87595,8.18825
|
||||
2016-03-18,6.25359,6.32400,8.47826,1.24381,9.26976,11.91322,1.05881,0.07370,2.02554,0.98439,5.59067,0.12063,1.00000,0.23538,2.86880,8.20950
|
||||
"@
|
||||
|
||||
$xlfile = "$env:TEMP\sparklines.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$excel = $data | Export-Excel $xlfile -WorksheetName SEKRates -AutoSize -PassThru
|
||||
|
||||
# Add a column sparkline for all currencies
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range "A2:A12" -NumberFormat "yyyy-mm-dd" -AutoSize
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range A15 -Value Column -AutoSize
|
||||
|
||||
$sparklineCol = $excel.SEKRates.SparklineGroups.Add(
|
||||
"Column",
|
||||
$excel.SEKRates.Cells["B15:Q15"],
|
||||
$excel.SEKRates.Cells["B2:Q12"]
|
||||
)
|
||||
|
||||
$sparklineCol.High = $true
|
||||
$sparklineCol.ColorHigh.SetColor("Red")
|
||||
|
||||
# Add a line sparkline for all currencies
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range A16 -Value Line -AutoSize
|
||||
$sparklineLine = $excel.SEKRates.SparklineGroups.Add(
|
||||
"Line",
|
||||
$excel.SEKRates.Cells["B16:Q16"],
|
||||
$excel.SEKRates.Cells["B2:Q12"]
|
||||
)
|
||||
|
||||
$sparklineLine.DateAxisRange = $excel.SEKRates.Cells["A2:A12"]
|
||||
|
||||
# Add some more random values and add a stacked sparkline.
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range A17 -Value Stacked -AutoSize
|
||||
|
||||
$numbers = 2, -1, 3, -4, 8, 5, -12, 18, 99, 1, -4, 12, -8, 9, 0, -8
|
||||
|
||||
$col = 2 # Column B
|
||||
foreach ($n in $numbers) {
|
||||
$excel.SEKRates.Cells[17, $col++].Value = $n
|
||||
}
|
||||
|
||||
$sparklineStacked = $excel.SEKRates.SparklineGroups.Add(
|
||||
"Stacked",
|
||||
$excel.SEKRates.Cells["R17"],
|
||||
$excel.SEKRates.Cells["B17:Q17"]
|
||||
)
|
||||
|
||||
$sparklineStacked.High = $true
|
||||
$sparklineStacked.ColorHigh.SetColor("Red")
|
||||
$sparklineStacked.Low = $true
|
||||
$sparklineStacked.ColorLow.SetColor("Green")
|
||||
$sparklineStacked.Negative = $true
|
||||
$sparklineStacked.ColorNegative.SetColor("Blue")
|
||||
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range "A15:A17" -Bold -Height 50 -AutoSize
|
||||
|
||||
$v = @"
|
||||
High - Red
|
||||
Low - Green
|
||||
Negative - Blue
|
||||
"@
|
||||
|
||||
Set-Format -WorkSheet $excel.SEKRates -Range S17 -Value $v -WrapText -Width 20 -HorizontalAlignment Center -VerticalAlignment Center
|
||||
|
||||
Close-ExcelPackage $excel -Show
|
||||
35
Examples/Styles/MultipleStyles.ps1
Normal file
35
Examples/Styles/MultipleStyles.ps1
Normal file
@@ -0,0 +1,35 @@
|
||||
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
|
||||
|
||||
$xlfile = "$env:TEMP\test.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv @"
|
||||
Region,Item,TotalSold
|
||||
North,melon,38
|
||||
South,screwdriver,21
|
||||
South,peach,33
|
||||
South,saw,81
|
||||
South,kiwi,70
|
||||
North,orange,59
|
||||
North,avocado,25
|
||||
South,lime,48
|
||||
South,nail,83
|
||||
North,apple,2
|
||||
"@
|
||||
|
||||
$styleParams = @{
|
||||
FontSize = 13
|
||||
Bold = $true
|
||||
}
|
||||
|
||||
$styles = $(
|
||||
New-ExcelStyle -BackgroundColor LightBlue -FontSize 14 -Bold -Range "A1:H1" -HorizontalAlignment Center -Merge
|
||||
|
||||
New-ExcelStyle -BackgroundColor LimeGreen -Range "B10" @styleParams
|
||||
New-ExcelStyle -BackgroundColor PeachPuff -Range "B5" @styleParams
|
||||
New-ExcelStyle -BackgroundColor Orange -Range "B8" @styleParams
|
||||
New-ExcelStyle -BackgroundColor Red -Range "B12" @styleParams
|
||||
)
|
||||
|
||||
$reportTitle = "This is a report Title"
|
||||
$data | Export-Excel $xlfile -Show -AutoSize -AutoFilter -Title $reportTitle -Style $styles
|
||||
23
Examples/Styles/NewExcelStyle.ps1
Normal file
23
Examples/Styles/NewExcelStyle.ps1
Normal file
@@ -0,0 +1,23 @@
|
||||
# https://raw.githubusercontent.com/dfinke/ImportExcel/master/images/NewExcelStyle.png
|
||||
try { . $PSScriptRoot\..\..\LoadPSD1.ps1 } catch { }
|
||||
|
||||
$xlfile = "$env:TEMP\test.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$data = ConvertFrom-Csv @"
|
||||
Region,Item,TotalSold
|
||||
North,melon,38
|
||||
South,screwdriver,21
|
||||
South,peach,33
|
||||
South,saw,81
|
||||
South,kiwi,70
|
||||
North,orange,59
|
||||
North,avocado,25
|
||||
South,lime,48
|
||||
South,nail,83
|
||||
North,apple,2
|
||||
"@
|
||||
|
||||
$reportTitle = "This is a report Title"
|
||||
$style = New-ExcelStyle -BackgroundColor LightBlue -FontSize 14 -Bold -Range "A1:H1" -HorizontalAlignment Center -Merge
|
||||
$data | Export-Excel $xlfile -Show -AutoSize -AutoFilter -Title $reportTitle -Style $style
|
||||
@@ -1,4 +1,4 @@
|
||||
Import-Module ..\ImportExcel.psd1 -Force
|
||||
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
|
||||
|
||||
$file = "C:\Temp\test.xlsx"
|
||||
|
||||
|
||||
38
Examples/VBA/HelloWorldVBA.ps1
Normal file
38
Examples/VBA/HelloWorldVBA.ps1
Normal file
@@ -0,0 +1,38 @@
|
||||
$xlfile = "$env:temp\test.xlsm"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
|
||||
$Excel = ConvertFrom-Csv @"
|
||||
Region,Item,TotalSold
|
||||
West,screwdriver,98
|
||||
West,kiwi,19
|
||||
North,kiwi,47
|
||||
West,screws,48
|
||||
West,avocado,52
|
||||
East,avocado,40
|
||||
South,drill,61
|
||||
North,orange,92
|
||||
South,drill,29
|
||||
South,saw,36
|
||||
"@ | Export-Excel $xlfile -PassThru -AutoSize
|
||||
|
||||
$wb = $Excel.Workbook
|
||||
$sheet = $wb.Worksheets["Sheet1"]
|
||||
$wb.CreateVBAProject()
|
||||
|
||||
$code = @"
|
||||
Public Function HelloWorld() As String
|
||||
HelloWorld = "Hello World"
|
||||
End Function
|
||||
|
||||
Public Function DoSum() As Integer
|
||||
DoSum = Application.Sum(Range("C:C"))
|
||||
End Function
|
||||
"@
|
||||
|
||||
$module = $wb.VbaProject.Modules.AddModule("PSExcelModule")
|
||||
$module.Code = $code
|
||||
|
||||
Set-Format -WorkSheet $sheet -Range "h7" -Formula "HelloWorld()" -AutoSize
|
||||
Set-Format -WorkSheet $sheet -Range "h8" -Formula "DoSum()" -AutoSize
|
||||
|
||||
Close-ExcelPackage $Excel -Show
|
||||
135
Export-Excel.ps1
135
Export-Excel.ps1
@@ -84,9 +84,9 @@
|
||||
.PARAMETER RangeName
|
||||
Makes the data in the worksheet a named range.
|
||||
.PARAMETER TableName
|
||||
Makes the data in the worksheet a table with a name, and 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
|
||||
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
|
||||
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
|
||||
.PARAMETER ColumnChart
|
||||
@@ -138,7 +138,7 @@
|
||||
.PARAMETER Activate
|
||||
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
|
||||
The -Now switch is a shortcut that automatically creates 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", "TableName" and "Show", and opens the file immediately.
|
||||
.PARAMETER NumberFormat
|
||||
Formats all values that can be converted to a number to the format specified.
|
||||
|
||||
@@ -422,11 +422,11 @@
|
||||
[OutputType([OfficeOpenXml.ExcelPackage])]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||
Param(
|
||||
[Parameter(ParameterSetName = "Default", Position = 0)]
|
||||
[Parameter(ParameterSetName = "Table" , Position = 0)]
|
||||
|
||||
[Parameter(ParameterSetName = 'Default', Position = 0)]
|
||||
[String]$Path,
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageDefault")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "Package")]
|
||||
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
[Parameter(ValueFromPipeline = $true)]
|
||||
[Alias('TargetData')]
|
||||
@@ -462,8 +462,8 @@
|
||||
[Switch]$FreezeFirstColumn,
|
||||
[Switch]$FreezeTopRowFirstColumn,
|
||||
[Int[]]$FreezePane,
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Parameter(ParameterSetName = 'PackageDefault')]
|
||||
|
||||
|
||||
[Switch]$AutoFilter,
|
||||
[Switch]$BoldTopRow,
|
||||
[Switch]$NoHeader,
|
||||
@@ -473,16 +473,11 @@
|
||||
else { $true }
|
||||
})]
|
||||
[String]$RangeName,
|
||||
[ValidateScript( {
|
||||
if (-not $_) { throw 'Tablename is null or empty.' }
|
||||
elseif ($_[0] -notmatch '[a-z]') { throw 'Tablename starts with an invalid character.' }
|
||||
else { $true }
|
||||
})]
|
||||
[Parameter(ParameterSetName = 'Table' , Mandatory = $true, ValueFromPipelineByPropertyName)]
|
||||
[Parameter(ParameterSetName = 'PackageTable' , Mandatory = $true, ValueFromPipelineByPropertyName)]
|
||||
[String]$TableName,
|
||||
[Parameter(ParameterSetName = 'Table')]
|
||||
[Parameter(ParameterSetName = 'PackageTable')]
|
||||
|
||||
|
||||
$TableName,
|
||||
|
||||
|
||||
[OfficeOpenXml.Table.TableStyles]$TableStyle,
|
||||
[Switch]$Barchart,
|
||||
[Switch]$PieChart,
|
||||
@@ -499,6 +494,7 @@
|
||||
[Switch]$AutoNameRange,
|
||||
[Int]$StartRow = 1,
|
||||
[Int]$StartColumn = 1,
|
||||
[alias('PT')]
|
||||
[Switch]$PassThru,
|
||||
[String]$Numberformat = 'General',
|
||||
[string[]]$ExcludeProperty,
|
||||
@@ -507,10 +503,11 @@
|
||||
[String[]]$NoNumberConversion,
|
||||
[Object[]]$ConditionalFormat,
|
||||
[Object[]]$ConditionalText,
|
||||
[Object[]]$Style,
|
||||
[ScriptBlock]$CellStyleSB,
|
||||
#If there is already content in the workbook the sheet with the PivotTable will not be active UNLESS Activate is specified
|
||||
[switch]$Activate,
|
||||
[Parameter(ParameterSetName = 'Now')]
|
||||
[Parameter(ParameterSetName = 'Default')]
|
||||
[Switch]$Now,
|
||||
[Switch]$ReturnRange,
|
||||
#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.
|
||||
@@ -529,12 +526,15 @@
|
||||
try {
|
||||
$script:Header = $null
|
||||
if ($Append -and $ClearSheet) {throw "You can't use -Append AND -ClearSheet."}
|
||||
$TableName = if ($null -eq $TableName -or ($TableName -is [bool] -and $false -eq $TableName)) { $null } else {[String]$TableName}
|
||||
if ($PSBoundParameters.Keys.Count -eq 0 -Or $Now -or (-not $Path -and -not $ExcelPackage) ) {
|
||||
$Path = [System.IO.Path]::GetTempFileName() -replace '\.tmp', '.xlsx'
|
||||
$Show = $true
|
||||
$AutoSize = $true
|
||||
if (-not $TableName) {
|
||||
$AutoFilter = $true
|
||||
if (-not $PSBoundParameters.ContainsKey("Path")) { $Path = [System.IO.Path]::GetTempFileName() -replace '\.tmp', '.xlsx' }
|
||||
if (-not $PSBoundParameters.ContainsKey("Show")) { $Show = $true }
|
||||
if (-not $PSBoundParameters.ContainsKey("AutoSize")) { $AutoSize = $true }
|
||||
if (-not $PSBoundParameters.ContainsKey("TableName") -and
|
||||
-not $PSBoundParameters.ContainsKey("TableStyle") -and
|
||||
-not $AutoFilter) {
|
||||
$TableName = ''
|
||||
}
|
||||
}
|
||||
if ($ExcelPackage) {
|
||||
@@ -576,7 +576,7 @@
|
||||
}
|
||||
|
||||
#if we did not get a table name but there is a table which covers the active part of the sheet, set table name to that, and don't do anything with autofilter
|
||||
if (-not $TableName -and $ws.Tables.Where({$_.address.address -eq $ws.dimension.address})) {
|
||||
if ($null -eq $TableName -and $ws.Tables.Where({$_.address.address -eq $ws.dimension.address})) {
|
||||
$TableName = $ws.Tables.Where({$_.address.address -eq $ws.dimension.address},'First', 1).Name
|
||||
$AutoFilter = $false
|
||||
}
|
||||
@@ -793,9 +793,12 @@
|
||||
Add-ExcelName -RangeName $targetRangeName -Range $ws.Cells[$targetRow, ($StartColumn + $c ), $LastRow, ($StartColumn + $c )]
|
||||
try {#this test can throw with some names, surpress any error
|
||||
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': $_" }
|
||||
@@ -803,14 +806,17 @@
|
||||
#Empty string is not allowed as a name for ranges or tables.
|
||||
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 ($null -ne $TableName) {
|
||||
if ($PSBoundParameters.ContainsKey('TableStyle')) {
|
||||
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
|
||||
}
|
||||
else {Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName}
|
||||
}
|
||||
|
||||
if ($AutoFilter) {
|
||||
elseif ($PSBoundParameters.ContainsKey('TableStyle')) {
|
||||
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName "" -TableStyle $TableStyle
|
||||
}
|
||||
elseif ($AutoFilter) {
|
||||
try {
|
||||
$ws.Cells[$dataRange].AutoFilter = $true
|
||||
Write-Verbose -Message "Enabled autofilter. "
|
||||
@@ -1016,7 +1022,10 @@
|
||||
}
|
||||
catch {throw "Error applying conditional formatting to worksheet $_"}
|
||||
}
|
||||
|
||||
foreach ($s in $Style) {
|
||||
if (-not $s.Range) {$s["Range"] = $ws.Dimension.Address }
|
||||
Set-ExcelRange -WorkSheet $ws @s
|
||||
}
|
||||
if ($CellStyleSB) {
|
||||
try {
|
||||
$TotalRows = $ws.Dimension.Rows
|
||||
@@ -1235,7 +1244,7 @@ function Select-Worksheet {
|
||||
}
|
||||
}
|
||||
|
||||
Function Add-ExcelName {
|
||||
function Add-ExcelName {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Adds a named-range to an existing Excel worksheet.
|
||||
@@ -1299,9 +1308,8 @@ function Add-ExcelTable {
|
||||
#The range of cells to assign to a table.
|
||||
[Parameter(Mandatory=$true)]
|
||||
[OfficeOpenXml.ExcelRange]$Range,
|
||||
#The name for the Table - this should be unqiue in the Workbook.
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$TableName,
|
||||
#The name for the Table - this should be unqiue in the Workbook - auto generated names will be used if this is left empty.
|
||||
[String]$TableName = "",
|
||||
#The Style for the table, by default "Medium6" is used
|
||||
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
|
||||
#By default the header row is shown - it can be turned off with -ShowHeader:$false.
|
||||
@@ -1324,32 +1332,37 @@ function Add-ExcelTable {
|
||||
[Switch]$PassThru
|
||||
)
|
||||
try {
|
||||
if ([OfficeOpenXml.FormulaParsing.ExcelUtilities.ExcelAddressUtil]::IsValidAddress($TableName)) {
|
||||
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
|
||||
if ($TableName -eq "" -or $null -eq $TableName) {
|
||||
$tbl = $Range.Worksheet.Tables.Add($Range, "")
|
||||
}
|
||||
else {
|
||||
$tbl = $ws.Tables.Add($Range, $TableName)
|
||||
Write-Verbose -Message "Defined table '$TableName' at $($Range.Address)"
|
||||
if ([OfficeOpenXml.FormulaParsing.ExcelUtilities.ExcelAddressUtil]::IsValidAddress($TableName)) {
|
||||
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.
|
||||
if ($PSBoundParameters.ContainsKey('ShowHeader')) {$tbl.ShowHeader = [bool]$ShowHeader}
|
||||
@@ -1358,7 +1371,7 @@ function Add-ExcelTable {
|
||||
foreach ($k in $TotalSettings.keys) {
|
||||
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") ) {
|
||||
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]}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
$measure = "Open"
|
||||
)
|
||||
|
||||
$xl = "$env:TEMP\Stocks.xlsx"
|
||||
$xl = Join-Path ([IO.Path]::GetTempPath()) 'Stocks.xlsx'
|
||||
|
||||
Remove-Item $xl -ErrorAction SilentlyContinue
|
||||
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
<#
|
||||
.Synopsis
|
||||
Exports the charts in an Excel spreadSheet
|
||||
Exports the charts in an Excel spreadSheet
|
||||
.Example
|
||||
Export-Charts .\test.xlsx
|
||||
Exports the charts in test.xlsx to JPEG files in the current directory.
|
||||
|
||||
.Example
|
||||
Export-Charts -path .\test,xlsx -destination [System.Environment+SpecialFolder]::MyDocuments -outputType PNG -passthrough
|
||||
Exports the charts to PNG files in MyDocuments , and returns file objects representing the newly created files
|
||||
Export-Charts -path .\test,xlsx -destination [System.Environment+SpecialFolder]::MyDocuments -outputType PNG -passthrough
|
||||
Exports the charts to PNG files in MyDocuments , and returns file objects representing the newly created files
|
||||
|
||||
#>
|
||||
Param (
|
||||
#Path to the Excel file whose chars we will export.
|
||||
$Path = "C:\Users\public\Documents\stats.xlsx",
|
||||
#If specified, output file objects representing the image files
|
||||
[switch]$Passthru,
|
||||
#Format to write - JPG by default
|
||||
#Path to the Excel file whose chars we will export.
|
||||
$Path = "C:\Users\public\Documents\stats.xlsx",
|
||||
#If specified, output file objects representing the image files
|
||||
[switch]$Passthru,
|
||||
#Format to write - JPG by default
|
||||
[ValidateSet("JPG","PNG","GIF")]
|
||||
$OutputType = "JPG",
|
||||
#Folder to write image files to (defaults to same one as the Excel file is in)
|
||||
$OutputType = "JPG",
|
||||
#Folder to write image files to (defaults to same one as the Excel file is in)
|
||||
$Destination
|
||||
)
|
||||
|
||||
#if no output folder was specified, set destination to the folder where the Excel file came from
|
||||
if (-not $Destination) {$Destination = Split-Path -Path $Path -Parent }
|
||||
#if no output folder was specified, set destination to the folder where the Excel file came from
|
||||
if (-not $Destination) {$Destination = Split-Path -Path $Path -Parent }
|
||||
|
||||
#Call up Excel and tell it to open the file.
|
||||
try { $excelApp = New-Object -ComObject "Excel.Application" }
|
||||
catch { Write-Warning "Could not start Excel application - which usually means it is not installed." ; return }
|
||||
#Call up Excel and tell it to open the file.
|
||||
try { $excelApp = New-Object -ComObject "Excel.Application" }
|
||||
catch { Write-Warning "Could not start Excel application - which usually means it is not installed." ; return }
|
||||
|
||||
try { $excelWorkBook = $excelApp.Workbooks.Open($Path) }
|
||||
catch { Write-Warning -Message "Could not Open $Path." ; return }
|
||||
try { $excelWorkBook = $excelApp.Workbooks.Open($Path) }
|
||||
catch { Write-Warning -Message "Could not Open $Path." ; return }
|
||||
|
||||
#For each worksheet, for each chart, jump to the chart, create a filename of "WorksheetName_ChartTitle.jpg", and export the file.
|
||||
#For each worksheet, for each chart, jump to the chart, create a filename of "WorksheetName_ChartTitle.jpg", and export the file.
|
||||
foreach ($excelWorkSheet in $excelWorkBook.Worksheets) {
|
||||
#note somewhat unusual way of telling excel we want all the charts.
|
||||
#note somewhat unusual way of telling excel we want all the charts.
|
||||
foreach ($excelchart in $excelWorkSheet.ChartObjects([System.Type]::Missing)) {
|
||||
#if you don't go to the chart the image will be zero size !
|
||||
#if you don't go to the chart the image will be zero size !
|
||||
$excelApp.Goto($excelchart.TopLeftCell,$true)
|
||||
$imagePath = Join-Path -Path $Destination -ChildPath ($excelWorkSheet.Name + "_" + ($excelchart.Chart.ChartTitle.Text -split "\s\d\d:\d\d,")[0] + ".$OutputType")
|
||||
if ( $excelchart.Chart.Export($imagePath, $OutputType, $false) ) { # Export returs true/false for success/failure
|
||||
if ($Passthru) {Get-Item -Path $imagePath } # when succesful return a file object (-Passthru) or print a verbose message, write warning for any failures
|
||||
if ( $excelchart.Chart.Export($imagePath, $OutputType, $false) ) { # Export returs true/false for success/failure
|
||||
if ($Passthru) {Get-Item -Path $imagePath } # when succesful return a file object (-Passthru) or print a verbose message, write warning for any failures
|
||||
else {Write-Verbose -Message "Exported $imagePath"}
|
||||
}
|
||||
else {Write-Warning -Message "Failure exporting $imagePath" }
|
||||
}
|
||||
else {Write-Warning -Message "Failure exporting $imagePath" }
|
||||
}
|
||||
}
|
||||
$excelApp.DisplayAlerts = $false
|
||||
|
||||
@@ -29,7 +29,7 @@ Function Get-ExcelSheetInfo {
|
||||
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path,'Open','Read','ReadWrite'
|
||||
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
||||
$workbook = $xl.Workbook
|
||||
|
||||
|
||||
if ($workbook -and $workbook.Worksheets) {
|
||||
$workbook.Worksheets |
|
||||
Select-Object -Property name,index,hidden,@{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Function Get-ExcelWorkbookInfo {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieve information of an Excel workbook.
|
||||
.DESCRIPTION
|
||||
.DESCRIPTION
|
||||
The Get-ExcelWorkbookInfo cmdlet retrieves information (LastModifiedBy, LastPrinted, Created, Modified, ...) fron an Excel workbook. These are the same details that are visible in Windows Explorer when right clicking the Excel file, selecting Properties and check the Details tabpage.
|
||||
.PARAMETER Path
|
||||
Specifies the path to the Excel file. This parameter is required.
|
||||
@@ -10,22 +10,22 @@
|
||||
Get-ExcelWorkbookInfo .\Test.xlsx
|
||||
|
||||
CorePropertiesXml : #document
|
||||
Title :
|
||||
Subject :
|
||||
Title :
|
||||
Subject :
|
||||
Author : Konica Minolta User
|
||||
Comments :
|
||||
Keywords :
|
||||
Comments :
|
||||
Keywords :
|
||||
LastModifiedBy : Bond, James (London) GBR
|
||||
LastPrinted : 2017-01-21T12:36:11Z
|
||||
Created : 17/01/2017 13:51:32
|
||||
Category :
|
||||
Status :
|
||||
Category :
|
||||
Status :
|
||||
ExtendedPropertiesXml : #document
|
||||
Application : Microsoft Excel
|
||||
HyperlinkBase :
|
||||
HyperlinkBase :
|
||||
AppVersion : 14.0300
|
||||
Company : Secret Service
|
||||
Manager :
|
||||
Manager :
|
||||
Modified : 10/02/2017 12:45:37
|
||||
CustomPropertiesXml : #document
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
.LINK
|
||||
https://github.com/dfinke/ImportExcel
|
||||
#>
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Alias('FullName')]
|
||||
@@ -52,12 +52,12 @@
|
||||
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
||||
$workbook = $xl.Workbook
|
||||
$workbook.Properties
|
||||
|
||||
|
||||
$stream.Close()
|
||||
$stream.Dispose()
|
||||
$xl.Dispose()
|
||||
$xl = $null
|
||||
}
|
||||
}
|
||||
Catch {
|
||||
throw "Failed retrieving Excel workbook information for '$Path': $_"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ function Get-HtmlTable {
|
||||
)
|
||||
|
||||
$r = Invoke-WebRequest $url -UseDefaultCredentials: $UseDefaultCredentials
|
||||
|
||||
|
||||
$table = $r.ParsedHtml.getElementsByTagName("table")[$tableIndex]
|
||||
$propertyNames=$Header
|
||||
$totalRows=@($table.rows).count
|
||||
@@ -19,7 +19,7 @@ function Get-HtmlTable {
|
||||
for ($idx = $FirstDataRow; $idx -lt $totalRows; $idx++) {
|
||||
|
||||
$row = $table.rows[$idx]
|
||||
$cells = @($row.cells)
|
||||
$cells = @($row.cells)
|
||||
|
||||
if(!$propertyNames) {
|
||||
if($cells[0].tagName -eq 'th') {
|
||||
@@ -28,7 +28,7 @@ function Get-HtmlTable {
|
||||
$propertyNames = @(1..($cells.Count + 2) | Foreach-Object { "P$_" })
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
$result = [ordered]@{}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ function ConvertFrom-ExcelColumnName {
|
||||
$sum
|
||||
}
|
||||
|
||||
ipmo .\ImportExcel.psd1 -Force
|
||||
Import-Module .\ImportExcel.psd1 -Force
|
||||
|
||||
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
|
||||
Get-ExcelTable .\testTable.xlsx Table3
|
||||
@@ -2,19 +2,19 @@
|
||||
function Import-Html {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
$url,
|
||||
$url,
|
||||
$index,
|
||||
$Header,
|
||||
[int]$FirstDataRow=0,
|
||||
[Switch]$UseDefaultCredentials
|
||||
)
|
||||
|
||||
|
||||
$xlFile = [System.IO.Path]::GetTempFileName() -replace "tmp","xlsx"
|
||||
rm $xlFile -ErrorAction Ignore
|
||||
Remove-Item $xlFile -ErrorAction Ignore
|
||||
|
||||
Write-Verbose "Exporting to Excel file $($xlFile)"
|
||||
|
||||
$data = Get-HtmlTable -url $url -tableIndex $index -Header $Header -FirstDataRow $FirstDataRow -UseDefaultCredentials: $UseDefaultCredentials
|
||||
|
||||
|
||||
$data | Export-Excel $xlFile -Show -AutoSize
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
RootModule = 'ImportExcel.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '6.0.0'
|
||||
ModuleVersion = '6.5.0'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
|
||||
@@ -16,7 +16,7 @@
|
||||
CompanyName = 'Doug Finke'
|
||||
|
||||
# Copyright statement for this module
|
||||
Copyright = 'c 2015 All rights reserved.'
|
||||
Copyright = 'c 2019 All rights reserved.'
|
||||
|
||||
# Description of the functionality provided by this module
|
||||
Description = @'
|
||||
@@ -103,6 +103,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5
|
||||
'New-ConditionalFormattingIconSet',
|
||||
'New-ConditionalText',
|
||||
'New-ExcelChartDefinition',
|
||||
'New-ExcelStyle',
|
||||
'New-PivotTableDefinition',
|
||||
'New-Plot',
|
||||
'New-PSItem',
|
||||
@@ -117,6 +118,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5
|
||||
'Set-ExcelColumn',
|
||||
'Set-ExcelRange',
|
||||
'Set-ExcelRow',
|
||||
'Set-WorkSheetProtection',
|
||||
'Test-Boolean',
|
||||
'Test-Date',
|
||||
'Test-Integer',
|
||||
|
||||
187
ImportExcel.psm1
187
ImportExcel.psm1
@@ -4,8 +4,8 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
|
||||
. $PSScriptRoot\AddDataValidation.ps1
|
||||
. $PSScriptRoot\Charting.ps1
|
||||
. $PSScriptRoot\ColorCompletion.ps1
|
||||
. $PSScriptRoot\ConvertExcelToImageFile.ps1
|
||||
. $PSScriptRoot\Compare-WorkSheet.ps1
|
||||
. $PSScriptRoot\ConvertExcelToImageFile.ps1
|
||||
. $PSScriptRoot\ConvertFromExcelData.ps1
|
||||
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
|
||||
. $PSScriptRoot\ConvertToExcelXlsx.ps1
|
||||
@@ -22,7 +22,7 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
|
||||
. $PSScriptRoot\Import-Html.ps1
|
||||
. $PSScriptRoot\InferData.ps1
|
||||
. $PSScriptRoot\Invoke-Sum.ps1
|
||||
. $PSScriptRoot\Join-WorkSheet.ps1
|
||||
. $PSScriptRoot\Join-Worksheet.ps1
|
||||
. $PSScriptRoot\Merge-Worksheet.ps1
|
||||
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
|
||||
. $PSScriptRoot\New-ConditionalText.ps1
|
||||
@@ -31,6 +31,7 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
|
||||
. $PSScriptRoot\Open-ExcelPackage.ps1
|
||||
. $PSScriptRoot\Pivot.ps1
|
||||
. $PSScriptRoot\PivotTable.ps1
|
||||
#. $PSScriptRoot\Plot.ps1
|
||||
. $PSScriptRoot\RemoveWorksheet.ps1
|
||||
. $PSScriptRoot\Send-SQLDataToExcel.ps1
|
||||
. $PSScriptRoot\Set-CellStyle.ps1
|
||||
@@ -48,6 +49,7 @@ if ($PSVersionTable.PSVersion.Major -ge 5) {
|
||||
. $PSScriptRoot\Plot.ps1
|
||||
|
||||
Function New-Plot {
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'New-Plot does not change system state')]
|
||||
Param()
|
||||
|
||||
[PSPlot]::new()
|
||||
@@ -58,6 +60,25 @@ else {
|
||||
Write-Warning 'PowerShell 5 is required for plot.ps1'
|
||||
Write-Warning 'PowerShell Excel is ready, except for that functionality'
|
||||
}
|
||||
if ($IsLinux -or $IsMacOS) {
|
||||
$ExcelPackage = [OfficeOpenXml.ExcelPackage]::new()
|
||||
$Cells = ($ExcelPackage | Add-WorkSheet).Cells['A1']
|
||||
$Cells.Value = 'Test'
|
||||
try {
|
||||
$Cells.AutoFitColumns()
|
||||
}
|
||||
catch {
|
||||
if ($IsLinux) {
|
||||
Write-Warning -Message 'ImportExcel Module Cannot Autosize. Please run the following command to install dependencies: "sudo apt-get install -y --no-install-recommends libgdiplus libc6-dev"'
|
||||
}
|
||||
if ($IsMacOS) {
|
||||
Write-Warning -Message 'ImportExcel Module Cannot Autosize. Please run the following command to install dependencies: "brew install mono-libgdiplus"'
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$ExcelPackage | Close-ExcelPackage -NoSave
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
function Import-Excel {
|
||||
<#
|
||||
@@ -73,7 +94,11 @@ function Import-Excel {
|
||||
|
||||
.PARAMETER Path
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -82,19 +107,15 @@ function Import-Excel {
|
||||
|
||||
.PARAMETER HeaderName
|
||||
Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
.PARAMETER NoHeader
|
||||
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.
|
||||
|
||||
.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.
|
||||
|
||||
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
|
||||
@@ -261,20 +282,27 @@ function Import-Excel {
|
||||
.NOTES
|
||||
#>
|
||||
|
||||
[CmdLetBinding(DefaultParameterSetName)]
|
||||
[CmdLetBinding()]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
|
||||
Param (
|
||||
[Alias('FullName')]
|
||||
[Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0, Mandatory)]
|
||||
[ValidateScript( {(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '.xls$|.xlsx$|.xlsm$')})]
|
||||
[Parameter(ParameterSetName = "PathA", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||
[Parameter(ParameterSetName = "PathB", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||
[Parameter(ParameterSetName = "PathC", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
|
||||
[String]$Path,
|
||||
[Parameter(ParameterSetName = "PackageA", Mandatory)]
|
||||
[Parameter(ParameterSetName = "PackageB", Mandatory)]
|
||||
[Parameter(ParameterSetName = "PackageC", Mandatory)]
|
||||
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
|
||||
[Alias('Sheet')]
|
||||
[Parameter(Position = 1)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$WorksheetName,
|
||||
[Parameter(ParameterSetName = 'B', Mandatory)]
|
||||
[Parameter(ParameterSetName = 'PathB' , Mandatory)]
|
||||
[Parameter(ParameterSetName = 'PackageB', Mandatory)]
|
||||
[String[]]$HeaderName ,
|
||||
[Parameter(ParameterSetName = 'C', Mandatory)]
|
||||
[Parameter(ParameterSetName = 'PathC' , Mandatory)]
|
||||
[Parameter(ParameterSetName = 'PackageC', Mandatory)]
|
||||
[Switch]$NoHeader ,
|
||||
[Alias('HeaderRow', 'TopRow')]
|
||||
[ValidateRange(1, 9999)]
|
||||
@@ -289,14 +317,15 @@ function Import-Excel {
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$Password
|
||||
)
|
||||
Begin {
|
||||
begin {
|
||||
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
Function Get-PropertyNames {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
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 (
|
||||
[Parameter(Mandatory)]
|
||||
[Int[]]$Columns,
|
||||
@@ -309,98 +338,93 @@ function Import-Excel {
|
||||
$i = 0
|
||||
foreach ($C in $Columns) {
|
||||
$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) {
|
||||
$i = 0
|
||||
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++
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($StartRow -eq 0) {
|
||||
throw 'The top row can never be equal to 0 when we need to retrieve headers from the worksheet.'
|
||||
if ($StartRow -lt 1) {
|
||||
throw 'The top row can never be less than 1 when we need to retrieve headers from the worksheet.' ; return
|
||||
}
|
||||
|
||||
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 {
|
||||
throw "Failed creating property names: $_"
|
||||
throw "Failed creating property names: $_" ; return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
#region Open file
|
||||
try {
|
||||
$Path = (Resolve-Path $Path).ProviderPath
|
||||
Write-Verbose "Import Excel workbook '$Path' with worksheet '$Worksheetname'"
|
||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
|
||||
}
|
||||
Catch {throw "Could not open $Path ; $_ "}
|
||||
|
||||
if ($Password) {
|
||||
Try {
|
||||
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
|
||||
$excel.Load( $Stream, $Password)
|
||||
process {
|
||||
if ($path) {
|
||||
$extension = [System.IO.Path]::GetExtension($Path)
|
||||
if ($extension -notmatch '.xlsx$|.xlsm$') {
|
||||
throw "Import-Excel does not support reading this extension type $($extension)"
|
||||
}
|
||||
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."
|
||||
}
|
||||
|
||||
$resolvedPath = (Resolve-Path $Path -ErrorAction SilentlyContinue)
|
||||
if ($resolvedPath) {
|
||||
$Path = $resolvedPath.ProviderPath
|
||||
}
|
||||
else {
|
||||
$Worksheet = $Excel.Workbook.Worksheets | Select-Object -First 1
|
||||
throw "'$($Path)' file not found"
|
||||
}
|
||||
#endregion
|
||||
|
||||
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
|
||||
$ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage
|
||||
if ($Password) { $ExcelPackage.Load($stream,$Password)}
|
||||
else { $ExcelPackage.Load($stream) }
|
||||
}
|
||||
try {
|
||||
#Select worksheet
|
||||
if (-not $WorksheetName) { $Worksheet = $ExcelPackage.Workbook.Worksheets[1] }
|
||||
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
|
||||
}
|
||||
|
||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||
#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 (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row }
|
||||
if (-not $EndColumn) {$EndColumn = $Worksheet.Dimension.End.Column }
|
||||
if (-not $EndRow ) { $EndRow = $Worksheet.Dimension.End.Row }
|
||||
if (-not $EndColumn) { $EndColumn = $Worksheet.Dimension.End.Column }
|
||||
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]", 0, 0)
|
||||
if ($DataOnly) {
|
||||
#If we are using headers startrow will be the headerrow so examine data from startRow + 1,
|
||||
if ($NoHeader) {$range = "A" + ($StartRow ) + ":" + $endAddress }
|
||||
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
|
||||
#If we are using headers startrow will be the header-row so examine data from startRow + 1,
|
||||
if ($NoHeader) { $range = "A" + ($StartRow ) + ":" + $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.
|
||||
#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,
|
||||
#using Hash tables: "we've seen it" is all we need, no need to worry about "seen it before" / "Seen it many times".
|
||||
$colHash = @{}
|
||||
$rowHash = @{}
|
||||
$colHash = @{ }
|
||||
$rowHash = @{ }
|
||||
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[$_]})
|
||||
$columns = ($StartColumn..$EndColumn).Where( {$colHash[$_]})
|
||||
$rows = ( $StartRow..$EndRow ).Where( { $rowHash[$_] })
|
||||
$columns = ($StartColumn..$EndColumn).Where( { $colHash[$_] })
|
||||
}
|
||||
else {
|
||||
$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."} }
|
||||
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."}}
|
||||
$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." } }
|
||||
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
|
||||
#region Create property names
|
||||
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) {
|
||||
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
|
||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||
@@ -412,7 +436,7 @@ function Import-Excel {
|
||||
foreach ($R in $Rows) {
|
||||
#Disabled write-verbose for speed
|
||||
# Write-Verbose "Import row '$R'"
|
||||
$NewRow = [Ordered]@{}
|
||||
$NewRow = [Ordered]@{ }
|
||||
|
||||
foreach ($P in $PropertyNames) {
|
||||
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
|
||||
@@ -425,14 +449,9 @@ function Import-Excel {
|
||||
}
|
||||
Write-Debug $sw.Elapsed.TotalMilliseconds
|
||||
}
|
||||
Catch {
|
||||
throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"
|
||||
}
|
||||
Finally {
|
||||
$Stream.Close()
|
||||
$Stream.Dispose()
|
||||
$Excel.Dispose()
|
||||
$Excel = $null
|
||||
catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return }
|
||||
finally {
|
||||
if ($Path) { $stream.close(); $ExcelPackage.Dispose() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,13 +493,13 @@ function ConvertFrom-ExcelSheet {
|
||||
)
|
||||
|
||||
$Path = (Resolve-Path $Path).Path
|
||||
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, "Open", "Read", "ReadWrite"
|
||||
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
|
||||
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, "Open", "Read", "ReadWrite"
|
||||
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
|
||||
$workbook = $xl.Workbook
|
||||
|
||||
$targetSheets = $workbook.Worksheets | Where-Object {$_.Name -like $SheetName}
|
||||
$targetSheets = $workbook.Worksheets | Where-Object { $_.Name -like $SheetName }
|
||||
|
||||
$params = @{} + $PSBoundParameters
|
||||
$params = @{ } + $PSBoundParameters
|
||||
$params.Remove("OutputPath")
|
||||
$params.Remove("SheetName")
|
||||
$params.Remove('Extension')
|
||||
@@ -494,8 +513,8 @@ function ConvertFrom-ExcelSheet {
|
||||
Import-Excel $Path -Sheet $($sheet.Name) | Export-Csv @params
|
||||
}
|
||||
|
||||
$stream.Close()
|
||||
$stream.Dispose()
|
||||
$Stream.Close()
|
||||
$Stream.Dispose()
|
||||
$xl.Dispose()
|
||||
}
|
||||
|
||||
@@ -511,7 +530,7 @@ function Export-MultipleExcelSheets {
|
||||
[Switch]$AutoSize
|
||||
)
|
||||
|
||||
$parameters = @{} + $PSBoundParameters
|
||||
$parameters = @{ } + $PSBoundParameters
|
||||
$parameters.Remove("InfoMap")
|
||||
$parameters.Remove("Show")
|
||||
|
||||
@@ -524,17 +543,17 @@ function Export-MultipleExcelSheets {
|
||||
& $entry.Value | Export-Excel @parameters
|
||||
}
|
||||
|
||||
if ($Show) {Invoke-Item $Path}
|
||||
if ($Show) { Invoke-Item $Path }
|
||||
}
|
||||
|
||||
Function WorksheetArgumentCompleter {
|
||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||
$xlPath = $fakeBoundParameter['Path']
|
||||
if (Test-Path -Path $xlPath) {
|
||||
$xlpkg = Open-ExcelPackage -Path $xlPath
|
||||
$xlpkg = Open-ExcelPackage -ReadOnly -Path $xlPath
|
||||
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name
|
||||
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 "'$_'",
|
||||
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
|
||||
}
|
||||
|
||||
281
Install.ps1
281
Install.ps1
@@ -1,104 +1,213 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Download the module files from GitHub.
|
||||
|
||||
.DESCRIPTION
|
||||
Download the module files from GitHub to the local client in the module folder.
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs module from Git clone or directly from GitHub.
|
||||
File must not have BOM for GitHub deploy to work.
|
||||
#>
|
||||
|
||||
[CmdLetBinding()]
|
||||
[CmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
Param (
|
||||
# Path to install the module to, if not provided -Scope used.
|
||||
[Parameter(Mandatory, ParameterSetName = 'ModulePath')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$ModuleName = 'ImportExcel',
|
||||
[String]$InstallDirectory,
|
||||
[String]$ModulePath,
|
||||
|
||||
# Path to install the module to, PSModulePath "CurrentUser" or "AllUsers", if not provided "CurrentUser" used.
|
||||
[Parameter(Mandatory, ParameterSetName = 'Scope')]
|
||||
[ValidateSet('CurrentUser', 'AllUsers')]
|
||||
[string]
|
||||
$Scope = 'CurrentUser',
|
||||
|
||||
# Get module from GitHub instead of local Git clone, for example "https://raw.githubusercontent.com/ili101/Module.Template/master/Install.ps1"
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$GitPath = 'https://raw.github.com/dfinke/ImportExcel/master'
|
||||
[Uri]$FromGitHub
|
||||
)
|
||||
# Set Files and Folders patterns to Include/Exclude.
|
||||
$IncludeFiles = @(
|
||||
'*.dll',
|
||||
'*.psd1',
|
||||
'*.psm1',
|
||||
'AddConditionalFormatting.ps1',
|
||||
'AddDataValidation.ps1',
|
||||
'Charting.ps1',
|
||||
'ColorCompletion.ps1',
|
||||
'Compare-WorkSheet.ps1',
|
||||
'ConvertExcelToImageFile.ps1',
|
||||
'ConvertFromExcelData.ps1',
|
||||
'ConvertFromExcelToSQLInsert.ps1',
|
||||
'ConvertToExcelXlsx.ps1',
|
||||
'Copy-ExcelWorkSheet.ps1',
|
||||
'Export-Excel.ps1',
|
||||
'Export-ExcelSheet.ps1',
|
||||
'Export-StocksToExcel.ps1',
|
||||
'Get-ExcelColumnName.ps1',
|
||||
'Get-ExcelSheetInfo.ps1',
|
||||
'Get-ExcelWorkbookInfo.ps1',
|
||||
'Get-HtmlTable.ps1',
|
||||
'Get-Range.ps1',
|
||||
'Get-XYRange.ps1',
|
||||
'Import-Html.ps1',
|
||||
'InferData.ps1',
|
||||
'Invoke-Sum.ps1',
|
||||
'Join-Worksheet.ps1',
|
||||
'Merge-Worksheet.ps1',
|
||||
'New-ConditionalFormattingIconSet.ps1',
|
||||
'New-ConditionalText.ps1',
|
||||
'New-ExcelChart.ps1',
|
||||
'New-PSItem.ps1',
|
||||
'Open-ExcelPackage.ps1',
|
||||
'Pivot.ps1',
|
||||
'PivotTable.ps1',
|
||||
'Plot.ps1',
|
||||
'RemoveWorksheet.ps1',
|
||||
'Send-SQLDataToExcel.ps1',
|
||||
'Set-CellStyle.ps1',
|
||||
'Set-Column.ps1',
|
||||
'Set-Row.ps1',
|
||||
'Set-WorkSheetProtection.ps1',
|
||||
'SetFormat.ps1',
|
||||
'TrackingUtils.ps1',
|
||||
'Update-FirstObjectProperties.ps1'
|
||||
)
|
||||
$ExcludeFiles = @(
|
||||
'Install.ps1'
|
||||
)
|
||||
|
||||
Begin {
|
||||
Try {
|
||||
Write-Verbose "$ModuleName module installation started"
|
||||
|
||||
$Files = @(
|
||||
'AddConditionalFormatting.ps1',
|
||||
'Charting.ps1',
|
||||
'ColorCompletion.ps1',
|
||||
'ConvertFromExcelData.ps1',
|
||||
'ConvertFromExcelToSQLInsert.ps1',
|
||||
'ConvertExcelToImageFile.ps1',
|
||||
'ConvertToExcelXlsx.ps1',
|
||||
'Copy-ExcelWorkSheet.ps1',
|
||||
'EPPlus.dll',
|
||||
'Export-charts.ps1',
|
||||
'Export-Excel.ps1',
|
||||
'Export-ExcelSheet.ps1',
|
||||
'formatting.ps1',
|
||||
'Get-ExcelColumnName.ps1',
|
||||
'Get-ExcelSheetInfo.ps1',
|
||||
'Get-ExcelWorkbookInfo.ps1',
|
||||
'Get-HtmlTable.ps1',
|
||||
'Get-Range.ps1',
|
||||
'Get-XYRange.ps1',
|
||||
'Import-Html.ps1',
|
||||
'ImportExcel.psd1',
|
||||
'ImportExcel.psm1',
|
||||
'InferData.ps1',
|
||||
'Invoke-Sum.ps1',
|
||||
'New-ConditionalFormattingIconSet.ps1',
|
||||
'New-ConditionalText.ps1',
|
||||
'New-ExcelChart.ps1',
|
||||
'New-PSItem.ps1',
|
||||
'Open-ExcelPackage.ps1',
|
||||
'Pivot.ps1',
|
||||
'plot.ps1',
|
||||
'Send-SqlDataToExcel.ps1',
|
||||
'Set-CellStyle.ps1',
|
||||
'Set-Column.ps1',
|
||||
'Set-Row.ps1',
|
||||
'SetFormat.ps1',
|
||||
'TrackingUtils.ps1',
|
||||
'Update-FirstObjectProperties.ps1'
|
||||
)
|
||||
function Invoke-MultiLike {
|
||||
[alias("LikeAny")]
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
$InputObject,
|
||||
[Parameter(Mandatory)]
|
||||
[String[]]$Filters,
|
||||
[Switch]$Not
|
||||
)
|
||||
$FiltersRegex = foreach ($Filter In $Filters) {
|
||||
$Filter = [regex]::Escape($Filter)
|
||||
if ($Filter -match "^\\\*") {
|
||||
$Filter = $Filter.Remove(0, 2)
|
||||
}
|
||||
else {
|
||||
$Filter = '^' + $Filter
|
||||
}
|
||||
if ($Filter -match "\\\*$") {
|
||||
$Filter = $Filter.Substring(0, $Filter.Length - 2)
|
||||
}
|
||||
else {
|
||||
$Filter = $Filter + '$'
|
||||
}
|
||||
$Filter
|
||||
}
|
||||
Catch {
|
||||
throw "Failed installing the module in the install directory '$InstallDirectory': $_"
|
||||
if ($Not) {
|
||||
$InputObject -notmatch ($FiltersRegex -join '|').replace('\*', '.*').replace('\?', '.')
|
||||
}
|
||||
else {
|
||||
$InputObject -match ($FiltersRegex -join '|').replace('\*', '.*').replace('\?', '.')
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
Try {
|
||||
if (-not $InstallDirectory) {
|
||||
Write-Verbose "$ModuleName no installation directory provided"
|
||||
Try {
|
||||
Write-Verbose -Message 'Module installation started'
|
||||
|
||||
$PersonalModules = Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath WindowsPowerShell\Modules
|
||||
|
||||
if (($env:PSModulePath -split ';') -notcontains $PersonalModules) {
|
||||
Write-Warning "$ModuleName personal module path '$PersonalModules' not found in '`$env:PSModulePath'"
|
||||
}
|
||||
|
||||
if (-not (Test-Path $PersonalModules)) {
|
||||
Write-Error "$ModuleName path '$PersonalModules' does not exist"
|
||||
}
|
||||
|
||||
$InstallDirectory = Join-Path -Path $PersonalModules -ChildPath $ModuleName
|
||||
Write-Verbose "$ModuleName default installation directory is '$InstallDirectory'"
|
||||
if (!$ModulePath) {
|
||||
if ($Scope -eq 'CurrentUser') {
|
||||
$ModulePathIndex = 0
|
||||
}
|
||||
|
||||
if (-not (Test-Path $InstallDirectory)) {
|
||||
$null = New-Item -Path $InstallDirectory -ItemType Directory -EA Stop
|
||||
Write-Verbose "$ModuleName created module folder '$InstallDirectory'"
|
||||
else {
|
||||
$ModulePathIndex = 1
|
||||
}
|
||||
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
|
||||
$Files | ForEach-Object {
|
||||
$WebClient.DownloadFile("$GitPath/$_","$installDirectory\$_")
|
||||
Write-Verbose "$ModuleName installed module file '$_'"
|
||||
if ($IsLinux -or $IsMacOS) {
|
||||
$ModulePathSeparator = ':'
|
||||
}
|
||||
|
||||
Write-Verbose "$ModuleName module installation successful"
|
||||
else {
|
||||
$ModulePathSeparator = ';'
|
||||
}
|
||||
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator)[$ModulePathIndex]
|
||||
}
|
||||
Catch {
|
||||
throw "Failed installing the module in the install directory '$InstallDirectory': $_"
|
||||
|
||||
# Get $ModuleName, $TargetPath, [$Links]
|
||||
if ($FromGitHub) {
|
||||
# Fix Could not create SSL/TLS secure channel
|
||||
#$SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol
|
||||
#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$WebClient = [System.Net.WebClient]::new()
|
||||
$GitUri = $FromGitHub.AbsolutePath.Split('/')[1, 2] -join '/'
|
||||
$GitBranch = $FromGitHub.AbsolutePath.Split('/')[3]
|
||||
$Links = (Invoke-RestMethod -Uri "https://api.github.com/repos/$GitUri/contents" -Body @{ref = $GitBranch }) | Where-Object { (LikeAny $_.name $IncludeFiles) -and (LikeAny $_.name $ExcludeFiles -Not) }
|
||||
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension(($Links | Where-Object { $_.name -like '*.psm1' }).name)
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Invoke-WebRequest -Uri ($Links | Where-Object { $_.name -eq "$ModuleName.psd1" }).download_url)))).ModuleVersion
|
||||
}
|
||||
else {
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path $PSScriptRoot))
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path (Join-Path $PSScriptRoot "$ModuleName.psd1") | Out-String)))).ModuleVersion
|
||||
}
|
||||
$TargetPath = Join-Path -Path $ModulePath -ChildPath $ModuleName
|
||||
$TargetPath = Join-Path -Path $TargetPath -ChildPath $ModuleVersion
|
||||
|
||||
# Create Directory
|
||||
if (-not (Test-Path -Path $TargetPath)) {
|
||||
$null = New-Item -Path $TargetPath -ItemType Directory -ErrorAction Stop
|
||||
Write-Verbose -Message ('Created module folder: "{0}"' -f $TargetPath)
|
||||
}
|
||||
|
||||
# Copy Files
|
||||
if ($FromGitHub) {
|
||||
foreach ($Link in $Links) {
|
||||
$TargetPathItem = Join-Path -Path $TargetPath -ChildPath $Link.name
|
||||
if ($Link.type -ne 'dir') {
|
||||
$WebClient.DownloadFile($Link.download_url, $TargetPathItem)
|
||||
Write-Verbose -Message ('Installed module file: "{0}"' -f $Link.name)
|
||||
}
|
||||
else {
|
||||
if (-not (Test-Path -Path $TargetPathItem)) {
|
||||
$null = New-Item -Path $TargetPathItem -ItemType Directory -ErrorAction Stop
|
||||
Write-Verbose -Message 'Created module folder: "{0}"' -f $TargetPathItem
|
||||
}
|
||||
$SubLinks = (Invoke-RestMethod -Uri $Link.git_url -Body @{recursive = '1' }).tree
|
||||
foreach ($SubLink in $SubLinks) {
|
||||
$TargetPathSub = Join-Path -Path $TargetPathItem -ChildPath $SubLink.path
|
||||
if ($SubLink.'type' -EQ 'tree') {
|
||||
if (-not (Test-Path -Path $TargetPathSub)) {
|
||||
$null = New-Item -Path $TargetPathSub -ItemType Directory -ErrorAction Stop
|
||||
Write-Verbose -Message 'Created module folder: "{0}"' -f $TargetPathSub
|
||||
}
|
||||
}
|
||||
else {
|
||||
$WebClient.DownloadFile(
|
||||
('https://raw.githubusercontent.com/{0}/{1}/{2}/{3}' -f $GitUri, $GitBranch, $Link.name, $SubLink.path),
|
||||
$TargetPathSub
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Get-ChildItem -Path $PSScriptRoot -Exclude $ExcludeFiles | Where-Object { LikeAny $_.Name $IncludeFiles } | ForEach-Object {
|
||||
if ($_.Attributes -ne 'Directory') {
|
||||
Copy-Item -Path $_ -Destination $TargetPath
|
||||
Write-Verbose -Message ('Installed module file "{0}"' -f $_)
|
||||
}
|
||||
else {
|
||||
Copy-Item -Path $_ -Destination $TargetPath -Recurse -Force
|
||||
Write-Verbose -Message ('Installed module folder "{0}"' -f $_)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Import Module
|
||||
Write-Verbose -Message "$ModuleName module installation successful to $TargetPath"
|
||||
Import-Module -Name $ModuleName -Force
|
||||
Write-Verbose -Message "Module installed"
|
||||
}
|
||||
Catch {
|
||||
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
|
||||
}
|
||||
finally {
|
||||
#if ($FromGitHub) {
|
||||
# [Net.ServicePointManager]::SecurityProtocol = $SecurityProtocol
|
||||
#}
|
||||
Write-Verbose -Message 'Module installation end'
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
$fullPath = 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel'
|
||||
|
||||
Robocopy . $fullPath /mir /XD .vscode .git examples testimonials images spikes /XF appveyor.yml .gitattributes .gitignore
|
||||
@@ -18,7 +18,7 @@ function Invoke-Sum {
|
||||
$h.$key=[ordered]@{}
|
||||
}
|
||||
|
||||
foreach($m in $measure) {
|
||||
foreach($m in $measure) {
|
||||
$value = $item.$m
|
||||
if($value -is [string] -or $value -is [System.Enum]) {
|
||||
$value = 1
|
||||
@@ -27,15 +27,15 @@ function Invoke-Sum {
|
||||
$h.$key.$m+=$value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($entry in $h.GetEnumerator()){
|
||||
|
||||
|
||||
$nh=[ordered]@{Name=$entry.key}
|
||||
|
||||
|
||||
foreach ($item in $entry.value.getenumerator()) {
|
||||
$nh.($item.key)=$item.value
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[pscustomobject]$nh
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
if((Get-Module -list ImportExcel) -eq $null) {
|
||||
if($null -eq (Get-Module -ListAvailable ImportExcel) ) {
|
||||
Import-Module $PSScriptRoot\ImportExcel.psd1 -force
|
||||
}
|
||||
@@ -316,10 +316,10 @@
|
||||
}
|
||||
|
||||
Function Merge-MultipleSheets {
|
||||
<#
|
||||
.Synopsis
|
||||
<#
|
||||
.Synopsis
|
||||
Merges Worksheets into a single Worksheet with differences marked up.
|
||||
.Description
|
||||
.Description
|
||||
The Merge Worksheet command combines two sheets. Merge-MultipleSheets is
|
||||
designed to merge more than two. So if asked to merge sheets A,B,C which
|
||||
contain Services, with a Name, Displayname and Start mode, where "Name" is
|
||||
@@ -353,30 +353,32 @@ Function Merge-MultipleSheets {
|
||||
sheet. However if Sheet B is the reference sheet, A and C will be seen to
|
||||
have an item removed; and if B is processed before C, the extra item is
|
||||
known when C is processed and so C is considered to be missing that item.
|
||||
.Example
|
||||
.Example
|
||||
dir Server*.xlsx | Merge-MulipleSheets -WorksheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
|
||||
Here we are auditing servers and each one has a workbook in the current
|
||||
directory which contains a "Services" Worksheet (the result of
|
||||
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode)
|
||||
No key is specified so the key is assumed to be the "Name" column.
|
||||
The files are merged and the result is opened on completion.
|
||||
.Example
|
||||
.Example
|
||||
dir Serv*.xlsx | Merge-MulipleSheets -WorksheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
|
||||
The server audit files in the previous example also have "Software" worksheet,
|
||||
but no single field on that sheet works as a key. Specifying "*" for the key
|
||||
produces a compound key using all non-excluded fields (and the installation
|
||||
date and file location are excluded).
|
||||
.Example
|
||||
.Example
|
||||
Merge-MulipleSheets -Path hotfixes.xlsx -WorksheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
|
||||
This time all the servers have written their hotfix information to their own
|
||||
worksheets in a shared Excel workbook named "Hotfixes.xlsx" (the information was
|
||||
obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
|
||||
This ignores any sheets which are not named "Serv*", and uses the HotfixID as
|
||||
the key; in this version the row numbers are hidden.
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
#[Alias("Merge-MulipleSheets")] #There was a spelling error in the first release. This was there to ensure things didn't break but intelisense gave the alias first.
|
||||
param (
|
||||
#>
|
||||
[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)]
|
||||
$Path ,
|
||||
@@ -418,9 +420,9 @@ Function Merge-MultipleSheets {
|
||||
#If specified, opens the output workbook.
|
||||
[Switch]$Show
|
||||
)
|
||||
begin { $filestoProcess = @() }
|
||||
process { $filestoProcess += $Path}
|
||||
end {
|
||||
begin { $filestoProcess = @() }
|
||||
process { $filestoProcess += $Path}
|
||||
end {
|
||||
if ($filestoProcess.Count -eq 1 -and $WorksheetName -match '\*') {
|
||||
Write-Progress -Activity "Merging sheets" -CurrentOperation "Expanding * to names of sheets in $($filestoProcess[0]). "
|
||||
$excel = Open-ExcelPackage -Path $filestoProcess
|
||||
@@ -532,5 +534,5 @@ Function Merge-MultipleSheets {
|
||||
if ($Passthru) {$excel}
|
||||
else {Close-ExcelPackage -ExcelPackage $excel -Show:$Show}
|
||||
Write-Progress -Activity "Merging sheets" -Completed
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ function New-ConditionalFormattingIconSet {
|
||||
Add-Add-ConditionalFormatting
|
||||
New-ConditionalText
|
||||
#>
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Range,
|
||||
|
||||
@@ -39,11 +39,11 @@ function New-ConditionalText {
|
||||
"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
|
||||
Add-ConditionalFormatting
|
||||
New-ConditionalFormattingIconSet
|
||||
#>
|
||||
|
||||
[cmdletbinding()]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||
param(
|
||||
#[Parameter(Mandatory=$true)]
|
||||
[Alias("ConditionValue")]
|
||||
|
||||
@@ -97,10 +97,12 @@
|
||||
#>
|
||||
[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()]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Does not change system State')]
|
||||
param(
|
||||
$Title = "Chart Title",
|
||||
$Header,
|
||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
|
||||
[OfficeOpenXml.Drawing.Chart.eTrendLine[]]$ChartTrendLine,
|
||||
$XRange,
|
||||
$YRange,
|
||||
$Width = 500,
|
||||
@@ -137,11 +139,12 @@
|
||||
$YMinValue,
|
||||
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition
|
||||
)
|
||||
if ( $Header ) {Write-Warning "The header parameter is ignored."} #Nothing was done with it when creating a chart.
|
||||
if ( $Header ) { Write-Warning "The header parameter is ignored." } #Nothing was done with it when creating a chart.
|
||||
#might be able to do [PSCustomObject]$PsboundParameters, the defaults here match those in Add-Excel Chart
|
||||
[PSCustomObject]@{
|
||||
Title = $Title
|
||||
ChartType = $ChartType
|
||||
ChartTrendLine = $ChartTrendLine
|
||||
XRange = $XRange
|
||||
YRange = $YRange
|
||||
Width = $Width
|
||||
@@ -150,14 +153,14 @@
|
||||
RowOffSetPixels = $RowOffSetPixels
|
||||
Column = $Column
|
||||
ColumnOffSetPixels = $ColumnOffSetPixels
|
||||
LegendPosition = $LegendPosition
|
||||
LegendPosition = $LegendPosition
|
||||
LegendSize = $LegendSize
|
||||
Legendbold = $LegendBold
|
||||
NoLegend = $NoLegend -as [Boolean]
|
||||
NoLegend = $NoLegend -as [Boolean]
|
||||
ShowCategory = $ShowCategory -as [Boolean]
|
||||
ShowPercent = $ShowPercent -as [Boolean]
|
||||
ShowPercent = $ShowPercent -as [Boolean]
|
||||
SeriesHeader = $SeriesHeader
|
||||
TitleBold = $TitleBold -as [Boolean]
|
||||
TitleBold = $TitleBold -as [Boolean]
|
||||
TitleSize = $TitleSize
|
||||
XAxisTitleText = $XAxisTitleText
|
||||
XAxisTitleBold = $XAxisTitleBold -as [Boolean]
|
||||
@@ -169,7 +172,7 @@
|
||||
XMinValue = $XMinValue
|
||||
XAxisPosition = $XAxisPosition
|
||||
YAxisTitleText = $YAxisTitleText
|
||||
YAxisTitleBold = $YAxisTitleBold -as [Boolean]
|
||||
YAxisTitleBold = $YAxisTitleBold -as [Boolean]
|
||||
YAxisTitleSize = $YAxisTitleSize
|
||||
YAxisNumberformat = $YAxisNumberformat
|
||||
YMajorUnit = $YMajorUnit
|
||||
@@ -325,24 +328,25 @@ function Add-ExcelChart {
|
||||
and is marked off in units of 0.25 shown to two decimal places.
|
||||
The key will for the chart will be at the bottom in 8 point bold type and the line will be named "Sin(x)".
|
||||
#>
|
||||
[cmdletbinding(DefaultParameterSetName='Worksheet')]
|
||||
[cmdletbinding(DefaultParameterSetName = 'Worksheet')]
|
||||
[OutputType([OfficeOpenXml.Drawing.Chart.ExcelChart])]
|
||||
param(
|
||||
[Parameter(ParameterSetName='Workshet',Mandatory=$true)]
|
||||
[Parameter(ParameterSetName = 'Workshet', Mandatory = $true)]
|
||||
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
|
||||
[Parameter(ParameterSetName='PivotTable',Mandatory=$true)]
|
||||
[Parameter(ParameterSetName = 'PivotTable', Mandatory = $true)]
|
||||
[OfficeOpenXml.Table.PivotTable.ExcelPivotTable]$PivotTable ,
|
||||
[String]$Title,
|
||||
#$Header, Not used but referenced previously
|
||||
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
|
||||
[OfficeOpenXml.Drawing.Chart.eTrendLine[]]$ChartTrendLine,
|
||||
$XRange,
|
||||
$YRange,
|
||||
[int]$Width = 500,
|
||||
[int]$Height = 350,
|
||||
[int]$Row = 0,
|
||||
[int]$RowOffSetPixels = 10,
|
||||
[int]$Column = 6,
|
||||
[int]$ColumnOffSetPixels = 5,
|
||||
[int]$Width = 500,
|
||||
[int]$Height = 350,
|
||||
[int]$Row = 0,
|
||||
[int]$RowOffSetPixels = 10,
|
||||
[int]$Column = 6,
|
||||
[int]$ColumnOffSetPixels = 5,
|
||||
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
|
||||
$LegendSize,
|
||||
[Switch]$LegendBold,
|
||||
@@ -371,11 +375,11 @@ function Add-ExcelChart {
|
||||
$YMinValue,
|
||||
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition,
|
||||
[Switch]$PassThru
|
||||
)
|
||||
)
|
||||
try {
|
||||
if ($PivotTable) {
|
||||
$Worksheet = $PivotTable.WorkSheet
|
||||
$chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ),$ChartType,$PivotTable)
|
||||
$chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ), $ChartType, $PivotTable)
|
||||
}
|
||||
else {
|
||||
$ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', ''
|
||||
@@ -383,75 +387,85 @@ function Add-ExcelChart {
|
||||
$chartDefCount = @($YRange).Count
|
||||
if ($chartDefCount -eq 1) {
|
||||
$Series = $chart.Series.Add($YRange, $XRange)
|
||||
if ($SeriesHeader) { $Series.Header = $SeriesHeader}
|
||||
else { $Series.Header = 'Series 1'}
|
||||
if ($ChartTrendLine) {
|
||||
if ($ChartType -notmatch "stacked|3D$|pie|Doughnut|Cone|Cylinder|Pyramid") {
|
||||
foreach ($trendLine in $ChartTrendLine) {
|
||||
$null = $Series.TrendLines.Add($trendLine)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Warning "Chart trend line is not supported for chart type: $ChartType"
|
||||
}
|
||||
}
|
||||
if ($SeriesHeader) { $Series.Header = $SeriesHeader }
|
||||
else { $Series.Header = 'Series 1' }
|
||||
}
|
||||
else {
|
||||
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
|
||||
if ($Yrange.count -eq $xrange.count) {
|
||||
$Series = $chart.Series.Add($YRange[$idx], $XRange[$idx])
|
||||
$Series = $chart.Series.Add($YRange[$idx], $XRange[$idx])
|
||||
}
|
||||
else {
|
||||
$Series = $chart.Series.Add($YRange[$idx], $XRange)
|
||||
$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] }
|
||||
if ($SeriesHeader[$idx] -match '^=') { $Series.HeaderAddress = $SeriesHeader[$idx] -replace '^=', '' }
|
||||
else { $Series.Header = $SeriesHeader[$idx] }
|
||||
}
|
||||
else { $Series.Header = "Series $($idx)"}
|
||||
else { $Series.Header = "Series $($idx)" }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Title) {
|
||||
$chart.Title.Text = $Title
|
||||
if ($TitleBold) {$chart.Title.Font.Bold = $true}
|
||||
if ($TitleSize) {$chart.Title.Font.Size = $TitleSize}
|
||||
if ($TitleBold) { $chart.Title.Font.Bold = $true }
|
||||
if ($TitleSize) { $chart.Title.Font.Size = $TitleSize }
|
||||
}
|
||||
if ($NoLegend) { $chart.Legend.Remove() }
|
||||
else {
|
||||
if ($PSBoundParameters.ContainsKey('LegendPosition')) {$chart.Legend.Position = $LegendPosition}
|
||||
if ($PSBoundParameters.ContainsKey('LegendBold')) {$chart.Legend.Font.Bold = [boolean]$LegendBold}
|
||||
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
|
||||
if ($PSBoundParameters.ContainsKey('LegendPosition')) { $chart.Legend.Position = $LegendPosition }
|
||||
if ($PSBoundParameters.ContainsKey('LegendBold')) { $chart.Legend.Font.Bold = [boolean]$LegendBold }
|
||||
if ($LegendSize) { $chart.Legend.Font.Size = $LegendSize }
|
||||
}
|
||||
|
||||
if ($XAxisTitleText) {
|
||||
if ($XAxisTitleText) {
|
||||
$chart.XAxis.Title.Text = $XAxisTitleText
|
||||
if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) {
|
||||
$chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold
|
||||
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" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
|
||||
if ($XMajorUnit) {$chart.XAxis.MajorUnit = $XMajorUnit}
|
||||
if ($XMinorUnit) {$chart.XAxis.MinorUnit = $XMinorUnit}
|
||||
if ($null -ne $XMinValue) {$chart.XAxis.MinValue = $XMinValue}
|
||||
if ($null -ne $XMaxValue) {$chart.XAxis.MaxValue = $XMaxValue}
|
||||
if ($XAxisNumberformat) {$chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat)}
|
||||
if ($XAxisPosition) { Write-Warning "X-axis position is not being set propertly at the moment, parameter ignored" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
|
||||
if ($XMajorUnit) { $chart.XAxis.MajorUnit = $XMajorUnit }
|
||||
if ($XMinorUnit) { $chart.XAxis.MinorUnit = $XMinorUnit }
|
||||
if ($null -ne $XMinValue) { $chart.XAxis.MinValue = $XMinValue }
|
||||
if ($null -ne $XMaxValue) { $chart.XAxis.MaxValue = $XMaxValue }
|
||||
if ($XAxisNumberformat) { $chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat) }
|
||||
|
||||
if ($YAxisTitleText) {
|
||||
if ($YAxisTitleText) {
|
||||
$chart.YAxis.Title.Text = $YAxisTitleText
|
||||
if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) {
|
||||
$chart.YAxis.Title.Font.Bold = [boolean]$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" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
|
||||
if ($YMajorUnit) {$chart.YAxis.MajorUnit = $YMajorUnit}
|
||||
if ($YMinorUnit) {$chart.YAxis.MinorUnit = $YMinorUnit}
|
||||
if ($null -ne $YMinValue){$chart.YAxis.MinValue = $YMinValue}
|
||||
if ($null -ne $YMaxValue){$chart.YAxis.MaxValue = $YMaxValue}
|
||||
if ($YAxisNumberformat) {$chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat)}
|
||||
if ($YAxisPosition) { Write-Warning "Y-axis position is not being set propertly at the moment, parameter ignored" }
|
||||
#$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
|
||||
if ($YMajorUnit) { $chart.YAxis.MajorUnit = $YMajorUnit }
|
||||
if ($YMinorUnit) { $chart.YAxis.MinorUnit = $YMinorUnit }
|
||||
if ($null -ne $YMinValue) { $chart.YAxis.MinValue = $YMinValue }
|
||||
if ($null -ne $YMaxValue) { $chart.YAxis.MaxValue = $YMaxValue }
|
||||
if ($YAxisNumberformat) { $chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat) }
|
||||
if ($null -ne $chart.Datalabel) {
|
||||
$chart.Datalabel.ShowCategory = [boolean]$ShowCategory
|
||||
$chart.Datalabel.ShowPercent = [boolean]$ShowPercent
|
||||
$chart.Datalabel.ShowCategory = [boolean]$ShowCategory
|
||||
$chart.Datalabel.ShowPercent = [boolean]$ShowPercent
|
||||
}
|
||||
|
||||
$chart.SetPosition($Row, $RowOffsetPixels, $Column, $ColumnOffsetPixels)
|
||||
$chart.SetSize($Width, $Height)
|
||||
|
||||
if ($PassThru) {return $chart}
|
||||
if ($PassThru) { return $chart }
|
||||
}
|
||||
catch {Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_"}
|
||||
catch { Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_" }
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='New*', Justification='Does not change system State')]
|
||||
param()
|
||||
function New-PSItem {
|
||||
|
||||
$totalArgs = $args.Count
|
||||
|
||||
@@ -272,8 +272,11 @@
|
||||
Write-Warning -Message "PivotTable defined in $($pivotTableName) already exists, only the data range will be changed."
|
||||
$pivotTable = $wsPivot.PivotTables[$pivotTableName]
|
||||
if (-not $SourceRange) { $SourceRange = $SourceWorkSheet.Dimension.Address}
|
||||
$pivotTable.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref = $SourceRange
|
||||
}
|
||||
$pivotTable.CacheDefinition.SourceRange = $SourceWorkSheet.cells[$SourceRange]
|
||||
#change for epPlus 4.5 - Previously needed to hack the xml
|
||||
# $pivotTable.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref = $SourceRange
|
||||
|
||||
}
|
||||
|
||||
#Create the chart if it doesn't exist, leave alone if it does.
|
||||
if ($IncludePivotChart -and -not $wsPivot.Drawings["Chart$pivotTableName"] ) {
|
||||
@@ -312,6 +315,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.
|
||||
#>
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[Alias("PivtoTableName")]#Previous typo - use alias to avoid breaking scripts
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="False positives")]
|
||||
param()
|
||||
class PSPlot {
|
||||
hidden $path
|
||||
hidden $pkg
|
||||
hidden $pkg
|
||||
hidden $ws
|
||||
hidden $chart
|
||||
|
||||
@@ -11,62 +13,62 @@ class PSPlot {
|
||||
}
|
||||
|
||||
[PSPlot] Plot($yValues) {
|
||||
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
|
||||
$xValues = 0..$yValues.Count
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
$this.SetChartPosition($yCol)
|
||||
|
||||
|
||||
return $this
|
||||
}
|
||||
|
||||
[PSPlot] Plot($yValues,[string]$options) {
|
||||
$this.NewChart()
|
||||
|
||||
|
||||
$xValues = 0..$yValues.Count
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
|
||||
$this.SetMarkerInfo($options)
|
||||
$this.SetMarkerInfo($options)
|
||||
$this.SetChartPosition($yCol)
|
||||
|
||||
return $this
|
||||
}
|
||||
|
||||
[PSPlot] Plot($xValues,$yValues) {
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
|
||||
$this.SetChartPosition($yCol)
|
||||
|
||||
return $this
|
||||
}
|
||||
|
||||
|
||||
[PSPlot] Plot($xValues,$yValues,[string]$options) {
|
||||
$this.NewChart()
|
||||
$this.NewChart()
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
|
||||
|
||||
$this.SetMarkerInfo($options)
|
||||
|
||||
$this.SetChartPosition($yCol)
|
||||
@@ -75,19 +77,19 @@ class PSPlot {
|
||||
}
|
||||
|
||||
[PSPlot] Plot($xValues,$yValues,$x1Values,$y1Values) {
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
|
||||
$xCol=$this.GetNextColumnName($yCol)
|
||||
$yCol=$this.GetNextColumnName($xCol)
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x1','y1',$x1Values,$y1Values)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x1','y1',$x1Values,$y1Values)
|
||||
$this.AddSeries($xCol,$yCol,$y1Values)
|
||||
|
||||
$this.SetChartPosition($yCol)
|
||||
@@ -96,32 +98,32 @@ class PSPlot {
|
||||
}
|
||||
|
||||
[PSPlot] Plot($xValues,$yValues,$x1Values,$y1Values,$x2Values,$y2Values) {
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$this.NewChart()
|
||||
|
||||
$xCol = 'A'
|
||||
$yCol = 'B'
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x','y',$xValues,$yValues)
|
||||
$this.AddSeries($xCol,$yCol,$yValues)
|
||||
|
||||
$xCol=$this.GetNextColumnName($yCol)
|
||||
$yCol=$this.GetNextColumnName($xCol)
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x1','y1',$x1Values,$y1Values)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x1','y1',$x1Values,$y1Values)
|
||||
$this.AddSeries($xCol,$yCol,$y1Values)
|
||||
|
||||
$xCol=$this.GetNextColumnName($yCol)
|
||||
$yCol=$this.GetNextColumnName($xCol)
|
||||
|
||||
$this.AddDataToSheet($xCol,$yCol,'x2','y2',$x2Values,$y2Values)
|
||||
$this.AddDataToSheet($xCol,$yCol,'x2','y2',$x2Values,$y2Values)
|
||||
$this.AddSeries($xCol,$yCol,$y2Values)
|
||||
|
||||
$this.SetChartPosition($yCol)
|
||||
|
||||
return $this
|
||||
}
|
||||
|
||||
|
||||
[PSPLot] SetChartPosition($yCol) {
|
||||
$columnNumber = $this.GetColumnNumber($yCol)+1
|
||||
$this.chart.SetPosition(1,0,$columnNumber,0)
|
||||
@@ -131,29 +133,29 @@ class PSPlot {
|
||||
|
||||
AddSeries($xCol,$yCol,$yValues) {
|
||||
$yRange = "{0}2:{0}{1}" -f $yCol,($yValues.Count+1)
|
||||
$xRange = "{0}2:{0}{1}" -f $xCol,($yValues.Count+1)
|
||||
$Series=$this.chart.Series.Add($yRange,$xRange)
|
||||
$xRange = "{0}2:{0}{1}" -f $xCol,($yValues.Count+1)
|
||||
$Series=$this.chart.Series.Add($yRange,$xRange)
|
||||
}
|
||||
|
||||
hidden SetMarkerInfo([string]$options) {
|
||||
$c=$options.Substring(0,1)
|
||||
$m=$options.Substring(1)
|
||||
|
||||
|
||||
$cmap=@{r='red';g='green';b='blue';i='indigo';v='violet';c='cyan'}
|
||||
$mmap=@{Ci='Circle';Da='Dash';di='diamond';do='dot';pl='plus';sq='square';tr='triangle'}
|
||||
|
||||
|
||||
$this.chart.Series[0].Marker = $mmap.$m
|
||||
$this.chart.Series[0].MarkerColor = $cmap.$c
|
||||
$this.chart.Series[0].MarkerLineColor = $cmap.$c
|
||||
}
|
||||
|
||||
hidden [string]GetNextColumnName($columnName) {
|
||||
return $this.GetColumnName($this.GetColumnNumber($columnName)+1)
|
||||
return $this.GetColumnName($this.GetColumnNumber($columnName)+1)
|
||||
}
|
||||
|
||||
hidden [int]GetColumnNumber($columnName) {
|
||||
$sum=0
|
||||
|
||||
|
||||
$columnName.ToCharArray() |
|
||||
ForEach-Object {
|
||||
$sum*=26
|
||||
@@ -179,20 +181,20 @@ class PSPlot {
|
||||
$count=$yValues.Count
|
||||
$this.ws.Cells["$($xColumn)1"].Value=$xHeader
|
||||
$this.ws.Cells["$($yColumn)1"].Value=$yHeader
|
||||
|
||||
for ($idx= 0; $idx-lt $count; $idx++) {
|
||||
$row=$idx+2
|
||||
|
||||
for ($idx= 0; $idx-lt $count; $idx++) {
|
||||
$row=$idx+2
|
||||
$this.ws.Cells["$($xColumn)$($row)"].Value=$xValues[$idx]
|
||||
$this.ws.Cells["$($yColumn)$($row)"].Value=$yValues[$idx]
|
||||
}
|
||||
}
|
||||
|
||||
hidden NewChart() {
|
||||
hidden NewChart() {
|
||||
$chartType="XYScatter"
|
||||
#$chartType="line"
|
||||
$this.chart=$this.ws.Drawings.AddChart("plot", $chartType)
|
||||
$this.chart.Title.Text = 'Plot'
|
||||
$this.chart.Legend.Remove()
|
||||
$this.chart.Legend.Remove()
|
||||
$this.SetChartSize(300,300)
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
$p = @{
|
||||
Name = "ImportExcel"
|
||||
NuGetApiKey = $NuGetApiKey
|
||||
ReleaseNote = "Add NumberFormat parameter"
|
||||
}
|
||||
|
||||
Publish-Module @p
|
||||
95
README.md
95
README.md
@@ -7,23 +7,21 @@ If this project helped you reduce the time to get your job done, let me know.
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<p align="center">
|
||||
<a href="https://ci.appveyor.com/project/dfinke/importexcel/branch/master"><img src="https://ci.appveyor.com/api/projects/status/21hko6eqtpccrkba/branch/master?svg=true"></a>
|
||||
<a href="https://dougfinke.visualstudio.com/ImportExcel/_build?definitionId=10"><img src="https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/ImportExcel-CI?branchName=master"></a>
|
||||
<p>
|
||||
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img src="https://img.shields.io/powershellgallery/v/ImportExcel.svg"></a>
|
||||
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img src="https://img.shields.io/powershellgallery/dt/ImportExcel.svg"></a>
|
||||
<a href="./LICENSE.txt"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="./LICENSE.txt"><img
|
||||
src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>
|
||||
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img
|
||||
src="https://img.shields.io/powershellgallery/dt/ImportExcel.svg"></a>
|
||||
<a href="https://www.powershellgallery.com/packages/ImportExcel"><img
|
||||
src="https://img.shields.io/powershellgallery/v/ImportExcel.svg"></a>
|
||||
</p>
|
||||
| CI System | Environment | Status |
|
||||
|--------------|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| AppVeyor | Windows, Core preview, Ubuntu | [](https://ci.appveyor.com/project/dfinke/importexcel/branch/master) |
|
||||
| Azure DevOps | Windows | [](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
|
||||
| Azure DevOps | Windows (Core) | [](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
|
||||
| Azure DevOps | Ubuntu | [](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
|
||||
| Azure DevOps | macOS | [](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
|
||||
|
||||
<!-- /BADGES -->
|
||||
|
||||
@@ -37,7 +35,8 @@ This PowerShell Module allows you to read and write Excel files without installi
|
||||

|
||||
|
||||
# How to Videos
|
||||
* [PowerShell Excel Module - ImportExcel](https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5uoqS92stXioZw-u-ze_NtvSo0k0K0kq)
|
||||
|
||||
* [PowerShell Excel Module - ImportExcel](https://www.youtube.com/watch?v=fvKKdIzJCws&list=PL5uoqS92stXioZw-u-ze_NtvSo0k0K0kq)
|
||||
|
||||
Installation
|
||||
-
|
||||
@@ -53,6 +52,72 @@ Install-Module ImportExcel -scope CurrentUser
|
||||
Install-Module ImportExcel
|
||||
```
|
||||
|
||||
# What's new 6.5.0
|
||||
|
||||
This is now using the latest version of EPPlus. Unit tests are updated and passing, if you hit problems, please open an issue.
|
||||
You can rollback to an older version from the PowerShell Gallery if you are blocked.
|
||||
|
||||
- Unit tests were updated and fixed
|
||||
- "Set-WorksheetProtection" is now switched on
|
||||
- Made a change to make Set-Excel range more friendly when Auto Sizing on non-windows platforms
|
||||
- Fixed - Windows only tests don't attempt to run on non-windows systems
|
||||
- Tests based on Get-Process don't attempt to run if <20 processes are returned
|
||||
- If $env:TEMP is not set (as will be the case on Linux)
|
||||
- Join-Path if used so paths are built with / or with \ as suits the OS where the test is running.
|
||||
- Excel Sparklines now supported, check out the examples [SalesByQuarter](https://github.com/dfinke/ImportExcel/blob/master/Examples/Sparklines/SalesByQuarter.ps1) and [Sparklines](https://github.com/dfinke/ImportExcel/blob/master/Examples/Sparklines/Sparklines.ps1).
|
||||
|
||||

|
||||
|
||||
|
||||
# What's new 6.2.4
|
||||
|
||||
Sensible parameter defaults, make your life easier and gets things done faster.
|
||||
|
||||
- Thank you to [DomRRuggeri](https://github.com/DomRRuggeri) for the initial Out-Excel PR and kicking off the conversation on the improvements.
|
||||
- Thank you to [ili101](https://github.com/ili101) for refactoring and improving the defaults, and adding the tests for parameters.
|
||||
|
||||
- Creates a table, with filtering
|
||||
- Chooses a `TableStyle`
|
||||
- Displays the Excel spreadsheet automatically
|
||||
|
||||
```powershell
|
||||
Get-Process | select Company, Name, Handles | Export-Excel
|
||||
```
|
||||
|
||||

|
||||
|
||||
# What's new 6.2.3
|
||||
|
||||
Thank you [jhoneill](https://github.com/jhoneill).
|
||||
|
||||
- Refactored copy sheet and added pipe support
|
||||
- Add `ClearAll` to `Set-ExcelRange`
|
||||
- Fix broken test & regression for `passwords`
|
||||
- **Note**: Passwords do not work on `pwsh`. The EPPlus library does not support these dotnet core APIs at this time.
|
||||
|
||||
# What's new 6.2.2
|
||||
|
||||
- Added requested feature, chart trendlines.
|
||||
- [Example PowerShell script](https://github.com/dfinke/ImportExcel/blob/master/Examples/Charts/NumberOfVisitors.ps1)
|
||||
|
||||

|
||||
|
||||
- Fixed Import-Excel and relative path issue, added unit tests.
|
||||
|
||||
# What's new 6.2.0
|
||||
Thank you to [James O'Neill](https://github.com/jhoneill)
|
||||
|
||||
- Fixed, Import-Excel can read xlsx files even if already open in Excel
|
||||
- Added `New-ExcelStyle`, plus `-Style` to `Export-Excel` and `-Merge` to `Set-ExcelRange`
|
||||
- Added [Style Examples](https://github.com/dfinke/ImportExcel/tree/master/Examples/Styles)
|
||||
|
||||

|
||||
|
||||
# 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.
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
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)]
|
||||
@@ -34,9 +35,10 @@
|
||||
|
||||
if ($pkg) {
|
||||
foreach ($wsn in $WorksheetName) {
|
||||
$pkg.Workbook.Worksheets.Delete($wsn)
|
||||
if ($PSCmdlet.ShouldProcess($FullName,"Remove Sheet $wsn")) {
|
||||
$pkg.Workbook.Worksheets.Delete($wsn)
|
||||
}
|
||||
}
|
||||
|
||||
Close-ExcelPackage -ExcelPackage $pkg -Show:$Show
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
Export-Excel
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName="none")]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Justification="Allowed to use DBSessions Global variable from GETSQL Module")]
|
||||
|
||||
param (
|
||||
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
|
||||
[Parameter(ParameterSetName="ODBCConnection", Mandatory=$true)]
|
||||
@@ -1,4 +1,7 @@
|
||||
function Set-CellStyle {
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='Set*', Justification='Does not change system state')]
|
||||
param()
|
||||
|
||||
function Set-CellStyle {
|
||||
param(
|
||||
$WorkSheet,
|
||||
$Row,
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
"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.
|
||||
When a value begins with "=", it is treated as a formula.
|
||||
If value is a script block it will be evaluated, so here the string "=E$row/C$Row"
|
||||
will have the number of the current row inserted. See the value parameter for a list of
|
||||
variables which can be used. Note than when evaluating an expression in a string,
|
||||
it is necessary to wrap it in $() so $row is valid but $($row+1) is needed. To prevent
|
||||
Variables merging into other parts of the string, use the back tick "$columnName`4" will
|
||||
be "G4" - withouth the backtick the string will look for a variable named "columnName4"
|
||||
|
||||
.EXAMPLE
|
||||
Set-ExcelColumn -Worksheet $ws -Heading "Link" -Value {"https://en.wikipedia.org" + $worksheet.cells["B$Row"].value } -AutoSize
|
||||
|
||||
@@ -44,6 +52,8 @@
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Column")]
|
||||
[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 (
|
||||
#If specifying the worksheet by name, the ExcelPackage object which contains the worksheet also needs to be passed.
|
||||
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||
@@ -138,7 +148,7 @@
|
||||
process {
|
||||
if ($null -eq $workSheet.Dimension) {Write-Warning "Can't format an empty worksheet."; return}
|
||||
if ($Column -eq 0 ) {$Column = $endColumn + 1 }
|
||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
$columnName = (New-Object 'OfficeOpenXml.ExcelCellAddress' @(1, $column)).Address -replace "1",""
|
||||
Write-Verbose -Message "Updating Column $columnName"
|
||||
#If there is a heading, insert it and use it as the name for a range (if we're creating one)
|
||||
if ($PSBoundParameters.ContainsKey('Heading')) {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
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 endof the data in
|
||||
Set-ExcelRow will select the next row after the end of the data in
|
||||
the sheet. The first cell in the row will contain "Total", and
|
||||
each of the other cells will contain
|
||||
=Sum(xx2:xx99)
|
||||
@@ -33,6 +33,8 @@
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Row")]
|
||||
[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 (
|
||||
#An Excel package object - e.g. from Export-Excel -PassThru - requires a sheet name.
|
||||
[Parameter(ParameterSetName="Package",Mandatory=$true)]
|
||||
@@ -143,7 +145,7 @@
|
||||
#Fill in the data
|
||||
if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) {
|
||||
#We might want the column name in a script block
|
||||
$columnName = [OfficeOpenXml.ExcelCellAddress]::new(1,$column).Address -replace "1",""
|
||||
$columnName = (New-Object -TypeName OfficeOpenXml.ExcelCellAddress @(1,$column)).Address -replace "1",""
|
||||
if ($Value -is [scriptblock] ) {
|
||||
#re-create the script block otherwise variables from this function are out of scope.
|
||||
$cellData = & ([scriptblock]::create( $Value ))
|
||||
@@ -177,7 +179,7 @@
|
||||
if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]}
|
||||
}
|
||||
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
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
|
||||
.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
|
||||
Turns on protection for the worksheet in $planSheet, checks all the allow boxes except 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)]
|
||||
@@ -47,7 +48,7 @@
|
||||
[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"
|
||||
#Address range for cells to lock in the form "A:Z" or "1:10" or "A1:Z10". If No range is specified, the whole sheet is locked by default.
|
||||
[string]$LockAddress,
|
||||
#Address range for cells to Unlock in the form "A:Z" or "1:10" or "A1:Z10"
|
||||
[string]$UnLockAddress
|
||||
@@ -71,10 +72,13 @@
|
||||
}
|
||||
Else {Write-Warning -Message "You haven't said if you want to turn protection off, or on." }
|
||||
|
||||
if ($LockAddress) {
|
||||
Set-ExcelRange -Range $WorkSheet.cells[$LockAddress] -Locked
|
||||
}
|
||||
elseif ($IsProtected) {
|
||||
Set-ExcelRange -Range $WorkSheet.Cells -Locked
|
||||
}
|
||||
if ($UnlockAddress) {
|
||||
Set-ExcelRange -Range $WorkSheet.cells[$UnlockAddress] -Locked:$false
|
||||
}
|
||||
if ($lockAddress) {
|
||||
Set-ExcelRange -Range $WorkSheet.cells[$UnlockAddress] -Locked
|
||||
}
|
||||
}
|
||||
133
SetFormat.ps1
133
SetFormat.ps1
@@ -1,4 +1,4 @@
|
||||
Function Set-ExcelRange {
|
||||
function Set-ExcelRange {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Applies number, font, alignment and/or color formatting, values or formulas to a range of Excel cells.
|
||||
@@ -32,6 +32,7 @@
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
[Alias("Set-Format")]
|
||||
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system state')]
|
||||
Param (
|
||||
#One or more row(s), Column(s) and/or block(s) of cells to format.
|
||||
[Parameter(ValueFromPipeline = $true,Position=0)]
|
||||
@@ -55,6 +56,7 @@
|
||||
#Style for the right border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||
#Colour for the text - if none is specified it will be left as it is.
|
||||
[Alias('ForegroundColor')]
|
||||
$FontColor,
|
||||
#Value for the cell.
|
||||
$Value,
|
||||
@@ -106,7 +108,9 @@
|
||||
#Hide a row or column (not a range); use -Hidden:$false to unhide.
|
||||
[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
|
||||
[Switch]$Locked,
|
||||
#Merges cells - it is recommended that you explicitly set -HorizontalAlignment
|
||||
[Switch]$Merge
|
||||
)
|
||||
process {
|
||||
if ($Range -is [Array]) {
|
||||
@@ -120,7 +124,10 @@
|
||||
$Range = $WorkSheet.Cells[$Range]
|
||||
}
|
||||
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.
|
||||
#else we assume $Range is a range.
|
||||
if ($ClearAll) {
|
||||
$Range.Clear()
|
||||
}
|
||||
if ($ResetFont) {
|
||||
$Range.Style.Font.Color.SetColor( ([System.Drawing.Color]::Black))
|
||||
$Range.Style.Font.Bold = $false
|
||||
@@ -167,6 +174,9 @@
|
||||
if ($PSBoundParameters.ContainsKey('VerticalAlignment')) {
|
||||
$Range.Style.VerticalAlignment = $VerticalAlignment
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Merge')) {
|
||||
$Range.Merge = [boolean]$Merge
|
||||
}
|
||||
if ($PSBoundParameters.ContainsKey('Value')) {
|
||||
if ($Value -match '^=') {$PSBoundParameters["Formula"] = $Value -replace '^=','' }
|
||||
else {
|
||||
@@ -220,12 +230,15 @@
|
||||
else {Write-Warning -Message ("Can set the height of a row or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
}
|
||||
if ($Autosize) {
|
||||
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.AutoFit() }
|
||||
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
|
||||
$Range.AutoFitColumns()
|
||||
}
|
||||
else {Write-Warning -Message ("Can autofit a column or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
try {
|
||||
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.AutoFit() }
|
||||
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
|
||||
$Range.AutoFitColumns()
|
||||
|
||||
}
|
||||
else {Write-Warning -Message ("Can autofit a column or a range but not a {0} object" -f ($Range.GetType().name)) }
|
||||
}
|
||||
catch {Write-Warning -Message "Failed autosizing columns of worksheet '$WorksheetName': $_"}
|
||||
}
|
||||
elseif ($PSBoundParameters.ContainsKey('Width')) {
|
||||
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.Width = $Width}
|
||||
@@ -250,7 +263,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
Function NumberFormatCompletion {
|
||||
function NumberFormatCompletion {
|
||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||
$numformats = [ordered]@{
|
||||
"General" = "General" # format ID 0
|
||||
@@ -293,6 +306,7 @@ Function NumberFormatCompletion {
|
||||
if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
|
||||
Register-ArgumentCompleter -CommandName Add-ConditionalFormatting -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Export-Excel -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName NumberFormat -ScriptBlock $Function:NumberFormatCompletion
|
||||
@@ -304,7 +318,28 @@ if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter)
|
||||
Register-ArgumentCompleter -CommandName Add-ExcelChart -ParameterName YAxisNumberformat -ScriptBlock $Function:NumberFormatCompletion
|
||||
}
|
||||
|
||||
Function Expand-NumberFormat {
|
||||
function ListFonts {
|
||||
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
|
||||
if (-not $script:FontFamilies) {
|
||||
$script:FontFamilies = @("","")
|
||||
try {
|
||||
$script:FontFamilies = (New-Object System.Drawing.Text.InstalledFontCollection).Families.Name
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
$script:FontFamilies.where({$_ -Gt "" -and $_ -like "$wordToComplete*"} ) | ForEach-Object {
|
||||
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'" , $_ ,
|
||||
([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
|
||||
}
|
||||
}
|
||||
if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter) {
|
||||
Register-ArgumentCompleter -CommandName New-ExcelStyle -ParameterName FontName -ScriptBlock $Function:ListFonts
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName FontName -ScriptBlock $Function:ListFonts
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontName -ScriptBlock $Function:ListFonts
|
||||
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontName -ScriptBlock $Function:ListFonts
|
||||
}
|
||||
|
||||
function Expand-NumberFormat {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Converts short names for number formats to the formatting strings used in Excel
|
||||
@@ -380,3 +415,81 @@ Function Expand-NumberFormat {
|
||||
Default {return $NumberFormat}
|
||||
}
|
||||
}
|
||||
|
||||
function New-ExcelStyle {
|
||||
param (
|
||||
[Alias("Address")]
|
||||
$Range ,
|
||||
#Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc.
|
||||
[Alias("NFormat")]
|
||||
$NumberFormat,
|
||||
#Style of border to draw around the range.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround,
|
||||
#Color of the border.
|
||||
$BorderColor=[System.Drawing.Color]::Black,
|
||||
#Style for the bottom border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom,
|
||||
#Style for the top border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderTop,
|
||||
#Style for the left border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft,
|
||||
#Style for the right border.
|
||||
[OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight,
|
||||
#Colour for the text - if none is specified it will be left as it is.
|
||||
[Alias('ForegroundColor')]
|
||||
$FontColor,
|
||||
#Value for the cell.
|
||||
$Value,
|
||||
#Formula for the cell.
|
||||
$Formula,
|
||||
#Specifies formula should be an array formula (a.k.a CSE [ctrl-shift-enter] formula).
|
||||
[Switch]$ArrayFormula,
|
||||
#Clear Bold, Italic, StrikeThrough and Underline and set color to Black.
|
||||
[Switch]$ResetFont,
|
||||
#Make text bold; use -Bold:$false to remove bold.
|
||||
[Switch]$Bold,
|
||||
#Make text italic; use -Italic:$false to remove italic.
|
||||
[Switch]$Italic,
|
||||
#Underline the text using the underline style in -UnderlineType; use -Underline:$false to remove underlining.
|
||||
[Switch]$Underline,
|
||||
#Specifies whether underlining should be single or double, normal or accounting mode. The default is "Single".
|
||||
[OfficeOpenXml.Style.ExcelUnderLineType]$UnderLineType = [OfficeOpenXml.Style.ExcelUnderLineType]::Single,
|
||||
#Strike through text; use -Strikethru:$false to remove Strike through
|
||||
[Switch]$StrikeThru,
|
||||
#Subscript or Superscript (or none).
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignmentFont]$FontShift,
|
||||
#Font to use - Excel defaults to Calibri.
|
||||
[String]$FontName,
|
||||
#Point size for the text.
|
||||
[float]$FontSize,
|
||||
#Change background color.
|
||||
$BackgroundColor,
|
||||
#Background pattern - Solid by default.
|
||||
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::Solid ,
|
||||
#Secondary color for background pattern.
|
||||
[Alias("PatternColour")]
|
||||
$PatternColor,
|
||||
#Turn on Text-Wrapping; use -WrapText:$false to turn off wrapping.
|
||||
[Switch]$WrapText,
|
||||
#Position cell contents to Left, Right, Center etc. default is 'General'.
|
||||
[OfficeOpenXml.Style.ExcelHorizontalAlignment]$HorizontalAlignment,
|
||||
#Position cell contents to Top, Bottom or Center.
|
||||
[OfficeOpenXml.Style.ExcelVerticalAlignment]$VerticalAlignment,
|
||||
#Degrees to rotate text. Up to +90 for anti-clockwise ("upwards"), or to -90 for clockwise.
|
||||
[ValidateRange(-90, 90)]
|
||||
[int]$TextRotation ,
|
||||
#Autofit cells to width (columns or ranges only).
|
||||
[Alias("AutoFit")]
|
||||
[Switch]$AutoSize,
|
||||
#Set cells to a fixed width (columns or ranges only), ignored if Autosize is specified.
|
||||
[float]$Width,
|
||||
#Set cells to a fixed height (rows or ranges only).
|
||||
[float]$Height,
|
||||
#Hide a row or column (not a range); use -Hidden:$false to unhide.
|
||||
[Switch]$Hidden,
|
||||
#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,
|
||||
[Switch]$Merge
|
||||
)
|
||||
$PSBoundParameters
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
[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 {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Updates the first object to contain all the properties of the object with the most properties in the array.
|
||||
|
||||
.DESCRIPTION
|
||||
@@ -30,7 +35,7 @@ Function Update-FirstObjectProperties {
|
||||
$Array = $Obj1, $Obj2, $Obj3
|
||||
$Array | Out-GridView -Title 'Not showing Member3 and Member4'
|
||||
$Array | Update-FirstObjectProperties | Out-GridView -Title 'All properties are visible'
|
||||
|
||||
|
||||
Updates the fist object of the array by adding Member3 and Member4.
|
||||
|
||||
.EXAMPLE
|
||||
@@ -79,7 +84,7 @@ Function Update-FirstObjectProperties {
|
||||
$Union = @()
|
||||
$Input | ForEach-Object {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
49
__tests__/AddTrendlinesToAChart.tests.ps1
Normal file
49
__tests__/AddTrendlinesToAChart.tests.ps1
Normal file
@@ -0,0 +1,49 @@
|
||||
Describe "Test adding trendlines to charts" {
|
||||
BeforeAll {
|
||||
$script:data = ConvertFrom-Csv @"
|
||||
Region,Item,TotalSold
|
||||
West,screws,60
|
||||
South,lemon,48
|
||||
South,apple,71
|
||||
East,screwdriver,70
|
||||
East,kiwi,32
|
||||
West,screwdriver,1
|
||||
South,melon,21
|
||||
East,apple,79
|
||||
South,apple,68
|
||||
South,avocado,73
|
||||
"@
|
||||
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
$xlfile = "TestDrive:\trendLine.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
It "Should add a linear trendline".PadRight(90) {
|
||||
|
||||
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine Linear
|
||||
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange
|
||||
|
||||
$excel = Open-ExcelPackage -Path $xlfile
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
|
||||
$ws.Drawings[0].Series.TrendLines.Type | Should Be 'Linear'
|
||||
|
||||
Close-ExcelPackage $excel
|
||||
}
|
||||
|
||||
It "Should add a MovingAvgerage trendline".PadRight(90) {
|
||||
|
||||
$cd = New-ExcelChartDefinition -XRange Region -YRange TotalSold -ChartType ColumnClustered -ChartTrendLine MovingAvgerage
|
||||
$data | Export-Excel $xlfile -ExcelChartDefinition $cd -AutoNameRange
|
||||
|
||||
$excel = Open-ExcelPackage -Path $xlfile
|
||||
$ws = $excel.Workbook.Worksheets["Sheet1"]
|
||||
|
||||
$ws.Drawings[0].Series.TrendLines.Type | Should Be 'MovingAvgerage'
|
||||
|
||||
Close-ExcelPackage $excel
|
||||
}
|
||||
}
|
||||
132
__tests__/CI.ps1
Normal file
132
__tests__/CI.ps1
Normal file
@@ -0,0 +1,132 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Handel Continuous Integration Testing in AppVeyor and Azure DevOps Pipelines.
|
||||
#>
|
||||
param
|
||||
(
|
||||
# AppVeyor Only - Update AppVeyor build name.
|
||||
[Switch]$Initialize,
|
||||
# Installs the module and invoke the Pester tests with the current version of PowerShell.
|
||||
[Switch]$Test,
|
||||
# AppVeyor Only - Upload results to AppVeyor "Tests" tab.
|
||||
[Switch]$Finalize,
|
||||
# AppVeyor and Azure - Upload module as AppVeyor Artifact.
|
||||
[Switch]$Artifact
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if ($Initialize) {
|
||||
$Psd1 = (Get-ChildItem -File -Filter *.psd1 -Name -Path (Split-Path $PSScriptRoot)).PSPath
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path $Psd1 | Out-String)))).ModuleVersion
|
||||
Update-AppveyorBuild -Version "$ModuleVersion ($env:APPVEYOR_BUILD_NUMBER) $env:APPVEYOR_REPO_BRANCH"
|
||||
}
|
||||
if ($Test) {
|
||||
function Get-EnvironmentInfo {
|
||||
if ($null -eq $IsWindows -or $IsWindows) {
|
||||
# Get Windows Version
|
||||
try {
|
||||
$WinRelease, $WinVer = Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ReleaseId, CurrentMajorVersionNumber, CurrentMinorVersionNumber, CurrentBuildNumber, UBR
|
||||
$WindowsVersion = "$($WinVer -join '.') ($WinRelease)"
|
||||
}
|
||||
catch {
|
||||
$WindowsVersion = [System.Environment]::OSVersion.Version
|
||||
}
|
||||
|
||||
# Get .Net Version
|
||||
# https://stackoverflow.com/questions/3487265/powershell-script-to-return-versions-of-net-framework-on-a-machine
|
||||
$Lookup = @{
|
||||
378389 = [version]'4.5'
|
||||
378675 = [version]'4.5.1'
|
||||
378758 = [version]'4.5.1'
|
||||
379893 = [version]'4.5.2'
|
||||
393295 = [version]'4.6'
|
||||
393297 = [version]'4.6'
|
||||
394254 = [version]'4.6.1'
|
||||
394271 = [version]'4.6.1'
|
||||
394802 = [version]'4.6.2'
|
||||
394806 = [version]'4.6.2'
|
||||
460798 = [version]'4.7'
|
||||
460805 = [version]'4.7'
|
||||
461308 = [version]'4.7.1'
|
||||
461310 = [version]'4.7.1'
|
||||
461808 = [version]'4.7.2'
|
||||
461814 = [version]'4.7.2'
|
||||
528040 = [version]'4.8'
|
||||
528049 = [version]'4.8'
|
||||
}
|
||||
|
||||
# For One True framework (latest .NET 4x), change the Where-Object match
|
||||
# to PSChildName -eq "Full":
|
||||
$DotNetVersion = Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
|
||||
Get-ItemProperty -name Version, Release -EA 0 |
|
||||
Where-Object { $_.PSChildName -eq "Full" } |
|
||||
Select-Object @{name = ".NET Framework"; expression = { $_.PSChildName } },
|
||||
@{name = "Product"; expression = { $Lookup[$_.Release] } },
|
||||
Version, Release
|
||||
|
||||
# Output
|
||||
[PSCustomObject]($PSVersionTable + @{
|
||||
ComputerName = $env:Computername
|
||||
WindowsVersion = $WindowsVersion
|
||||
'.Net Version' = '{0} (Version: {1}, Release: {2})' -f $DotNetVersion.Product, $DotNetVersion.Version, $DotNetVersion.Release
|
||||
#EnvironmentPath = $env:Path
|
||||
})
|
||||
}
|
||||
else {
|
||||
# Output
|
||||
[PSCustomObject]($PSVersionTable + @{
|
||||
ComputerName = $env:Computername
|
||||
#EnvironmentPath = $env:Path
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
'[Info] Testing On:'
|
||||
Get-EnvironmentInfo
|
||||
'[Progress] Installing Module.'
|
||||
. .\Install.ps1
|
||||
'[Progress] Invoking Pester.'
|
||||
Invoke-Pester -OutputFile ('TestResultsPS{0}.xml' -f $PSVersionTable.PSVersion)
|
||||
}
|
||||
if ($Finalize) {
|
||||
'[Progress] Finalizing.'
|
||||
$Failure = $false
|
||||
$AppVeyorResultsUri = 'https://ci.appveyor.com/api/testresults/nunit/{0}' -f $env:APPVEYOR_JOB_ID
|
||||
foreach ($TestResultsFile in Get-ChildItem -Path 'TestResultsPS*.xml') {
|
||||
$TestResultsFilePath = $TestResultsFile.FullName
|
||||
"[Info] Uploading Files: $AppVeyorResultsUri, $TestResultsFilePath."
|
||||
# Add PowerShell version to test results
|
||||
$PSVersion = $TestResultsFile.Name.Replace('TestResults', '').Replace('.xml', '')
|
||||
[Xml]$Xml = Get-Content -Path $TestResultsFilePath
|
||||
Select-Xml -Xml $Xml -XPath '//test-case' | ForEach-Object { $_.Node.name = "$PSVersion " + $_.Node.name }
|
||||
$Xml.OuterXml | Out-File -FilePath $TestResultsFilePath
|
||||
|
||||
#Invoke-RestMethod -Method Post -Uri $AppVeyorResultsUri -Body $Xml
|
||||
[Net.WebClient]::new().UploadFile($AppVeyorResultsUri, $TestResultsFilePath)
|
||||
|
||||
if ($Xml.'test-results'.failures -ne '0') {
|
||||
$Failure = $true
|
||||
}
|
||||
}
|
||||
if ($Failure) {
|
||||
throw 'Tests failed.'
|
||||
}
|
||||
}
|
||||
if ($Artifact) {
|
||||
# Get Module Info
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path (Split-Path $PSScriptRoot)))
|
||||
$ModulePath = (Get-Module -Name $ModuleName -ListAvailable).ModuleBase | Split-Path
|
||||
$VersionLocal = ((Get-Module -Name $ModuleName -ListAvailable).Version | Measure-Object -Maximum).Maximum
|
||||
"[Progress] Artifact Start for Module: $ModuleName, Version: $VersionLocal."
|
||||
if ($env:APPVEYOR) {
|
||||
$ZipFileName = "{0} {1} {2} {3:yyyy-MM-dd HH-mm-ss}.zip" -f $ModuleName, $VersionLocal, $env:APPVEYOR_REPO_BRANCH, (Get-Date)
|
||||
$ZipFileFullPath = Join-Path -Path $PSScriptRoot -ChildPath $ZipFileName
|
||||
"[Info] Artifact. $ModuleName, ZipFileName: $ZipFileName."
|
||||
#Compress-Archive -Path $ModulePath -DestinationPath $ZipFileFullPath
|
||||
[System.IO.Compression.ZipFile]::CreateFromDirectory($ModulePath, $ZipFileFullPath, [System.IO.Compression.CompressionLevel]::Optimal, $true)
|
||||
Push-AppveyorArtifact $ZipFileFullPath -DeploymentName $ModuleName
|
||||
}
|
||||
elseif ($env:AGENT_NAME) {
|
||||
#Write-Host "##vso[task.setvariable variable=ModuleName]$ModuleName"
|
||||
Copy-Item -Path $ModulePath -Destination $env:Build_ArtifactStagingDirectory -Recurse
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,32 @@
|
||||
#Requires -Modules Pester
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
if ($PSVersionTable.PSVersion.Major -gt 5) { Write-Warning "Can't test grid view on V6" }
|
||||
else {Add-Type -AssemblyName System.Windows.Forms }
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
Describe "Compare Worksheet" {
|
||||
Context "Simple comparison output" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path "$env:temp\server*.xlsx"
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name, RequiredServices, CanPauseAndContinue, CanShutdown, CanStop, DisplayName, DependentServices, MachineName
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
$s[2].DisplayName = "Changed from the orginal"
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d)
|
||||
$row6Name = $s[5].name
|
||||
$s.RemoveAt(5)
|
||||
$s | Export-Excel -Path $env:temp\server2.xlsx
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" | Sort-Object -Property _row, _file
|
||||
BeforeAll {
|
||||
if ($PSVersionTable.PSVersion.Major -gt 5) {
|
||||
It "GridView Support" {
|
||||
Set-ItResult -Pending -Because "Can't test grid view on V6 and later"
|
||||
}
|
||||
}
|
||||
else { Add-Type -AssemblyName System.Windows.Forms }
|
||||
. "$PSScriptRoot\Samples\Samples.ps1"
|
||||
Remove-Item -Path "TestDrive:\server*.xlsx"
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name, RequiredServices, CanPauseAndContinue, CanShutdown, CanStop, DisplayName, DependentServices, MachineName
|
||||
$s | Export-Excel -Path TestDrive:\server1.xlsx
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
$s[2].DisplayName = "Changed from the orginal"
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d)
|
||||
$row6Name = $s[5].name
|
||||
$s.RemoveAt(5)
|
||||
$s | Export-Excel -Path TestDrive:\server2.xlsx
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
$comp = compare-WorkSheet "TestDrive:\server1.xlsx" "TestDrive:\server2.xlsx" | Sort-Object -Property _row, _file
|
||||
}
|
||||
Context "Simple comparison output" {
|
||||
it "Found the right number of differences " {
|
||||
$comp | should not beNullOrEmpty
|
||||
$comp.Count | should be 4
|
||||
@@ -55,13 +61,13 @@ Describe "Compare Worksheet" {
|
||||
$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')
|
||||
. $PowerShellPath -Command ('Import-Module {0}; $null = Compare-WorkSheet "{1}server1.xlsx" "{1}server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView; Start-Sleep -sec 5' -f $ModulePath, (Resolve-Path 'TestDrive:').ProviderPath)
|
||||
}
|
||||
else {
|
||||
$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView:$useGrid
|
||||
$null = Compare-WorkSheet "TestDrive:\server1.xlsx" "TestDrive:\server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView:$useGrid
|
||||
}
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$xl1 = Open-ExcelPackage -Path "TestDrive:\server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "TestDrive:\server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||
$s2Sheet = $xl2.Workbook.Worksheets[1]
|
||||
}
|
||||
@@ -85,9 +91,9 @@ Describe "Compare Worksheet" {
|
||||
|
||||
Context "Setting the forgound to highlight changed properties" {
|
||||
BeforeAll {
|
||||
$null = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -AllDataBackgroundColor([System.Drawing.Color]::white) -BackgroundColor ([System.Drawing.Color]::LightGreen) -FontColor ([System.Drawing.Color]::DarkRed)
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$null = compare-WorkSheet "TestDrive:\server1.xlsx" "TestDrive:\server2.xlsx" -AllDataBackgroundColor([System.Drawing.Color]::white) -BackgroundColor ([System.Drawing.Color]::LightGreen) -FontColor ([System.Drawing.Color]::DarkRed)
|
||||
$xl1 = Open-ExcelPackage -Path "TestDrive:\server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "TestDrive:\server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets[1]
|
||||
$s2Sheet = $xl2.Workbook.Worksheets[1]
|
||||
}
|
||||
@@ -114,9 +120,9 @@ Describe "Compare Worksheet" {
|
||||
|
||||
Context "More complex comparison: output check and different worksheet names " {
|
||||
BeforeAll {
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property RequiredServices, CanPauseAndContinue, CanShutdown, CanStop,
|
||||
[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 TestDrive:\server1.xlsx -WorkSheetname server1
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
$s[2].DisplayName = "Changed from the orginal"
|
||||
@@ -128,11 +134,11 @@ Describe "Compare Worksheet" {
|
||||
$s.RemoveAt(5)
|
||||
$s[10].ServiceType = "Changed should not matter"
|
||||
|
||||
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path $env:temp\server2.xlsx -WorkSheetname server2
|
||||
$s | Select-Object -Property ServiceName, DisplayName, StartType, ServiceType | Export-Excel -Path TestDrive:\server2.xlsx -WorkSheetname server2
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
$comp = compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -WorkSheetName Server1,Server2 -Key ServiceName -Property DisplayName,StartType -AllDataBackgroundColor ([System.Drawing.Color]::AliceBlue) -BackgroundColor ([System.Drawing.Color]::White) -FontColor ([System.Drawing.Color]::Red) | Sort-Object _row,_file
|
||||
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
|
||||
$comp = compare-WorkSheet "TestDrive:\server1.xlsx" "TestDrive:\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 "TestDrive:\server1.xlsx"
|
||||
$xl2 = Open-ExcelPackage -Path "TestDrive:\server2.xlsx"
|
||||
$s1Sheet = $xl1.Workbook.Worksheets["server1"]
|
||||
$s2Sheet = $xl2.Workbook.Worksheets["server2"]
|
||||
}
|
||||
@@ -186,36 +192,36 @@ Describe "Compare Worksheet" {
|
||||
}
|
||||
|
||||
Describe "Merge Worksheet" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path "TestDrive:\server*.xlsx" , "TestDrive:\combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property *
|
||||
|
||||
$s | Export-Excel -Path TestDrive:\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[2].DisplayName = "Changed from the orginal"
|
||||
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d)
|
||||
|
||||
$s.RemoveAt(5)
|
||||
|
||||
$s | Export-Excel -Path TestDrive:\server2.xlsx
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
Merge-Worksheet -Referencefile "TestDrive:\server1.xlsx" -Differencefile "TestDrive:\server2.xlsx" -OutputFile "TestDrive:\combined1.xlsx" -Property name,displayname,startType -Key name
|
||||
$excel = Open-ExcelPackage -Path "TestDrive:\combined1.xlsx"
|
||||
$ws = $excel.Workbook.Worksheets["sheet1"]
|
||||
}
|
||||
Context "Merge with 3 properties" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property *
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$s[2].DisplayName = "Changed from the orginal"
|
||||
|
||||
$d = $s[-1] | Select-Object -Property *
|
||||
$d.DisplayName = "Dummy Service"
|
||||
$d.Name = "Dummy"
|
||||
$s.Insert(3,$d)
|
||||
|
||||
$s.RemoveAt(5)
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server2.xlsx
|
||||
#Assume default worksheet name, (sheet1) and column header for key ("name")
|
||||
Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined1.xlsx" -Property name,displayname,startType -Key name
|
||||
$excel = Open-ExcelPackage -Path "$env:temp\combined1.xlsx"
|
||||
$ws = $excel.Workbook.Worksheets["sheet1"]
|
||||
}
|
||||
it "Created a worksheet with the correct headings " {
|
||||
$ws | should not beNullOrEmpty
|
||||
$ws.Cells[ 1,1].Value | Should be "name"
|
||||
$ws.Cells[ 1,2].Value | Should be "DisplayName"
|
||||
$ws.Cells[ 1,3].Value | Should be "StartType"
|
||||
$ws.Cells[ 1,4].Value | Should be "Server2 DisplayName"
|
||||
$ws.Cells[ 1,5].Value | Should be "Server2 StartType"
|
||||
$ws.Cells[ 1,4].Value | Should be "server2 DisplayName"
|
||||
$ws.Cells[ 1,5].Value | Should be "server2 StartType"
|
||||
}
|
||||
it "Joined the two sheets correctly " {
|
||||
$ws.Cells[ 2,2].Value | Should be $ws.Cells[ 2,4].Value
|
||||
@@ -247,16 +253,16 @@ Describe "Merge Worksheet" {
|
||||
}
|
||||
Context "Wider data set" {
|
||||
it "Coped with columns beyond Z in the Output sheet " {
|
||||
{ Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined2.xlsx" } | Should not throw
|
||||
{ Merge-Worksheet -Referencefile "TestDrive:\server1.xlsx" -Differencefile "TestDrive:\server2.xlsx" -OutputFile "TestDrive:\combined2.xlsx" } | Should not throw
|
||||
}
|
||||
}
|
||||
}
|
||||
Describe "Merge Multiple sheets" {
|
||||
Context "Merge 3 sheets with 3 properties" {
|
||||
BeforeAll {
|
||||
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path "TestDrive:\server*.xlsx" , "TestDrive:\combined*.xlsx" -ErrorAction SilentlyContinue
|
||||
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name,DisplayName,StartType
|
||||
$s | Export-Excel -Path $env:temp\server1.xlsx
|
||||
$s | Export-Excel -Path TestDrive:\server1.xlsx
|
||||
|
||||
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s
|
||||
$row4Displayname = $s[2].DisplayName
|
||||
@@ -269,7 +275,7 @@ Describe "Merge Multiple sheets" {
|
||||
|
||||
$s.RemoveAt(5)
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server2.xlsx
|
||||
$s | Export-Excel -Path TestDrive:\server2.xlsx
|
||||
|
||||
$s[2].displayname = $row4Displayname
|
||||
|
||||
@@ -279,26 +285,26 @@ Describe "Merge Multiple sheets" {
|
||||
$s.Insert(6,$d)
|
||||
$s.RemoveAt(8)
|
||||
|
||||
$s | Export-Excel -Path $env:temp\server3.xlsx
|
||||
$s | Export-Excel -Path TestDrive:\server3.xlsx
|
||||
|
||||
Merge-MultipleSheets -Path "$env:temp\server1.xlsx", "$env:temp\Server2.xlsx","$env:temp\Server3.xlsx" -OutputFile "$env:temp\combined3.xlsx" -Property name,displayname,startType -Key name
|
||||
$excel = Open-ExcelPackage -Path "$env:temp\combined3.xlsx"
|
||||
Merge-MultipleSheets -Path "TestDrive:\server1.xlsx", "TestDrive:\server2.xlsx","TestDrive:\server3.xlsx" -OutputFile "TestDrive:\combined3.xlsx" -Property name,displayname,startType -Key name
|
||||
$excel = Open-ExcelPackage -Path "TestDrive:\combined3.xlsx"
|
||||
$ws = $excel.Workbook.Worksheets["sheet1"]
|
||||
|
||||
}
|
||||
it "Created a worksheet with the correct headings " {
|
||||
$ws | Should not beNullOrEmpty
|
||||
$ws.Cells[ 1,2 ].Value | Should be "name"
|
||||
$ws.Cells[ 1,3 ].Value | Should be "Server1 DisplayName"
|
||||
$ws.Cells[ 1,4 ].Value | Should be "Server1 StartType"
|
||||
$ws.Cells[ 1,5 ].Value | Should be "Server2 DisplayName"
|
||||
$ws.Cells[ 1,6 ].Value | Should be "Server2 StartType"
|
||||
$ws.Cells[ 1,3 ].Value | Should be "server1 DisplayName"
|
||||
$ws.Cells[ 1,4 ].Value | Should be "server1 StartType"
|
||||
$ws.Cells[ 1,5 ].Value | Should be "server2 DisplayName"
|
||||
$ws.Cells[ 1,6 ].Value | Should be "server2 StartType"
|
||||
$ws.Column(7).hidden | Should be $true
|
||||
$ws.Cells[ 1,8].Value | Should be "Server2 Row"
|
||||
$ws.Cells[ 1,9 ].Value | Should be "Server3 DisplayName"
|
||||
$ws.Cells[ 1,10].Value | Should be "Server3 StartType"
|
||||
$ws.Cells[ 1,8].Value | Should be "server2 Row"
|
||||
$ws.Cells[ 1,9 ].Value | Should be "server3 DisplayName"
|
||||
$ws.Cells[ 1,10].Value | Should be "server3 StartType"
|
||||
$ws.Column(11).hidden | Should be $true
|
||||
$ws.Cells[ 1,12].Value | Should be "Server3 Row"
|
||||
$ws.Cells[ 1,12].Value | Should be "server3 Row"
|
||||
}
|
||||
it "Joined the three sheets correctly " {
|
||||
$ws.Cells[ 2,3 ].Value | Should be $ws.Cells[ 2,5 ].Value
|
||||
@@ -328,7 +334,7 @@ Describe "Merge Multiple sheets" {
|
||||
$ws.Cells[12,9 ].Value | Should be $ws.Cells[12,5].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.Count | Should be 17
|
||||
$cf[16].Address.Address | Should be 'B2:B1048576'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
$xlFile = ".\testSQL.xlsx"
|
||||
$xlFile = "TestDrive:\testSQL.xlsx"
|
||||
|
||||
Describe "ConvertFrom-ExcelToSQLInsert" {
|
||||
|
||||
@@ -16,7 +16,7 @@ Describe "ConvertFrom-ExcelToSQLInsert" {
|
||||
Remove-Item $xlFile -Recurse -Force -ErrorAction Ignore
|
||||
}
|
||||
|
||||
It "Should be empty double single quotes" {
|
||||
It "Should be empty double single quotes".PadRight(90) {
|
||||
$expected="INSERT INTO Sheet1 ('Name', 'Age') Values('John', '');"
|
||||
|
||||
$actual = ConvertFrom-ExcelToSQLInsert -Path $xlFile Sheet1
|
||||
@@ -24,7 +24,7 @@ Describe "ConvertFrom-ExcelToSQLInsert" {
|
||||
$actual | should be $expected
|
||||
}
|
||||
|
||||
It "Should have NULL" {
|
||||
It "Should have NULL".PadRight(90) {
|
||||
$expected="INSERT INTO Sheet1 ('Name', 'Age') Values('John', NULL);"
|
||||
|
||||
$actual = ConvertFrom-ExcelToSQLInsert -Path $xlFile Sheet1 -ConvertEmptyStringsToNull
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
$path1 = "$env:TEMP\Test1.xlsx"
|
||||
$path2 = "$env:TEMP\Test2.xlsx"
|
||||
Remove-item -Path $path1, $path2 -ErrorAction SilentlyContinue
|
||||
|
||||
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
|
||||
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
|
||||
else {$OtherCurrencySymbol = "£"}
|
||||
[PSCustOmobject][Ordered]@{
|
||||
Date = Get-Date
|
||||
Formula1 = '=SUM(F2:G2)'
|
||||
String1 = 'My String'
|
||||
Float = [math]::pi
|
||||
IPAddress = '10.10.25.5'
|
||||
StrLeadZero = '07670'
|
||||
StrComma = '0,26'
|
||||
StrEngThousand = '1,234.56'
|
||||
StrEuroThousand = '1.555,83'
|
||||
StrDot = '1.2'
|
||||
StrNegInt = '-31'
|
||||
StrTrailingNeg = '31-'
|
||||
StrParens = '(123)'
|
||||
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
|
||||
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
|
||||
StrE164Phone = '+32 (444) 444 4444'
|
||||
StrAltPhone1 = '+32 4 4444 444'
|
||||
StrAltPhone2 = '+3244444444'
|
||||
StrLeadSpace = ' 123'
|
||||
StrTrailSpace = '123 '
|
||||
Link1 = [uri]"https://github.com/dfinke/ImportExcel"
|
||||
Link2 = "https://github.com/dfinke/ImportExcel" # Links are not copied correctly, hopefully this will be fixed at some future date
|
||||
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -WorkSheetname MixedTypes -Path $path2
|
||||
Describe "Copy-Worksheet" {
|
||||
$path1 = "TestDrive:\Test1.xlsx"
|
||||
$path2 = "TestDrive:\Test2.xlsx"
|
||||
Remove-Item -Path $path1, $path2 -ErrorAction SilentlyContinue
|
||||
|
||||
$ProcRange = Get-Process | Export-Excel $path1 -DisplayPropertySet -WorkSheetname Processes -ReturnRange
|
||||
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") { $OtherCurrencySymbol = "$" }
|
||||
else { $OtherCurrencySymbol = "£" }
|
||||
[PSCustOmobject][Ordered]@{
|
||||
Date = Get-Date
|
||||
Formula1 = '=SUM(F2:G2)'
|
||||
String1 = 'My String'
|
||||
Float = [math]::pi
|
||||
IPAddress = '10.10.25.5'
|
||||
StrLeadZero = '07670'
|
||||
StrComma = '0,26'
|
||||
StrEngThousand = '1,234.56'
|
||||
StrEuroThousand = '1.555,83'
|
||||
StrDot = '1.2'
|
||||
StrNegInt = '-31'
|
||||
StrTrailingNeg = '31-'
|
||||
StrParens = '(123)'
|
||||
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
|
||||
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
|
||||
StrE164Phone = '+32 (444) 444 4444'
|
||||
StrAltPhone1 = '+32 4 4444 444'
|
||||
StrAltPhone2 = '+3244444444'
|
||||
StrLeadSpace = ' 123'
|
||||
StrTrailSpace = '123 '
|
||||
Link1 = [uri]"https://github.com/dfinke/ImportExcel"
|
||||
Link2 = "https://github.com/dfinke/ImportExcel" # Links are not copied correctly, hopefully this will be fixed at some future date
|
||||
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -WorkSheetname MixedTypes -Path $path2
|
||||
Context "Simplest copy" {
|
||||
BeforeAll {
|
||||
Copy-ExcelWorkSheet -SourceWorkbook $path1 -DestinationWorkbook $path2
|
||||
@@ -60,39 +60,39 @@ Describe "Copy-Worksheet" {
|
||||
it "Copied the expected data into the worksheet " {
|
||||
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
|
||||
$ws.Cells[2, 2].Formula | Should be 'SUM(F2:G2)'
|
||||
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
|
||||
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
|
||||
($ws.Cells[2, 11].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, 11].Value | Should beLessThan 0
|
||||
$ws.Cells[2, 12].Value | Should beLessThan 0
|
||||
$ws.Cells[2, 13].Value | Should beLessThan 0
|
||||
($ws.Cells[2, 11].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, 11].Value | Should beLessThan 0
|
||||
$ws.Cells[2, 12].Value | Should beLessThan 0
|
||||
$ws.Cells[2, 13].Value | Should beLessThan 0
|
||||
if ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ",") {
|
||||
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
|
||||
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
|
||||
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
|
||||
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
|
||||
}
|
||||
elseif ((Get-Culture).NumberFormat.NumberGroupSeparator -EQ ".") {
|
||||
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
|
||||
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
|
||||
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
|
||||
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
|
||||
}
|
||||
($ws.Cells[2, 14].Value -is [valuetype] ) | Should be $true
|
||||
$ws.Cells[2, 15].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, 19].Value -is [valuetype] ) | Should be $true
|
||||
($ws.Cells[2, 20].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, 16].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, 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"
|
||||
$xlfile = "TestDrive:\reports.xlsx"
|
||||
$xlfileArchive = "TestDrive:\reportsArchive.xlsx"
|
||||
|
||||
rm $xlfile -ErrorAction SilentlyContinue
|
||||
rm $xlfileArchive -ErrorAction SilentlyContinue
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
Remove-Item $xlfileArchive -ErrorAction SilentlyContinue
|
||||
|
||||
$sheets = echo 1.1.2019 1.2.2019 1.3.2019 1.4.2019 1.5.2019
|
||||
|
||||
@@ -101,7 +101,7 @@ Describe "Copy-Worksheet" {
|
||||
}
|
||||
}
|
||||
|
||||
it "Should copy and remove sheets" {
|
||||
it "Should copy and remove sheets " {
|
||||
$targetSheets = echo 1.1.2019 1.4.2019
|
||||
|
||||
$targetSheets | ForEach-Object {
|
||||
@@ -113,4 +113,28 @@ Describe "Copy-Worksheet" {
|
||||
(Get-ExcelSheetInfo -Path $xlfile ).Count | Should Be 3
|
||||
}
|
||||
}
|
||||
|
||||
Context "Copy worksheet should support piped input" {
|
||||
BeforeAll {
|
||||
$xlfile = "TestDrive:\reports.xlsx"
|
||||
$xlfileArchive = "TestDrive:\reportsArchive.xlsx"
|
||||
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
Remove-Item $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 $_
|
||||
}
|
||||
$e = Open-ExcelPackage $xlfile
|
||||
$e.Workbook.Worksheets | Copy-ExcelWorkSheet -DestinationWorkbook $xlfileArchive
|
||||
Close-ExcelPackage -NoSave $e
|
||||
}
|
||||
it "Should copy sheets piped into the command " {
|
||||
$excel = Open-ExcelPackage $xlfileArchive
|
||||
$excel.Workbook.Worksheets.Count | should be 5
|
||||
$excel.Workbook.Worksheets['1.3.2019'].Cells['A1'].Value | should be 'Hello World'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,19 @@
|
||||
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
if (Get-process -Name Excel,xlim -ErrorAction SilentlyContinue) { Write-Warning -Message "You need to close Excel before running the tests." ; return}
|
||||
Describe ExportExcel {
|
||||
. "$PSScriptRoot\Samples\Samples.ps1"
|
||||
if (Get-process -Name Excel,xlim -ErrorAction SilentlyContinue) {
|
||||
It "Excel is open" {
|
||||
$Warning = "You need to close Excel before running the tests."
|
||||
Write-Warning -Message $Warning
|
||||
Set-ItResult -Inconclusive -Because $Warning
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Context "#Example 1 # Creates and opens a file with the right number of rows and columns" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test with a maximum of 100 processes for speed; export all properties, then export smaller subsets.
|
||||
$processes = Get-Process | where {$_.StartTime} | Select-Object -first 100 -Property * -excludeProperty Parent
|
||||
@@ -68,7 +76,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # NoAliasOrScriptPropeties -ExcludeProperty and -DisplayPropertySet work" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
$processes = Get-Process | Select-Object -First 100
|
||||
$propertyNames = $Processes[0].psobject.properties.where( {$_.MemberType -eq 'Property'}).name
|
||||
@@ -117,7 +125,7 @@ Describe ExportExcel {
|
||||
|
||||
Context "#Example 2 # Exports a list of numbers and applies number format " {
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#testing -ReturnRange switch and applying number format to Formulas as well as values.
|
||||
$returnedRange = @($null, -1, 0, 34, 777, "", -0.5, 119, -0.1, 234, 788,"=A9+A10") | Export-Excel -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00' -Path $path -ReturnRange
|
||||
@@ -156,7 +164,7 @@ Describe ExportExcel {
|
||||
|
||||
Context " # Number format parameter" {
|
||||
BeforeAll {
|
||||
$path = "$env:temp\test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
1..10 | Export-Excel -Path $path -Numberformat 'Number'
|
||||
1..10 | Export-Excel -Path $path -Numberformat 'Percentage' -Append
|
||||
@@ -179,7 +187,7 @@ Describe ExportExcel {
|
||||
|
||||
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
|
||||
else {$OtherCurrencySymbol = "£"}
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
$warnVar = $null
|
||||
#Test correct export of different data types and number formats; test hyperlinks, test -NoNumberConversion test object is converted to a string with no warnings, test calcuation of formula
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
@@ -296,7 +304,7 @@ Describe ExportExcel {
|
||||
|
||||
Context "# # Setting cells for different data types with -noHeader" {
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test -NoHeader & -NoNumberConversion
|
||||
[PSCustOmobject][Ordered]@{
|
||||
@@ -357,7 +365,7 @@ Describe ExportExcel {
|
||||
#Test New-ConditionalText builds correctly
|
||||
$ct = New-ConditionalText -ConditionalType GreaterThan 525 -ConditionalTextColor ([System.Drawing.Color]::DarkRed) -BackgroundColor ([System.Drawing.Color]::LightPink)
|
||||
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test -ConditionalText with a single conditional spec.
|
||||
Write-Output 489 668 299 777 860 151 119 497 234 788 | Export-Excel -Path $path -ConditionalText $ct
|
||||
@@ -384,18 +392,19 @@ Describe ExportExcel {
|
||||
}
|
||||
}
|
||||
|
||||
Context "#Example 6 # Adding multiple conditional formats using short form syntax. " {
|
||||
#Test adding mutliple conditional blocks and using the minimal syntax for new-ConditionalText
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test adding mutliple conditional blocks and using the minimal syntax for new-ConditionalText
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
|
||||
#Testing -Passthrough
|
||||
$Excel = Get-Service | Select-Object Name, Status, DisplayName, ServiceName |
|
||||
Export-Excel $path -PassThru -ConditionalText $(
|
||||
New-ConditionalText Stop ([System.Drawing.Color]::DarkRed) ([System.Drawing.Color]::LightPink)
|
||||
New-ConditionalText Running ([System.Drawing.Color]::Blue) ([System.Drawing.Color]::Cyan)
|
||||
)
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
#Testing -Passthrough
|
||||
$Excel = Get-Service | Select-Object Name, Status, DisplayName, ServiceName |
|
||||
Export-Excel $path -PassThru -ConditionalText $(
|
||||
New-ConditionalText Stop ([System.Drawing.Color]::DarkRed) ([System.Drawing.Color]::LightPink)
|
||||
New-ConditionalText Running ([System.Drawing.Color]::Blue) ([System.Drawing.Color]::Cyan)
|
||||
)
|
||||
$ws = $Excel.Workbook.Worksheets[1]
|
||||
|
||||
Context "#Example 6 # Adding multiple conditional formats using short form syntax. " {
|
||||
it "Added two blocks of conditional formating for the data range " {
|
||||
$ws.ConditionalFormatting.Count | Should be 2
|
||||
$ws.ConditionalFormatting[0].Address | Should be ($ws.Dimension.Address)
|
||||
@@ -408,8 +417,8 @@ Describe ExportExcel {
|
||||
$ws.ConditionalFormatting[1].Type | Should be "ContainsText"
|
||||
#Add RGB Comparison
|
||||
}
|
||||
Close-ExcelPackage -ExcelPackage $Excel
|
||||
}
|
||||
Close-ExcelPackage -ExcelPackage $Excel
|
||||
|
||||
Context "#Example 7 # Update-FirstObjectProperties works " {
|
||||
$Array = @()
|
||||
@@ -448,7 +457,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context "#Examples 8 & 9 # Adding Pivot tables and charts from parameters" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test -passthru and -worksheetName creating a new, named, sheet in an existing file.
|
||||
$Excel = Get-Process | Select-Object -first 20 -Property Name, cpu, pm, handles, company | Export-Excel $path -WorkSheetname Processes -PassThru
|
||||
#Testing -Excel Pacakage and adding a Pivot-table as a second step. Want to save and re-open it ...
|
||||
@@ -461,11 +470,14 @@ Describe ExportExcel {
|
||||
$excel.ProcessesPivotTable | Should not beNullOrEmpty
|
||||
$PTws | Should not beNullOrEmpty
|
||||
$PTws.PivotTables.Count | Should be 1
|
||||
$PTws.View.TabSelected | Should be $true
|
||||
$Excel.Workbook.Worksheets["Processes"] | Should not beNullOrEmpty
|
||||
$Excel.Workbook.Worksheets.Count | Should beGreaterThan 2
|
||||
$excel.Workbook.Worksheets["Processes"].Dimension.rows | Should be 21 #20 data + 1 header
|
||||
}
|
||||
it "Selected the Pivottable page " {
|
||||
Set-ItResult -Pending -Because "Bug in EPPLus 4.5"
|
||||
$PTws.View.TabSelected | Should be $true
|
||||
}
|
||||
$pt = $PTws.PivotTables[0]
|
||||
it "Built the expected Pivot table " {
|
||||
$pt.RowFields.Count | Should be 1
|
||||
@@ -505,7 +517,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # Add-Worksheet inserted sheets, moved them correctly, and copied a sheet" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test the -CopySource and -Movexxxx parameters for Add-WorkSheet
|
||||
$Excel = Open-ExcelPackage $path
|
||||
#At this point Sheets Should be in the order Sheet1, Processes, ProcessesPivotTable
|
||||
@@ -540,7 +552,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # Create and append with Start row and Start Column, inc ranges and Pivot table. " {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
#Catch warning
|
||||
$warnVar = $null
|
||||
@@ -590,7 +602,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # Create and append explicit and auto table and range extension" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test -Append automatically extends a table, even when it is not specified in the append command;
|
||||
Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company | Export-Excel -Path $path -TableName ProcTab -AutoNameRange -WorkSheetname NoOffset -ClearSheet
|
||||
#Test number format applying to new data
|
||||
@@ -623,7 +635,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context "#Example 11 # Create and append with title, inc ranges and Pivot table" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test New-PivotTableDefinition builds definition using -Pivotfilter and -PivotTotals options.
|
||||
$ptDef = [ordered]@{}
|
||||
$ptDef += New-PivotTableDefinition -PivotTableName "PT1" -SourceWorkSheet 'Sheet1' -PivotRows "Status" -PivotData @{'Status' = 'Count'} -PivotTotals Columns -PivotFilter "StartType" -IncludePivotChart -ChartType BarClustered3D -ChartTitle "Services by status" -ChartHeight 512 -ChartWidth 768 -ChartRow 10 -ChartColumn 0 -NoLegend -PivotColumns CanPauseAndContinue
|
||||
@@ -678,10 +690,10 @@ Describe ExportExcel {
|
||||
$PC1 = $ptsheet1.Drawings[0]
|
||||
$PC2 = $ptsheet2.Drawings[0]
|
||||
it "Created the pivot tables linked to the right data. " {
|
||||
$PT1.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be ("A1:" + $ws1.Dimension.End.Address)
|
||||
$PT2.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.ref |
|
||||
Should be ("A2:" + $ws2.Dimension.End.Address) #Title in row 1
|
||||
$PT1.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.name|
|
||||
Should be "All_services"
|
||||
$PT2.CacheDefinition.CacheDefinitionXml.pivotCacheDefinition.cacheSource.worksheetSource.name |
|
||||
Should be "Processes"
|
||||
}
|
||||
it "Set the other pivot tables and chart options from the definitions. " {
|
||||
$pt1.PageFields[0].Name | Should be 'StartType'
|
||||
@@ -705,7 +717,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context "#Example 13 # Formatting and another way to do a pivot. " {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item $path
|
||||
#Test freezing top row/first column, adding formats and a pivot table - from Add-Pivot table not a specification variable - after the export
|
||||
$excel = Get-Process | Select-Object -Property Name, Company, Handles, CPU, PM, NPM, WS | Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -FreezeTopRowFirstColumn -PassThru
|
||||
@@ -785,7 +797,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # Chart from MultiSeries.ps1 in the Examples\charts Directory" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
#Test we haven't missed any parameters on New-ChartDefinition which are on add chart or vice versa.
|
||||
|
||||
@@ -843,7 +855,7 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # variation of plot.ps1 from Examples Directory using Add chart outside ExportExcel" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test inserting a fomual
|
||||
$excel = 0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path $path -WorkSheetname SinX -ClearSheet -FreezeFirstColumn -PassThru
|
||||
#Test-Add Excel Chart to existing data. Test add Conditional formatting with a formula
|
||||
@@ -883,8 +895,9 @@ Describe ExportExcel {
|
||||
}
|
||||
Close-ExcelPackage -ExcelPackage $excel -nosave
|
||||
}
|
||||
|
||||
Context " # Quick line chart" {
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
#test drawing a chart when data doesn't have a string
|
||||
0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path $path -LineChart
|
||||
@@ -901,11 +914,9 @@ Describe ExportExcel {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Context " # Quick Pie chart and three icon conditional formating" {
|
||||
$path = "$Env:TEMP\Pie.xlsx"
|
||||
$path = "TestDrive:\Pie.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
|
||||
$range = Get-Process| Group-Object -Property company | Where-Object -Property name |
|
||||
Select-Object -Property Name, @{n="TotalPm";e={($_.group | Measure-Object -sum -Property pm).sum }} |
|
||||
Export-Excel -NoHeader -AutoNameRange -path $path -ReturnRange -PieChart -ShowPercent
|
||||
@@ -941,10 +952,16 @@ Describe ExportExcel {
|
||||
}
|
||||
|
||||
Context " # Awkward multiple tables" {
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
#Test creating 3 on overlapping tables on the same page. Create rightmost the left most then middle.
|
||||
remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
$r = Get-ChildItem -path C:\WINDOWS\system32 -File
|
||||
if ($IsLinux -or $IsMacOS) {
|
||||
$SystemFolder = '/etc'
|
||||
}
|
||||
else {
|
||||
$SystemFolder = 'C:\WINDOWS\system32'
|
||||
}
|
||||
$r = Get-ChildItem -path $SystemFolder -File
|
||||
|
||||
"Biggest files" | Export-Excel -Path $path -StartRow 1 -StartColumn 7
|
||||
$r | Sort-Object length -Descending | Select-Object -First 14 Name, @{n="Size";e={$_.Length}} |
|
||||
@@ -975,4 +992,86 @@ Describe ExportExcel {
|
||||
}
|
||||
}
|
||||
|
||||
Context " # Parameters and ParameterSets" {
|
||||
$Path = Join-Path (Resolve-Path 'TestDrive:').ProviderPath "test.xlsx"
|
||||
Remove-Item -Path $Path -ErrorAction SilentlyContinue
|
||||
$Processes = Get-Process | Select-Object -first 10 -Property Name, cpu, pm, handles, company
|
||||
|
||||
it "Default Set with Path".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Path $Path -PassThru
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$ExcelPackage.File | Should Be $Path
|
||||
$Worksheet.Cells['A1'].Value | Should Be 'Name'
|
||||
$Worksheet.Tables | Should BeNullOrEmpty
|
||||
$Worksheet.AutoFilterAddress | Should BeNullOrEmpty
|
||||
}
|
||||
it "ExcelPackage Set. Path and (ExcelPackage or Now) should throw".PadRight(87) {
|
||||
$ExcelPackage = Export-Excel -Path $Path -PassThru
|
||||
{Export-Excel -ExcelPackage $ExcelPackage -Path $Path} | Should Throw 'Parameter set cannot be resolved using the specified named parameters'
|
||||
{Export-Excel -ExcelPackage $ExcelPackage -Now} | Should Throw 'Parameter set cannot be resolved using the specified named parameters'
|
||||
|
||||
$Processes | Export-Excel -ExcelPackage $ExcelPackage
|
||||
Remove-Item -Path $Path
|
||||
}
|
||||
it "If TableName and AutoFilter provided AutoFilter will be ignored".PadRight(87) {
|
||||
$ExcelPackage = Export-Excel -Path $Path -PassThru -TableName 'Data' -AutoFilter
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$Worksheet.Tables[0].Name | Should Be 'Data'
|
||||
$Worksheet.AutoFilterAddress | Should BeNullOrEmpty
|
||||
}
|
||||
it "Default Set with Path and TableName with generated name".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Path $Path -PassThru -TableName ''
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$ExcelPackage.File | Should Be $Path
|
||||
$Worksheet.Tables[0].Name | Should Be 'Table1'
|
||||
}
|
||||
it "Now will use temp Path, set TableName with generated name and AutoSize".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Now -PassThru
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$ExcelPackage.File | Should BeLike ([IO.Path]::GetTempPath() + '*')
|
||||
$Worksheet.Tables[0].Name | Should Be 'Table1'
|
||||
$Worksheet.AutoFilterAddress | Should BeNullOrEmpty
|
||||
$Worksheet.Column(5).Width | Should BeGreaterThan 9.5
|
||||
}
|
||||
it "Now allows override of Path and TableName".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Now -PassThru -Path $Path -TableName:$false
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$ExcelPackage.File | Should Be $Path
|
||||
$Worksheet.Tables | Should BeNullOrEmpty
|
||||
$Worksheet.AutoFilterAddress | Should BeNullOrEmpty
|
||||
$Worksheet.Column(5).Width | Should BeGreaterThan 9.5
|
||||
}
|
||||
<# Mock looks unreliable need to check
|
||||
Mock -CommandName 'Invoke-Item'
|
||||
it "Now will Show".PadRight(87) {
|
||||
$Processes | Export-Excel
|
||||
Assert-MockCalled -CommandName 'Invoke-Item' -Times 1 -Exactly -Scope 'It'
|
||||
}
|
||||
it "Now allows override of Show".PadRight(87) {
|
||||
$Processes | Export-Excel -Show:$false
|
||||
Assert-MockCalled -CommandName 'Invoke-Item' -Times 0 -Exactly -Scope 'It'
|
||||
}
|
||||
#>
|
||||
it "Now allows override of AutoSize and TableName to AutoFilter".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Now -PassThru -AutoSize:$false -AutoFilter
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$Worksheet.Tables | Should BeNullOrEmpty
|
||||
$Worksheet.AutoFilterAddress | Should Not BeNullOrEmpty
|
||||
[math]::Round($Worksheet.Column(5).Width, 2) | Should Be 9.14
|
||||
}
|
||||
it "Now allows to set TableName".PadRight(87) {
|
||||
$ExcelPackage = $Processes | Export-Excel -Now -PassThru -TableName 'Data'
|
||||
$Worksheet = $ExcelPackage.Workbook.Worksheets[1]
|
||||
|
||||
$Worksheet.Tables[0].Name | Should Be 'Data'
|
||||
$Worksheet.AutoFilterAddress | Should BeNullOrEmpty
|
||||
$Worksheet.Column(5).Width | Should BeGreaterThan 9.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
remove-item -path $path -ErrorAction SilentlyContinue
|
||||
ConvertFrom-Csv @"
|
||||
Describe "Creating workbook with a single line" {
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
remove-item -path $path -ErrorAction SilentlyContinue
|
||||
ConvertFrom-Csv @"
|
||||
Product, City, Gross, Net
|
||||
Apple, London , 300, 250
|
||||
Orange, London , 400, 350
|
||||
@@ -10,16 +11,15 @@ Banana, London , 300, 200
|
||||
Orange, Paris, 600, 500
|
||||
Banana, Paris, 300, 200
|
||||
Apple, New York, 1200,700
|
||||
|
||||
|
||||
"@ | Export-Excel -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"} -ExcelChartDefinition @{ChartType="Doughnut";XRange="A2:B7"; YRange="C2:C7"; width=800; } -PivotTableDefinition @{Sales=@{
|
||||
PivotRows="City"; PivotColumns="Product"; PivotData=@{Gross="Sum";Net="Sum"}; PivotNumberFormat="$#,##0.00"; PivotTotals="Both"; PivotTableStyle="Medium12"; Activate=$true
|
||||
|
||||
|
||||
PivotChartDefinition=@{Title="Gross and net by city and product"; ChartType="ColumnClustered"; Column=6; Width=600; Height=360; YMajorUnit=500; YMinorUnit=100; YAxisNumberformat="$#,##0"; LegendPosition="Bottom"}}}
|
||||
|
||||
$excel = Open-ExcelPackage $path
|
||||
$ws1 = $excel.Workbook.Worksheets[1]
|
||||
$ws2 = $excel.Workbook.Worksheets[2]
|
||||
Describe "Creating workbook with a single line" {
|
||||
$excel = Open-ExcelPackage $path
|
||||
$ws1 = $excel.Workbook.Worksheets[1]
|
||||
$ws2 = $excel.Workbook.Worksheets[2]
|
||||
Context "Data Page" {
|
||||
It "Inserted the data and created the table " {
|
||||
$ws1.Tables[0] | Should not beNullOrEmpty
|
||||
@@ -40,7 +40,7 @@ Describe "Creating workbook with a single line" {
|
||||
}
|
||||
}
|
||||
Context "PivotTable" {
|
||||
it "Created the PivotTable on a new page and made it active " {
|
||||
it "Created the PivotTable on a new page " {
|
||||
$ws2 | Should not beNullOrEmpty
|
||||
$ws2.PivotTables[0] | Should not beNullOrEmpty
|
||||
$ws2.PivotTables[0].Fields.Count | Should be 4
|
||||
@@ -49,6 +49,9 @@ Describe "Creating workbook with a single line" {
|
||||
$ws2.PivotTables[0].ColumnFields[0].Name | Should be "Product"
|
||||
$ws2.PivotTables[0].RowGrandTotals | Should be $true
|
||||
$ws2.PivotTables[0].ColumGrandTotals | Should be $true #Epplus's mis-spelling of column not mine
|
||||
}
|
||||
it "Made the PivotTable page active " {
|
||||
Set-ItResult -Pending -Because "Bug in EPPLus 4.5"
|
||||
$ws2.View.TabSelected | Should be $true
|
||||
}
|
||||
it "Created the Pivot Chart " {
|
||||
|
||||
@@ -3,7 +3,7 @@ $dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
|
||||
|
||||
Describe "Creating small named ranges with hyperlinks" {
|
||||
BeforeAll {
|
||||
$path = "$env:TEMP\Results.xlsx"
|
||||
$path = "TestDrive:\Results.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
#Read race results, and group by race name : export 1 row to get headers, leaving enough rows aboce to put in a link for each race
|
||||
$results = Import-Csv -Path $dataPath |
|
||||
@@ -81,7 +81,7 @@ Describe "Creating small named ranges with hyperlinks" {
|
||||
$placesMade = $Sheet.Cells[(2 + $results.Count), 5].value - $Sheet.Cells[(2 + $results.Count), 3].value
|
||||
$sheet.Cells[(2 + $results.Count), $columns].value | Should be $placesmade
|
||||
}
|
||||
It "Applied ConditionalFormatting, including StopIfTrue, Priority and Reverse " {
|
||||
It "Applied ConditionalFormatting, including StopIfTrue, Priority " {
|
||||
$sheet.ConditionalFormatting[0].Address.Start.Column | should be $columns
|
||||
$sheet.ConditionalFormatting[0].Address.End.Column | should be $columns
|
||||
$sheet.ConditionalFormatting[0].Address.End.Row | should be $expectedRows
|
||||
@@ -90,6 +90,9 @@ Describe "Creating small named ranges with hyperlinks" {
|
||||
$sheet.ConditionalFormatting[0].Icon3.Value | Should be 1
|
||||
$sheet.ConditionalFormatting[1].Priority | Should be 1
|
||||
$sheet.ConditionalFormatting[1].StopIfTrue | Should be $true
|
||||
}
|
||||
It "Applied ConditionalFormatting, including Reverse " {
|
||||
Set-ItResult -Pending -Because "Bug in EPPLus 4.5"
|
||||
$sheet.ConditionalFormatting[3].LowValue.Color.R | Should begreaterThan 180
|
||||
$sheet.ConditionalFormatting[3].LowValue.Color.G | Should beLessThan 128
|
||||
$sheet.ConditionalFormatting[3].HighValue.Color.R | Should beLessThan 128
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#Requires -Modules Pester
|
||||
remove-module importExcel -erroraction silentlyContinue
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
#remove-module importExcel -erroraction silentlyContinue
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
|
||||
Describe "Check if Function aliases exist" {
|
||||
|
||||
It "Set-Column should exist" {
|
||||
It "Set-Column should exist".PadRight(90) {
|
||||
${Alias:Set-Column} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
It "Set-Row should exist" {
|
||||
It "Set-Row should exist".PadRight(90) {
|
||||
${Alias:Set-Row} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
It "Set-Format should exist" {
|
||||
It "Set-Format should exist".PadRight(90) {
|
||||
${Alias:Set-Format} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Describe "Check if Function aliases exist" {
|
||||
Get-Command Merge-MulipleSheets | Should Not Be $null
|
||||
}
|
||||
#>
|
||||
It "New-ExcelChart should exist" {
|
||||
It "New-ExcelChart should exist".PadRight(90) {
|
||||
${Alias:New-ExcelChart} | Should Not BeNullOrEmpty
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Describe "ImportExcel File List" {
|
||||
It "All files should exist" {
|
||||
It "All files should exist".PadRight(90) {
|
||||
$fileList = Get-Content "$PSScriptRoot\..\filelist.txt"
|
||||
|
||||
foreach ($file in $fileList) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Import-Module $PSScriptRoot\..\..\ImportExcel.psd1
|
||||
#Import-Module $PSScriptRoot\..\..\ImportExcel.psd1
|
||||
|
||||
Describe "Tests" {
|
||||
BeforeAll {
|
||||
@@ -8,20 +8,20 @@ Describe "Tests" {
|
||||
}
|
||||
}
|
||||
|
||||
It "Should have two items" {
|
||||
It "Should have two items".PadRight(90) {
|
||||
$data.count | Should be 2
|
||||
}
|
||||
|
||||
It "Should have items a and b" {
|
||||
It "Should have items a and b".PadRight(90) {
|
||||
$data[0].p1 | Should be "a"
|
||||
$data[1].p1 | Should be "b"
|
||||
}
|
||||
|
||||
It "Should read fast < 2100 milliseconds" {
|
||||
It "Should read fast < 2100 milliseconds".PadRight(90) {
|
||||
$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".PadRight(90) {
|
||||
$timer = Measure-Command {
|
||||
$null = Import-Excel $PSScriptRoot\LargerFile.xlsx
|
||||
}
|
||||
@@ -29,4 +29,14 @@ Describe "Tests" {
|
||||
$timer.TotalMilliseconds | should BeLessThan 3000
|
||||
}
|
||||
|
||||
It "Should be able to open, read and close as seperate actions".PadRight(90) {
|
||||
$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"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
Describe "Exporting with -Inputobject" {
|
||||
BeforeAll {
|
||||
$path = "$env:TEMP\Results.xlsx"
|
||||
$path = "TestDrive:\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
|
||||
|
||||
26
__tests__/InstallPowerShell.ps1
Normal file
26
__tests__/InstallPowerShell.ps1
Normal file
@@ -0,0 +1,26 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Installs PowerShell Core on Windows.
|
||||
#>
|
||||
[CmdLetBinding()]
|
||||
Param
|
||||
(
|
||||
# Version to install in the format from the .msi, for example "7.0.0-preview.1"
|
||||
[Parameter(Mandatory)]
|
||||
[String]$Version
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
'[Progress] Downloading PowerShell Core.'
|
||||
$MsiPath = Join-Path $env:TEMP "PowerShell-$Version-win-x64.msi"
|
||||
[System.Net.WebClient]::new().DownloadFile("https://github.com/PowerShell/PowerShell/releases/download/v$Version/PowerShell-$Version-win-x64.msi", $MsiPath)
|
||||
|
||||
'[Progress] Installing PowerShell Core.'
|
||||
Start-Process 'msiexec.exe' -Wait -ArgumentList "/i $MsiPath /quiet"
|
||||
Remove-Item -Path $MsiPath
|
||||
$PowerShellFolder = $Version[0]
|
||||
if ($Version -like "*preview*") {
|
||||
$PowerShellFolder += '-preview'
|
||||
}
|
||||
$env:Path = "$env:ProgramFiles\PowerShell\$PowerShellFolder;$env:Path"
|
||||
'[Progress] PowerShell Core Installed.'
|
||||
@@ -24,7 +24,8 @@ ID,Product,Quantity,Price,Total
|
||||
|
||||
Describe "Join Worksheet part 1" {
|
||||
BeforeAll {
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
. "$PSScriptRoot\Samples\Samples.ps1"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item -Path $path -ErrorAction SilentlyContinue
|
||||
$data1 | Export-Excel -Path $path -WorkSheetname Oxford
|
||||
$data2 | Export-Excel -Path $path -WorkSheetname Abingdon
|
||||
@@ -50,6 +51,7 @@ Describe "Join Worksheet part 1" {
|
||||
$excel.Workbook.Worksheets["SummaryPivot"].Hidden | Should be 'Visible'
|
||||
}
|
||||
it "Activated the correct worksheet " {
|
||||
Set-ItResult -Pending -Because "Bug in EPPLus 4.5"
|
||||
$excel.Workbook.worksheets["SummaryPivot"].View.TabSelected | Should be $true
|
||||
$excel.Workbook.worksheets["Total"].View.TabSelected | Should be $false
|
||||
}
|
||||
@@ -89,14 +91,14 @@ Describe "Join Worksheet part 1" {
|
||||
}
|
||||
}
|
||||
}
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
$path = "TestDrive:\Test.xlsx"
|
||||
Remove-item -Path $path -ErrorAction SilentlyContinue
|
||||
IF ($PSVersionTable.PSVersion.Major -gt 5) {Write-warning -message "Part 2 Does not run on V6"; return}
|
||||
#switched to CIM objects so test runs on V6
|
||||
Describe "Join Worksheet part 2" {
|
||||
Get-WmiObject -Class win32_logicaldisk |
|
||||
Get-CimInstance -ClassName win32_logicaldisk |
|
||||
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
|
||||
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 |
|
||||
Export-Excel -Path $path -WorkSheetname NetAdapters
|
||||
|
||||
@@ -122,6 +124,6 @@ Describe "Join Worksheet part 2" {
|
||||
$ws.Cells["A$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].Cells["A2"].value
|
||||
$ws.Cells["B$NextRow"].Value | Should be $excel.Workbook.Worksheets[2].Cells["B2"].value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
Describe "Password Support" {
|
||||
Context "Password protected sheet" {
|
||||
BeforeAll {
|
||||
$password = "YouMustRememberThis"
|
||||
$path = "$env:TEMP\Test.xlsx"
|
||||
|
||||
|
||||
Describe "Password Support" {
|
||||
if ($PSVersionTable.PSVersion.Major -GT 5) {
|
||||
It "Password Supported" {
|
||||
Set-ItResult -Pending -Because "Can't test passwords on V6 and later"
|
||||
}
|
||||
return
|
||||
}
|
||||
Context "Password protected sheet" {
|
||||
BeforeAll {
|
||||
$password = "YouMustRememberThis"
|
||||
$path = "TestDrive:\Test.xlsx"
|
||||
Remove-Item $path -ErrorAction SilentlyContinue
|
||||
Get-Service | Select-Object -First 10 | Export-excel -password $password -Path $Path -DisplayPropertySet
|
||||
Get-Service | Select-Object -First 10 | Export-excel -password $password -Path $Path -DisplayPropertySet
|
||||
}
|
||||
it "Threw an error when the password was omitted " {
|
||||
{Open-ExcelPackage -Path $path } | should throw
|
||||
}
|
||||
it "Was able to append when the password was included " {
|
||||
{Get-Service | Select-Object -First 10 |
|
||||
{Get-Service | Select-Object -First 10 |
|
||||
Export-excel -password $password -Path $Path -Append } | should not throw
|
||||
}
|
||||
it "Kept the password on the file when it was saved " {
|
||||
{Import-Excel $Path } | should throw
|
||||
{Import-Excel $Path } | should throw
|
||||
}
|
||||
it "Could read the file when the password was included " {
|
||||
(import-excel $path -Password $password).count | should be 20
|
||||
it "Could read the file when the password was included " {
|
||||
(import-excel $path -Password $password).count | should be 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
__tests__/Path.tests.ps1
Normal file
38
__tests__/Path.tests.ps1
Normal file
@@ -0,0 +1,38 @@
|
||||
Describe "Test reading relative paths" {
|
||||
BeforeAll {
|
||||
$script:xlfileName = "TestR.xlsx"
|
||||
@{data = 1 } | Export-Excel (Join-Path $PWD "TestR.xlsx")
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
Remove-Item (Join-Path $PWD "$($script:xlfileName)")
|
||||
}
|
||||
|
||||
It "Should read local file".PadRight(90) {
|
||||
$actual = Import-Excel -Path ".\$($script:xlfileName)"
|
||||
$actual | Should Not Be $null
|
||||
$actual.Count | Should Be 1
|
||||
}
|
||||
|
||||
It "Should read with pwd".PadRight(90){
|
||||
$actual = Import-Excel -Path (Join-Path $PWD "$($script:xlfileName)")
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
|
||||
It "Should read with just a file name and resolve to cwd".PadRight(90){
|
||||
$actual = Import-Excel -Path "$($script:xlfileName)"
|
||||
$actual | Should Not Be $null
|
||||
}
|
||||
|
||||
It "Should fail for not found".PadRight(90){
|
||||
{ Import-Excel -Path "ExcelFileDoesNotExist.xlsx" } | Should Throw "'ExcelFileDoesNotExist.xlsx' file not found"
|
||||
}
|
||||
|
||||
It "Should fail for xls extension".PadRight(90){
|
||||
{ Import-Excel -Path "ExcelFileDoesNotExist.xls" } | Should Throw "Import-Excel does not support reading this extension type .xls"
|
||||
}
|
||||
|
||||
It "Should fail for xlsxs extension".PadRight(90){
|
||||
{ Import-Excel -Path "ExcelFileDoesNotExist.xlsxs" } | Should Throw "Import-Excel does not support reading this extension type .xlsxs"
|
||||
}
|
||||
}
|
||||
36
__tests__/ProtectWorksheet.tests.ps1
Normal file
36
__tests__/ProtectWorksheet.tests.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
Describe "Setting worksheet protection " {
|
||||
BeforeAll {
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
Remove-Item -path $path -ErrorAction SilentlyContinue
|
||||
$excel = ConvertFrom-Csv @"
|
||||
Product, City, Gross, Net
|
||||
Apple, London , 300, 250
|
||||
Orange, London , 400, 350
|
||||
Banana, London , 300, 200
|
||||
Orange, Paris, 600, 500
|
||||
Banana, Paris, 300, 200
|
||||
Apple, New York, 1200,700
|
||||
|
||||
"@ | Export-Excel -Path $path -WorksheetName Sheet1 -PassThru
|
||||
|
||||
$ws = $excel.sheet1
|
||||
|
||||
Set-WorkSheetProtection -WorkSheet $ws -IsProtected -BlockEditObject -AllowFormatRows -UnLockAddress "1:1"
|
||||
|
||||
Close-ExcelPackage -ExcelPackage $excel
|
||||
$excel = Open-ExcelPackage -Path $path
|
||||
$ws = $ws = $excel.sheet1
|
||||
}
|
||||
it "Turned on protection for the sheet " {
|
||||
$ws.Protection.IsProtected | should be $true
|
||||
}
|
||||
it "Set sheet-wide protection options " {
|
||||
$ws.Protection.AllowEditObject | should be $false
|
||||
$ws.Protection.AllowFormatRows | should be $true
|
||||
$ws.cells["a2"].Style.Locked | should be $true
|
||||
}
|
||||
it "Unprotected some cells " {
|
||||
$ws.cells["a1"].Style.Locked | should be $false
|
||||
}
|
||||
}
|
||||
|
||||
105
__tests__/Publish.ps1
Normal file
105
__tests__/Publish.ps1
Normal file
@@ -0,0 +1,105 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Deploy module to PowerShellGallery.
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName = 'ModuleName')]
|
||||
Param
|
||||
(
|
||||
# The name of the installed module to be deployed, if not provided the name of the .psm1 file in the parent folder is used.
|
||||
[Parameter(ParameterSetName = 'ModuleName')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$ModuleName,
|
||||
|
||||
# Publish module from path (module folder), if not provided -ModuleName is used.
|
||||
[Parameter(Mandatory, ParameterSetName = 'Path')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$Path,
|
||||
|
||||
# Key for PowerShellGallery deployment, if not provided $env:NugetApiKey is used.
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$NugetApiKey,
|
||||
|
||||
# Skip Version verification for PowerShellGallery deployment, can be used for first release.
|
||||
[Switch]$Force
|
||||
)
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if ($Path) {
|
||||
$Path = Resolve-Path -Path $Path
|
||||
if ($Path.Count -ne 1) {
|
||||
throw ('Invalid Path, $Path.Count: {0}.' -f $Path.Count)
|
||||
}
|
||||
$Psd1Path = (Get-ChildItem -File -Filter *.psd1 -Path $Path -Recurse)[0].FullName
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension($Psd1Path)
|
||||
$VersionLocal = (. ([Scriptblock]::Create((Get-Content -Path $Psd1Path | Out-String)))).ModuleVersion
|
||||
}
|
||||
else {
|
||||
# Get Script Root
|
||||
if ($PSScriptRoot) {
|
||||
$ScriptRoot = $PSScriptRoot
|
||||
}
|
||||
elseif ($psISE.CurrentFile.IsUntitled -eq $false) {
|
||||
$ScriptRoot = Split-Path -Path $psISE.CurrentFile.FullPath
|
||||
}
|
||||
elseif ($null -ne $psEditor.GetEditorContext().CurrentFile.Path -and $psEditor.GetEditorContext().CurrentFile.Path -notlike 'untitled:*') {
|
||||
$ScriptRoot = Split-Path -Path $psEditor.GetEditorContext().CurrentFile.Path
|
||||
}
|
||||
else {
|
||||
$ScriptRoot = '.'
|
||||
}
|
||||
|
||||
# Get Module Info
|
||||
if (!$ModuleName) {
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path (Split-Path $ScriptRoot)))
|
||||
}
|
||||
$VersionLocal = ((Get-Module -Name $ModuleName -ListAvailable).Version | Measure-Object -Maximum).Maximum
|
||||
}
|
||||
|
||||
"[Progress] Deploy Script Start for Module: $ModuleName, Version: $VersionLocal."
|
||||
|
||||
# Deploy to PowerShell Gallery if run locally OR from AppVeyor & GitHub master
|
||||
if (!$env:APPVEYOR -or $env:APPVEYOR_REPO_BRANCH -eq 'master') {
|
||||
if ($env:APPVEYOR) {
|
||||
$Success = $true
|
||||
$AppVeyorProject = Invoke-RestMethod -Uri "https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG"
|
||||
$AppVeyorProject.build.jobs | ForEach-Object {
|
||||
'[Info] AppVeyor job name: "{0}", Id: {1}, Status: {2}.' -f $_.name, $_.jobId, $_.status
|
||||
if ($_.jobId -ne $env:APPVEYOR_JOB_ID -and $_.status -ne "success") {
|
||||
$Success = $false
|
||||
}
|
||||
}
|
||||
if (!$Success) {
|
||||
'[Info] There are filed jobs skipping PowerShell Gallery deploy.'
|
||||
break
|
||||
}
|
||||
}
|
||||
try {
|
||||
$VersionGallery = (Find-Module -Name $ModuleName -ErrorAction Stop).Version
|
||||
}
|
||||
catch {
|
||||
if ($_.Exception.Message -notlike 'No match was found for the specified search criteria*' -or !$Force) {
|
||||
throw $_
|
||||
}
|
||||
}
|
||||
|
||||
"[Info] PowerShellGallery. $ModuleName, VersionGallery: $VersionGallery, VersionLocal: $VersionLocal."
|
||||
if ($VersionGallery -lt $VersionLocal -or $Force) {
|
||||
if (!$NugetApiKey) {
|
||||
$NugetApiKey = $env:NugetApiKey
|
||||
}
|
||||
"[Info] PowerShellGallery. Deploying $ModuleName version $VersionLocal."
|
||||
if ($Path) {
|
||||
Publish-Module -NuGetApiKey $NugetApiKey -Path $Path
|
||||
}
|
||||
else {
|
||||
Publish-Module -NuGetApiKey $NugetApiKey -Name $ModuleName -RequiredVersion $VersionLocal
|
||||
}
|
||||
}
|
||||
else {
|
||||
'[Info] PowerShellGallery Deploy Skipped (Version Check).'
|
||||
}
|
||||
}
|
||||
else {
|
||||
'[Info] PowerShellGallery Deploy Skipped.'
|
||||
}
|
||||
'[Progress] Deploy Ended.'
|
||||
@@ -1,4 +1,4 @@
|
||||
$path = "$env:temp\test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
describe "Consistent passing of ranges." {
|
||||
Context "Conditional Formatting" {
|
||||
Remove-Item -path $path -ErrorAction SilentlyContinue
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Requires -Modules Pester
|
||||
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
#Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
|
||||
|
||||
Describe "Remove Worksheet" {
|
||||
Context "Remove a worksheet output" {
|
||||
@@ -10,7 +10,7 @@ Name,Age
|
||||
Jane,10
|
||||
John,20
|
||||
"@
|
||||
$xlFile1 = "$env:TEMP\RemoveWorsheet1.xlsx"
|
||||
$xlFile1 = "TestDrive:\RemoveWorsheet1.xlsx"
|
||||
Remove-Item $xlFile1 -ErrorAction SilentlyContinue
|
||||
|
||||
$data | Export-Excel -Path $xlFile1 -WorksheetName Target1
|
||||
@@ -18,7 +18,7 @@ John,20
|
||||
$data | Export-Excel -Path $xlFile1 -WorksheetName Target3
|
||||
$data | Export-Excel -Path $xlFile1 -WorksheetName Sheet1
|
||||
|
||||
$xlFile2 = "$env:TEMP\RemoveWorsheet2.xlsx"
|
||||
$xlFile2 = "TestDrive:\RemoveWorsheet2.xlsx"
|
||||
Remove-Item $xlFile2 -ErrorAction SilentlyContinue
|
||||
|
||||
$data | Export-Excel -Path $xlFile2 -WorksheetName Target1
|
||||
@@ -27,11 +27,11 @@ John,20
|
||||
$data | Export-Excel -Path $xlFile2 -WorksheetName Sheet1
|
||||
}
|
||||
|
||||
it "Should throw about the Path" {
|
||||
it "Should throw about the Path".PadRight(87) {
|
||||
{Remove-WorkSheet} | Should throw 'Remove-WorkSheet requires the and Excel file'
|
||||
}
|
||||
|
||||
it "Should delete Target2" {
|
||||
it "Should delete Target2".PadRight(87) {
|
||||
Remove-WorkSheet -Path $xlFile1 -WorksheetName Target2
|
||||
|
||||
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||
@@ -42,7 +42,7 @@ John,20
|
||||
$actual[2].Name | Should Be "Sheet1"
|
||||
}
|
||||
|
||||
it "Should delete Sheet1" {
|
||||
it "Should delete Sheet1".PadRight(87) {
|
||||
Remove-WorkSheet -Path $xlFile1
|
||||
|
||||
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||
@@ -53,7 +53,7 @@ John,20
|
||||
$actual[2].Name | Should Be "Target3"
|
||||
}
|
||||
|
||||
it "Should delete multiple sheets" {
|
||||
it "Should delete multiple sheets".PadRight(87) {
|
||||
Remove-WorkSheet -Path $xlFile1 -WorksheetName Target1, Sheet1
|
||||
|
||||
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||
@@ -63,9 +63,9 @@ John,20
|
||||
$actual[1].Name | Should Be "Target3"
|
||||
}
|
||||
|
||||
it "Should delete sheet from multiple workbooks" {
|
||||
it "Should delete sheet from multiple workbooks".PadRight(87) {
|
||||
|
||||
Get-ChildItem "$env:TEMP\RemoveWorsheet*.xlsx" | Remove-WorkSheet
|
||||
Get-ChildItem "TestDrive:\RemoveWorsheet*.xlsx" | Remove-WorkSheet
|
||||
|
||||
$actual = Get-ExcelSheetInfo -Path $xlFile1
|
||||
|
||||
|
||||
BIN
__tests__/Samples/Get-CimInstanceDisk.xml
Normal file
BIN
__tests__/Samples/Get-CimInstanceDisk.xml
Normal file
Binary file not shown.
BIN
__tests__/Samples/Get-CimInstanceNetAdapter.xml
Normal file
BIN
__tests__/Samples/Get-CimInstanceNetAdapter.xml
Normal file
Binary file not shown.
BIN
__tests__/Samples/Get-Process.xml
Normal file
BIN
__tests__/Samples/Get-Process.xml
Normal file
Binary file not shown.
BIN
__tests__/Samples/Get-Service.xml
Normal file
BIN
__tests__/Samples/Get-Service.xml
Normal file
Binary file not shown.
53
__tests__/Samples/Samples.ps1
Normal file
53
__tests__/Samples/Samples.ps1
Normal file
@@ -0,0 +1,53 @@
|
||||
if ($IsLinux -or $IsMacOS) {
|
||||
if (-not (Get-Command 'Get-Service' -ErrorAction SilentlyContinue)) {
|
||||
function Get-Service {
|
||||
Import-Clixml -Path (Join-Path $PSScriptRoot Get-Service.xml)
|
||||
}
|
||||
}
|
||||
if (-not (Get-Command 'Get-CimInstance' -ErrorAction SilentlyContinue)) {
|
||||
function Get-CimInstance {
|
||||
param (
|
||||
$ClassName,
|
||||
$Namespace,
|
||||
$class
|
||||
)
|
||||
if ($ClassName -eq 'win32_logicaldisk') {
|
||||
Import-Clixml -Path (Join-Path $PSScriptRoot Get-CimInstanceDisk.xml)
|
||||
}
|
||||
elseif ($class -eq 'MSFT_NetAdapter') {
|
||||
Import-Clixml -Path (Join-Path $PSScriptRoot Get-CimInstanceNetAdapter.xml)
|
||||
}
|
||||
}
|
||||
}
|
||||
function Get-Process {
|
||||
param (
|
||||
$Name,
|
||||
$Id
|
||||
)
|
||||
if (-not $Name) {
|
||||
if ($Id) {
|
||||
(Import-Clixml -Path (Join-Path $PSScriptRoot Get-Process.xml))[0]
|
||||
}
|
||||
else {
|
||||
Import-Clixml -Path (Join-Path $PSScriptRoot Get-Process.xml)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# Creating the samples
|
||||
Get-Service | Select-Object -First 30 | Export-Clixml -Path Get-Service.xml
|
||||
|
||||
$Disk = Get-CimInstance -ClassName win32_logicaldisk | Select-Object -Property DeviceId,VolumeName, Size,Freespace
|
||||
$Disk | Export-Clixml -Path Get-CimInstanceDisk.xml
|
||||
|
||||
$NetAdapter = Get-CimInstance -Namespace root/StandardCimv2 -class MSFT_NetAdapter | Select-Object -Property Name, InterfaceDescription, MacAddress, LinkSpeed
|
||||
$NetAdapter | Export-Clixml -Path Get-CimInstanceNetAdapter.xml
|
||||
|
||||
$Process = Get-Process | Where-Object { $_.StartTime -and $_.StartInfo -and $_.Modules -and $_.Company -notlike '*Microsoft*' } | Select-Object -first 20
|
||||
$Process | Export-Clixml -Path $Path
|
||||
$Process = Import-Clixml -Path $Path
|
||||
$Process | foreach {$_.Threads = 'System.Diagnostics.ProcessThreadCollection'}
|
||||
$Process | foreach {$_.Modules = 'System.Diagnostics.ProcessThreadCollection'}
|
||||
$Process | Export-Clixml -Path $Path
|
||||
#>
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
|
||||
$data = ConvertFrom-Csv -InputObject @"
|
||||
ID,Product,Quantity,Price
|
||||
@@ -283,7 +282,7 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
|
||||
|
||||
Describe "Conditional Formatting" {
|
||||
BeforeAll {
|
||||
Remove-Item $path
|
||||
#Remove-Item $path
|
||||
$data = Get-Process | Where-Object company | Select-Object company, name, pm, handles, *mem*
|
||||
$cfmt = New-ConditionalFormattingIconSet -Range "c:c" -ConditionalFormat ThreeIconSet -IconType Arrows
|
||||
$data | Export-Excel -path $Path -AutoSize -ConditionalFormat $cfmt
|
||||
@@ -299,7 +298,7 @@ Describe "Conditional Formatting" {
|
||||
}
|
||||
|
||||
}
|
||||
$path = "$Env:TEMP\test.xlsx"
|
||||
$path = "TestDrive:\test.xlsx"
|
||||
$data2 = ConvertFrom-Csv -InputObject @"
|
||||
ID,Product,Quantity,Price,Total
|
||||
12001,Nails,37,3.99,147.63
|
||||
@@ -320,7 +319,7 @@ ID,Product,Quantity,Price,Total
|
||||
|
||||
Describe "AutoNameRange data with a single property name" {
|
||||
BeforeEach {
|
||||
$xlfile = "$Env:TEMP\testNamedRange.xlsx"
|
||||
$xlfile = "TestDrive:\testNamedRange.xlsx"
|
||||
Remove-Item $xlfile -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
@@ -358,7 +357,7 @@ Sold,ID
|
||||
|
||||
Describe "Table Formatting" {
|
||||
BeforeAll {
|
||||
Remove-Item $path
|
||||
#Remove-Item $path
|
||||
$excel = $data2 | Export-excel -path $path -WorksheetName Hardware -AutoNameRange -AutoSize -BoldTopRow -FreezeTopRow -PassThru
|
||||
$ws = $excel.Workbook.Worksheets[1]
|
||||
#test showfilter & TotalSettings
|
||||
|
||||
@@ -7,7 +7,7 @@ ID,Product,Quantity,Price
|
||||
12011,Crowbar,7,23.48
|
||||
"@
|
||||
|
||||
$path = "$Env:TEMP\DataValidation.xlsx"
|
||||
$path = "TestDrive:\DataValidation.xlsx"
|
||||
|
||||
Describe "Data validation and protection" {
|
||||
Context "Data Validation rules" {
|
||||
@@ -32,7 +32,6 @@ Describe "Data validation and protection" {
|
||||
$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'
|
||||
|
||||
BIN
__tests__/testRelative.xlsx
Normal file
BIN
__tests__/testRelative.xlsx
Normal file
Binary file not shown.
72
appveyor.yml
72
appveyor.yml
@@ -1,17 +1,67 @@
|
||||
image:
|
||||
- Visual Studio 2015
|
||||
# - Ubuntu
|
||||
# Version format
|
||||
version: '({build})'
|
||||
|
||||
# Build worker image (VM templates)
|
||||
image:
|
||||
- Ubuntu1804
|
||||
- 'Visual Studio 2019'
|
||||
|
||||
# Fix CRLF on Windows
|
||||
init:
|
||||
- cmd: 'git config --global --unset core.autocrlf'
|
||||
|
||||
# To disable automatic builds
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- ps: .\DoTests.ps1
|
||||
- pwsh: .\DoTests.ps1 -DontCreateZip
|
||||
|
||||
# Skipping commits with particular message or from specific user
|
||||
skip_commits:
|
||||
message: '/\[skip av\]/'
|
||||
files:
|
||||
- README.md
|
||||
- '*.md'
|
||||
|
||||
artifacts:
|
||||
- path: ImportExcel*.zip
|
||||
name: ImportExcel
|
||||
# Including commits with particular message or from specific user
|
||||
#only_commits:
|
||||
# message: '/\[build\]/' # Start a new build if message contains 'build'
|
||||
|
||||
# Scripts that run after cloning repository
|
||||
install:
|
||||
- ps: 'Install-Module -Name Pester -Force -SkipPublisherCheck'
|
||||
- ps: 'Install-Module -Name Assert -Force'
|
||||
# PowerShell Core
|
||||
- ps: '& .\__tests__\InstallPowerShell.ps1 -Version "7.0.0-preview.3"' # Install other PowerShell Core version (Optional)
|
||||
- pwsh: 'Install-Module -Name Pester -Force'
|
||||
- pwsh: 'Install-Module -Name Assert -Force'
|
||||
|
||||
# To run your custom scripts instead of automatic tests
|
||||
test_script:
|
||||
- ps: '& .\__tests__\CI.ps1 -Test'
|
||||
- pwsh: '& .\__tests__\CI.ps1 -Test'
|
||||
- ps: '& .\__tests__\CI.ps1 -Finalize' # Collect and upload results
|
||||
|
||||
# Deploy
|
||||
deploy_script:
|
||||
- ps: '& .\__tests__\CI.ps1 -Artifact'
|
||||
#- ps: '$null = Install-PackageProvider -Name NuGet -Force ; & .\__tests__\Publish.ps1'
|
||||
|
||||
# Linux setup
|
||||
for:
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- image: Ubuntu1804
|
||||
# Install other PowerShell Core version (Optional)
|
||||
init:
|
||||
- sh: 'sudo apt-get -qq update && sudo apt-get -qq install powershell-preview && sudo rm /usr/bin/pwsh && sudo ln -s /opt/microsoft/powershell/7-preview/pwsh /usr/bin/pwsh'
|
||||
- sh: 'export LANG=en_US.UTF-8' # Fix for PowerShell 7.0.0-preview.2, Remove if using other version.
|
||||
# Scripts that run after cloning repository
|
||||
install:
|
||||
- pwsh: '& .\__tests__\CI.ps1 -Initialize' # Set AppVeyor build version
|
||||
- pwsh: 'Install-Module -Name Pester -Force'
|
||||
- pwsh: 'Install-Module -Name Assert -Force'
|
||||
# To run your custom scripts instead of automatic tests
|
||||
test_script:
|
||||
- pwsh: '& .\__tests__\CI.ps1 -Test'
|
||||
- pwsh: '& .\__tests__\CI.ps1 -Finalize' # Collect and upload results
|
||||
# Skip Deploy
|
||||
deploy_script:
|
||||
- pwsh: '"Deploy skiped on Linux."'
|
||||
@@ -1,15 +1,93 @@
|
||||
resources:
|
||||
- repo: self
|
||||
queue:
|
||||
name: Hosted VS2017
|
||||
steps:
|
||||
- powershell: ./ '.\DoTests.ps1'
|
||||
displayName: 'PowerShell Script'
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'Archive $(Build.BinariesDirectory)'
|
||||
# Starter pipeline
|
||||
# Start with a minimal pipeline that you can customize to build and deploy your code.
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
# - master
|
||||
# - releases/*
|
||||
paths:
|
||||
exclude:
|
||||
- README.md
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
|
||||
jobs:
|
||||
- job: Windows
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
steps:
|
||||
- powershell: 'Install-Module -Name Pester -Force -SkipPublisherCheck'
|
||||
displayName: 'Update Pester'
|
||||
- powershell: './__tests__/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- powershell: './__tests__/CI.ps1 -Artifact'
|
||||
displayName: 'Prepare Artifact'
|
||||
- task: PublishPipelineArtifact@1
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
artifact: 'Modules'
|
||||
- task: PublishPipelineArtifact@1
|
||||
inputs:
|
||||
targetPath: '$(Build.SourcesDirectory)'
|
||||
artifact: 'Source'
|
||||
|
||||
- job: WindowsPSCore
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
steps:
|
||||
- pwsh: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- pwsh: './__tests__/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: Ubuntu
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- powershell: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- powershell: './__tests__/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: macOS
|
||||
pool:
|
||||
vmImage: 'macOS-latest'
|
||||
|
||||
steps:
|
||||
- script: brew install mono-libgdiplus
|
||||
displayName: 'Install mono-libgdiplus'
|
||||
- powershell: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- powershell: './__tests__/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
@@ -2,17 +2,18 @@
|
||||
*.psd1
|
||||
*.psm1
|
||||
AddConditionalFormatting.ps1
|
||||
AddDataValidation.ps1
|
||||
Charting.ps1
|
||||
ColorCompletion.ps1
|
||||
Compare-Worksheet.ps1
|
||||
Compare-WorkSheet.ps1
|
||||
ConvertExcelToImageFile.ps1
|
||||
ConvertFromExcelData.ps1
|
||||
ConvertFromExcelToSQLInsert.ps1
|
||||
ConvertToExcelXlsx.ps1
|
||||
Copy-ExcelWorkSheet.ps1
|
||||
Export-Charts.ps1
|
||||
Export-Excel.ps1
|
||||
Export-ExcelSheet.ps1
|
||||
Export-StocksToExcel.ps1
|
||||
Get-ExcelColumnName.ps1
|
||||
Get-ExcelSheetInfo.ps1
|
||||
Get-ExcelWorkbookInfo.ps1
|
||||
@@ -32,10 +33,12 @@ Open-ExcelPackage.ps1
|
||||
Pivot.ps1
|
||||
PivotTable.ps1
|
||||
Plot.ps1
|
||||
RemoveWorksheet.ps1
|
||||
Send-SQLDataToExcel.ps1
|
||||
Set-CellStyle.ps1
|
||||
Set-Column.ps1
|
||||
Set-Row.ps1
|
||||
Set-WorkSheetProtection.ps1
|
||||
SetFormat.ps1
|
||||
TrackingUtils.ps1
|
||||
Update-FirstObjectProperties.ps1
|
||||
BIN
images/ChartTrendlines.png
Normal file
BIN
images/ChartTrendlines.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
images/ImproveNowDefaults.png
Normal file
BIN
images/ImproveNowDefaults.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
BIN
images/NewExcelStyle.png
Normal file
BIN
images/NewExcelStyle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
images/Sparklines.png
Normal file
BIN
images/Sparklines.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
Reference in New Issue
Block a user