Compare commits

...

74 Commits

Author SHA1 Message Date
dfinke
e6827ba2c5 Updated readme 2019-11-01 19:10:05 -04:00
dfinke
c6b188f915 bump version 2019-11-01 19:09:48 -04:00
dfinke
3f79a43dc4 Remove requires, formatting updated 2019-11-01 19:04:22 -04:00
Doug Finke
53e57b25a6 Merge pull request #706 from jhoneill/master
SQL -Force , import -asText , test fixes, better Linux behavior
2019-11-01 18:57:02 -04:00
Doug Finke
b87fcf6c08 Merge pull request #711 from uSlackr/patch-2
Adding test for Get-ColumnName for https://github.com/dfinke/ImportExcel/issues/708
2019-11-01 18:53:48 -04:00
Doug Finke
35066c0f5d Merge pull request #710 from uSlackr/patch-1
Fixes Column order issue for https://github.com/dfinke/ImportExcel/issues/708
2019-11-01 18:53:14 -04:00
uSlackr
912fc35693 Update Get-ExcelColumnName.Test.ps1 2019-11-01 17:15:27 -04:00
uSlackr
2711ad5522 Adding test for Get-ColumnName 2019-11-01 17:13:10 -04:00
uSlackr
79c3077162 Fixes Column order issue
Column letters were returned out of order.  Issue #708
2019-11-01 13:41:31 -04:00
jhoneill
24ca8da4c3 Merge remote-tracking branch 'upstream/master' 2019-11-01 01:57:47 +00:00
jhoneill
6b626e8f5f Better handling of autosize (again) 2019-11-01 01:57:04 +00:00
jhoneill
4d17a09537 Better .NET version detection 2019-11-01 01:56:11 +00:00
jhoneill
065fc2f1ad Better handling of linux autosize issue. 2019-10-31 15:48:49 +00:00
jhoneill
c71afe802e *Selective* -asText on import & 1 linux test bug 2019-10-31 15:47:44 +00:00
jhoneill
3284f592b9 -Force behavior clearer in Send-SQLData 2019-10-31 10:31:54 +00:00
jhoneill
5d92442488 New tests for import -asText and send-SQL -Force 2019-10-30 17:38:09 +00:00
jhoneill
fb9a592e9e Wasn't removing force from Param to passed thru 2019-10-30 16:16:41 +00:00
jhoneill
d2a378ffda Ensured tests the module in Azure CI 2019-10-30 11:55:54 +00:00
jhoneill
463944ae2d Added support for Send-SQLData -force 2019-10-30 10:59:45 +00:00
jhoneill
34fe2f429a Added support for Import-Excel -ASTEXT 2019-10-30 10:59:23 +00:00
jhoneill
f65e198986 Adaptation for V6 broke under V5. Fixed 2019-10-30 10:58:59 +00:00
dfinke
9e92f2dbc6 Refactored 2019-09-22 11:58:13 -04:00
dfinke
e45c07c40b Add ReadAllSheets example, update readme bump version 2019-09-22 11:43:47 -04:00
dfinke
fbae59b386 Bumped the version 2019-08-31 19:40:42 -04:00
dfinke
e3f3ae74a4 Updated appveyor badge 2019-08-29 19:15:20 -04:00
dfinke
fda61ca10f Updated badges 2019-08-29 18:55:18 -04:00
Doug Finke
29efd505ed Merge pull request #668 from ili101/TestsRebase
Tests improvments and Linux support
2019-08-29 18:43:14 -04:00
ili101
600d95199c Merge branch 'master' into TestsRebase 2019-08-30 01:29:00 +03:00
ili101
1ad80825ca Poke 2019-08-30 01:24:51 +03:00
dfinke
a2b322d45c Only run tests on Windows PS 5.1 2019-08-29 18:13:38 -04:00
ili101
bb9aa9233b Linux dependencies missing warning 2019-08-29 23:50:10 +03:00
ili101
591b854e2b Tests statuses improve 2019-08-29 01:53:07 +03:00
ili101
15eb2130b5 Mereg 2019-08-29 01:22:55 +03:00
ili101
ea8927394f Remove duplicate files with different case 2019-08-29 00:33:17 +03:00
ili101
cfd89f5afc Samples 2019-08-29 00:33:17 +03:00
ili101
3a6946466f xlsx case 2019-08-29 00:33:16 +03:00
ili101
89a59b1eba Samples tests workaround for Linux 2019-08-29 00:32:26 +03:00
ili101
8047631014 Linux Tests rm and macOS mono-libgdiplus 2019-08-29 00:31:46 +03:00
ili101
9458a29a6b Readme 2019-08-29 00:31:46 +03:00
ili101
ab2405edad Scope fixes for TestDrive 2019-08-29 00:31:45 +03:00
ili101
d1592f8739 Replace $env:TEMP 2019-08-29 00:30:22 +03:00
ili101
6650ecd5b8 FileList Case 2019-08-29 00:22:47 +03:00
ili101
b27f6bec3c Module.Template 2.0.2 2019-08-29 00:22:46 +03:00
dfinke
99f742fa8c Updated readme 2019-08-26 20:41:03 -04:00
dfinke
558070bb60 Bump version 2019-08-26 20:25:25 -04:00
Doug Finke
1e0dd763ca Merge pull request #666 from jhoneill/master
Cross platform test support
2019-08-26 19:58:06 -04:00
jhoneill
a783b9c8ca Fixes to tests to be run x-plaform 2019-08-27 00:31:30 +01:00
jhoneill
9abbe2983b Set-ExcelRange now handles autosize on non-windows 2019-08-27 00:30:56 +01:00
dfinke
0556e4947a Added examples to use Excel sparklines to show data trends 2019-08-26 18:38:30 -04:00
Doug Finke
859b1e5467 Merge pull request #664 from jhoneill/master
Fixes issues with newer EPPLus.
2019-08-26 18:29:08 -04:00
jhoneill
0f4e491076 Two lines went missing from a test. Put back. 2019-08-25 20:25:22 +01:00
jhoneill
b30a91d64f Merge remote-tracking branch 'upstream/master' 2019-08-25 18:39:53 +01:00
jhoneill
d1f794c933 Fixes around EPPlus update 2019-08-25 18:35:46 +01:00
dfinke
a016f069a5 Added Azure DevOps pipeline for three OSes 2019-08-25 12:04:14 -04:00
dfinke
fb16ec4677 Updated az yml to test on Linux and Mac 2019-08-25 08:55:43 -04:00
dfinke
1a51d38c0f Add image showing defaults 2019-08-21 17:37:19 -04:00
dfinke
554163a911 Update readme 2019-08-21 17:37:05 -04:00
dfinke
efd8dcd60a Bump version 2019-08-21 17:36:57 -04:00
Doug Finke
1c77bd31b5 Merge pull request #661 from ili101/Out-Excel
Out-Excel and -Now
2019-08-21 17:06:30 -04:00
ili101
35e013fe1d Reverted to Pester Old syntax 2019-08-18 22:37:24 +03:00
ili101
8ac9927cfa ParameterSets Tests and Out-Excel Example 2019-08-18 22:09:28 +03:00
ili101
9c305a1dae Change -Now default from -AutoFilter to -TableName 2019-08-17 08:03:52 +03:00
ili101
aa738629f7 Out-Excel 2019-08-17 06:29:59 +03:00
jhoneill
c1a26f4f4b Added Protect-Worksheet Tests 2019-08-16 14:14:31 +01:00
jhoneill
63f41ceaec WS protection & better control of export -now 2019-08-15 16:03:42 +01:00
dfinke
b82888527f Updated 2019-07-24 09:54:24 -04:00
dfinke
a3c71de190 Bump version 2019-07-24 09:54:20 -04:00
Doug Finke
f3a99f04ce Merge pull request #638 from jhoneill/master
Updates for copy sheet, clear all in Set-Excel range and fixing a password regression
2019-07-24 09:49:42 -04:00
jhoneill
f631a20269 Conflict resolution 2019-07-24 13:02:39 +01:00
jhoneill
dbd35721ee Fix broken test & regression re: passwords 2019-07-24 12:02:22 +01:00
jhoneill
8759070636 add clearall to set-ExcelRange; 2019-07-24 12:01:06 +01:00
Doug Finke
6259b8d091 Merge pull request #630 from 1DontEx1st/patch-1
Fix typo
2019-07-11 13:21:29 -04:00
1DontEx1st
7086c3707c Fix typo
Changed "Autofiler" to "Autofilter" in -Now description.
2019-07-11 12:01:36 -04:00
jhoneill
8b28172616 Refactored copy sheet and added pipe support 2019-07-09 19:10:51 +01:00
63 changed files with 1903 additions and 596 deletions

3
.gitignore vendored
View File

@@ -60,7 +60,8 @@ test.xlsx
testCCFMT.ps1
testHide.ps1
ImportExcel.zip
.vscode/launch.json
.vscode/settings.json
~$*
InstallModule.ps1
PublishToGallery.ps1

56
.vscode/launch.json vendored Normal file
View 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": ""
}
]
}

View File

@@ -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."
}
}
}

View File

@@ -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 = (Invoke-Command -ScriptBlock ([scriptblock]::Create((Get-Content -Raw .\ImportExcel.psd1)))).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."
}

Binary file not shown.

View 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
#>
}

View File

@@ -0,0 +1,54 @@
param(
[Parameter(Mandatory)]
$path
)
$sheet1 = ConvertFrom-Csv @"
Region,Item,TotalSold
West,melon,27
North,avocado,21
West,kiwi,84
East,melon,23
North,kiwi,8
North,nail,29
North,kiwi,46
South,nail,83
East,pear,10
South,avocado,40
"@
$sheet2 = ConvertFrom-Csv @"
Region,Item,TotalSold
West,lemon,24
North,hammer,41
East,nail,87
West,lemon,68
North,screwdriver,9
North,drill,76
West,lime,28
West,pear,78
North,apple,95
South,melon,40
"@
$sheet3 = ConvertFrom-Csv @"
Region,Item,TotalSold
South,drill,100
East,saw,22
North,saw,5
West,orange,78
East,saw,27
North,screwdriver,57
South,hammer,66
East,saw,62
West,nail,98
West,nail,98
"@
Remove-Item $path -ErrorAction SilentlyContinue
$sheet1 | Export-Excel $path -WorksheetName Sheet1
$sheet2 | Export-Excel $path -WorksheetName Sheet2
$sheet3 | Export-Excel $xlfile -WorksheetName Sheet3
$path

View File

@@ -0,0 +1,19 @@
# Get-ExcelSheets
param(
[Parameter(Mandatory)]
$path
)
$hash = @{ }
$e = Open-ExcelPackage $path
foreach ($sheet in $e.workbook.worksheets) {
$hash[$sheet.name] = Import-Excel -ExcelPackage $e -WorksheetName $sheet.name
}
Close-ExcelPackage $e -NoSave
$hash

View File

@@ -0,0 +1,4 @@
$xlfile = "$env:TEMP\MultipleSheets.xlsx"
.\GenerateXlsx.ps1 $xlfile
.\Get-ExcelSheets.ps1 $xlfile

View 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

View 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

View File

@@ -1,4 +1,4 @@
Import-Module ..\ImportExcel.psd1 -Force
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$file = "C:\Temp\test.xlsx"

View File

@@ -76,7 +76,7 @@
.PARAMETER ConditionalText
Applies a Conditional formatting rule defined with New-ConditionalText. When specific conditions are met the format is applied.
.PARAMETER NoNumberConversion
By default we convert all values to numbers if possible, but this isn't always desirable. NoNumberConversion allows you to add exceptions for the conversion. Wildcards (like '*') are allowed.
By default we convert all values to numbers if possible, but this isn't always desirable. NoNumberConversion allows you to add exceptions for the conversion. The only Wildcard allowed is * for all properties
.PARAMETER BoldTopRow
Makes the top row boldface.
.PARAMETER NoHeader
@@ -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.
@@ -418,12 +418,12 @@
.LINK
https://github.com/dfinke/ImportExcel
#>
[CmdletBinding(DefaultParameterSetName = 'Now')]
[CmdletBinding(DefaultParameterSetName = 'Default')]
[OutputType([OfficeOpenXml.ExcelPackage])]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
Param(
[Parameter(Mandatory = $true, ParameterSetName = "Path", Position = 0)]
[Parameter(ParameterSetName = 'Default', Position = 0)]
[String]$Path,
[Parameter(Mandatory = $true, ParameterSetName = "Package")]
@@ -473,14 +473,9 @@
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 }
})]
[String]$TableName,
$TableName,
[OfficeOpenXml.Table.TableStyles]$TableStyle,
@@ -512,7 +507,7 @@
[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.
@@ -531,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) {
@@ -578,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
}
@@ -809,7 +807,7 @@
if ($RangeName) { Add-ExcelName -Range $ws.Cells[$dataRange] -RangeName $RangeName}
#Allow table to be inserted by specifying Name, or Style or both; only process autoFilter if there is no table (they clash).
if ($TableName) {
if ($null -ne $TableName) {
if ($PSBoundParameters.ContainsKey('TableStyle')) {
Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName -TableStyle $TableStyle
}
@@ -911,7 +909,7 @@
}
catch {Write-Warning -Message "Failed setting the top row to bold in worksheet '$WorksheetName': $_"}
}
if ($AutoSize) {
if ($AutoSize -and -not $env:NoAutoSize) {
try {
#Don't fit the all the columns in the sheet; if we are adding cells beside things with hidden columns, that unhides them
if ($MaxAutoSizeRows -and $MaxAutoSizeRows -lt $LastRow ) {
@@ -923,6 +921,7 @@
}
catch { Write-Warning -Message "Failed autosizing columns of worksheet '$WorksheetName': $_"}
}
elseif ($AutoSize) {Write-Warning -Message "Auto-fitting columns is not available with this OS configuration." }
foreach ($Sheet in $HideSheet) {
try {

View File

@@ -5,7 +5,7 @@
$measure = "Open"
)
$xl = "$env:TEMP\Stocks.xlsx"
$xl = Join-Path ([IO.Path]::GetTempPath()) 'Stocks.xlsx'
Remove-Item $xl -ErrorAction SilentlyContinue

View File

@@ -6,10 +6,15 @@ function Get-ExcelColumnName {
Process {
$dividend = $columnNumber
$columnName = @()
$columnName = New-Object System.Collections.ArrayList($null)
while($dividend -gt 0) {
$modulo = ($dividend - 1) % 26
$columnName += [char](65 + $modulo)
if ($columnName.length -eq 0) {
[char](65 + $modulo)
} else {
$columnName.insert(0,[char](65 + $modulo))
}
$dividend = [int](($dividend -$modulo)/26)
}
@@ -19,4 +24,4 @@ function Get-ExcelColumnName {
}
}
}
}

View File

@@ -4,7 +4,7 @@
RootModule = 'ImportExcel.psm1'
# Version number of this module.
ModuleVersion = '6.2.2'
ModuleVersion = '6.5.3'
# 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 = @'
@@ -118,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',

View File

@@ -4,8 +4,8 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
. $PSScriptRoot\AddDataValidation.ps1
. $PSScriptRoot\Charting.ps1
. $PSScriptRoot\ColorCompletion.ps1
. $PSScriptRoot\Compare-WorkSheet.ps1
. $PSScriptRoot\ConvertExcelToImageFile.ps1
. $PSScriptRoot\compare-workSheet.ps1
. $PSScriptRoot\ConvertFromExcelData.ps1
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
. $PSScriptRoot\ConvertToExcelXlsx.ps1
@@ -23,7 +23,7 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
. $PSScriptRoot\InferData.ps1
. $PSScriptRoot\Invoke-Sum.ps1
. $PSScriptRoot\Join-Worksheet.ps1
. $PSScriptRoot\Merge-worksheet.ps1
. $PSScriptRoot\Merge-Worksheet.ps1
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
. $PSScriptRoot\New-ConditionalText.ps1
. $PSScriptRoot\New-ExcelChart.ps1
@@ -31,8 +31,9 @@ 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\Send-SQLDataToExcel.ps1
. $PSScriptRoot\Set-CellStyle.ps1
. $PSScriptRoot\Set-Column.ps1
. $PSScriptRoot\Set-Row.ps1
@@ -45,7 +46,7 @@ Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
New-Alias -Name Use-ExcelData -Value "ConvertFrom-ExcelData" -Force
if ($PSVersionTable.PSVersion.Major -ge 5) {
. $PSScriptRoot\plot.ps1
. $PSScriptRoot\Plot.ps1
Function New-Plot {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'New-Plot does not change system state')]
@@ -59,6 +60,29 @@ else {
Write-Warning 'PowerShell 5 is required for plot.ps1'
Write-Warning 'PowerShell Excel is ready, except for that functionality'
}
if (($IsLinux -or $IsMacOS) -or $env:NoAutoSize) {
$ExcelPackage = [OfficeOpenXml.ExcelPackage]::new()
$Cells = ($ExcelPackage | Add-WorkSheet).Cells['A1']
$Cells.Value = 'Test'
try {
$Cells.AutoFitColumns()
if ($env:NoAutoSize) {Remove-Item Env:\NoAutoSize}
}
catch {
$env:NoAutoSize = $true
if ($IsLinux) {
Write-Warning -Message ('ImportExcel Module Cannot Autosize. Please run the following command to install dependencies:' + [environment]::newline +
'"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:' + [environment]::newline +
'"brew install mono-libgdiplus"')
}
}
finally {
$ExcelPackage | Close-ExcelPackage -NoSave
}
}
#endregion
function Import-Excel {
<#
@@ -107,6 +131,9 @@ function Import-Excel {
.PARAMETER EndColumn
By default the import reads up to the last populated column, -EndColumn tells the import to stop at an earlier number.
.PARAMETER AsText
Normally Import-Excel returns the Cell values. AsText allows selected columns to be returned as the text displayed in their cells. * is supported as a wildcard.
.PARAMETER Password
Accepts a string that will be used to open a password protected Excel file.
@@ -294,6 +321,7 @@ function Import-Excel {
[Alias('RightColumn')]
[Int]$EndColumn ,
[Switch]$DataOnly,
[string[]]$AsText,
[ValidateNotNullOrEmpty()]
[String]$Password
)
@@ -360,8 +388,9 @@ function Import-Excel {
}
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
if ($Password) { $ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream , $Password }
else { $ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream }
$ExcelPackage = New-Object -TypeName OfficeOpenXml.ExcelPackage
if ($Password) { $ExcelPackage.Load($stream,$Password)}
else { $ExcelPackage.Load($stream) }
}
try {
#Select worksheet
@@ -412,16 +441,33 @@ function Import-Excel {
}
else {
#region Create one object per row
if ($AsText) {
<#join items in AsText together with ~~~ . Escape any regex special characters...
# which turns * into \* make it .*. Convert ~~~ to $|^ and top and tail with ^%;
So if we get "Week", "[Time]" and "*date*" ; make the expression ^week$|^\[Time\]$|^.*Date.*$
$make a regex for this which is case insensitive (option 1) and compiled (option 8)
#>
$TextColExpression = "^" + [regex]::Escape($AsText -join "~~~").replace("\*",".*").replace("~~~","$|^") +"$"
$TextColRegEx = New-Object -TypeName regex -ArgumentList $TextColExpression , 9
}
foreach ($R in $Rows) {
#Disabled write-verbose for speed
# Write-Verbose "Import row '$R'"
$NewRow = [Ordered]@{ }
foreach ($P in $PropertyNames) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
# Write-Verbose "Import cell '$($Worksheet.Cells[$R, $P.Column].Address)' with property name '$($p.Value)' and value '$($Worksheet.Cells[$R, $P.Column].Value)'."
if ($TextColRegEx) {
foreach ($P in $PropertyNames) {
if ($TextColRegEx.IsMatch($P.Value)) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Text
}
else {$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value}
}
}
else {
foreach ($P in $PropertyNames) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
# Write-Verbose "Import cell '$($Worksheet.Cells[$R, $P.Column].Address)' with property name '$($p.Value)' and value '$($Worksheet.Cells[$R, $P.Column].Value)'."
}
}
[PSCustomObject]$NewRow
}
#endregion

View File

@@ -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.
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'
}

View File

@@ -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

View File

@@ -512,7 +512,8 @@ Function Merge-MultipleSheets {
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("AND(" +(($sameChecks -join ",") -replace '<>"Same"','="Changed"') +")" ) -BackgroundColor $ChangeBackgroundColor
}
#We've made a bunch of things wider so now is the time to autofit columns. Any hiding has to come AFTER this, because it unhides things
$sheet.Cells.AutoFitColumns()
if ($env:NoAutoSize) {Write-Warning "Autofit is not available with this OS configuration."}
else {$sheet.Cells.AutoFitColumns()}
#if we have a key field (we didn't concatenate all fields) use what we built up in $sameChecks to apply conditional formatting to it (Row no will be in column A, Key in Column B)
if ($Key -ne '*') {

View File

@@ -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"] ) {

View File

View File

@@ -1,7 +0,0 @@
$p = @{
Name = "ImportExcel"
NuGetApiKey = $NuGetApiKey
ReleaseNote = "Add NumberFormat parameter"
}
Publish-Module @p

View File

@@ -7,23 +7,21 @@ If this project helped you reduce the time to get your job done, let me know.
![](https://media.giphy.com/media/hpXxJ78YtpT0s/giphy.gif)
<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 | [![Build status](https://ci.appveyor.com/api/projects/status/21hko6eqtpccrkba/branch/master?svg=true)](https://ci.appveyor.com/project/dfinke/importexcel/branch/master) |
| Azure DevOps | Windows | [![Build Status](https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/dfinke.ImportExcel?branchName=master&jobName=Windows)](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
| Azure DevOps | Windows (Core) | [![Build Status](https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/dfinke.ImportExcel?branchName=master&jobName=WindowsPSCore)](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
| Azure DevOps | Ubuntu | [![Build Status](https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/dfinke.ImportExcel?branchName=master&jobName=Ubuntu)](https://dougfinke.visualstudio.com/ImportExcel/_build/latest?definitionId=21&branchName=master) |
| Azure DevOps | macOS | [![Build Status](https://dougfinke.visualstudio.com/ImportExcel/_apis/build/status/dfinke.ImportExcel?branchName=master&jobName=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
![](https://raw.githubusercontent.com/dfinke/ImportExcel/master/images/testimonial.png)
# 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,15 +52,73 @@ Install-Module ImportExcel -scope CurrentUser
Install-Module ImportExcel
```
# What's new 6.2.1
# What's new 6.5.3
Thank you [uSlackr](https://github.com/uSlackr)
- Fixes Column order issue (plus tests) for `Get-ExcelColumnName`
Thank you [jhoneill](https://github.com/jhoneill)
- Linux. Now set an environment variable if the support needed for Autosize is present, and use that Environment variable to decide to skip autosize operations.
- Fixed tests which needed autosize to work so they skip of the environment variable is set.
- Fixed another break where on azure the module never loaded.
- Added -Force to Send-SQLDataToExcel so it sends something even if no rows are returned. (see [#703](https://github.com/dfinke/ImportExcel/issues/703))
- Added -asText to import-Excel see (#164)[https://github.com/dfinke/ImportExcel/issues/164] and multiple others
- Add a comment to ci.ps1 re better .NET version detection and left some commented out code.
# What's new 6.5.2
- Added the example ReadAllSheets.ps1 based on the thread https://github.com/dfinke/ImportExcel/issues/678
# 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).
![](./images/Sparklines.png)
# 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
```
![image](./images/ImproveNowDefaults.png)
# 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)
![](/images/ChartTrendlines.png)
# What's new 6.2.2
- Fixed Import-Excel and relative path issue, added unit tests.
# What's new 6.2.0

View File

@@ -29,6 +29,8 @@
A System.Data.DataTable object containing the data to be inserted into the spreadsheet without running a query.
This remains supported to avoid breaking older scripts, but if you have a DataTable object you can pass the it
into Export-Excel using -InputObject.
.PARAMETER Force
If specified Export-Excel will be called with parameters specified, even if there is no data to send
.EXAMPLE
C:\> Send-SQLDataToExcel -MsSQLserver -Connection localhost -SQL "select name,type,type_desc from [master].[sys].[all_objects]" -Path .\temp.xlsx -WorkSheetname master -AutoSize -FreezeTopRow -AutoFilter -BoldTopRow
@@ -108,7 +110,8 @@
[string]$SQL,
[int]$QueryTimeout,
[Parameter(ParameterSetName="Pre-FetchedData", Mandatory=$true)]
[System.Data.DataTable]$DataTable
[System.Data.DataTable]$DataTable,
[switch]$Force
)
#Import the parameters from Export-Excel, we will pass InputObject, and we have the common parameters so exclude those,
#and re-write the [Parmameter] attribute on each one to avoid parameterSetName here competing with the settings in Export excel.
@@ -125,7 +128,7 @@
return $paramDictionary
}
process {
#Dynamic params mean we can get passed parameter combination Export-Excel will reject, so throw here, rather than get data and then have Export-Excel error.
#region Dynamic params mean we can get passed parameter combination Export-Excel will reject, so throw here, rather than get data and then have Export-Excel error.
if ($PSBoundParameters.Path -and $PSBoundParameters.ExcelPackage) {
throw 'Parameter error: you cannot specify both a path and an Excel Package.'
return
@@ -134,42 +137,68 @@
Write-Warning "Tables are automatically auto-filtered, -AutoFilter will be ignored"
$null = $PSBoundParameters.Remove('AutoFilter')
}
#We were either given a session object or a connection string (with, optionally a MSSQLServer parameter)
#If we got -MSSQLServer, create a SQL connection, if we didn't but we got -Connection create an ODBC connection
if ($MsSQLserver -and $Connection) {
#endregion
#region if we were either given a session object or a connection string (& optionally -MSSQLServer) make sure we can connect
try {
#If we got -MSSQLServer, create a SQL connection, if we didn't but we got -Connection create an ODBC connection
if ($MsSQLserver -and $Connection) {
if ($Connection -notmatch '=') {$Connection = "server=$Connection;trusted_connection=true;timeout=60"}
$Session = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $Connection
if ($Session.State -ne 'Open') {$Session.Open()}
if ($DataBase) {$Session.ChangeDatabase($DataBase) }
}
elseif ($Connection) {
}
elseif ($Connection) {
$Session = New-Object -TypeName System.Data.Odbc.OdbcConnection -ArgumentList $Connection ; $Session.ConnectionTimeout = 30
}
}
catch {
Write-Warning "An Error occured trying to connect to $Connection, the error was $([Environment]::NewLine + $_.Exception.InnerException))"
}
if ($Session -is [String] -and $Global:DbSessions[$Session]) {$Session = $Global:DbSessions[$Session]}
#endregion
#region we may have been given a table, but if there is a db session to connect to, send the query
if ($Session) {
#A session was either passed in or just created. If it's a SQL one make a SQL DataAdapter, otherwise make an ODBC one
if ($Session -is [String] -and $Global:DbSessions[$Session]) {$Session = $Global:DbSessions[$Session]}
if ($Session.GetType().name -match "SqlConnection") {
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
}
else {
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
}
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $QueryTimeout}
try {
#If the session a SQL one make a SQL DataAdapter, otherwise make an ODBC one
if ($Session.GetType().name -match "SqlConnection") {
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
}
else {
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
}
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $QueryTimeout}
#Both adapter types output the same kind of table, create one and fill it from the adapter
$DataTable = New-Object -TypeName System.Data.DataTable
$rowCount = $dataAdapter.fill($dataTable)
Write-Verbose -Message "Query returned $rowCount row(s)"
#Both adapter types output the same kind of table, create one and fill it from the adapter
$DataTable = New-Object -TypeName System.Data.DataTable
$rowCount = $dataAdapter.fill($dataTable)
Write-Verbose -Message "Query returned $rowCount row(s)"
}
catch {
Write-Warning "An Error occured trying to run the query, the error was $([Environment]::NewLine + $_.Exception.InnerException))"
}
}
#endregion
#region send the table to Excel
#remove parameters which relate to querying SQL, leaving the ones used by Export-Excel
'Connection' , 'Database' , 'Session' , 'MsSQLserver' , 'SQL' , 'DataTable' , 'QueryTimeout' , 'Force' |
ForEach-Object {$null = $PSBoundParameters.Remove($_) }
#if force was specified export even if there are no rows. If there are no columns, the query failed and export "null" if forced
if ($DataTable.Rows.Count) {
#Call export-excel removing parameters which relate to the SQL query, and keeping the rest.
'Connection' , 'Database' , 'Session' , 'MsSQLserver' , 'SQL' , 'DataTable' , 'QueryTimeout' | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
Export-Excel @PSBoundParameters -InputObject $DataTable
}
elseif ($Force -and $DataTable.Columns.Count) {
Write-Warning -Message "Zero rows returned, and -Force was specified, sending empty table to Excel."
Export-Excel @PSBoundParameters -InputObject $DataTable
}
else {Write-Warning -Message ' No Data to insert.' }
#If we were passed a connection and opened a session, close that session.
elseif ($Force) {
Write-Warning -Message "-Force was specified but there is no data to send."
Export-Excel @PSBoundParameters -InputObject $null
}
else {Write-Warning -Message 'There is no Data to insert, and -Force was not specified.' }
#endregion
#If we were passed a connection and opened a session, close that session.
if ($Connection) {$Session.close() }
}
}

View File

@@ -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

View File

@@ -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)

View File

@@ -7,7 +7,7 @@
.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 (
@@ -48,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
@@ -72,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
}
}

View File

@@ -124,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
@@ -226,14 +229,18 @@
}
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)) }
if ($Autosize -and -not $env:NoAutoSize) {
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 ($AutoSize) {Write-Warning -Message "Auto-fitting columns is not available with this OS configuration." }
elseif ($PSBoundParameters.ContainsKey('Width')) {
if ($Range -is [OfficeOpenXml.ExcelColumn]) {$Range.Width = $Width}
elseif ($Range -is [OfficeOpenXml.ExcelRange] ) {
@@ -332,6 +339,7 @@ if (Get-Command -ErrorAction SilentlyContinue -name Register-ArgumentCompleter)
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontName -ScriptBlock $Function:ListFonts
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontName -ScriptBlock $Function:ListFonts
}
function Expand-NumberFormat {
<#
.SYNOPSIS

View File

@@ -1,4 +1,7 @@
Describe "Test adding trendlines to charts" {
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
Describe "Test adding trendlines to charts" {
BeforeAll {
$script:data = ConvertFrom-Csv @"
Region,Item,TotalSold
@@ -17,11 +20,11 @@ South,avocado,73
}
BeforeEach {
$xlfile = "$env:TEMP\trendLine.xlsx"
$xlfile = "TestDrive:\trendLine.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
}
It "Should add a linear trendline" {
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
@@ -34,7 +37,7 @@ South,avocado,73
Close-ExcelPackage $excel
}
It "Should add a MovingAvgerage trendline" {
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

142
__tests__/CI.ps1 Normal file
View File

@@ -0,0 +1,142 @@
<#
.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 ([environment]::OSVersion.Platform -like "win*") {
# 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
}
#TODO FIXME BUG this gets the latest version of the .NET Framework on the machine (ok for powershell.exe), not the version of .NET CORE in use by PWSH.EXE
<#
$VersionFilePath = (Get-Process -Id $PID | Select-Object -ExpandProperty Modules |
Where-Object -Property modulename -eq "clrjit.dll").FileName
if (-not $VersionFilePath) {
$VersionFilePath = [System.Reflection.Assembly]::LoadWithPartialName("System.Core").location
}
(Get-ItemProperty -Path $VersionFilePath).VersionInfo |
Select-Object -Property @{n="Version"; e={$_.ProductName + " " + $_.FileVersion}}, ProductName, FileVersionRaw, FileName
#>
# 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
}
}

View File

@@ -1,26 +1,33 @@
#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 }
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
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
@@ -48,20 +55,11 @@ Describe "Compare Worksheet" {
}
}
Context "Setting the background to highlight different rows, use of grid view." {
Context "Setting the background to highlight different rows" {
BeforeAll {
$useGrid = ($PSVersionTable.PSVersion.Major -LE 5)
if ($useGrid) {
$ModulePath = (Get-Command -Name 'Compare-WorkSheet').Module.Path
$PowerShellExec = if ($PSEdition -eq 'Core') {'pwsh.exe'} else {'powershell.exe'}
$PowerShellPath = Join-Path -Path $PSHOME -ChildPath $PowerShellExec
. $PowerShellPath -Command ("Import-Module $ModulePath; " + '$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView; Start-Sleep -sec 5')
}
else {
$null = Compare-WorkSheet "$env:temp\Server1.xlsx" "$env:temp\Server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen) -GridView:$useGrid
}
$xl1 = Open-ExcelPackage -Path "$env:temp\Server1.xlsx"
$xl2 = Open-ExcelPackage -Path "$env:temp\Server2.xlsx"
$null = Compare-WorkSheet "TestDrive:\server1.xlsx" "TestDrive:\server2.xlsx" -BackgroundColor ([System.Drawing.Color]::LightGreen)
$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 +83,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]
}
@@ -116,7 +114,7 @@ Describe "Compare Worksheet" {
BeforeAll {
[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 +126,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 +184,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 +245,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 +267,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 +277,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

View File

@@ -1,6 +1,7 @@
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
$xlFile = "$env:TEMP\testSQL.xlsx"
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
$xlFile = "TestDrive:\testSQL.xlsx"
Describe "ConvertFrom-ExcelToSQLInsert" {
@@ -16,7 +17,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 +25,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

View File

@@ -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'
}
}
}

View File

@@ -1,12 +1,23 @@
#Requires -Modules Pester
#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}
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
if ($null -eq $IsWindows) {$IsWindows = [environment]::OSVersion.Platform -like "win*"}
$WarningAction = "SilentlyContinue"
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 +79,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 +128,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 +167,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 +190,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 +307,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 +368,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 +395,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 +420,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 +460,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 +473,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 +520,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 +555,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 +605,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 +638,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
@@ -642,20 +657,21 @@ Describe ExportExcel {
#Catch warning
$warnvar = $null
#Test create two data pages; as part of adding the second give both their own pivot table, test -autosize switch
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType, CanPauseAndContinue | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningAction SilentlyContinue -WarningVariable warnvar
Get-Service | Select-Object -Property Status, Name, DisplayName, StartType, CanPauseAndContinue | Export-Excel -Path $path -AutoSize -TableName "All Services" -TableStyle Medium1 -WarningVariable warnvar
Get-Process | Select-Object -Property Name, Company, Handles, CPU, VM | Export-Excel -Path $path -AutoSize -WorkSheetname 'sheet2' -TableName "Processes" -TableStyle Light1 -Title "Processes" -TitleFillPattern Solid -TitleBackgroundColor ([System.Drawing.Color]::AliceBlue) -TitleBold -TitleSize 22 -PivotTableDefinition $ptDef
$Excel = Open-ExcelPackage $path
$ws1 = $Excel.Workbook.Worksheets["Sheet1"]
$ws2 = $Excel.Workbook.Worksheets["Sheet2"]
it "Set Column widths (with autosize) " {
if ($isWindows) {
it "Set Column widths (with autosize) " {
$ws1.Column(2).Width | Should not be $ws1.DefaultColWidth
$ws2.Column(1).width | Should not be $ws2.DefaultColWidth
}
}
it "Added tables to both sheets (handling illegal chars) and a title in sheet 2 " {
$warnvar.count | Should be 1
$warnvar.count | Should beGreaterThan 0
$ws1.tables.Count | Should be 1
$ws2.tables.Count | Should be 1
$ws1.Tables[0].Address.Start.Row | Should be 1
@@ -678,10 +694,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,12 +721,13 @@ 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
$sheet = $excel.Workbook.Worksheets["Processes"]
$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit
if ($isWindows) {$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit }
else {$sheet.Column(1) | Set-ExcelRange -Bold }
$sheet.Column(2) | Set-ExcelRange -Width 29 -WrapText
$sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NFormat "#,###"
Set-ExcelRange -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
@@ -721,7 +738,7 @@ Describe ExportExcel {
$rule = Add-ConditionalFormatting -passthru -Address $sheet.cells["C:C"] -RuleType TopPercent -ConditionValue 20 -Bold -StrikeThru
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor ([System.Drawing.Color]::Red) -Bold -Italic -Underline -BackgroundColor ([System.Drawing.Color]::Beige) -BackgroundPattern LightUp -PatternColor ([System.Drawing.Color]::Gray)
#Test Set-ExcelRange with a column
foreach ($c in 5..9) {Set-ExcelRange $sheet.Column($c) -AutoFit }
if ($isWindows) { foreach ($c in 5..9) {Set-ExcelRange $sheet.Column($c) -AutoFit } }
Add-PivotTable -PivotTableName "PT_Procs" -ExcelPackage $excel -SourceWorkSheet 1 -PivotRows Company -PivotData @{'Name' = 'Count'} -IncludePivotChart -ChartType ColumnClustered -NoLegend
Export-Excel -ExcelPackage $excel -WorksheetName "Processes" -AutoNameRange #Test adding named ranges seperately from adding data.
@@ -734,8 +751,10 @@ Describe ExportExcel {
}
it "Applied the formating " {
$sheet | Should not beNullOrEmpty
$sheet.Column(1).wdith | Should not be $sheet.DefaultColWidth
$sheet.Column(7).wdith | Should not be $sheet.DefaultColWidth
if ($isWindows) {
$sheet.Column(1).width | Should not be $sheet.DefaultColWidth
$sheet.Column(7).width | Should not be $sheet.DefaultColWidth
}
$sheet.Column(1).style.font.bold | Should be $true
$sheet.Column(2).style.wraptext | Should be $true
$sheet.Column(2).width | Should be 29
@@ -785,7 +804,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 +862,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 +902,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 +921,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 +959,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 +999,92 @@ 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
if ($isWindows) {
$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
if ($isWindows) {
$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
if ($isWindows) {
$Worksheet.Column(5).Width | Should BeGreaterThan 9.5
}
}
}
}

View File

@@ -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 " {

View File

@@ -1,9 +1,10 @@
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
$WarningAction = "SilentlyContinue"
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 +82,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 +91,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

View File

@@ -1,19 +1,19 @@
#Requires -Modules Pester
remove-module importExcel -erroraction silentlyContinue
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
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
}

View File

@@ -0,0 +1,29 @@
$map = @{
1024 = 'AMJ'
2048 = 'BZT'
3072 = 'DND'
4096 = 'FAN'
5120 = 'GNX'
6144 = 'IBH'
7168 = 'JOR'
8192 = 'LCB'
9216 = 'MPL'
10240 = 'OCV'
11264 = 'PQF'
12288 = 'RDP'
13312 = 'SQZ'
14336 = 'UEJ'
15360 = 'VRT'
16384 = 'XFD'
}
(Get-ExcelColumnName 26).columnName | Should be 'Z'
(Get-ExcelColumnName 27).columnName | Should be 'AA'
(Get-ExcelColumnName 28).columnNamee | Should be 'AB'
(Get-ExcelColumnName 30).columnName | Should be 'AD'
(Get-ExcelColumnName 48).columnName | Should be 'AV'
1..16 | ForEach-Object {
$number = $_ * 1024
(Get-ExcelColumnName $number).columnName | Should be $map.$number
}

View File

@@ -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) {

View File

@@ -1,5 +1,6 @@
Import-Module $PSScriptRoot\..\..\ImportExcel.psd1
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\..\ImportExcel.psd1
}
Describe "Tests" {
BeforeAll {
$data = $null
@@ -8,20 +9,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,7 +30,7 @@ Describe "Tests" {
$timer.TotalMilliseconds | should BeLessThan 3000
}
It "Should be able to open, read and close as seperate actions" {
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

View File

@@ -1,8 +1,8 @@
Describe "Exporting with -Inputobject" {
Describe "Exporting with -Inputobject; table handling, Send SQL Data and import as " {
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
. "$PSScriptRoot\Samples\Samples.ps1"
$results = ((Get-Process) + (Get-Process -id $PID)) | Select-Object -last 10 -Property Name, cpu, pm, handles, StartTime
$DataTable = [System.Data.DataTable]::new('Test')
$null = $DataTable.Columns.Add('Name')
@@ -16,6 +16,9 @@ Describe "Exporting with -Inputobject" {
export-excel -Path $path -InputObject $results -WorksheetName Sheet1 -RangeName "Whole"
export-excel -Path $path -InputObject $DataTable -WorksheetName Sheet2 -AutoNameRange
Send-SQLDataToExcel -path $path -DataTable $DataTable -WorkSheetname Sheet3 -TableName "Data"
$DataTable.Rows.Clear()
Send-SQLDataToExcel -path $path -DataTable $DataTable -WorkSheetname Sheet4 -force -WarningVariable WVOne -WarningAction SilentlyContinue
Send-SQLDataToExcel -path $path -DataTable ([System.Data.DataTable]::new('Test2')) -WorkSheetname Sheet5 -force -WarningVariable wvTwo -WarningAction SilentlyContinue
$excel = Open-ExcelPackage $path
$sheet = $excel.Sheet1
}
@@ -60,7 +63,7 @@ Describe "Exporting with -Inputobject" {
}
$sheet = $excel.Sheet3
Context "Table of processes via Send-SQLDataToExcel" {
it "Put the correct rows and columns into the sheet " {
it "Put the correct data rows and columns into the sheet " {
$sheet.Dimension.Rows | should be ($results.Count + 1)
$sheet.Dimension.Columns | should be 5
$sheet.cells["A1"].Value | should be "Name"
@@ -76,4 +79,33 @@ Describe "Exporting with -Inputobject" {
$sheet.Cells["E11"].Style.Numberformat.NumFmtID | should be 22
}
}
$Sheet = $excel.Sheet4
Context "Zero-row Data Table sent with Send-SQLDataToExcel -Force" {
it "Raised a warning and put the correct data headers into the sheet " {
$sheet.Dimension.Rows | should be 1
$sheet.Dimension.Columns | should be 5
$sheet.cells["A1"].Value | should be "Name"
$sheet.cells["E1"].Value | should be "StartTime"
$sheet.cells["A3"].Value | should beNullOrEmpty
$wvone | should not beNullOrEmpty
}
}
$Sheet = $excel.Sheet5
Context "Zero-column Data Table handled by Send-SQLDataToExcel -Force" {
it "Put Created a blank Sheet and raised a warning " {
$sheet.Dimension | should beNullOrEmpty
$wvTwo | should not beNullOrEmpty
}
}
Close-ExcelPackage $excel
Context "Import As Text returns text values" {
$x = import-excel $path -WorksheetName sheet3 -AsText StartTime,hand* | Select-Object -last 1
it "Had fields of type string, not date or int, where specified as ASText " {
$x.Handles.GetType().Name | should be "String"
$x.StartTime.GetType().Name | should be "String"
$x.CPU.GetType().Name | should not be "String"
}
}
}

View 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.'

View File

@@ -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,7 +91,7 @@ Describe "Join Worksheet part 1" {
}
}
}
$path = "$env:TEMP\Test.xlsx"
$path = "TestDrive:\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
#switched to CIM objects so test runs on V6
Describe "Join Worksheet part 2" {

View File

@@ -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
}
}
}

View File

@@ -1,38 +1,38 @@
Describe "Test reading relative paths" {
BeforeAll {
$script:xlfileName = "TestR.xlsx"
@{data = 1 } | Export-Excel "$pwd\TestR.xlsx"
@{data = 1 } | Export-Excel (Join-Path $PWD "TestR.xlsx")
}
AfterAll {
Remove-Item "$pwd\$($script:xlfileName)"
Remove-Item (Join-Path $PWD "$($script:xlfileName)")
}
It "Should read local file" {
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" {
$actual = Import-Excel -Path "$pwd\$($script:xlfileName)"
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" {
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" {
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" {
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" {
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"
}
}

View 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
View 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.'

View File

@@ -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

View File

@@ -1,6 +1,7 @@
#Requires -Modules Pester
Import-Module $PSScriptRoot\..\ImportExcel.psd1 -Force
if (-not (get-command Import-Excel -ErrorAction SilentlyContinue)) {
Import-Module $PSScriptRoot\..\ImportExcel.psd1
}
Describe "Remove Worksheet" {
Context "Remove a worksheet output" {
BeforeEach {
@@ -10,7 +11,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 +19,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 +28,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 +43,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 +54,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 +64,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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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
#>

View File

@@ -1,5 +1,4 @@

$path = "$Env:TEMP\test.xlsx"
$path = "TestDrive:\test.xlsx"
$data = ConvertFrom-Csv -InputObject @"
ID,Product,Quantity,Price
@@ -143,8 +142,10 @@ Describe "Set-ExcelColumn, Set-ExcelRow and Set-ExcelRange" {
Set-ExcelRange -WorkSheet $ws -Range "E1" -ResetFont -HorizontalAlignment General -FontName "Courier New" -fontSize 9
Set-ExcelRange -Address $ws.Cells["E7"] -ResetFont -WrapText -BackgroundColor ([System.Drawing.Color]::AliceBlue) -BackgroundPattern DarkTrellis -PatternColor ([System.Drawing.Color]::Red) -NumberFormat "£#,###.00"
Set-ExcelRange -Address $ws.Column(1) -Width 0
Set-ExcelRange -Address $ws.Column(2) -AutoFit
Set-ExcelRange -Address $ws.Cells["E:E"] -AutoFit
if (-not $env:NoAutoSize) {
Set-ExcelRange -Address $ws.Column(2) -AutoFit
Set-ExcelRange -Address $ws.Cells["E:E"] -AutoFit
}
#Test alias
Set-Format -Address $ws.row(5) -Height 0
$rr = $r.row
@@ -283,7 +284,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 +300,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,45 +321,45 @@ 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
}
it "Should have a single item as a named range" {
$excel = ConvertFrom-Csv @"
it "Should have a single item as a named range " {
$excel = ConvertFrom-Csv @"
Sold
1
2
3
4
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws.Names.Count | Should Be 1
$ws.Names[0].Name | Should Be 'Sold'
}
$ws.Names.Count | Should Be 1
$ws.Names[0].Name | Should Be 'Sold'
}
it "Should have a more than a single item as a named range" {
$excel = ConvertFrom-Csv @"
it "Should have a more than a single item as a named range " {
$excel = ConvertFrom-Csv @"
Sold,ID
1,a
2,b
3,c
4,d
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
"@ | Export-Excel $xlfile -PassThru -AutoNameRange
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws.Names.Count | Should Be 2
$ws.Names[0].Name | Should Be 'Sold'
$ws.Names[1].Name | Should Be 'ID'
}
$ws.Names.Count | Should Be 2
$ws.Names[0].Name | Should Be 'Sold'
$ws.Names[1].Name | Should Be '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

View File

@@ -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'

View File

@@ -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."'

View File

@@ -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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
images/Sparklines.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB