Compare commits

..

265 Commits

Author SHA1 Message Date
dfinke
0f9b308d53 Bump version 2019-05-26 14:46:57 -04:00
Doug Finke
847c9a1dc4 Merge pull request #602 from jhoneill/master
Allow import Excel to take packages not just paths
2019-05-24 20:38:52 -04:00
jhoneill
b488ffc700 Allow import Excel to take packages not just paths 2019-05-24 16:23:13 +01:00
dfinke
3ec2481750 Added Pivoting Pester Test Results 2019-05-06 12:14:33 -04:00
Doug Finke
2d26c854d9 Merge pull request #593 from jhoneill/master
added "Analyze this"
2019-05-06 10:51:55 -04:00
jhoneill
a4348ddca7 Merge branch 'master' of https://github.com/jhoneill/ImportExcel 2019-05-06 09:52:19 +01:00
jhoneill
6bfdea6d3e Example : Analyze_this 2019-05-06 09:52:12 +01:00
jhoneill
cfd3db5803 Example : Analyze_this 2019-05-06 09:43:38 +01:00
jhoneill
f20a9de3df New "Analyze-This" example 2019-05-03 12:45:30 -07:00
jhoneill
978e8d38b5 Added Example for PSScriptAnalyzer 2019-05-02 16:34:00 -07:00
Doug Finke
e7d2b528e5 Merge pull request #590 from jhoneill/master
Fixed case on file names, and applied a new rules from script analyzer
2019-05-01 16:22:42 -04:00
jhoneill
899a8215e5 Changed test from Get-Netadapter to CIM for v6 2019-05-01 11:24:36 -07:00
jhoneill
b06e9e35b7 Fixed file case errors impacting loading on Linux 2019-05-01 10:16:13 -07:00
jhoneill
6c7f00b031 Linted with the updated PSScriptAnalyzer. 2019-04-30 13:28:52 -07:00
dfinke
337af82ae2 Updated readme.md 2019-04-12 16:02:47 -04:00
Doug Finke
77ef2ebc40 Merge pull request #576 from ili101/FixDataTablePerformance
Double DataTable performance
2019-04-08 16:42:28 -04:00
ili101
92c97b25c3 Replace [void] with $null 2019-04-08 13:34:31 +03:00
ili101
52231254a5 Replace " | Out-Null" with "$null = " everywhere just in case it degrades performance in other places 2019-04-07 22:26:48 +03:00
ili101
494ac51ae5 Replace " | Out-Null" with "$null = " doble performance on DataTable 2019-04-07 22:11:31 +03:00
Doug Finke
0febb4a3c2 Merge pull request #575 from ili101/TableStyleFix
TableStyle is set to Medium6 but ignored
2019-04-07 14:47:06 -04:00
Doug Finke
62f0faa5c5 Merge pull request #574 from ili101/TestsFix
Fix Test accidentally closing focused window
2019-04-07 12:50:56 -04:00
ili101
1055bc41bf TableStyle is set to Medium6 but ignored 2019-04-07 18:16:35 +03:00
ili101
e100fa7a36 Fix Test accidentally closing focused window if focus not switched to Out-GridView. 2019-04-07 15:02:50 +03:00
dfinke
83bd387f98 Update what's new 2019-04-06 11:30:10 -04:00
dfinke
caf0059ef5 Bumped version, sorted function exports 2019-04-06 11:20:15 -04:00
Doug Finke
965831ba57 Merge pull request #573 from jhoneill/master
Perf improvements for Export-Excel
2019-04-06 11:13:47 -04:00
jhoneill
a49cab5efc Slimmed down send-sqlData - undid previous 2019-04-06 10:49:57 +01:00
jhoneill
17bcea15e8 Fixed a poss parameter set issue; 2019-04-06 00:21:48 +01:00
jhoneill
79fb29740d Rolled back readme for merge purposes 2019-04-04 18:03:49 +01:00
jhoneill
2984fe2ef5 Merge branch 'master' of https://github.com/jhoneill/ImportExcel 2019-04-04 18:01:31 +01:00
jhoneill
8734dbd26c Readme update 2019-04-04 18:01:26 +01:00
jhoneill
0211edf008 Readme update 2019-04-04 17:42:33 +01:00
jhoneill
552552b93d Perf improvments and direct table handling for Export Excel, 2019-04-04 17:08:05 +01:00
jhoneill
2229bfb3ed Moved Add-CellValue 2019-04-04 09:45:10 +01:00
Doug Finke
25e7962100 Merge pull request #564 from slestak/patch-1
Update Export-Excel.ps1 - Add-Worksheet help typo
2019-03-19 13:02:01 -04:00
Steve Romanow
6071f77218 Update Export-Excel.ps1
fix typo
2019-03-19 11:56:20 -04:00
dfinke
52b9333d7c added regions 2019-03-03 12:56:35 -05:00
dfinke
d3d8d76a71 fixed psm1. added .ps1 to Set-WorkSheetProtection 2019-03-02 14:03:26 -05:00
dfinke
f5f97fcd56 bumped the read up 100 ms 2019-03-02 13:24:19 -05:00
dfinke
6665c2952d fix readme 2019-03-02 13:17:22 -05:00
dfinke
31444320cb Updated 2019-03-02 13:15:16 -05:00
dfinke
d5734ff9b2 Pulled from the tests. Added additional rule 2019-03-02 13:13:53 -05:00
dfinke
4481637c21 spell check 2019-03-02 12:40:45 -05:00
dfinke
6caf247f5b bump version 2019-03-02 12:38:10 -05:00
Doug Finke
65641955ba Merge pull request #552 from jhoneill/master
Minor fixes and added data-validation support
2019-03-02 12:32:43 -05:00
jhoneill
f2c13949a4 Fixed Send-SQLData behavior with tables/ranges when adding to a sheet 2019-03-01 08:31:43 +00:00
jhoneill
878ca570fb Updated readme for recent commits 2019-02-28 07:42:22 +00:00
jhoneill
28fd5512bb Fixed broken tests 2019-02-25 20:53:11 +00:00
jhoneill
7e465e3729 Merge remote-tracking branch 'upstream/master' 2019-02-25 19:33:51 +00:00
jhoneill
22283604f8 Sync with DFinke's master 2019-02-25 18:14:46 +00:00
jhoneill
0c603afc0e improved handing of Hyperlinks in Export 2019-02-21 19:25:53 +00:00
Doug Finke
a4a989c556 Update Get-HtmlTable.ps1 2019-02-20 19:26:43 -05:00
dfinke
d94db666d7 Added module 2019-02-18 14:06:18 -05:00
dfinke
438be760f7 updated 2019-02-18 13:51:50 -05:00
dfinke
2949ecc173 update 2019-02-17 18:27:41 -05:00
dfinke
639ca738f6 rearrange 2019-02-17 18:27:36 -05:00
dfinke
736dd648f4 Updated git ignore 2019-02-17 15:36:05 -05:00
dfinke
acdbd4a618 added demo 2019-02-13 19:08:01 -05:00
dfinke
ad35d39850 Removed unneed tests 2019-02-13 16:23:37 -05:00
dfinke
e7afe166a4 Updated to point to new rest api for stock info 2019-02-02 16:58:57 -05:00
dfinke
37b076706e rename file 2019-02-02 16:58:57 -05:00
jhoneill
3303116658 Test for validation rules had un-necessary cleanup step which caused an error 2019-01-21 14:31:04 +00:00
jhoneill
89a8cb0469 Added data validation 2019-01-21 14:20:57 +00:00
Doug Finke
bb9f4c31a6 Delete ImportExcel-5.4.2-20181217155848.zip
not needed
2019-01-18 19:49:14 -05:00
Doug Finke
996d1246cf Merge pull request #523 from stahler/patch-1
Update Export-Excel.ps1
2019-01-11 21:08:24 -05:00
Wes Stahler
0bb08fcb20 Update Export-Excel.ps1 2019-01-11 20:49:08 -05:00
Doug Finke
d004019761 Merge pull request #520 from dfinke/FixCopyExcelWorksheetStreamClose-dcf
Fix Copy-ExcelWorkSheet so Remove-WorkSheet works. Resolves #516
2019-01-05 09:57:17 -05:00
dfinke
a54ca228e9 Resolves #516 2019-01-05 09:54:52 -05:00
dfinke
bb6ff474a8 updated readme 2019-01-05 09:53:38 -05:00
dfinke
86b5c13543 Close the $Stream so the xlsx won't be locked 2019-01-05 09:49:48 -05:00
dfinke
c2525b0348 Add tests to show the IOException: The process cannot access the file 2019-01-05 09:42:37 -05:00
dfinke
9625e4a8ac Update ReadME 2018-12-31 18:53:54 -05:00
dfinke
82177da695 Bump release 2018-12-31 18:53:45 -05:00
Doug Finke
b3f7a60be8 Merge pull request #517 from dfinke/FixAutoNameRange-dcf
Fix auto name range when a single property is incoming
2018-12-31 18:48:09 -05:00
dfinke
643610c267 Add test for a single property name 2018-12-31 18:45:26 -05:00
dfinke
bd7d70a050 Fix when only one property name is in the incoming data 2018-12-31 18:45:16 -05:00
Doug Finke
d1f41012a1 Merge pull request #514 from dfinke/AddRemoveWorksheet-dcf
Add Remove-Workseet
2018-12-30 09:42:53 -05:00
dfinke
0fbe9dbc9b update readme 2018-12-30 09:38:43 -05:00
dfinke
e0b2d15c53 bump version 2018-12-30 09:38:36 -05:00
dfinke
34c924ae19 Handles piping in the a list of xlsx files 2018-12-30 09:34:44 -05:00
dfinke
9217962306 Update and fix tests 2018-12-30 08:52:19 -05:00
dfinke
56acf56430 Add code to do removal 2018-12-30 08:52:11 -05:00
dfinke
ef9be471ab First test 2018-12-30 08:45:51 -05:00
dfinke
9db2bc068e Added to psm1 2018-12-30 08:29:18 -05:00
dfinke
9560ea83f9 updated 2018-12-20 09:15:25 -05:00
dfinke
9c79ba573c updated 2018-12-20 09:13:45 -05:00
Doug Finke
894e645a47 Update MultiplePivotTables.ps1 2018-12-20 09:01:21 -05:00
dfinke
f3dc390bfa Added example showing how to create mutiple pivottables on a single sheet 2018-12-17 16:00:40 -05:00
dfinke
f0f58f84a0 Added Timestamp Bucket example 2018-12-10 15:16:11 -05:00
dfinke
7ded24d2f9 updated with example for grouping numeric 2018-12-08 08:35:20 -05:00
dfinke
cf964e3e4f added grouping image for example 2018-12-08 08:32:20 -05:00
dfinke
8c5b3b2f5f Added Places and Points examples. Taken from unit tests 2018-12-07 18:08:50 -05:00
dfinke
8409adeeba Fix param names in tests 2018-12-07 14:42:04 -05:00
dfinke
153d4d8c45 bump version 2018-12-07 14:33:44 -05:00
dfinke
69f9ba7d17 Fix spelling for GroupNumber* params 2018-12-07 14:33:38 -05:00
dfinke
e4deb5801e fixed spelling 2018-12-07 13:25:20 -05:00
Doug Finke
1a74c0f0d0 Merge pull request #501 from jhoneill/master
Added Pivot table grouping
2018-12-07 13:17:40 -05:00
jhoneill
72e44da219 Put back DoTests and yml file. Updated readme for pivot groups 2018-12-06 21:38:13 +00:00
jhoneill
bef2f29651 Revert "Update DoTests.ps1"
This reverts commit c5cc018eb5.
2018-12-06 20:16:45 +00:00
jhoneill
787dda70ee Revert "Take verbose back out of DoTests"
This reverts commit 268d48ce3d.
2018-12-06 20:16:34 +00:00
jhoneill
285e9e4949 Revert "Update azure-pipelines.yml"
This reverts commit eca631670c.
2018-12-06 20:16:25 +00:00
jhoneill
01e3ea206d Revert "One more"
This reverts commit 284560e109.
2018-12-06 20:16:09 +00:00
jhoneill
6f3420d11e Revert "path fix"
This reverts commit 234615dfdb.
2018-12-06 20:15:45 +00:00
jhoneill
2981bf23b1 Added Pivot table grouping 2018-12-06 17:45:10 +00:00
jhoneill
c5cc018eb5 Update DoTests.ps1 2018-11-30 16:58:08 +00:00
jhoneill
268d48ce3d Take verbose back out of DoTests 2018-11-30 16:45:11 +00:00
jhoneill
eca631670c Update azure-pipelines.yml 2018-11-30 16:33:06 +00:00
jhoneill
284560e109 One more 2018-11-30 16:26:45 +00:00
jhoneill
234615dfdb path fix 2018-11-30 16:25:02 +00:00
jhoneill
d31cd04781 Merge remote-tracking branch 'upstream/master' 2018-11-30 16:20:01 +00:00
jhoneill
77481f2901 More of the same 2018-11-30 16:18:46 +00:00
jhoneill
54fec69f88 Merge branch 'master' of https://github.com/jhoneill/ImportExcel 2018-11-30 16:06:07 +00:00
jhoneill
1dc9a02d7d Updates to azure pipeline 2018-11-30 16:05:58 +00:00
azure-pipelines[bot]
f86fdbab22 Set up CI with Azure Pipelines 2018-11-30 14:46:43 +00:00
dfinke
66937db040 Did expand alias 2018-11-27 09:55:05 -05:00
dfinke
80520299aa Added Apply Style example 2018-11-27 09:44:15 -05:00
jhoneill
2753a6876a Better handling of Empry values when setting Columns/Rows 2018-11-27 11:03:06 +00:00
dfinke
ade442b18c animation for export stocks 2018-11-25 16:16:39 -05:00
dfinke
45ba112f73 bump version 2018-11-25 16:16:28 -05:00
dfinke
e1fe36699b Added Export-StocksToExcel 2018-11-25 16:16:16 -05:00
dfinke
b3f4b188da updated 2018-11-20 19:16:22 -05:00
dfinke
0ce75794e6 Added Mortgate Calculator 2018-11-20 13:21:04 -05:00
jhoneill
3afe2059e5 Added message to say title is ignored when exporting with -Append. 2018-11-20 10:52:29 +00:00
dfinke
66b7b64779 fix fontcolor 2018-11-19 18:50:13 -05:00
Doug Finke
d90cd6d2d0 Merge pull request #493 from jhoneill/master
TO Do #491 Done
2018-11-18 09:20:49 -05:00
jhoneill
1d1f266fb6 Better checks for invalid table names 2018-11-15 16:22:36 +00:00
jhoneill
4945b4d6e3 Fix to readme 2018-11-15 12:33:03 +00:00
jhoneill
21b5a11aca Trap invalid worksheet name in Set-ExcelRow/Column 2018-11-13 10:16:51 +00:00
dfinke
d1976bf3a9 Prepped for 5.4.0 2018-11-03 11:33:15 -04:00
Doug Finke
ffcdd39ae9 Merge pull request #488 from jhoneill/master
Chart supports multiple X ranges and headers from cells
2018-11-03 15:03:45 +00:00
jhoneill
b4b5e75d28 Chart supports multiple X ranges and headers from cells 2018-11-03 13:20:30 +00:00
Doug Finke
4c3eb792d6 Merge pull request #482 from jhoneill/master
Parameter clean up, improvements to Merge-MultipleSheets
2018-11-01 22:07:41 +00:00
jhoneill
c4ef920bdf Fix stray $ in addConditionalFormatting. Updated readme 2018-11-01 21:56:37 +00:00
jhoneill
d81c2055e9 Found/Fixed more issues where zero or empty parameters should be allowed but where skipped. 2018-10-29 11:55:51 +00:00
jhoneill
4528f3b052 Merge remote-tracking branch 'upstream/master' 2018-10-29 07:34:12 +00:00
dfinke
5acec641fe updated 2018-10-25 18:32:44 -04:00
Doug Finke
04d06ff008 Merge pull request #474 from conradagramont/patch-1
Create AddMultiWorkSheet.ps1
2018-10-25 22:15:29 +00:00
jhoneill
1974beef2d Improved handling of Piped files in Merge-MultipleSheets 2018-10-25 15:11:21 +01:00
jhoneill
49f0c97635 Merge remote-tracking branch 'upstream/master' 2018-10-25 10:40:51 +01:00
jhoneill
0710724e2d Added code for -Passthru in Merge-MultipleSheets 2018-10-25 09:40:50 +01:00
Doug Finke
a6438d468a Update appveyor.yml
Save for another time. Looks like path separators are the first issue
2018-10-24 19:56:25 -04:00
Doug Finke
ce92461efc Update appveyor.yml
Enable Linux image for CI
2018-10-24 19:50:47 -04:00
Doug Finke
b3c4a334b5 Merge pull request #477 from jhoneill/master
Tests now handle V6 Process objects (more properties)
2018-10-24 23:47:08 +00:00
Conrad Agramont
6b2190bfff Updated AddMultiWorkSheet
Removed the extra code that wasn't required.
2018-10-24 16:37:10 -07:00
jhoneill
5822ef330e Merge remote-tracking branch 'upstream/master' 2018-10-24 23:32:58 +01:00
jhoneill
d78e3fff98 Tests now handle V6 Process objects (more properties) 2018-10-24 23:23:26 +01:00
Doug Finke
85bd85ee69 Merge pull request #475 from jhoneill/master
Colors for PS core and proof reading
2018-10-24 21:26:35 +00:00
jhoneill
04e8faaccc Re-instated trap for empty sheet in set row/col 2018-10-24 17:45:51 +01:00
jhoneill
2c062a4e5d Merge branch 'master' into master 2018-10-24 17:27:23 +01:00
jhoneill
80c1a945f0 Revert "Trap set row and column on empty shet"
This reverts commit 1d5ec26b04.
2018-10-24 17:18:59 +01:00
jhoneill
1d5ec26b04 Trap set row and column on empty shet 2018-10-24 17:14:33 +01:00
Conrad Agramont
860b2724f5 Create AddMultiWorkSheet.ps1
This example shows how to add multiple tabs within the same file.
2018-10-23 10:01:29 -07:00
jhoneill
c38648a654 Fix for color not casting strings in PS Core 2018-10-22 17:21:09 +01:00
jhoneill
dcd730a4d1 Fixed stray char in addConditional formatting 2018-10-21 22:33:59 +01:00
jhoneill
0fdaeb977b Help updates after more proof-reading 2018-10-19 11:12:46 +01:00
jhoneill
61173d5e40 Updates after proof reading help 2018-10-17 11:23:15 +01:00
jhoneill
d26f0c66dd More PS6 friendly tests. Help and pos param tweaks in Conditional Fmt 2018-10-15 13:14:14 +01:00
dfinke
fe4fcff444 Added synopsis 2018-10-10 14:12:23 -04:00
jhoneill
01c58faea8 Color constants are now [color] objects, not string for V6 compat. 2018-10-10 10:36:36 +01:00
dfinke
dce2f6d108 Set switch -DontCreateZip 2018-10-09 20:05:38 -04:00
dfinke
49afad6977 added pwsh to run tests in 2018-10-09 19:59:48 -04:00
jhoneill
b7add5f9e1 Changed color default parameters away from strings 2018-10-09 23:01:55 +01:00
Doug Finke
c07fc81dfe Merge pull request #458 from jhoneill/master
Fixed #457 & a couple more tweaks
2018-10-08 17:05:41 -04:00
jhoneill
3835ceeebb Better parameter sets for merge. Fixed bug with setting font name. 2018-10-08 21:35:19 +01:00
Doug Finke
6683bed799 Merge pull request #455 from SQLvariant/master
Added Example for SQL Server
2018-10-08 14:47:27 -04:00
dfinke
20aade4bdd Add Switch $DontCreateZip 2018-10-08 14:17:09 -04:00
dfinke
b6965e0724 azure devops did *not* skip 2018-10-06 16:26:15 -04:00
dfinke
9d85c6cb81 test for azure build pipeline to skip the build 2018-10-06 16:25:12 -04:00
dfinke
a17fc95415 adde azure devops yaml file 2018-10-06 16:21:54 -04:00
dfinke
ecb045274a remove line from readme 2018-10-06 16:13:40 -04:00
dfinke
e5c4a715d6 see if appveyor skips after checking in the readme 2018-10-06 16:12:16 -04:00
dfinke
e27e98a9eb Added skip_commits section 2018-10-06 16:10:02 -04:00
Doug Finke
9da8bf8bf7 Merge pull request #456 from dbaileyut/dbaileyut-patch-fixTypo
* Fix typo in Import-Excel help description
2018-10-05 17:59:32 -04:00
dbaileyut
50905c7989 * Fix typo in Import-Excel help description 2018-10-05 16:04:19 -05:00
jhoneill
91a7c17341 perf: removed verbose from loop in import. tests: better alias check 2018-10-04 21:31:47 +01:00
Aaron Nelson
3c18af50b9 Added Example for SQL Server to Import-Excel
Added an example for INSERTing rows into a SQL Server table from the Import-Excel function.
2018-10-04 15:36:42 -04:00
jhoneill
66f5d09ace Better param sets in Merge-WS & conditional formatting in Merge-Multi 2018-10-04 20:13:33 +01:00
Aaron Nelson
fa64299760 Added Example for SQL Server
Added an example for running a query from a SQL Server database using the Invoke-Sqlcmd cmdlet, and then exporting the results to Excel.
2018-10-04 14:29:33 -04:00
Doug Finke
c36e5fb582 Merge pull request #454 from dfinke/FixPivotStyleName
Renamed PivotTableSyle to PivotTableStyle - fixes #453
2018-10-04 10:00:18 -04:00
dfinke
5158addc36 Hotfix for misnamed parameter 2018-10-04 09:57:22 -04:00
dfinke
bf2e37ac9f bumped version to 5.3.4 2018-10-04 09:57:04 -04:00
dfinke
d22d40cdc2 Renamed PivotTableSyle to PivotTableStyle - fixes #453 2018-10-03 19:26:37 -04:00
dfinke
df49e04c6c tweak readme 2018-10-03 08:38:58 -04:00
dfinke
f60ca87358 bumped version 2018-10-03 08:34:45 -04:00
dfinke
cef95f9ebe Added to the readme 2018-10-03 08:34:31 -04:00
Doug Finke
288071035f Merge pull request #450 from jhoneill/master
Readme only
2018-10-03 08:25:31 -04:00
jhoneill
414d1ac72b Git Markup stuck in Readme 2018-10-03 12:05:01 +01:00
jhoneill
1c7241774f Three extra lines in readme.md 2018-10-03 10:55:54 +01:00
jhoneill
7c773ff915 Three extra lines in Readme.MD 2018-10-03 10:54:15 +01:00
jhoneill
46de6c5934 Two extra lines in Readme.MD 2018-10-03 10:47:04 +01:00
Doug Finke
955c737bb7 Merge pull request #449 from jhoneill/master
Fix for bug handling null and zero; date format applied in send-sql
2018-10-02 16:58:22 -04:00
jhoneill
74e5fee161 Fixed bugs relating to handling of null. zero and empty string as data. 2018-10-02 21:15:16 +01:00
Doug Finke
c3331e8f09 Merge pull request #446 from lazywinadmin/master
Expand a few aliases
2018-10-01 20:18:42 -04:00
François-Xavier Cat
1951a61699 Expand a few aliases 2018-10-01 17:01:15 -07:00
jhoneill
5b29ccd9c2 Send-SQLDataToExcel applies formatting to date fields. 2018-09-30 22:49:35 +01:00
Doug Finke
d8bd5a8cb6 Merge pull request #444 from jhoneill/master
Minor improvements
2018-09-28 17:42:45 -04:00
Doug Finke
820722b481 Merge branch 'master' into master 2018-09-28 17:40:58 -04:00
Doug Finke
08c82977f5 Merge pull request #442 from dfinke/RenameToLegendPosition
Renamed LegendPostion to LegendPosition
2018-09-28 17:33:40 -04:00
jhoneill
a2dd42fc80 Blitz on spelling mistakes in help. Still not 100% proof-read. 2018-09-28 12:07:22 +01:00
jhoneill
c1d778ef85 Readme update 2018-09-27 15:05:07 +01:00
jhoneill
7abb5dde89 Updates to help text (more proof reading still needed) 2018-09-27 14:55:21 +01:00
jhoneill
0f15f3e3e5 fixed incorrect range in chart test 2018-09-27 12:26:43 +01:00
jhoneill
3194bb0ee4 Merge branch 'master' of https://github.com/jhoneill/ImportExcel 2018-09-27 12:24:31 +01:00
jhoneill
b1f716f0d5 Better handling of autonamerange including piping columns to Set-Column to do multiple ranges. 2018-09-27 12:24:23 +01:00
jhoneill
a8f7a13248 Better handling of autonamerange including piping columns to Set-Column to do multiple ranges. 2018-09-27 12:00:01 +01:00
dfinke
d200a2929b Added Azure-DevOps build tag 2018-09-26 18:47:58 -04:00
dfinke
99e69bd6c0 Renamed LegendPostion to LegendPosition 2018-09-26 16:32:10 -04:00
dfinke
4f0c0d7c28 bumped, fix for aliases 2018-09-20 13:58:13 -04:00
Doug Finke
968d5a57b6 Merge pull request #438 from dfinke/TestFunctionAliases
Added ps1 to for testing aliases
2018-09-20 12:33:06 -04:00
dfinke
bdefb45095 Remove space from Alias attribute 2018-09-20 12:12:53 -04:00
dfinke
4297d2ef82 Confirms the errors 2018-09-20 12:09:19 -04:00
dfinke
a49bdb3abc Added ps1 to for testing aliases 2018-09-20 12:01:34 -04:00
dfinke
a983ecd765 Move to using Robocopy and the /mir flag 2018-09-20 11:44:53 -04:00
dfinke
5a7d84e624 Added comment for usage 2018-09-20 10:22:36 -04:00
dfinke
e0f5d9f789 Removed these files - look unused 2018-09-20 10:22:27 -04:00
dfinke
7d3bcb810c bumped build # 2018-09-20 09:25:14 -04:00
dfinke
8975aa2e95 Added PivotTable.ps1 2018-09-20 09:24:50 -04:00
dfinke
77f30f105b Spell check 2018-09-19 13:49:44 -04:00
dfinke
972142f727 Bumped version, add header to readme 2018-09-19 08:11:33 -04:00
Doug Finke
cfd1ac99b2 Merge pull request #435 from jhoneill/master
Improved help, minor bugfixes and parameter improvments, more tests
2018-09-19 07:48:41 -04:00
jhoneill
e09c5e5207 Further polish to help 2018-09-11 15:34:37 +01:00
jhoneill
3ff59907ff Improvements to help 2018-09-11 14:05:23 +01:00
jhoneill
ef4ac9777b Updates to examples . Minor bug fix to format in Merge-Multiple 2018-09-10 14:26:29 +01:00
jhoneill
65b1f79d53 Range handling for Add-Conditional format and range tests 2018-09-09 15:10:05 +01:00
jhoneill
ecad48acb3 Set-Format,row and column renamed; definitions as hashtables, 2018-09-08 18:36:51 +01:00
jhoneill
f47887f7fe Support for hash tables as definitions; more tests 2018-09-07 13:07:40 +01:00
jhoneill
061ae22bfe Added TotalSettings to Add-ExcelTable 2018-09-06 20:39:40 +01:00
jhoneill
53b63b3780 Better support of reverse in add-conditional formatting. Tidied Exampes 2018-09-06 15:23:58 +01:00
jhoneill
378a20a094 Further refinements to Conditional format, made new test more robust 2018-09-05 16:56:48 +01:00
jhoneill
7edf5f8a3a Conditional formatting supports named ranges, & booleans in the sheet 2018-09-05 13:38:17 +01:00
jhoneill
6393701a2f Further updates to on-line help 2018-09-05 11:44:41 +01:00
jhoneill
71c22d647d A blitz on on line help 2018-09-04 22:56:20 +01:00
jhoneill
ef656f72b3 Updated Tests 2018-09-02 13:57:21 +01:00
jhoneill
dfd9b23cd7 See readme.md for details 2018-08-31 17:22:52 +01:00
jhoneill
f94a075f52 Better checks and more choice in Conditional formatting 2018-08-23 12:14:47 +01:00
jhoneill
cea9713129 Relocation of and parameter improvments to Chart, & Pivot table; 2018-08-23 12:12:56 +01:00
dfinke
343687c418 bump version 2018-08-18 06:29:08 -04:00
dfinke
d4d2b4a856 Spell check 2018-08-16 19:26:50 -04:00
Doug Finke
bed52d456d Merge pull request #416 from jhoneill/master
Fix for #415, auto extend ranges/tables on append, password fixes, wildcards in Exclude property
2018-08-16 13:23:30 -04:00
jhoneill
31e6eaf59b Clean-up of Set-Row/Column (value no long mandatory); support array formulas in set-format 2018-08-16 17:33:44 +01:00
jhoneill
d770646dc7 Fixed small bug with Append and simple data types 2018-08-15 23:44:00 +01:00
jhoneill
bc65699068 Improved behavior of -NumberFormat in Export-Excel 2018-08-15 22:52:22 +01:00
jhoneill
ce3fd2021f Fix currency parsing Test when "." isn't a seperator in local culture 2018-08-14 17:32:34 +01:00
jhoneill
10f670b4e6 Added timespan support to export Excel 2018-08-14 16:35:19 +01:00
jhoneill
c49b7b6db0 Epplus is not setting chart axis position properly, so disabled for now 2018-08-14 15:40:52 +01:00
jhoneill
f768634214 Refined fix for #419 2018-08-14 12:54:17 +01:00
jhoneill
07342235b9 Fixed bug exporting nested objects; removed = in cond fmt expressions 2018-08-14 10:53:50 +01:00
jhoneill
2793ff1c21 Added -Calculate, fixed formula creation to be EPPlus-friendly 2018-08-13 20:58:10 +01:00
jhoneill
121346f939 Merge branch 'master' of https://github.com/jhoneill/ImportExcel 2018-08-12 15:07:16 +01:00
jhoneill
dc8a096732 Reduced number of proccess in tests to be appveyor freindly 2018-08-12 15:03:33 +01:00
jhoneill
c63512e658 Further fix to DLL screw up 2018-08-12 14:37:09 +01:00
jhoneill
e46fe6d3e9 Updated tests (and resulting refinements) 2018-08-12 14:01:56 +01:00
jhoneill
6ae50c3193 Mistakenly committed renamed epplus.dll 2018-08-12 11:41:46 +01:00
jhoneill
ee2378150c Merge remote-tracking branch 'upstream/master' 2018-08-10 10:23:03 +01:00
jhoneill
259c7e8ae6 Export-Excel -append now automatically extends ranges & tables 2018-08-10 09:29:17 +01:00
dfinke
ae30bfe6c3 don't test ps core 2018-08-08 19:44:09 -04:00
dfinke
3756cd6ad8 set scope 2018-08-08 19:40:33 -04:00
dfinke
1014250e0b try it in PS Core 6 and on Linux 2018-08-08 19:32:15 -04:00
jhoneill
951364da51 Now supports more than 26 columns. 2018-08-08 15:48:53 +01:00
jhoneill
c1604fc08a Exclude Property in Export-Excel now supports wildcards 2018-08-07 16:16:45 +01:00
jhoneill
5a235e309e Tider errors for file open on import; password tests 2018-08-07 15:00:33 +01:00
jhoneill
af77580b5e Password support fixes 2018-08-06 14:30:10 +01:00
jhoneill
b06a5059c5 Updated test for better currency string 2018-08-06 14:21:35 +01:00
jhoneill
edab941c44 Bug fix Export list of dates and Title background color 2018-08-06 11:13:27 +01:00
jhoneill
91fb314bca Expand Number format now sets regional layout for currency 2018-08-06 11:12:41 +01:00
138 changed files with 6504 additions and 4859 deletions

6
.gitignore vendored
View File

@@ -2,6 +2,8 @@
Thumbs.db
ehthumbs.db
*.gitignore
# Folder config file
Desktop.ini
@@ -14,6 +16,8 @@ $RECYCLE.BIN/
*.msm
*.msp
*.dll
# Windows shortcuts
*.lnk
@@ -57,4 +61,6 @@ testCCFMT.ps1
testHide.ps1
ImportExcel.zip
.vscode/launch.json
.vscode/settings.json
~$*

View File

@@ -28,3 +28,10 @@ PivtoTableName
New-Excelchart
paypal
dll
enums
Numberformat
ChartDefiniton
hashtables
Agramont
AGramont
Jhoneill

View File

@@ -1,148 +1,270 @@
Function Add-ConditionalFormatting {
<#
.Synopsis
Adds contitional formatting to worksheet.
Adds conditional formatting to all or part of a worksheet.
.Description
Conditional formatting allows Excel to:
* Mark cells with icons depending on their value
* Show a databar whose length indicates the value or a two or three color scale where the color indicates the relative value
* Change the color, font, or number format of cells which meet given criteria
Add-ConditionalFormatting allows these parameters to be set; for fine tuning of
the rules, the -PassThru switch will return the rule so that you can modify
things which are specific to that type of rule, example, the values which
correspond to each icon in an Icon-Set.
.Example
>
$excel = $avdata | Export-Excel -Path (Join-path $FilePath "\Machines.XLSX" ) -WorksheetName "Server Anti-Virus" -AutoSize -FreezeTopRow -AutoFilter -PassThru
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "b2:b1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "2003"
Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Address "i2:i1048576" -ForeGroundColor "RED" -RuleType ContainsText -ConditionValue "Disabled"
$excel.Workbook.Worksheets[1].Cells["D1:G1048576"].Style.Numberformat.Format = [cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern
$excel.Workbook.Worksheets[1].Row(1).style.font.bold = $true
$excel.Save() ; $excel.Dispose()
Here Export-Excel is called with the -passThru parameter so the Excel Package object is stored in $Excel
The desired worksheet is selected and the then columns B and i are conditially formatted (excluding the top row) to show red text if
the columns contain "2003" or "Disabled respectively. A fixed date formats are then applied to columns D..G, and the top row is formatted.
Finally the workbook is saved and the Excel object closed.
Here Export-Excel is called with the -PassThru parameter so the ExcelPackage object
representing Machines.XLSX is stored in $Excel.The desired worksheet is selected
and then columns" B" and "I" are conditionally formatted (excluding the top row)
to show red text if they contain "2003" or "Disabled" respectively.
A fixed date format is then applied to columns D to G, and the top row is formatted.
Finally the workbook is saved and the Excel package object is closed.
.Example
C:\> $r = Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Range "B1:B100" -ThreeIconsSet Flags -Passthru
C:\> $r.Reverse = $true ; $r.Icon1.Type = "Num"; $r.Icon2.Type = "Num" ; $r.Icon2.value = 100 ; $r.Icon3.type = "Num" ;$r.Icon3.value = 1000
>
$r = Add-ConditionalFormatting -WorkSheet $excel.Workbook.Worksheets[1] -Range "B1:B100" -ThreeIconsSet Flags -Passthru
$r.Reverse = $true ; $r.Icon1.Type = "Num"; $r.Icon2.Type = "Num" ; $r.Icon2.value = 100 ; $r.Icon3.type = "Num" ;$r.Icon3.value = 1000
Again Export-Excel has been called with -PassThru leaving a package object
in $Excel. This time B1:B100 has been conditionally formatted with 3 icons,
using the "Flags" Icon-Set. Add-ConditionalFormatting does not provide access
to every option in the formatting rule, so -PassThru has been used and the
rule is modified to apply the flags in reverse order, and transitions
between flags are set to 100 and 1000.
.Example
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
This time $sheet holds an ExcelWorkshseet object and databars are added to
column D, excluding the top row.
.Example
Add-ConditionalFormatting -Address $worksheet.cells["FinishPosition"] -RuleType Equal -ConditionValue 1 -ForeGroundColor Purple -Bold -Priority 1 -StopIfTrue
In this example a named range is used to select the cells where the condition
should apply, and instead of specifying a sheet and range within the sheet as
separate parameters, the cells where the format should apply are specified
directly. If a cell in the "FinishPosition" range is 1, then the text is
turned to Bold & Purple. This rule is moved to first in the priority list,
and where cells have a value of 1, no other rules will be processed.
.Example
>
$excel = Get-ChildItem | Select-Object -Property Name,Length,LastWriteTime,CreationTime | Export-Excel "$env:temp\test43.xlsx" -PassThru -AutoSize
$ws = $excel.Workbook.Worksheets["Sheet1"]
$ws.Cells["E1"].Value = "SavedAt"
$ws.Cells["F1"].Value = [datetime]::Now
$ws.Cells["F1"].Style.Numberformat.Format = (Expand-NumberFormat -NumberFormat 'Date-Time')
$lastRow = $ws.Dimension.End.Row
Add-ConditionalFormatting -WorkSheet $ws -address "A2:A$Lastrow" -RuleType LessThan -ConditionValue "A" -ForeGroundColor Gray
Add-ConditionalFormatting -WorkSheet $ws -address "B2:B$Lastrow" -RuleType GreaterThan -ConditionValue 1000000 -NumberFormat '#,###,,.00"M"'
Add-ConditionalFormatting -WorkSheet $ws -address "C2:C$Lastrow" -RuleType GreaterThan -ConditionValue "=INT($F$1-7)" -ForeGroundColor Green -StopIfTrue
Add-ConditionalFormatting -WorkSheet $ws -address "D2:D$Lastrow" -RuleType Equal -ConditionValue "=C2" -ForeGroundColor Blue -StopIfTrue
Close-ExcelPackage -Show $excel
The first few lines of code export a list of file and directory names, sizes
and dates to a spreadsheet. It puts the date of the export in cell F1.
The first Conditional format changes the color of files and folders that begin
with a ".", "_" or anything else which sorts before "A".
The second Conditional format changes the Number format of numbers bigger than
1 million, for example 1,234,567,890 will dispay as "1,234.57M"
The third highlights datestamps of files less than a week old when the export
was run; the = is necessary in the condition value otherwise the rule will
look for the the text INT($F$1-7), and the cell address for the date is fixed
using the standard Excel $ notation.
The final Conditional format looks for files which have not changed since they
were created. Here the condition value is "=C2". The = sign means C2 is treated
as a formula, not literal text. Unlike the file age, we want the cell used to
change for each cell where the conditional format applies. The first cell in
the conditional format range is D2, which is compared against C2, then D3 is
compared against C3 and so on. A common mistake is to include the title row in
the range and accidentally apply conditional formatting to it, or to begin the
range at row 2 but use row 1 as the starting point for comparisons.
.Example
Add-ConditionalFormatting $ws.Cells["B:B"] GreaterThan 10000000 -Fore Red -Stop -Pri 1
This version shows the shortest syntax - the Address, Ruletype, and
Conditionvalue can be identified from their position, and ForegroundColor,
StopIfTrue and Priority can all be shortend.
Again Export excel has been called with -passthru leaving a package object in $Excel
This time B1:B100 has been conditionally formatted with 3 icons, using the flags icon set.
Add-ConditionalFormatting does not provide access to every option in the formatting rule, so passthru has been used and the
rule is to apply the flags in reverse order, and boundaries for the number which will set the split are set to 100 and 1000
#>
Param (
#The worksheet where the format is to be applied
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
#The area of the worksheet where the format is to be applied
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[OfficeOpenXml.ExcelAddress]$Range ,
#One or more row(s), column(s) and/or block(s) of cells to format
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
#A block of cells to format - you can use a named range with -Address $ws.names[1] or $ws.cells["RangeName"]
[Parameter(Mandatory = $true, Position = 0)]
[Alias("Range")]
$Address ,
#One of the standard named rules - Top / Bottom / Less than / Greater than / Contains etc.
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 3)]
[Parameter(Mandatory = $true, ParameterSetName = "NamedRuleAddress", Position = 3)]
#The worksheet where the format is to be applied
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
#A standard named-rule - Top / Bottom / Less than / Greater than / Contains etc.
[Parameter(Mandatory = $true, ParameterSetName = "NamedRule", Position = 1)]
[OfficeOpenXml.ConditionalFormatting.eExcelConditionalFormattingRuleType]$RuleType ,
#Text colour for matching objects
[Alias("ForeGroundColour")]
[System.Drawing.Color]$ForeGroundColor,
#colour for databar type charts
#Text color for matching objects
[Parameter(ParameterSetName = "NamedRule")]
[Alias("ForegroundColour")]
$ForegroundColor,
#Color for databar type charts
[Parameter(Mandatory = $true, ParameterSetName = "DataBar")]
[Parameter(Mandatory = $true, ParameterSetName = "DataBarAddress")]
[Alias("DataBarColour")]
[System.Drawing.Color]$DataBarColor,
$DataBarColor,
#One of the three-icon set types (e.g. Traffic Lights)
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "ThreeIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting3IconsSetType]$ThreeIconsSet,
#A four-icon set name
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FourIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting4IconsSetType]$FourIconsSet,
#A five-icon set name
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSet")]
[Parameter(Mandatory = $true, ParameterSetName = "FiveIconSetAddress")]
[OfficeOpenXml.ConditionalFormatting.eExcelconditionalFormatting5IconsSetType]$FiveIconsSet,
#Use the icon set in reverse order
#Use the Icon-Set in reverse order, or reverse the orders of Two- & Three-Color Scales
[Parameter(ParameterSetName = "NamedRule")]
[Parameter(ParameterSetName = "ThreeIconSet")]
[Parameter(ParameterSetName = "ThreeIconSetAddress")]
[Parameter(ParameterSetName = "FourIconSet")]
[Parameter(ParameterSetName = "FourIconSetAddress")]
[Parameter(ParameterSetName = "FiveIconSet")]
[Parameter(ParameterSetName = "FiveIconSetAddress")]
[switch]$Reverse,
#A value for the condition (e.g. "2000" if the test is 'lessthan 2000')
[string]$ConditionValue,
#A second value for the conditions like "between x and Y"
[string]$ConditionValue2,
#Background colour for matching items
[System.Drawing.Color]$BackgroundColor,
#A value for the condition (for example 2000 if the test is 'lessthan 2000'; Formulas should begin with "=" )
[Parameter(ParameterSetName = "NamedRule",Position = 2)]
$ConditionValue,
#A second value for the conditions like "Between X and Y"
[Parameter(ParameterSetName = "NamedRule",Position = 3)]
$ConditionValue2,
#Background color for matching items
[Parameter(ParameterSetName = "NamedRule")]
$BackgroundColor,
#Background pattern for matching items
[Parameter(ParameterSetName = "NamedRule")]
[OfficeOpenXml.Style.ExcelFillStyle]$BackgroundPattern = [OfficeOpenXml.Style.ExcelFillStyle]::None ,
#Secondary colour when a background pattern requires it
[System.Drawing.Color]$PatternColor,
#Secondary color when a background pattern requires it
[Parameter(ParameterSetName = "NamedRule")]
$PatternColor,
#Sets the numeric format for matching items
[Parameter(ParameterSetName = "NamedRule")]
$NumberFormat,
#Put matching items in bold face
[Parameter(ParameterSetName = "NamedRule")]
[switch]$Bold,
#Put matching items in italic
[Parameter(ParameterSetName = "NamedRule")]
[switch]$Italic,
#Underline matching items
[Parameter(ParameterSetName = "NamedRule")]
[switch]$Underline,
#Strikethrough text of matching items
[Parameter(ParameterSetName = "NamedRule")]
[switch]$StrikeThru,
#Prevent the processing of subsequent rules
[Parameter(ParameterSetName = "NamedRule")]
[switch]$StopIfTrue,
#Set the sequence for rule processing
[int]$Priority,
#If specified pass the rule back to the caller to allow additional customization.
[switch]$Passthru
[switch]$PassThru
)
#Allow conditional formatting to work like Set-Format (with single ADDRESS parameter), split it to get worksheet and range of cells.
If ($Address -and -not $WorkSheet -and -not $Range) {
$WorkSheet = $Address.Worksheet[0]
$Range = $Address.Address
#Allow conditional formatting to work like Set-ExcelRange (with single ADDRESS parameter), split it to get worksheet and range of cells.
If ($Address -is [OfficeOpenXml.Table.ExcelTable]) {
$WorkSheet = $Address.Address.Worksheet
$Address = $Address.Address.Address
}
elseif ($Address.Address -and $Address.Worksheet -and -not $WorkSheet) { #Address is a rangebase or similar
$WorkSheet = $Address.Worksheet[0]
$Address = $Address.Address
}
elseif ($Address -is [String] -and $WorkSheet -and $WorkSheet.Names[$Address] ) { #Address is the name of a named range.
$Address = $WorkSheet.Names[$Address].Address
}
if (($Address -is [OfficeOpenXml.ExcelRow] -and -not $WorkSheet) -or
($Address -is [OfficeOpenXml.ExcelColumn] -and -not $WorkSheet) ){ #EPPLUs Can't get the worksheet object from a row or column object, so bail if that was tried
Write-Warning -Message "Add-ConditionalFormatting does not support Row or Column objects as an address; use a worksheet and/or specify 'R:R' or 'C:C' instead. "; return
}
elseif ($Address -is [OfficeOpenXml.ExcelRow]) { #But if we have a column or row object and a worksheet (I don't know *why*) turn them into a string for the range
$Address = "$($Address.Row):$($Address.Row)"
}
elseif ($Address -is [OfficeOpenXml.ExcelColumn]) {
$Address = (New-Object 'OfficeOpenXml.ExcelAddress' @(1, $address.ColumnMin, 1, $address.ColumnMax).Address) -replace '1',''
if ($Address -notmatch ':') {$Address = "$Address`:$Address"}
}
if ( $Address -is [string] -and $Address -match "!") {$Address = $Address -replace '^.*!',''}
#By this point we should have a worksheet object whose ConditionalFormatting collection we will add to. If not, bail.
if (-not $worksheet -or $WorkSheet -isnot [OfficeOpenXml.ExcelWorksheet]) {write-warning "You need to provide a worksheet object." ; return}
#region create a rule of the right type
if ($RuleType -match 'IconSet$') {Write-warning -Message "You cannot configure a Icon-Set rule in this way; please use -$RuleType <SetName>." ; return}
if ($PSBoundParameters.ContainsKey("DataBarColor" ) ) {if ($DataBarColor -is [string]) {$DataBarColor = [System.Drawing.Color]::$DataBarColor }
$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Address , $DataBarColor )
}
elseif ($PSBoundParameters.ContainsKey("ThreeIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Address , $ThreeIconsSet)}
elseif ($PSBoundParameters.ContainsKey("FourIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Address , $FourIconsSet )}
elseif ($PSBoundParameters.ContainsKey("FiveIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Address , $FiveIconsSet )}
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Address ) }
if ($Reverse) {
if ($rule.type -match 'IconSet$' ) {$rule.reverse = $true}
elseif ($rule.type -match 'ColorScale$') {$temp =$rule.LowValue.Color ; $rule.LowValue.Color = $rule.HighValue.Color; $rule.HighValue.Color = $temp}
else {Write-Warning -Message "-Reverse was ignored because $ruletype does not support it."}
}
#region Create a rule of the right type
if ($PSBoundParameters.ContainsKey("ThreeIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddThreeIconSet($Range , $ThreeIconsSet)}
elseif ($PSBoundParameters.ContainsKey("FourIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFourIconSet( $Range , $FourIconsSet) }
elseif ($PSBoundParameters.ContainsKey("FiveIconsSet" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddFiveIconSet( $Range , $FiveIconsSet) }
elseif ($PSBoundParameters.ContainsKey("DataBarColor" ) ) {$rule = $WorkSheet.ConditionalFormatting.AddDatabar( $Range , $DataBarColor) }
else {$rule = ($WorkSheet.ConditionalFormatting)."Add$RuleType"($Range)}
if ($PSBoundParameters.ContainsKey("Reverse" ) ) {$rule.reverse = [boolean]$Reverse}
#endregion
#region set the rule conditions
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Top|Botom" ) {$rule.Rank = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "StdDev" ) {$rule.StdDev = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Than|Equal|Expression" ) {$rule.Formula = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Text|With" ) {$rule.Text = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue") -and
$PSBoundParameters.ContainsKey("ConditionValue") -and
$RuleType -match "Between" ) {
$rule.Formula = $ConditionValue;
$rule.Formula2 = $ConditionValue2
#for lessThan/GreaterThan/Equal/Between conditions make sure that strings are wrapped in quotes. Formulas should be passed with = which will be stripped.
if ($RuleType -match "Than|Equal|Between" ) {
if ($PSBoundParameters.ContainsKey("ConditionValue" )) {
$number = $Null
#if the condition type is not a value type, but parses as a number, make it the number
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
$ConditionValue = $number
} #else if it is not a value type, or a formula, or wrapped in quotes, wrap it in quotes.
elseif (($ConditionValue -isnot [System.ValueType])-and ($ConditionValue -notmatch '^=') -and ($ConditionValue -notmatch '^".*"$') ) {
$ConditionValue = '"' + $ConditionValue +'"'
}
}
if ($PSBoundParameters.ContainsKey("ConditionValue2")) {
$number = $Null
if ($ConditionValue -isnot [System.ValueType] -and [Double]::TryParse($ConditionValue2, [System.Globalization.NumberStyles]::Any, [System.Globalization.NumberFormatInfo]::CurrentInfo, [Ref]$number) ) {
$ConditionValue2 = $number
}
elseif (($ConditionValue -isnot [System.ValueType]) -and ($ConditionValue2 -notmatch '^=') -and ($ConditionValue2 -notmatch '^".*"$') ) {
$ConditionValue2 = '"' + $ConditionValue2 + '"'
}
}
}
#But we don't usually want quotes round containstext | beginswith type rules. Can't be Certain they need to be removed, so warn the user their condition might be wrong
if ($RuleType -match "Text|With" -and $ConditionValue -match '^".*"$' ) {
Write-Warning -Message "The condition will look for the quotes at the start and end."
}
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
$RuleType -match "Top|Botom" ) {$rule.Rank = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
$RuleType -match "StdDev" ) {$rule.StdDev = $ConditionValue }
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
$RuleType -match "Than|Equal|Expression" ) {$rule.Formula = ($ConditionValue -replace '^=','') }
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
$RuleType -match "Text|With" ) {$rule.Text = ($ConditionValue -replace '^=','') }
if ($PSBoundParameters.ContainsKey("ConditionValue" ) -and
$PSBoundParameters.ContainsKey("ConditionValue2") -and
$RuleType -match "Between" ) {
$rule.Formula = ($ConditionValue -replace '^=','');
$rule.Formula2 = ($ConditionValue2 -replace '^=','')
}
if ($PSBoundParameters.ContainsKey("StopIfTrue") ) {$rule.StopIfTrue = $StopIfTrue }
if ($PSBoundParameters.ContainsKey("Priority") ) {$rule.Priority = $Priority }
#endregion
#region set the rule format
if ($PSBoundParameters.ContainsKey("NumberFormat" ) ) {$rule.Style.NumberFormat.Format = (Expand-NumberFormat $NumberFormat) }
#region set the rule format
if ($PSBoundParameters.ContainsKey("NumberFormat" ) ) {$rule.Style.NumberFormat.Format = (Expand-NumberFormat $NumberFormat) }
if ($Underline ) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::Single }
elseif ($PSBoundParameters.ContainsKey("Underline" ) ) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::None }
if ($PSBoundParameters.ContainsKey("Bold" ) ) {$rule.Style.Font.Bold = [boolean]$Bold }
if ($PSBoundParameters.ContainsKey("Italic" ) ) {$rule.Style.Font.Italic = [boolean]$Italic }
if ($PSBoundParameters.ContainsKey("StrikeThru") ) {$rule.Style.Font.Strike = [boolean]$StrikeThru }
if ($PSBoundParameters.ContainsKey("ForeGroundColor" ) ) {$rule.Style.Font.Color.color = $ForeGroundColor }
if ($PSBoundParameters.ContainsKey("BackgroundColor" ) ) {$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
elseif ($PSBoundParameters.ContainsKey("Underline" ) ) {$rule.Style.Font.Underline = [OfficeOpenXml.Style.ExcelUnderLineType]::None }
if ($PSBoundParameters.ContainsKey("Bold" ) ) {$rule.Style.Font.Bold = [boolean]$Bold }
if ($PSBoundParameters.ContainsKey("Italic" ) ) {$rule.Style.Font.Italic = [boolean]$Italic }
if ($PSBoundParameters.ContainsKey("StrikeThru" ) ) {$rule.Style.Font.Strike = [boolean]$StrikeThru }
if ($PSBoundParameters.ContainsKey("ForeGroundColor" ) ) {if ($ForeGroundColor -is [string]) {$ForeGroundColor = [System.Drawing.Color]::$ForeGroundColor }
$rule.Style.Font.Color.color = $ForeGroundColor }
if ($PSBoundParameters.ContainsKey("BackgroundColor" ) ) {if ($BackgroundColor -is [string]) {$BackgroundColor = [System.Drawing.Color]::$BackgroundColor }
$rule.Style.Fill.BackgroundColor.color = $BackgroundColor }
if ($PSBoundParameters.ContainsKey("BackgroundPattern") ) {$rule.Style.Fill.PatternType = $BackgroundPattern }
if ($PSBoundParameters.ContainsKey("PatternColor" ) ) {$rule.Style.Fill.PatternColor.color = $PatternColor }
#endregion
#Allow further tweaking by returning the rule, if passthru specified
if ($PSBoundParameters.ContainsKey("PatternColor" ) ) {if ($PatternColor -is [string]) {$PatternColor = [System.Drawing.Color]::$PatternColor }
$rule.Style.Fill.PatternColor.color = $PatternColor }
#endregion
#Allow further tweaking by returning the rule, if passthru specified
if ($Passthru) {$rule}
}

99
AddDataValidation.ps1 Normal file
View File

@@ -0,0 +1,99 @@
Function Add-ExcelDataValidationRule {
<#
.Synopsis
Adds data validation to a range of cells
.Example
>
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'E2:E1001' -ValidationType Integer -Operator between -Value 0 -Value2 100 `
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody 'Percentage must be a whole number between 0 and 100'
This defines a validation rule on cells E2-E1001; it is an integer rule and requires a number between 0 and 100
If a value is input with a fraction, negative number, or positive number > 100 a stop dialog box appears.
.Example
>
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'B2:B1001' -ValidationType List -Formula 'values!$a$2:$a$1000'
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody 'You must select an item from the list'
This defines a list rule on Cells B2:1001, and the posible values are in a sheet named "values" at cells A2 to A1000
Blank cells in this range are ignored. If $ signs are left out of the fomrmula B2 would be checked against A2-A1000
B3, against A3-A1001, B4 against A4-A1002 up to B1001 beng checked against A1001-A1999
.Example
>
>Add-ExcelDataValidationRule -WorkSheet $PlanSheet -Range 'I2:N1001' -ValidationType List -ValueSet @('yes','YES','Yes')
-ShowErrorMessage -ErrorStyle stop -ErrorTitle 'Invalid Data' -ErrorBody "Select Yes or leave blank for no"
Similar to the previous example but this time provides a value set; Excel comparisons are case sesnsitive, hence 3 versions of Yes.
#>
[CmdletBinding()]
Param(
#The range of cells to be validate, e.g. "B2:C100"
[Parameter(ValueFromPipeline = $true,Position=0)]
[Alias("Address")]
$Range ,
#The worksheet where the cells should be validated
[OfficeOpenXml.ExcelWorksheet]$WorkSheet ,
#An option corresponding to a choice from the 'Allow' pull down on the settings page in the Excel dialog. Any means "any allowed" i.e. no Validation
[ValidateSet('Any','Custom','DateTime','Decimal','Integer','List','TextLength','Time')]
$ValidationType,
#The operator to apply to Decimal, Integer, TextLength, DateTime and time fields, e.g. equal, between
[OfficeOpenXml.DataValidation.ExcelDataValidationOperator]$Operator = [OfficeOpenXml.DataValidation.ExcelDataValidationOperator]::equal ,
#For Decimal, Integer, TextLength, DateTime the [first] data value
$Value,
#When using the between operator, the second data value
$Value2,
#The [first] data value as a formula. Use absolute formulas $A$1 if (e.g.) you want all cells to check against the same list
$Formula,
#When using the between operator, the second data value as a formula
$Formula2,
#When using the list validation type, a set of values (rather than refering to Sheet!B$2:B$100 )
$ValueSet,
#Corresponds to the the 'Show Error alert ...' check box on error alert page in the Excel dialog
[switch]$ShowErrorMessage,
#Stop, Warning, or Infomation, corresponding to to the style setting in the Excel dialog
[OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle]$ErrorStyle,
#The title for the message box corresponding to to the title setting in the Excel dialog
[String]$ErrorTitle,
#The error message corresponding to to the Error message setting in the Excel dialog
[String]$ErrorBody,
#Corresponds to the the 'Show Input message ...' check box on input message page in the Excel dialog
[switch]$ShowPromptMessage,
#The prompt message corresponding to to the Input message setting in the Excel dialog
[String]$PromptBody,
#The title for the message box corresponding to to the title setting in the Excel dialog
[String]$PromptTitle,
#By default the 'Ignore blank' option will be selected, unless NoBlank is sepcified.
[String]$NoBlank
)
if ($Range -is [Array]) {
$null = $PSBoundParameters.Remove("Range")
$Range | Add-ExcelDataValidationRule @PSBoundParameters
}
else {
#We should accept, a worksheet and a name of a range or a cell address; a table; the address of a table; a named range; a row, a column or .Cells[ ]
if (-not $WorkSheet -and $Range.worksheet) {$WorkSheet = $Range.worksheet}
if ($Range.Address) {$Range = $Range.Address}
if ($Range -isnot [string] -or -not $WorkSheet) {Write-Warning -Message "You need to provide a worksheet and range of cells." ;return}
#else we assume Range is a range.
$validation = $WorkSheet.DataValidations."Add$ValidationType`Validation"($Range)
if ($validation.AllowsOperator) {$validation.Operator = $Operator}
if ($PSBoundParameters.ContainsKey('value')) {
$validation.Formula.Value = $Value
}
elseif ($Formula) {$validation.Formula.ExcelFormula = $Formula}
elseif ($ValueSet) {Foreach ($v in $ValueSet) {$validation.Formula.Values.Add($V)}}
if ($PSBoundParameters.ContainsKey('Value2')) {
$validation.Formula2.Value = $Value2
}
elseif ($Formula2) {$validation.Formula2.ExcelFormula = $Formula}
$validation.ShowErrorMessage = [bool]$ShowErrorMessage
$validation.ShowInputMessage = [bool]$ShowPromptMessage
$validation.AllowBlank = -not $NoBlank
if ($PromptTitle) {$validation.PromptTitle = $PromptTitle}
if ($ErrorTitle) {$validation.ErrorTitle = $ErrorTitle}
if ($PromptBody) {$validation.Prompt = $PromptBody}
if ($ErrorBody) {$validation.Error = $ErrorBody}
if ($ErrorStyle) {$validation.ErrorStyle = $ErrorStyle}
}
}

View File

@@ -15,6 +15,7 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Compare-Worksheet -ParameterName TabColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Join-Worksheet -ParameterName TitleBackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Merge-Worksheet -ParameterName AddBackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Merge-Worksheet -ParameterName ChangeBackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Merge-Worksheet ` -ParameterName DeleteBackgroundColor -ScriptBlock $Function:ColorCompletion
@@ -25,14 +26,16 @@ if (Get-Command -Name register-argumentCompleter -ErrorAction SilentlyContinue)
Register-ArgumentCompleter -CommandName Merge-MulipleSheets -ParameterName KeyFontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Format -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Column -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-Row -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName New-ConditionalText -ParameterName ConditionalTextColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName BorderColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRange -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelColumn -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName BackgroundColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName FontColor -ScriptBlock $Function:ColorCompletion
Register-ArgumentCompleter -CommandName Set-ExcelRow -ParameterName PatternColor -ScriptBlock $Function:ColorCompletion
}

View File

@@ -35,15 +35,15 @@
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Opening Workbook and copying data"
$xlWbk = $xlApp.Workbooks.Open($Path)
$xlWbk.Worksheets($workSheetname).Select()
$xlWbk.ActiveSheet.Range($range).Select() | Out-Null
$xlApp.Selection.Copy() | Out-Null
$null = $xlWbk.ActiveSheet.Range($range).Select()
$null = $xlApp.Selection.Copy()
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Saving copied data"
# Get-Clipboard came in with PS5. Older versions can use [System.Windows.Clipboard] but it is ugly.
$image = Get-Clipboard -Format Image
$image.Save($destination, $Format)
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Status "Closing Excel"
$xlWbk.ActiveSheet.Range("a1").Select() | Out-Null
$xlApp.Selection.Copy() | Out-Null
$null = $xlWbk.ActiveSheet.Range("a1").Select()
$null = $xlApp.Selection.Copy()
$xlApp.Quit()
Write-Progress -Activity "Exporting $range of $workSheetname in $Path" -Completed
if ($show) {Start-Process -FilePath $destination}

View File

@@ -3,7 +3,7 @@ function ConvertFrom-ExcelData {
.SYNOPSIS
Reads data from a sheet, and for each row, calls a custom scriptblock with a list of property names and the row of data.
.EXAMPLE
ConvertFrom-ExcelData .\testSQLGen.xlsx {
param($propertyNames, $record)

View File

@@ -1,18 +1,21 @@
Function ConvertTo-ExcelXlsx {
[CmdletBinding()]
<#
.SYNOPSIS
Converts an Excel xls to a xlsx using -ComObject
#>
[CmdletBinding()]
Param
(
[parameter(Mandatory=$true, ValueFromPipeline)]
[parameter(Mandatory = $true, ValueFromPipeline)]
[string]$Path,
[parameter(Mandatory=$false)]
[parameter(Mandatory = $false)]
[switch]$Force
)
Process
{
if(-Not ($Path | Test-Path) ){
throw "File not found"
Process {
if (-Not ($Path | Test-Path) ) {
throw "File not found"
}
if(-Not ($Path | Test-Path -PathType Leaf) ){
if (-Not ($Path | Test-Path -PathType Leaf) ) {
throw "Folder paths are not allowed"
}
@@ -20,31 +23,34 @@ Function ConvertTo-ExcelXlsx {
$xlsFile = Get-Item -Path $Path
$xlsxPath = "{0}x" -f $xlsFile.FullName
if($xlsFile.Extension -ne ".xls"){
if ($xlsFile.Extension -ne ".xls") {
throw "Expected .xls extension"
}
if(Test-Path -Path $xlsxPath){
if($Force){
if (Test-Path -Path $xlsxPath) {
if ($Force) {
try {
Remove-Item $xlsxPath -Force
} catch {
}
catch {
throw "{0} already exists and cannot be removed. The file may be locked by another application." -f $xlsxPath
}
Write-Verbose $("Removed {0}" -f $xlsxPath)
} else {
}
else {
throw "{0} already exists!" -f $xlsxPath
}
}
try{
try {
$Excel = New-Object -ComObject "Excel.Application"
} catch {
}
catch {
throw "Could not create Excel.Application ComObject. Please verify that Excel is installed."
}
$Excel.Visible = $false
$Excel.Workbooks.Open($xlsFile.FullName) | Out-Null
$null = $Excel.Workbooks.Open($xlsFile.FullName)
$Excel.ActiveWorkbook.SaveAs($xlsxPath, $xlFixedFormat)
$Excel.ActiveWorkbook.Close()
$Excel.Quit()

View File

@@ -1,5 +1,4 @@
function Copy-ExcelWorkSheet {
[CmdletBinding()]
<#
.SYNOPSIS
Copies a worksheet between workbooks or within the same workbook.
@@ -27,14 +26,15 @@
because -Show is not specified, so other steps can be carried using the package object, at the end the file is saved by Close-ExcelPackage
#>
[CmdletBinding()]
param(
#An ExcelWorkbook or ExcelPackage object or the path to an XLSx file where the data is found.
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
$SourceWorkbook,
#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)]
[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,
@@ -65,46 +65,47 @@
}
}
else {
if ($SourceWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {$sourcews=$SourceWorkbook.Worksheets[$SourceWorkSheet]}
elseif ($SourceWorkbook -is [OfficeOpenXml.ExcelPackage] ) {$sourcews=$SourceWorkbook.Workbook.Worksheets[$SourceWorkSheet]}
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}
$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}
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 ($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."
}
try {
if ($DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
$wb = $DestinationWorkbook
}
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorkSheet' in the destination workbook" ; return}
elseif ($DestinationWorkbook -is [OfficeOpenXml.ExcelPackage] ) {
$wb = $DestinationWorkbook.workbook
if ($show) {$package2 = $DestinationWorkbook}
}
else {
$package2 = Open-ExcelPackage -Create -Path $DestinationWorkbook
$wb = $package2.Workbook
}
if (-not $DestinationWorkSheet) {$DestinationWorkSheet = $SourceWs.Name}
if ($wb.Worksheets[$DestinationWorkSheet]) {
Write-Verbose "Destination workbook already has a sheet named '$DestinationWorkSheet', deleting it."
$wb.Worksheets.Delete($DestinationWorkSheet)
}
Write-Verbose "Copying $($SourceWorkSheet) from $($SourceWorkbook) to $($DestinationWorkSheet) in $($DestinationWorkbook)"
$null = Add-WorkSheet -ExcelWorkbook $wb -WorkSheetname $DestinationWorkSheet -CopySource $sourceWs
if ($Stream) {$Stream.Close() }
if ($package1) {Close-ExcelPackage -ExcelPackage $Package1 -NoSave }
if ($package2) {Close-ExcelPackage -ExcelPackage $Package2 -Show:$show }
if ($show -and $DestinationWorkbook -is [OfficeOpenXml.ExcelWorkbook]) {
Write-Warning -Message "-Show only works if the Destination workbook is given as a file path or an ExcelPackage object."
}
}
catch {Write-Warning -Message "Could not write to sheet '$DestinationWorkSheet' in the destination workbook" ; return}
}
}
}

View File

@@ -1,14 +1,24 @@
param(
[Switch]$DontCreateZip
)
##
# Used in Appveyor.yml
##
$PSVersionTable.PSVersion
## Create the zip before the tests run
## Otherwise the EPPlus.dll is in use after the Pester run
$ModuleVersion = (Get-Content -Raw .\ImportExcel.psd1) | Invoke-Expression | ForEach-Object ModuleVersion
$ModuleVersion = (Invoke-Command -ScriptBlock ([scriptblock]::Create((Get-Content -Raw .\ImportExcel.psd1)))).moduleVersion
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
Compress-Archive -Path . -DestinationPath .\$dest
if (!$DontCreateZip) {
$dest = "ImportExcel-{0}-{1}.zip" -f $ModuleVersion, (Get-Date).ToString("yyyyMMddHHmmss")
Compress-Archive -Path . -DestinationPath .\$dest
}
if ((Get-Module -ListAvailable pester) -eq $null) {
Install-Module -Name Pester -Repository PSGallery -Force
if ($null -eq (Get-Module -ListAvailable pester)) {
Install-Module -Name Pester -Repository PSGallery -Force -Scope CurrentUser
}
$result = Invoke-Pester -Script $PSScriptRoot\__tests__ -Verbose -PassThru

View File

@@ -0,0 +1,15 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$xlSourcefile = "$env:TEMP\Source.xlsx"
write-host "Save location: $xlSourcefile"
Remove-Item $xlSourcefile -ErrorAction Ignore
#Put some simple data in a worksheet and Get an excel package object to represent the file
$TabData1 = 1..5 | Export-Excel $xlSourcefile -WorksheetName 'Tab 1' -AutoSize -AutoFilter
#Add another tab. Replace the $TabData2 with your data
$TabData2 = 1..10 | Export-Excel $xlSourcefile -WorksheetName 'Tab 2' -AutoSize -AutoFilter
#Add another tab. Replace the $TabData3 with your data
$TabData3 = 1..15 | Export-Excel $xlSourcefile -WorksheetName 'Tab 3' -AutoSize -AutoFilter -Show

View File

@@ -4,8 +4,9 @@ $xlSourcefile = "$env:TEMP\Source.xlsx"
Remove-Item $xlSourcefile -ErrorAction Ignore
#Put some simple data in a worksheet and Get an excel package object to represent the file
$excel = 1..10 | Export-Excel $xlSourcefile -PassThru
#Add a new worksheet named 'NewSheet' and copying the sheet that was just made (Sheet1) to the new sheet
Add-WorkSheet -ExcelPackage $excel -WorkSheetname "NewSheet" -CopySource $excel.Workbook.Worksheets["Sheet1"]
#Save and open in Excel
Close-ExcelPackage -ExcelPackage $excel -Show

View File

@@ -11,7 +11,7 @@ A,B,C,Date
$c = New-ExcelChartDefinition -Title Impressions `
-ChartType Line `
-XRange "Impressions[Date]" `
-YRange "Impressions[B]" # @("Impressions[B]","Impressions[A]") `
-YRange @("Impressions[B]","Impressions[A]") `
-SeriesHeader 'B data','A data' `
-Row 0 -Column 0

View File

@@ -13,14 +13,14 @@ function plot {
$file = 'C:\temp\plot.xlsx'
Remove-Item $file -ErrorAction Ignore
$c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
# $c = New-ExcelChart -XRange X -YRange Y -ChartType Line -NoLegend -Title Plot -Column 2 -ColumnOffSetPixels 35
$(for ($i = $minx; $i -lt $maxx-.1; $i+=.1) {
[pscustomobject]@{
X=$i.ToString("N1")
Y=(&$f $i)
}
}) | Export-Excel $file -Show -AutoNameRange -ExcelChartDefinition $c
}) | Export-Excel $file -Show -AutoNameRange -LineChart -NoLegend #-ExcelChartDefinition $c
}
function pi {[math]::pi}

View File

@@ -1,5 +1,5 @@
echo Last7Days LastMonth LastWeek NextMonth NextWeek ThisMonth ThisWeek Today Tomorrow Yesterday |
% {
Foreach-Object {
$text = @"
`$f = ".\testExport.xlsx"

View File

@@ -1,13 +1,13 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$file = ".\conditionalTextFormatting.xlsx"
$file = "$env:temp\conditionalTextFormatting.xlsx"
Remove-Item $file -ErrorAction Ignore
Get-Service |
Select-Object Status, Name, DisplayName, ServiceName |
Export-Excel $file -Show -AutoSize -AutoFilter -ConditionalText $(
New-ConditionalText stop
New-ConditionalText runn darkblue cyan
New-ConditionalText -ConditionalType EndsWith svc wheat green
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat
New-ConditionalText stop #Stop is the condition value, the rule is defaults to 'Contains text' and the default Colors are used
New-ConditionalText runn darkblue cyan #runn is the condition value, the rule is defaults to 'Contains text'; the foregroundColur is darkblue and the background is cyan
New-ConditionalText -ConditionalType EndsWith svc wheat green #the rule here is 'Ends with' and the value is 'svc' the forground is wheat and the background dark green
New-ConditionalText -ConditionalType BeginsWith windows darkgreen wheat #this is 'Begins with "Windows"' the forground is dark green and the background wheat
)

View File

@@ -1,5 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
#Define a "Contains blanks" rule. No format is specified so it default to dark-red text on light-pink background.
$ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks
$data = $(
@@ -11,7 +12,8 @@ $data = $(
New-PSItem g h i
)
$file ="c:\temp\testblanks.xlsx"
$file ="$env:temp\testblanks.xlsx"
Remove-Item $file -ErrorAction Ignore
#use the conditional format definition created above
$data | Export-Excel $file -show -ConditionalText $ContainsBlanks

View File

@@ -1,23 +1,32 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
Remove-Item -Path .\test.xlsx -ErrorAction Ignore
$path = "$env:temp\test.xlsx"
Remove-Item -Path $path -ErrorAction Ignore
#Export processes, and get an ExcelPackage object representing the file.
$excel = Get-Process |
Select-Object -Property Name,Company,Handles,CPU,PM,NPM,WS |
Export-Excel -Path .\test.xlsx -ClearSheet -WorkSheetname "Processes" -PassThru
Export-Excel -Path $path -ClearSheet -WorkSheetname "Processes" -PassThru
$sheet = $excel.Workbook.Worksheets["Processes"]
$sheet.Column(1) | Set-Format -Bold -AutoFit
#Apply fixed formatting to columns. Set-Format is an Alias for Set-Excel Range, -NFormat is an alias for numberformat
$sheet.Column(1) | Set-ExcelRange -Bold -AutoFit
$sheet.Column(2) | Set-Format -Width 29 -WrapText
$sheet.Column(3) | Set-Format -HorizontalAlignment Right -NFormat "#,###"
Set-Format -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
Set-Format -Address $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
Set-ExcelRange -Range -Address $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NFormat "#,###"
#Set-Format is an alias for Set-ExcelRange
Set-Format -Range $sheet.Column(4) -HorizontalAlignment Right -NFormat "#,##0.0" -Bold
#In Set-ExcelRange / Set-Format "-Address" is an alias for "-Range"
Set-Format -Address $sheet.Row(1) -Bold -HorizontalAlignment Center
Add-ConditionalFormatting -WorkSheet $sheet -Range "D2:D1048576" -DataBarColor Red
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red
#Create a Red Data-bar for the values in Column D
Add-ConditionalFormatting -WorkSheet $sheet -Address "D2:D1048576" -DataBarColor Red
# Conditional formatting applies to "Addreses" aliases allow either "Range" or "Address" to be used in Set-ExcelRange or Add-Conditional formatting.
Add-ConditionalFormatting -WorkSheet $sheet -Range "G2:G1048576" -RuleType GreaterThan -ConditionValue "104857600" -ForeGroundColor Red
foreach ($c in 5..9) {Set-Format -Address $sheet.Column($c) -AutoFit }
#Create a pivot and save the file.
Export-Excel -ExcelPackage $excel -WorkSheetname "Processes" -IncludePivotChart -ChartType ColumnClustered -NoLegend -PivotRows company -PivotData @{'Name'='Count'} -Show

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$f = ".\testExport.xlsx"
$f = "$env:TEMP\testExport.xlsx"
Remove-Item $f -ErrorAction Ignore
@@ -21,6 +21,8 @@ $data = $(
New-PSItem Westerly 120
New-PSItem SouthWest 118
)
# in this example instead of doing $variable = New-Conditional text <parameters> .... ; Export-excel -conditionalText $variable <other parameters>
# the syntax is used is Export-excel -conditionalText (New-Conditional text <parameters>) <other parameters>
#$data | Export-Excel $f -Show -AutoSize -ConditionalText (New-ConditionalText -ConditionalType AboveAverage)

View File

@@ -1,10 +1,12 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
Remove-Item .\testExport.xlsx -ErrorAction Ignore
Remove-Item "$env:TEMP\testExport.xlsx" -ErrorAction Ignore
Get-Process | Where-Object Company | Select-Object Company, Name, PM, Handles, *mem* |
Export-Excel .\testExport.xlsx -Show -AutoSize -AutoNameRange `
#This example creates a 3 Icon set for the values in the "PM column, and Highlights company names (anywhere in the data) with different colors
Export-Excel "$env:TEMP\testExport.xlsx" -Show -AutoSize -AutoNameRange `
-ConditionalFormat $(
New-ConditionalFormattingIconSet -Range "C:C" `
-ConditionalFormat ThreeIconSet -IconType Arrows

View File

@@ -1,6 +1,4 @@
cls
ipmo ..\..\ImportExcel.psd1 -Force
try {ipmo ..\..\ImportExcel.psd1 -Force} catch {}
$data = $(
New-PSItem 100 (echo test testx)
@@ -10,8 +8,8 @@ $data = $(
New-PSItem 500
)
$file1 = "tryComparison1.xlsx"
$file2 = "tryComparison2.xlsx"
$file1 = "$env:Temp\tryComparison1.xlsx"
$file2 = "$env:Temp\tryComparison2.xlsx"
rm $file1 -ErrorAction Ignore
rm $file2 -ErrorAction Ignore
@@ -22,6 +20,6 @@ $data | Export-Excel $file1 -Show -ConditionalText $(
)
$data | Export-Excel $file2 -Show -ConditionalText $(
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
New-ConditionalText -ConditionalType GreaterThanOrEqual 275
New-ConditionalText -ConditionalType LessThanOrEqual 250 -BackgroundColor cyan
)

View File

@@ -51,7 +51,7 @@ Set-Format -Address $sheet1.Cells["E2:G2"] -BorderBottom $BorderBottom -BorderCo
Set-Format -Address $sheet1.Cells["I2:K2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["M2:O2"] -BorderBottom $BorderBottom -BorderColor $BorderColor
Set-Format -Address $sheet1.Cells["A2:C8"] -FontColor GrayText
Set-Format -Address $sheet1.Cells["A2:C8"] -FontColor Gray
$HorizontalAlignment = "Center"
Set-Format -Address $sheet1.Cells["F1"] -HorizontalAlignment $HorizontalAlignment -Bold -Value Revenue

View File

@@ -0,0 +1,85 @@
#region Setup
<#
This examples demos three types of validation:
* Creating a list using a PowerShell array
* Creating a list data from another Excel Worksheet
* Creating a rule for numbers to be between 0 an 10000
Run the script then try"
* Add random data in Column B
* Then choose from the drop down list
* Add random data in Column C
* Then choose from the drop down list
* Add .01 in column F
#>
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$path = "$Env:TEMP\DataValidation.xlsx"
Remove-Item $path -ErrorAction SilentlyContinue
$data = ConvertFrom-Csv -InputObject @"
ID,Region,Product,Quantity,Price
12001,North,Nails,37,3.99
12002,South,Hammer,5,12.10
12003,East,Saw,12,15.37
12010,West,Drill,20,8
12011,North,Crowbar,7,23.48
"@
# Export the raw data
$excelPackage = $Data |
Export-Excel -WorksheetName "Sales" -Path $path -PassThru
# Creates a sheet with data that will be used in a validation rule
$excelPackage = @('Chisel', 'Crowbar', 'Drill', 'Hammer', 'Nails', 'Saw', 'Screwdriver', 'Wrench') |
Export-excel -ExcelPackage $excelPackage -WorksheetName Values -PassThru
#endregion
#region Creating a list using a PowerShell array
$ValidationParams = @{
WorkSheet = $excelPackage.sales
ShowErrorMessage = $true
ErrorStyle = 'stop'
ErrorTitle = 'Invalid Data'
}
$MoreValidationParams = @{
Range = 'B2:B1001'
ValidationType = 'List'
ValueSet = @('North', 'South', 'East', 'West')
ErrorBody = "You must select an item from the list."
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Creating a list data from another Excel Worksheet
$MoreValidationParams = @{
Range = 'C2:C1001'
ValidationType = 'List'
Formula = 'values!$a$1:$a$10'
ErrorBody = "You must select an item from the list.`r`nYou can add to the list on the values page" #Bucket
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Creating a rule for numbers to be between 0 an 10000
$MoreValidationParams = @{
Range = 'F2:F1001'
ValidationType = 'Integer'
Operator = 'between'
Value = 0
Value2 = 10000
ErrorBody = 'Quantity must be a whole number between 0 and 10000'
}
Add-ExcelDataValidationRule @ValidationParams @MoreValidationParams
#endregion
#region Close Package
Close-ExcelPackage -ExcelPackage $excelPackage -Show
#endregion

Binary file not shown.

View File

@@ -0,0 +1,24 @@
$data = ConvertFrom-Csv @'
Item,Quantity,Price,Total Cost
Footballs,9,21.95,197.55
Cones,36,7.99,287.64
Shin Guards,14,10.95,153.3
Turf Shoes,22,79.95,1758.9
Baseballs,68,7.99,543.32
Baseball Gloves,31,65.00,2015.00
Baseball Bats,38,159.00,6042.00
'@
$f = "$env:TEMP\styles.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pkg = $data | Export-Excel -Path $f -AutoSize -PassThru
$ws = $pkg.Workbook.Worksheets["Sheet1"]
Set-ExcelRange -WorkSheet $ws -Range "A2:C6" -BackgroundColor PeachPuff -FontColor Purple -FontSize 12 -Width 12
Set-ExcelRange -WorkSheet $ws -Range "D2:D6" -BackgroundColor WhiteSmoke -FontColor Orange -Bold -FontSize 12 -Width 12
Set-ExcelRange -WorkSheet $ws -Range "A1:D1" -BackgroundColor BlueViolet -FontColor Wheat -FontSize 12 -Width 12
Set-ExcelRange -WorkSheet $ws -Range "A:A" -Width 15
Close-ExcelPackage -ExcelPackage $pkg -Show

View File

@@ -8,7 +8,7 @@
$sign=@{sign=echo + -}
$location=@{location=echo Atlanta Newark Washington Chicago Philadelphia Houston Phoneix}
$(1..6 | % {
$(1..6 | Foreach-Object {
$from=$to=""
while($from -eq $to) {

View File

@@ -0,0 +1,101 @@
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
French,24/06/2018,8,Carlos Sainz,7,Renault,4
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
1 Race Date FinishPosition Driver GridPosition Team Points
2 Australian 25/03/2018 1 Sebastian Vettel 3 Ferrari 25
3 Australian 25/03/2018 2 Lewis Hamilton 1 Mercedes 18
4 Australian 25/03/2018 3 Kimi Räikkönen 2 Ferrari 15
5 Australian 25/03/2018 4 Daniel Ricciardo 8 Red Bull Racing-TAG Heuer 12
6 Australian 25/03/2018 5 Fernando Alonso 10 McLaren-Renault 10
7 Australian 25/03/2018 6 Max Verstappen 4 Red Bull Racing-TAG Heuer 8
8 Australian 25/03/2018 7 Nico Hülkenberg 7 Renault 6
9 Australian 25/03/2018 8 Valtteri Bottas 15 Mercedes 4
10 Australian 25/03/2018 9 Stoffel Vandoorne 11 McLaren-Renault 2
11 Australian 25/03/2018 10 Carlos Sainz 9 Renault 1
12 Bahrain 08/04/2018 1 Sebastian Vettel 1 Ferrari 25
13 Bahrain 08/04/2018 2 Valtteri Bottas 3 Mercedes 18
14 Bahrain 08/04/2018 3 Lewis Hamilton 9 Mercedes 15
15 Bahrain 08/04/2018 4 Pierre Gasly 5 STR-Honda 12
16 Bahrain 08/04/2018 5 Kevin Magnussen 6 Haas-Ferrari 10
17 Bahrain 08/04/2018 6 Nico Hülkenberg 7 Renault 8
18 Bahrain 08/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
19 Bahrain 08/04/2018 8 Stoffel Vandoorne 14 McLaren-Renault 4
20 Bahrain 08/04/2018 9 Marcus Ericsson 17 Sauber-Ferrari 2
21 Bahrain 08/04/2018 10 Esteban Ocon 8 Force India-Mercedes 1
22 Chinese 15/04/2018 1 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 25
23 Chinese 15/04/2018 2 Valtteri Bottas 3 Mercedes 18
24 Chinese 15/04/2018 3 Kimi Räikkönen 2 Ferrari 15
25 Chinese 15/04/2018 4 Lewis Hamilton 4 Mercedes 12
26 Chinese 15/04/2018 5 Max Verstappen 5 Red Bull Racing-TAG Heuer 10
27 Chinese 15/04/2018 6 Nico Hülkenberg 7 Renault 8
28 Chinese 15/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
29 Chinese 15/04/2018 8 Sebastian Vettel 1 Ferrari 4
30 Chinese 15/04/2018 9 Carlos Sainz 9 Renault 2
31 Chinese 15/04/2018 10 Kevin Magnussen 11 Haas-Ferrari 1
32 Azerbaijan 29/04/2018 1 Lewis Hamilton 2 Mercedes 25
33 Azerbaijan 29/04/2018 2 Kimi Räikkönen 6 Ferrari 18
34 Azerbaijan 29/04/2018 3 Sergio Pérez 8 Force India-Mercedes 15
35 Azerbaijan 29/04/2018 4 Sebastian Vettel 1 Ferrari 12
36 Azerbaijan 29/04/2018 5 Carlos Sainz 9 Renault 10
37 Azerbaijan 29/04/2018 6 Charles Leclerc 13 Sauber-Ferrari 8
38 Azerbaijan 29/04/2018 7 Fernando Alonso 12 McLaren-Renault 6
39 Azerbaijan 29/04/2018 8 Lance Stroll 10 Williams-Mercedes 4
40 Azerbaijan 29/04/2018 9 Stoffel Vandoorne 16 McLaren-Renault 2
41 Azerbaijan 29/04/2018 10 Brendon Hartley 19 STR-Honda 1
42 Spanish 13/05/2018 1 Lewis Hamilton 1 Mercedes 25
43 Spanish 13/05/2018 2 Valtteri Bottas 2 Mercedes 18
44 Spanish 13/05/2018 3 Max Verstappen 5 Red Bull Racing-TAG Heuer 15
45 Spanish 13/05/2018 4 Sebastian Vettel 3 Ferrari 12
46 Spanish 13/05/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
47 Spanish 13/05/2018 6 Kevin Magnussen 7 Haas-Ferrari 8
48 Spanish 13/05/2018 7 Carlos Sainz 9 Renault 6
49 Spanish 13/05/2018 8 Fernando Alonso 8 McLaren-Renault 4
50 Spanish 13/05/2018 9 Sergio Pérez 15 Force India-Mercedes 2
51 Spanish 13/05/2018 10 Charles Leclerc 14 Sauber-Ferrari 1
52 Monaco 27/05/2018 1 Daniel Ricciardo 1 Red Bull Racing-TAG Heuer 25
53 Monaco 27/05/2018 2 Sebastian Vettel 2 Ferrari 18
54 Monaco 27/05/2018 3 Lewis Hamilton 3 Mercedes 15
55 Monaco 27/05/2018 4 Kimi Räikkönen 4 Ferrari 12
56 Monaco 27/05/2018 5 Valtteri Bottas 5 Mercedes 10
57 Monaco 27/05/2018 6 Esteban Ocon 6 Force India-Mercedes 8
58 Monaco 27/05/2018 7 Pierre Gasly 10 STR-Honda 6
59 Monaco 27/05/2018 8 Nico Hülkenberg 11 Renault 4
60 Monaco 27/05/2018 9 Max Verstappen 20 Red Bull Racing-TAG Heuer 2
61 Monaco 27/05/2018 10 Carlos Sainz 8 Renault 1
62 Canadian 10/06/2018 1 Sebastian Vettel 1 Ferrari 25
63 Canadian 10/06/2018 2 Valtteri Bottas 2 Mercedes 18
64 Canadian 10/06/2018 3 Max Verstappen 3 Red Bull Racing-TAG Heuer 15
65 Canadian 10/06/2018 4 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 12
66 Canadian 10/06/2018 5 Lewis Hamilton 4 Mercedes 10
67 Canadian 10/06/2018 6 Kimi Räikkönen 5 Ferrari 8
68 Canadian 10/06/2018 7 Nico Hülkenberg 7 Renault 6
69 Canadian 10/06/2018 8 Carlos Sainz 9 Renault 4
70 Canadian 10/06/2018 9 Esteban Ocon 8 Force India-Mercedes 2
71 Canadian 10/06/2018 10 Charles Leclerc 13 Sauber-Ferrari 1
72 French 24/06/2018 1 Lewis Hamilton 1 Mercedes 25
73 French 24/06/2018 2 Max Verstappen 4 Red Bull Racing-TAG Heuer 18
74 French 24/06/2018 3 Kimi Räikkönen 6 Ferrari 15
75 French 24/06/2018 4 Daniel Ricciardo 5 Red Bull Racing-TAG Heuer 12
76 French 24/06/2018 5 Sebastian Vettel 3 Ferrari 10
77 French 24/06/2018 6 Kevin Magnussen 9 Haas-Ferrari 8
78 French 24/06/2018 7 Valtteri Bottas 2 Mercedes 6
79 French 24/06/2018 8 Carlos Sainz 7 Renault 4
80 French 24/06/2018 9 Nico Hülkenberg 12 Renault 2
81 French 24/06/2018 10 Charles Leclerc 8 Sauber-Ferrari 1
82 Austrian 01/07/2018 1 Max Verstappen 4 Red Bull Racing-TAG Heuer 25
83 Austrian 01/07/2018 2 Kimi Räikkönen 3 Ferrari 18
84 Austrian 01/07/2018 3 Sebastian Vettel 6 Ferrari 15
85 Austrian 01/07/2018 4 Romain Grosjean 5 Haas-Ferrari 12
86 Austrian 01/07/2018 5 Kevin Magnussen 8 Haas-Ferrari 10
87 Austrian 01/07/2018 6 Esteban Ocon 11 Force India-Mercedes 8
88 Austrian 01/07/2018 7 Sergio Pérez 15 Force India-Mercedes 6
89 Austrian 01/07/2018 8 Fernando Alonso 20 McLaren-Renault 4
90 Austrian 01/07/2018 9 Charles Leclerc 17 Sauber-Ferrari 2
91 Austrian 01/07/2018 10 Marcus Ericsson 18 Sauber-Ferrari 1
92 British 08/07/2018 1 Sebastian Vettel 2 Ferrari 25
93 British 08/07/2018 2 Lewis Hamilton 1 Mercedes 18
94 British 08/07/2018 3 Kimi Räikkönen 3 Ferrari 15
95 British 08/07/2018 4 Valtteri Bottas 4 Mercedes 12
96 British 08/07/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
97 British 08/07/2018 6 Nico Hülkenberg 11 Renault 8
98 British 08/07/2018 7 Esteban Ocon 10 Force India-Mercedes 6
99 British 08/07/2018 8 Fernando Alonso 13 McLaren-Renault 4
100 British 08/07/2018 9 Kevin Magnussen 7 Haas-Ferrari 2
101 British 08/07/2018 10 Sergio Pérez 12 Force India-Mercedes 1

View File

@@ -0,0 +1,10 @@
$xlfile = "$env:TEMP\Points.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Points `
-PivotRows Driver, Date -PivotData @{Points = "SUM"} -GroupDateRow Date -GroupDatePart Years, Months
Import-Csv "$PSScriptRoot\First10Races.csv" |
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition

View File

@@ -0,0 +1,10 @@
$xlfile = "$env:TEMP\Places.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$PivotTableDefinition = New-PivotTableDefinition -Activate -PivotTableName Places `
-PivotRows Driver, FinishPosition -PivotData @{Date = "Count"} -GroupNumericRow FinishPosition -GroupNumericMin 1 -GroupNumericMax 25 -GroupNumericInterval 3
Import-Csv "$PSScriptRoot\First10Races.csv" |
Select-Object Race, @{n = "Date"; e = {[datetime]::ParseExact($_.date, "dd/MM/yyyy", (Get-Culture))}}, FinishPosition, Driver, GridPosition, Team, Points |
Export-Excel $xlfile -Show -AutoSize -PivotTableDefinition $PivotTableDefinition

View File

@@ -0,0 +1,39 @@
$data = ConvertFrom-Csv @"
Timestamp,Tenant
10/29/2018 3:00:00.123,1
10/29/2018 3:00:10.456,1
10/29/2018 3:01:20.389,1
10/29/2018 3:00:30.222,1
10/29/2018 3:00:40.143,1
10/29/2018 3:00:50.809,1
10/29/2018 3:01:00.193,1
10/29/2018 3:01:10.555,1
10/29/2018 3:01:20.739,1
10/29/2018 3:01:30.912,1
10/29/2018 3:01:40.989,1
10/29/2018 3:01:50.545,1
10/29/2018 3:02:00.999,1
"@ | Select-Object @{n = 'Timestamp'; e = {get-date $_.timestamp}}, tenant, @{n = 'Bucket'; e = { - (get-date $_.timestamp).Second % 30}}
$f = "$env:temp\pivottest.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pivotDefParams = @{
PivotTableName = 'Timestamp Buckets'
PivotRows = @('Timestamp', 'Tenant')
PivotData = @{'Bucket' = 'count'}
GroupDateRow = 'TimeStamp'
GroupDatePart = @('Hours', 'Minutes')
Activate = $true
}
$excelParams = @{
PivotTableDefinition = New-PivotTableDefinition @pivotDefParams
Path = $f
WorkSheetname = "Log Data"
AutoSize = $true
AutoFilter = $true
Show = $true
}
$data | Export-Excel @excelParams

View File

@@ -0,0 +1,101 @@
Race,Date,FinishPosition,Driver,GridPosition,Team,Points
Australian,25/03/2018,1,Sebastian Vettel,3,Ferrari,25
Australian,25/03/2018,2,Lewis Hamilton,1,Mercedes,18
Australian,25/03/2018,3,Kimi Räikkönen,2,Ferrari,15
Australian,25/03/2018,4,Daniel Ricciardo,8,Red Bull Racing-TAG Heuer,12
Australian,25/03/2018,5,Fernando Alonso,10,McLaren-Renault,10
Australian,25/03/2018,6,Max Verstappen,4,Red Bull Racing-TAG Heuer,8
Australian,25/03/2018,7,Nico Hülkenberg,7,Renault,6
Australian,25/03/2018,8,Valtteri Bottas,15,Mercedes,4
Australian,25/03/2018,9,Stoffel Vandoorne,11,McLaren-Renault,2
Australian,25/03/2018,10,Carlos Sainz,9,Renault,1
Bahrain,08/04/2018,1,Sebastian Vettel,1,Ferrari,25
Bahrain,08/04/2018,2,Valtteri Bottas,3,Mercedes,18
Bahrain,08/04/2018,3,Lewis Hamilton,9,Mercedes,15
Bahrain,08/04/2018,4,Pierre Gasly,5,STR-Honda,12
Bahrain,08/04/2018,5,Kevin Magnussen,6,Haas-Ferrari,10
Bahrain,08/04/2018,6,Nico Hülkenberg,7,Renault,8
Bahrain,08/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Bahrain,08/04/2018,8,Stoffel Vandoorne,14,McLaren-Renault,4
Bahrain,08/04/2018,9,Marcus Ericsson,17,Sauber-Ferrari,2
Bahrain,08/04/2018,10,Esteban Ocon,8,Force India-Mercedes,1
Chinese,15/04/2018,1,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,25
Chinese,15/04/2018,2,Valtteri Bottas,3,Mercedes,18
Chinese,15/04/2018,3,Kimi Räikkönen,2,Ferrari,15
Chinese,15/04/2018,4,Lewis Hamilton,4,Mercedes,12
Chinese,15/04/2018,5,Max Verstappen,5,Red Bull Racing-TAG Heuer,10
Chinese,15/04/2018,6,Nico Hülkenberg,7,Renault,8
Chinese,15/04/2018,7,Fernando Alonso,13,McLaren-Renault,6
Chinese,15/04/2018,8,Sebastian Vettel,1,Ferrari,4
Chinese,15/04/2018,9,Carlos Sainz,9,Renault,2
Chinese,15/04/2018,10,Kevin Magnussen,11,Haas-Ferrari,1
Azerbaijan,29/04/2018,1,Lewis Hamilton,2,Mercedes,25
Azerbaijan,29/04/2018,2,Kimi Räikkönen,6,Ferrari,18
Azerbaijan,29/04/2018,3,Sergio Pérez,8,Force India-Mercedes,15
Azerbaijan,29/04/2018,4,Sebastian Vettel,1,Ferrari,12
Azerbaijan,29/04/2018,5,Carlos Sainz,9,Renault,10
Azerbaijan,29/04/2018,6,Charles Leclerc,13,Sauber-Ferrari,8
Azerbaijan,29/04/2018,7,Fernando Alonso,12,McLaren-Renault,6
Azerbaijan,29/04/2018,8,Lance Stroll,10,Williams-Mercedes,4
Azerbaijan,29/04/2018,9,Stoffel Vandoorne,16,McLaren-Renault,2
Azerbaijan,29/04/2018,10,Brendon Hartley,19,STR-Honda,1
Spanish,13/05/2018,1,Lewis Hamilton,1,Mercedes,25
Spanish,13/05/2018,2,Valtteri Bottas,2,Mercedes,18
Spanish,13/05/2018,3,Max Verstappen,5,Red Bull Racing-TAG Heuer,15
Spanish,13/05/2018,4,Sebastian Vettel,3,Ferrari,12
Spanish,13/05/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
Spanish,13/05/2018,6,Kevin Magnussen,7,Haas-Ferrari,8
Spanish,13/05/2018,7,Carlos Sainz,9,Renault,6
Spanish,13/05/2018,8,Fernando Alonso,8,McLaren-Renault,4
Spanish,13/05/2018,9,Sergio Pérez,15,Force India-Mercedes,2
Spanish,13/05/2018,10,Charles Leclerc,14,Sauber-Ferrari,1
Monaco,27/05/2018,1,Daniel Ricciardo,1,Red Bull Racing-TAG Heuer,25
Monaco,27/05/2018,2,Sebastian Vettel,2,Ferrari,18
Monaco,27/05/2018,3,Lewis Hamilton,3,Mercedes,15
Monaco,27/05/2018,4,Kimi Räikkönen,4,Ferrari,12
Monaco,27/05/2018,5,Valtteri Bottas,5,Mercedes,10
Monaco,27/05/2018,6,Esteban Ocon,6,Force India-Mercedes,8
Monaco,27/05/2018,7,Pierre Gasly,10,STR-Honda,6
Monaco,27/05/2018,8,Nico Hülkenberg,11,Renault,4
Monaco,27/05/2018,9,Max Verstappen,20,Red Bull Racing-TAG Heuer,2
Monaco,27/05/2018,10,Carlos Sainz,8,Renault,1
Canadian,10/06/2018,1,Sebastian Vettel,1,Ferrari,25
Canadian,10/06/2018,2,Valtteri Bottas,2,Mercedes,18
Canadian,10/06/2018,3,Max Verstappen,3,Red Bull Racing-TAG Heuer,15
Canadian,10/06/2018,4,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,12
Canadian,10/06/2018,5,Lewis Hamilton,4,Mercedes,10
Canadian,10/06/2018,6,Kimi Räikkönen,5,Ferrari,8
Canadian,10/06/2018,7,Nico Hülkenberg,7,Renault,6
Canadian,10/06/2018,8,Carlos Sainz,9,Renault,4
Canadian,10/06/2018,9,Esteban Ocon,8,Force India-Mercedes,2
Canadian,10/06/2018,10,Charles Leclerc,13,Sauber-Ferrari,1
French,24/06/2018,1,Lewis Hamilton,1,Mercedes,25
French,24/06/2018,2,Max Verstappen,4,Red Bull Racing-TAG Heuer,18
French,24/06/2018,3,Kimi Räikkönen,6,Ferrari,15
French,24/06/2018,4,Daniel Ricciardo,5,Red Bull Racing-TAG Heuer,12
French,24/06/2018,5,Sebastian Vettel,3,Ferrari,10
French,24/06/2018,6,Kevin Magnussen,9,Haas-Ferrari,8
French,24/06/2018,7,Valtteri Bottas,2,Mercedes,6
French,24/06/2018,8,Carlos Sainz,7,Renault,4
French,24/06/2018,9,Nico Hülkenberg,12,Renault,2
French,24/06/2018,10,Charles Leclerc,8,Sauber-Ferrari,1
Austrian,01/07/2018,1,Max Verstappen,4,Red Bull Racing-TAG Heuer,25
Austrian,01/07/2018,2,Kimi Räikkönen,3,Ferrari,18
Austrian,01/07/2018,3,Sebastian Vettel,6,Ferrari,15
Austrian,01/07/2018,4,Romain Grosjean,5,Haas-Ferrari,12
Austrian,01/07/2018,5,Kevin Magnussen,8,Haas-Ferrari,10
Austrian,01/07/2018,6,Esteban Ocon,11,Force India-Mercedes,8
Austrian,01/07/2018,7,Sergio Pérez,15,Force India-Mercedes,6
Austrian,01/07/2018,8,Fernando Alonso,20,McLaren-Renault,4
Austrian,01/07/2018,9,Charles Leclerc,17,Sauber-Ferrari,2
Austrian,01/07/2018,10,Marcus Ericsson,18,Sauber-Ferrari,1
British,08/07/2018,1,Sebastian Vettel,2,Ferrari,25
British,08/07/2018,2,Lewis Hamilton,1,Mercedes,18
British,08/07/2018,3,Kimi Räikkönen,3,Ferrari,15
British,08/07/2018,4,Valtteri Bottas,4,Mercedes,12
British,08/07/2018,5,Daniel Ricciardo,6,Red Bull Racing-TAG Heuer,10
British,08/07/2018,6,Nico Hülkenberg,11,Renault,8
British,08/07/2018,7,Esteban Ocon,10,Force India-Mercedes,6
British,08/07/2018,8,Fernando Alonso,13,McLaren-Renault,4
British,08/07/2018,9,Kevin Magnussen,7,Haas-Ferrari,2
British,08/07/2018,10,Sergio Pérez,12,Force India-Mercedes,1
1 Race Date FinishPosition Driver GridPosition Team Points
2 Australian 25/03/2018 1 Sebastian Vettel 3 Ferrari 25
3 Australian 25/03/2018 2 Lewis Hamilton 1 Mercedes 18
4 Australian 25/03/2018 3 Kimi Räikkönen 2 Ferrari 15
5 Australian 25/03/2018 4 Daniel Ricciardo 8 Red Bull Racing-TAG Heuer 12
6 Australian 25/03/2018 5 Fernando Alonso 10 McLaren-Renault 10
7 Australian 25/03/2018 6 Max Verstappen 4 Red Bull Racing-TAG Heuer 8
8 Australian 25/03/2018 7 Nico Hülkenberg 7 Renault 6
9 Australian 25/03/2018 8 Valtteri Bottas 15 Mercedes 4
10 Australian 25/03/2018 9 Stoffel Vandoorne 11 McLaren-Renault 2
11 Australian 25/03/2018 10 Carlos Sainz 9 Renault 1
12 Bahrain 08/04/2018 1 Sebastian Vettel 1 Ferrari 25
13 Bahrain 08/04/2018 2 Valtteri Bottas 3 Mercedes 18
14 Bahrain 08/04/2018 3 Lewis Hamilton 9 Mercedes 15
15 Bahrain 08/04/2018 4 Pierre Gasly 5 STR-Honda 12
16 Bahrain 08/04/2018 5 Kevin Magnussen 6 Haas-Ferrari 10
17 Bahrain 08/04/2018 6 Nico Hülkenberg 7 Renault 8
18 Bahrain 08/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
19 Bahrain 08/04/2018 8 Stoffel Vandoorne 14 McLaren-Renault 4
20 Bahrain 08/04/2018 9 Marcus Ericsson 17 Sauber-Ferrari 2
21 Bahrain 08/04/2018 10 Esteban Ocon 8 Force India-Mercedes 1
22 Chinese 15/04/2018 1 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 25
23 Chinese 15/04/2018 2 Valtteri Bottas 3 Mercedes 18
24 Chinese 15/04/2018 3 Kimi Räikkönen 2 Ferrari 15
25 Chinese 15/04/2018 4 Lewis Hamilton 4 Mercedes 12
26 Chinese 15/04/2018 5 Max Verstappen 5 Red Bull Racing-TAG Heuer 10
27 Chinese 15/04/2018 6 Nico Hülkenberg 7 Renault 8
28 Chinese 15/04/2018 7 Fernando Alonso 13 McLaren-Renault 6
29 Chinese 15/04/2018 8 Sebastian Vettel 1 Ferrari 4
30 Chinese 15/04/2018 9 Carlos Sainz 9 Renault 2
31 Chinese 15/04/2018 10 Kevin Magnussen 11 Haas-Ferrari 1
32 Azerbaijan 29/04/2018 1 Lewis Hamilton 2 Mercedes 25
33 Azerbaijan 29/04/2018 2 Kimi Räikkönen 6 Ferrari 18
34 Azerbaijan 29/04/2018 3 Sergio Pérez 8 Force India-Mercedes 15
35 Azerbaijan 29/04/2018 4 Sebastian Vettel 1 Ferrari 12
36 Azerbaijan 29/04/2018 5 Carlos Sainz 9 Renault 10
37 Azerbaijan 29/04/2018 6 Charles Leclerc 13 Sauber-Ferrari 8
38 Azerbaijan 29/04/2018 7 Fernando Alonso 12 McLaren-Renault 6
39 Azerbaijan 29/04/2018 8 Lance Stroll 10 Williams-Mercedes 4
40 Azerbaijan 29/04/2018 9 Stoffel Vandoorne 16 McLaren-Renault 2
41 Azerbaijan 29/04/2018 10 Brendon Hartley 19 STR-Honda 1
42 Spanish 13/05/2018 1 Lewis Hamilton 1 Mercedes 25
43 Spanish 13/05/2018 2 Valtteri Bottas 2 Mercedes 18
44 Spanish 13/05/2018 3 Max Verstappen 5 Red Bull Racing-TAG Heuer 15
45 Spanish 13/05/2018 4 Sebastian Vettel 3 Ferrari 12
46 Spanish 13/05/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
47 Spanish 13/05/2018 6 Kevin Magnussen 7 Haas-Ferrari 8
48 Spanish 13/05/2018 7 Carlos Sainz 9 Renault 6
49 Spanish 13/05/2018 8 Fernando Alonso 8 McLaren-Renault 4
50 Spanish 13/05/2018 9 Sergio Pérez 15 Force India-Mercedes 2
51 Spanish 13/05/2018 10 Charles Leclerc 14 Sauber-Ferrari 1
52 Monaco 27/05/2018 1 Daniel Ricciardo 1 Red Bull Racing-TAG Heuer 25
53 Monaco 27/05/2018 2 Sebastian Vettel 2 Ferrari 18
54 Monaco 27/05/2018 3 Lewis Hamilton 3 Mercedes 15
55 Monaco 27/05/2018 4 Kimi Räikkönen 4 Ferrari 12
56 Monaco 27/05/2018 5 Valtteri Bottas 5 Mercedes 10
57 Monaco 27/05/2018 6 Esteban Ocon 6 Force India-Mercedes 8
58 Monaco 27/05/2018 7 Pierre Gasly 10 STR-Honda 6
59 Monaco 27/05/2018 8 Nico Hülkenberg 11 Renault 4
60 Monaco 27/05/2018 9 Max Verstappen 20 Red Bull Racing-TAG Heuer 2
61 Monaco 27/05/2018 10 Carlos Sainz 8 Renault 1
62 Canadian 10/06/2018 1 Sebastian Vettel 1 Ferrari 25
63 Canadian 10/06/2018 2 Valtteri Bottas 2 Mercedes 18
64 Canadian 10/06/2018 3 Max Verstappen 3 Red Bull Racing-TAG Heuer 15
65 Canadian 10/06/2018 4 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 12
66 Canadian 10/06/2018 5 Lewis Hamilton 4 Mercedes 10
67 Canadian 10/06/2018 6 Kimi Räikkönen 5 Ferrari 8
68 Canadian 10/06/2018 7 Nico Hülkenberg 7 Renault 6
69 Canadian 10/06/2018 8 Carlos Sainz 9 Renault 4
70 Canadian 10/06/2018 9 Esteban Ocon 8 Force India-Mercedes 2
71 Canadian 10/06/2018 10 Charles Leclerc 13 Sauber-Ferrari 1
72 French 24/06/2018 1 Lewis Hamilton 1 Mercedes 25
73 French 24/06/2018 2 Max Verstappen 4 Red Bull Racing-TAG Heuer 18
74 French 24/06/2018 3 Kimi Räikkönen 6 Ferrari 15
75 French 24/06/2018 4 Daniel Ricciardo 5 Red Bull Racing-TAG Heuer 12
76 French 24/06/2018 5 Sebastian Vettel 3 Ferrari 10
77 French 24/06/2018 6 Kevin Magnussen 9 Haas-Ferrari 8
78 French 24/06/2018 7 Valtteri Bottas 2 Mercedes 6
79 French 24/06/2018 8 Carlos Sainz 7 Renault 4
80 French 24/06/2018 9 Nico Hülkenberg 12 Renault 2
81 French 24/06/2018 10 Charles Leclerc 8 Sauber-Ferrari 1
82 Austrian 01/07/2018 1 Max Verstappen 4 Red Bull Racing-TAG Heuer 25
83 Austrian 01/07/2018 2 Kimi Räikkönen 3 Ferrari 18
84 Austrian 01/07/2018 3 Sebastian Vettel 6 Ferrari 15
85 Austrian 01/07/2018 4 Romain Grosjean 5 Haas-Ferrari 12
86 Austrian 01/07/2018 5 Kevin Magnussen 8 Haas-Ferrari 10
87 Austrian 01/07/2018 6 Esteban Ocon 11 Force India-Mercedes 8
88 Austrian 01/07/2018 7 Sergio Pérez 15 Force India-Mercedes 6
89 Austrian 01/07/2018 8 Fernando Alonso 20 McLaren-Renault 4
90 Austrian 01/07/2018 9 Charles Leclerc 17 Sauber-Ferrari 2
91 Austrian 01/07/2018 10 Marcus Ericsson 18 Sauber-Ferrari 1
92 British 08/07/2018 1 Sebastian Vettel 2 Ferrari 25
93 British 08/07/2018 2 Lewis Hamilton 1 Mercedes 18
94 British 08/07/2018 3 Kimi Räikkönen 3 Ferrari 15
95 British 08/07/2018 4 Valtteri Bottas 4 Mercedes 12
96 British 08/07/2018 5 Daniel Ricciardo 6 Red Bull Racing-TAG Heuer 10
97 British 08/07/2018 6 Nico Hülkenberg 11 Renault 8
98 British 08/07/2018 7 Esteban Ocon 10 Force India-Mercedes 6
99 British 08/07/2018 8 Fernando Alonso 13 McLaren-Renault 4
100 British 08/07/2018 9 Kevin Magnussen 7 Haas-Ferrari 2
101 British 08/07/2018 10 Sergio Pérez 12 Force India-Mercedes 1

View File

@@ -0,0 +1,27 @@
#First 10 races is a CSV file containing the top 10 finishers for the first 10 Formula one races of 2018. Read this file and group the results by race
#We will create links to each race in the first 10 rows of the spreadSheet
#The next row will be column labels
#After that will come a block for each race.
#Read the data, and decide how much space to leave for the hyperlinks
$scriptPath = Split-Path -Path $MyInvocation.MyCommand.path -Parent
$dataPath = Join-Path -Path $scriptPath -ChildPath "First10Races.csv"
$results = Import-Csv -Path $dataPath | Group-Object -Property RACE
$topRow = $lastDataRow = 1 + $results.Count
#Export the first row of the first group (race) with headers.
$path = "$env:TEMP\Results.xlsx"
Remove-Item -Path $path -ErrorAction SilentlyContinue
$excel = $results[0].Group[0] | Export-Excel -Path $path -StartRow $TopRow -BoldTopRow -PassThru
#export each group (race) below the last one, without headers, and create a range for each using the group (Race) name
foreach ($r in $results) {
$excel = $R.Group | Export-Excel -ExcelPackage $excel -NoHeader -StartRow ($lastDataRow +1) -RangeName $R.Name -PassThru -AutoSize
$lastDataRow += $R.Group.Count
}
#Create a hyperlink for each property with display text of "RaceNameGP" which links to the range created when the rows were exported a
$results | ForEach-Object {(New-Object -TypeName OfficeOpenXml.ExcelHyperLink -ArgumentList "Sheet1!$($_.Name)" , "$($_.name) GP")} |
Export-Excel -ExcelPackage $excel -AutoSize -Show

View File

@@ -0,0 +1,41 @@
#requires -modules "Get-IndexedItem"
[cmdletbinding()]
Param()
Remove-Item ~\documents\music.xlsx -ErrorAction SilentlyContinue
[System.Diagnostics.Stopwatch]$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
#Query system index for .MP3 files in C:\Users, where album artist is non-blank. Leave sorted table with columns of interest in $Music.
Get-IndexedItem "itemtype='.mp3'","AlbumArtist like '%'" -Recurse C:\Users -OutputVariable Music `
-OrderBy AlbumArtist, AlbumTitle, TrackNumber, Title -NoFiles `
-Property AlbumArtist, AlbumTitle, TrackNumber, Title, Duration, Size, SampleRate
Write-Verbose -Message ("Fetched " + $music.Rows.Count + " rows from index: " + $stopwatch.Elapsed.TotalSeconds)
#Send Table in $Music to Excel, format as a table, point $ws to the Worksheet
$excel = Send-SQLDataToExcel -Path ~\documents\music.xlsx -DataTable $music -WorkSheetname Music -TableName Music -Passthru
Write-Verbose -Message ("Inserted into Excel: " + $stopwatch.Elapsed.TotalSeconds)
$ws = $excel.Music
#Strip "SYSTEM.", "SYSTEM.AUDIO", "SYSTEM.MEDIA", "SYSTEM.MUSIC" from the column headings
#Convert Duration (column 5) from 100ns ticks to days and format as minutes, seconds, decimal
#Format filesize and sample rate nicely
#Autofit the columns.
Set-ExcelRow -Worksheet $ws -Row 1 -Value {($worksheet.cells[$row,$column].value -replace '^SYSTEM\.','') -replace '^MEDIA\.|^AUDIO\.|^MUSIC\.','' }
Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'mm:ss.0' -StartRow 2 -Value {$worksheet.cells[$row,$column].value / 864000000000 }
Write-Verbose -Message ("Cells Reset: " + $stopwatch.Elapsed.TotalSeconds)
Set-Column -Worksheet $ws -Column 6 -NumberFormat '#.#,,"MB"'
Set-ExcelColumn -Worksheet $ws -Column 7 -NumberFormat '0.0,"KHz"'
$ws.Cells[$ws.Dimension].AutoFitColumns()
#Make a Pivot table for sum of space and count of tracks by artist. Sort by artist, apply formatting to space, give it nice titles.
$pt = Add-PivotTable -PassThru -PivotTableName SpaceUsedByMusic -ExcelPackage $excel -SourceWorkSheet $ws `
-PivotRows ALBUMARTIST -PivotData ([ordered]@{"Size"="Sum"; "Duration"="Count"}) -PivotDataToColumn
$pt.RowFields[0].Sort = [OfficeOpenXml.Table.PivotTable.eSortType]::Ascending
$pt.DataFields[0].Format = '#.0,,"MB"'
$pt.DataFields[0].Name = 'Space Used'
$pt.DataFields[1].Name = 'Tracks'
#Save the file, and load it into Excel
$stopwatch.Stop()
Write-Verbose -Message ("Pivot Done: " + $stopwatch.Elapsed.TotalSeconds)
Close-ExcelPackage -show $excel

View File

@@ -0,0 +1,26 @@
param(
$PesterTestsPath = "$PSScriptRoot\..\..\..\__tests__\"
)
$xlfile = "$env:Temp\testResults.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$xlparams = @{
Path = $xlfile
InputObject = (Invoke-Pester -Script $PesterTestsPath -PassThru).TestResult | Sort-Object describe
WorksheetName = 'FullResults'
IncludePivotTable = $true
PivotRows = 'Describe'
PivotColumns = 'Passed'
PivotData = @{'Passed' = 'Count' }
IncludePivotChart = $true
ChartType = 'BarClustered'
AutoSize = $true
AutoFilter = $true
Activate = $true
}
Export-Excel -Show @xlparams

View File

@@ -0,0 +1,62 @@
<#
.Synopsis
Runs PsScriptAnalyzer against one or more folders and pivots the results to form a report.
.Example
Analyze_this.ps1
Invokes script analyzer on the current directory; creates a file in $env:temp and opens it in Excel
.Example
Analyze_this.ps1 -xlfile ..\mymodule.xlsx -quiet
Invokes script analyzer on the current directory; creates a file in the parent directory but does not open it
.Example
"." , (dir 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel\') | .\examples\ScriptAnalyzer\Analyze_this.ps1
run from a developemnt directory for importExcel it will produce a report for that directory compared against installed versions
this creates the file in the default location and opens it
#>
[CmdletBinding()]
param (
[parameter(ValueFromPipeline = $true)]
$Path = $PWD,
$xlfile = "$env:TEMP\ScriptAnalyzer.xlsx",
$ChartType = 'BarClustered' ,
$PivotColumns = 'Location',
[switch]$Quiet
)
begin {
Remove-Item -Path $xlfile -ErrorAction SilentlyContinue
$xlparams = @{
Path = $xlfile
WorksheetName = 'FullResults'
AutoSize = $true
AutoFilter = $true
Activate = $true
Show = (-not $Quiet)
}
$pivotParams = @{
PivotTableName = 'BreakDown'
PivotData = @{RuleName = 'Count' }
PivotRows = 'Severity', 'RuleName'
PivotColumns = 'Location'
PivotTotals = 'Rows'
}
$dirsToProcess = @()
}
process {
if ($path.fullName) {$dirsToProcess += $path.fullName}
elseif ($path.path) {$dirsToProcess += $path.Path}
else {$dirsToProcess += $path}
}
end {
$pivotParams['-PivotChartDefinition'] = New-ExcelChartDefinition -ChartType $chartType -Column (1 + $dirsToProcess.Count) -Title "Script analysis" -LegendBold
$xlparams['PivotTableDefinition'] = New-PivotTableDefinition @pivotParams
$dirsToProcess | ForEach-Object {
$dirName = (Resolve-Path -Path $_) -replace "^.*\\(.*?)\\(.*?)$", '$1-$2'
Write-Progress -Activity "Running Script Analyzer" -CurrentOperation $dirName
Invoke-ScriptAnalyzer -Path $_ -ErrorAction SilentlyContinue |
Add-Member -MemberType NoteProperty -Name Location -Value $dirName -PassThru
} | Export-Excel @xlparams
Write-Progress -Activity "Running Script Analyzer" -Completed
}

View File

@@ -40,4 +40,4 @@ $ptdef = New-PivotTableDefinition -PivotTableName "Summary" -PivotRows "Store" -
#Put in a title and freeze to top of the sheet including title and colmun headings
#Add the Pivot table.
#Show the result
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Summary" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef -show
Join-Worksheet -Path $path -WorkSheetName "Total" -Clearsheet -FromLabel "Store" -TableName "Combined" -TableStyle Light1 -AutoSize -BoldTopRow -FreezePane 2,1 -Title "Store Sales Summary" -TitleBold -TitleSize 14 -PivotTableDefinition $ptdef -show

View File

@@ -1,11 +1,13 @@
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
Get-WmiObject -Class win32_logicaldisk |
#Export disk volume, and Network adapter to their own sheets.
Get-WmiObject -Class win32_logicaldisk |
Select-Object -Property DeviceId,VolumeName, Size,Freespace |
Export-Excel -Path $path -WorkSheetname Volumes -NumberFormat "0,000"
Get-NetAdapter |
Select-Object -Property Name,InterfaceDescription,MacAddress,LinkSpeed |
Export-Excel -Path $path -WorkSheetname NetAdapters
#Create a summary page with a title of Summary, label the blocks with the name of the sheet they came from and hide the source sheets
Join-Worksheet -Path $path -HideSource -WorkSheetName Summary -NoHeader -LabelBlocks -AutoSize -Title "Summary" -TitleBold -TitleSize 22 -show

View File

@@ -11,12 +11,13 @@ $params = @{
ExcelChartDefinition = New-ExcelChartDefinition -XRange Item -YRange UnitSold -Title 'Units Sold'
Path = $xlfile
}
#Import 4 sets of sales data from 4 CSV files, using the parameters above.
Import-Csv $PSScriptRoot\NorthSales.csv | Export-Excel -WorkSheetname North @params
Import-Csv $PSScriptRoot\EastSales.csv | Export-Excel -WorkSheetname East @params
Import-Csv $PSScriptRoot\SouthSales.csv | Export-Excel -WorkSheetname South @params
Import-Csv $PSScriptRoot\WestSales.csv | Export-Excel -WorkSheetname West @params
#Join the 4 worksheets together on a sheet named Allsales, use the same parameters, except for AutoNameRange and ExcelChartDefinition.
$params.Remove("AutoNameRange")
$params.Remove("ExcelChartDefinition")
Join-Worksheet -WorkSheetName AllSales -Show @params

View File

@@ -0,0 +1,21 @@
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
#Get a subset of services into $s and export them
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property *
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
$s[2].DisplayName = "Changed from the orginal" #This will be row 4 in Excel - this should be highlighted as a change
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d) #This will be row 5 in Excel - this should be highlighted as a new item
$s.RemoveAt(5) #This will be row 7 in Excel - this should be highlighted as deleted item
$s | Export-Excel -Path $env:temp\server2.xlsx
#This use of Merge-worksheet Assumes a default worksheet name, (sheet1) We will check and output Name (the key), DisplayName and StartType and ignore other properties.
Merge-Worksheet -Referencefile "$env:temp\server1.xlsx" -Differencefile "$env:temp\Server2.xlsx" -OutputFile "$env:temp\combined1.xlsx" -Property name,displayname,startType -Key name -Show

View File

@@ -0,0 +1,34 @@
Remove-Item -Path "$env:temp\server*.xlsx" , "$env:temp\Combined*.xlsx" -ErrorAction SilentlyContinue
#Get a subset of services into $s and export them
[System.Collections.ArrayList]$s = get-service | Select-Object -first 25 -Property Name,DisplayName,StartType
$s | Export-Excel -Path $env:temp\server1.xlsx
#$s is a zero based array, excel rows are 1 based and excel has a header row so Excel rows will be 2 + index in $s.
#Change a row. Add a row. Delete a row. And export the changed $s to a second file.
$row4Displayname = $s[2].DisplayName
$s[2].DisplayName = "Changed from the orginal" #This will be excel row 4 and Server 2 will show as changed.
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Dummy Service"
$d.Name = "Dummy"
$s.Insert(3,$d) #This will be Excel row 5 and server 2 will show as changed - so will Server 3
$s.RemoveAt(5) #This will be Excel row 7 and Server 2 will show as missing.
$s | Export-Excel -Path $env:temp\server2.xlsx
#Make some more changes to $s and export it to a third file
$s[2].displayname = $row4Displayname #Server 3 row 4 will match server 1 so won't be highlighted
$d = $s[-1] | Select-Object -Property *
$d.DisplayName = "Second Service"
$d.Name = "Service2"
$s.Insert(6,$d) #This will be an extra row in Server 3 at row 8. It will show as missing in Server 2.
$s.RemoveAt(8) #This will show as missing in Server 3 at row 11 ()
$s | Export-Excel -Path $env:temp\server3.xlsx
#Now bring the three files together.
Merge-MultipleSheets -Path "$env:temp\server1.xlsx", "$env:temp\Server2.xlsx","$env:temp\Server3.xlsx" -OutputFile "$env:temp\combined3.xlsx" -Property name,displayname,startType -Key name -Show

View File

@@ -0,0 +1,55 @@
<#
Fixed Rate Loan/Mortgage Calculator in Excel
#>
param(
$Amount = 400000,
$InterestRate = .065,
$Term = 30
)
function New-CellData {
param(
$Range,
$Value,
$Format
)
$setFormatParams = @{
WorkSheet = $ws
Range = $Range
NumberFormat = $Format
}
if ($Value -is [string] -and $Value.StartsWith('=')) {
$setFormatParams.Formula = $Value
}
else {
$setFormatParams.Value = $Value
}
Set-Format @setFormatParams
}
$f = "$PSScriptRoot\mortgage.xlsx"
Remove-Item $f -ErrorAction SilentlyContinue
$pkg = "" | Export-Excel $f -Title 'Fixed Rate Loan Payments' -PassThru -AutoSize
$ws = $pkg.Workbook.Worksheets["Sheet1"]
New-CellData A3 'Amount'
New-CellData B3 $Amount '$#,##0'
New-CellData A4 "Interest Rate"
New-CellData B4 $InterestRate 'Percentage'
New-CellData A5 "Term (Years)"
New-CellData B5 $Term
New-CellData D3 "Monthly Payment"
New-CellData F3 "=-PMT(F4, B5*12, B3)" '$#,##0.#0'
New-CellData D4 "Monthly Rate"
New-CellData F4 "=((1+B4)^(1/12))-1" 'Percentage'
Close-ExcelPackage $pkg -Show

View File

@@ -3,7 +3,7 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$xlfile = "$env:TEMP\testThis.xlsx"
Remove-Item $xlfile -ErrorAction Ignore
1..10 | Export-Excel $xlfile -WorkSheetname First
11..20 | Export-Excel $xlfile -WorkSheetname Second -MoveToStart
21..30 | Export-Excel $xlfile -WorkSheetname Third -MoveBefore First
31..40 | Export-Excel $xlfile -WorkSheetname Fourth -MoveAfter Third -Show
1..10 | Export-Excel $xlfile -WorkSheetname First #'First' will be the only sheet
11..20 | Export-Excel $xlfile -WorkSheetname Second -MoveToStart #'Second' is moved before first so the order is 'Second', 'First'
21..30 | Export-Excel $xlfile -WorkSheetname Third -MoveBefore First #'Second' is moved before first so the order is 'Second', 'Third', 'First'
31..40 | Export-Excel $xlfile -WorkSheetname Fourth -MoveAfter Third -Show #'Fourth' is moved after third so the order is ' 'Second', 'Third', 'Fourth' First'

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$file = "disks.xlsx"
$file = "$env:TEMP\disks.xlsx"
Remove-Item $file -ErrorAction Ignore
@@ -11,5 +11,5 @@ $data = $(
New-PSItem -3.2 -4.1
New-PSItem -5.2 6.1
)
#Set the numbers throughout the sheet to format as positive in blue with a + sign, negative in Red with a - sign.
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat "[Blue]+0.#0;[Red]-0.#0"

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$file = "disks.xlsx"
$file = "$env:temp\disks.xlsx"
Remove-Item $file -ErrorAction Ignore
@@ -12,6 +12,5 @@ $data = $(
New-PSItem -5.2 6.1
New-PSItem 1000 -2000
)
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat '[Blue]$#,##0.00;[Red]-$#,##0.00'
#Number format can expand terms like Currency, to the local currency format
$data | Export-Excel -Path $file -Show -AutoSize -NumberFormat 'Currency'

Binary file not shown.

View File

@@ -0,0 +1,23 @@
# ConvertFrom-Excel
''
.\test.xlsx
Import-Excel .\test.xlsx | ft
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html
# Create a column definition
$columnOptions = @()
$columnOptions += New-ColumnOption -ColumnName Progress -formatter progress
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
$columnOptions += New-ColumnOption Activity -formatter lineFormatter
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
$columnOptions += New-ColumnOption -ColumnName Rating -formatter star
$columnOptions += New-ColumnOption Driver -formatter tickCross
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions
ConvertFrom-Excel -ExcelFile .\test.xlsx -outFile .\targetout.html -columnOptions $columnOptions -groupBy Gender

View File

@@ -0,0 +1,216 @@
## Start-Demo.ps1
##################################################################################################
## This is an overhaul of Jeffrey Snover's original Start-Demo script by Joel "Jaykul" Bennett
##
## I've switched it to using ReadKey instead of ReadLine (you don't have to hit Enter each time)
## As a result, I've changed the names and keys for a lot of the operations, so that they make
## sense with only a single letter to tell them apart (sorry if you had them memorized).
##
## I've also been adding features as I come across needs for them, and you'll contribute your
## improvements back to the PowerShell Script repository as well.
##################################################################################################
## Revision History (version 3.3)
## 3.3.3 Fixed: Script no longer says "unrecognized key" when you hit shift or ctrl, etc.
## Fixed: Blank lines in script were showing as errors (now printed like comments)
## 3.3.2 Fixed: Changed the "x" to match the "a" in the help text
## 3.3.1 Fixed: Added a missing bracket in the script
## 3.3 - Added: Added a "Clear Screen" option
## - Added: Added a "Rewind" function (which I'm not using much)
## 3.2 - Fixed: Put back the trap { continue; }
## 3.1 - Fixed: No Output when invoking Get-Member (and other cmdlets like it???)
## 3.0 - Fixed: Commands which set a variable, like: $files = ls
## - Fixed: Default action doesn't continue
## - Changed: Use ReadKey instead of ReadLine
## - Changed: Modified the option prompts (sorry if you had them memorized)
## - Changed: Various time and duration strings have better formatting
## - Enhance: Colors are settable: prompt, command, comment
## - Added: NoPauseAfterExecute switch removes the extra pause
## If you set this, the next command will be displayed immediately
## - Added: Auto Execute mode (FullAuto switch) runs the rest of the script
## at an automatic speed set by the AutoSpeed parameter (or manually)
## - Added: Automatically append an empty line to the end of the demo script
## so you have a chance to "go back" after the last line of you demo
##################################################################################################
##
param(
$file=".\demo.txt",
[int]$command=0,
[System.ConsoleColor]$promptColor="Yellow",
[System.ConsoleColor]$commandColor="White",
[System.ConsoleColor]$commentColor="Green",
[switch]$FullAuto,
[int]$AutoSpeed = 3,
[switch]$NoPauseAfterExecute
)
$RawUI = $Host.UI.RawUI
$hostWidth = $RawUI.BufferSize.Width
# A function for reading in a character
function Read-Char() {
$_OldColor = $RawUI.ForeGroundColor
$RawUI.ForeGroundColor = "Red"
$inChar=$RawUI.ReadKey("IncludeKeyUp")
# loop until they press a character, so Shift or Ctrl, etc don't terminate us
while($inChar.Character -eq 0){
$inChar=$RawUI.ReadKey("IncludeKeyUp")
}
$RawUI.ForeGroundColor = $_OldColor
return $inChar.Character
}
function Rewind($lines, $index, $steps = 1) {
$started = $index;
$index -= $steps;
while(($index -ge 0) -and ($lines[$index].Trim(" `t").StartsWith("#"))){
$index--
}
if( $index -lt 0 ) { $index = $started }
return $index
}
$file = Resolve-Path $file
while(-not(Test-Path $file)) {
$file = Read-Host "Please enter the path of your demo script (Crtl+C to cancel)"
$file = Resolve-Path $file
}
Clear-Host
$_lines = Get-Content $file
# Append an extra (do nothing) line on the end so we can still go back after the last line.
$_lines += "Write-Host 'The End'"
$_starttime = [DateTime]::now
$FullAuto = $false
Write-Host -nonew -back black -fore $promptColor $(" " * $hostWidth)
Write-Host -nonew -back black -fore $promptColor @"
<Demo Started :: $(split-path $file -leaf)>$(' ' * ($hostWidth -(18 + $(split-path $file -leaf).Length)))
"@
Write-Host -nonew -back black -fore $promptColor "Press"
Write-Host -nonew -back black -fore Red " ? "
Write-Host -nonew -back black -fore $promptColor "for help.$(' ' * ($hostWidth -17))"
Write-Host -nonew -back black -fore $promptColor $(" " * $hostWidth)
# We use a FOR and an INDEX ($_i) instead of a FOREACH because
# it is possible to start at a different location and/or jump
# around in the order.
for ($_i = $Command; $_i -lt $_lines.count; $_i++)
{
# Put the current command in the Window Title along with the demo duration
$Dur = [DateTime]::Now - $_StartTime
$RawUI.WindowTitle = "$(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s {3}" -f
$dur.Hours, $dur.Minutes, $dur.Seconds, $($_Lines[$_i])
# Echo out the commmand to the console with a prompt as though it were real
Write-Host -nonew -fore $promptColor "[$_i]$([char]0x2265) "
if ($_lines[$_i].Trim(" ").StartsWith("#") -or $_lines[$_i].Trim(" ").Length -le 0) {
Write-Host -fore $commentColor "$($_Lines[$_i]) "
continue
} else {
Write-Host -nonew -fore $commandColor "$($_Lines[$_i]) "
}
if( $FullAuto ) { Start-Sleep $autoSpeed; $ch = [char]13 } else { $ch = Read-Char }
switch($ch)
{
"?" {
Write-Host -Fore $promptColor @"
Running demo: $file
(n) Next (p) Previous
(q) Quit (s) Suspend
(t) Timecheck (v) View $(split-path $file -leaf)
(g) Go to line by number
(f) Find lines by string
(a) Auto Execute mode
(c) Clear Screen
"@
$_i-- # back a line, we're gonna step forward when we loop
}
"n" { # Next (do nothing)
Write-Host -Fore $promptColor "<Skipping Line>"
}
"p" { # Previous
Write-Host -Fore $promptColor "<Back one Line>"
while ($_lines[--$_i].Trim(" ").StartsWith("#")){}
$_i-- # back a line, we're gonna step forward when we loop
}
"a" { # EXECUTE (Go Faster)
$AutoSpeed = [int](Read-Host "Pause (seconds)")
$FullAuto = $true;
Write-Host -Fore $promptColor "<eXecute Remaining Lines>"
$_i-- # Repeat this line, and then just blow through the rest
}
"q" { # Quit
Write-Host -Fore $promptColor "<Quiting demo>"
$_i = $_lines.count;
break;
}
"v" { # View Source
$lines[0..($_i-1)] | Write-Host -Fore Yellow
$lines[$_i] | Write-Host -Fore Green
$lines[($_i+1)..$lines.Count] | Write-Host -Fore Yellow
$_i-- # back a line, we're gonna step forward when we loop
}
"t" { # Time Check
$dur = [DateTime]::Now - $_StartTime
Write-Host -Fore $promptColor $(
"{3} -- $(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s" -f
$dur.Hours, $dur.Minutes, $dur.Seconds, ([DateTime]::Now.ToShortTimeString()))
$_i-- # back a line, we're gonna step forward when we loop
}
"s" { # Suspend (Enter Nested Prompt)
Write-Host -Fore $promptColor "<Suspending demo - type 'Exit' to resume>"
$Host.EnterNestedPrompt()
$_i-- # back a line, we're gonna step forward when we loop
}
"g" { # GoTo Line Number
$i = [int](Read-Host "line number")
if($i -le $_lines.Count) {
if($i -gt 0) {
# extra line back because we're gonna step forward when we loop
$_i = Rewind $_lines $_i (($_i-$i)+1)
} else {
$_i = -1 # Start negative, because we step forward when we loop
}
}
}
"f" { # Find by pattern
$match = $_lines | Select-String (Read-Host "search string")
if($match -eq $null) {
Write-Host -Fore Red "Can't find a matching line"
} else {
$match | % { Write-Host -Fore $promptColor $("[{0,2}] {1}" -f ($_.LineNumber - 1), $_.Line) }
if($match.Count -lt 1) {
$_i = $match.lineNumber - 2 # back a line, we're gonna step forward when we loop
} else {
$_i-- # back a line, we're gonna step forward when we loop
}
}
}
"c" {
Clear-Host
$_i-- # back a line, we're gonna step forward when we loop
}
"$([char]13)" { # on enter
Write-Host
trap [System.Exception] {Write-Error $_; continue;}
Invoke-Expression ($_lines[$_i]) | out-default
if(-not $NoPauseAfterExecute -and -not $FullAuto) {
$null = $RawUI.ReadKey("NoEcho,IncludeKeyUp") # Pause after output for no apparent reason... ;)
}
}
default
{
Write-Host -Fore Green "`nKey not recognized. Press ? for help, or ENTER to execute the command."
$_i-- # back a line, we're gonna step forward when we loop
}
}
}
$dur = [DateTime]::Now - $_StartTime
Write-Host -Fore $promptColor $(
"<Demo Complete -- $(if($dur.Hours -gt 0){'{0}h '})$(if($dur.Minutes -gt 0){'{1}m '}){2}s>" -f
$dur.Hours, $dur.Minutes, $dur.Seconds, [DateTime]::Now.ToLongTimeString())
Write-Host -Fore $promptColor $([DateTime]::now)
Write-Host

View File

@@ -0,0 +1,80 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Out-TabulatorView</title>
</head>
<body>
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery-ui.min.js"></script>
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\tabulator.min.js"></script>
<script type="text/javascript" src="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\js\jquery.sparkline.min.js"></script>
<link href="file:///C:\Program Files\WindowsPowerShell\Modules\OutTabulatorView\css\tabulator.min.css" rel="stylesheet">
<div id="example-table"></div>
<script type="text/javascript">
var lineFormatter = function(cell, formatterParams){
setTimeout(function(){ //give cell enough time to be added to the DOM before calling sparkline formatter
cell.getElement().sparkline(cell.getValue(), {width:"100%", type:"line", disableTooltips:true});
}, 10);
};
var tabledata = [{"Name":"Alan Francis","Progress":90,"Activity":[4,17,11,7,6,12,14,13,11,10,9,6,11,12,0,5,12,14,18,11],"Gender":"male","Rating":3,"Color":"blue","dob":"07/08/1972","Driver":"true"},{"Name":"Brendon Philips","Progress":100,"Activity":[3,7,9,1,4,8,2,6,4,2,1,3,1,3,3,1,1,3,1,3],"Gender":"male","Rating":1,"Color":"orange","dob":"01/08/1980","Driver":""},{"Name":"Christine Lobowski","Progress":42,"Activity":[1,2,5,4,1,16,4,2,1,3,3,7,9,1,4,8,2,6,4,2],"Gender":"female","Rating":0,"Color":"green","dob":"22/05/1982","Driver":"true"},{"Name":"Ed White","Progress":70,"Activity":[20,17,15,11,16,9,4,17,11,12,0,5,12,14,18,11,12,14,20,12],"Gender":"male","Rating":0,"Color":"yellow","dob":"19/06/1976","Driver":""},{"Name":"Emily Sykes","Progress":42,"Activity":[11,15,19,20,17,16,16,5,3,2,1,2,3,4,5,4,2,5,9,8],"Gender":"female","Rating":1,"Color":"maroon","dob":"11/11/1970","Driver":""},{"Name":"Emma Netwon","Progress":40,"Activity":[3,7,9,1,4,8,3,7,9,1,4,8,2,6,4,2,2,6,4,2],"Gender":"female","Rating":4,"Color":"brown","dob":"07/10/1963","Driver":"true"},{"Name":"Frank Harbours","Progress":38,"Activity":[20,17,15,11,16,9,12,14,20,12,11,7,6,12,14,13,11,10,9,6],"Gender":"male","Rating":4,"Color":"red","dob":"12/05/1966","Driver":1},{"Name":"Gemma Jane","Progress":60,"Activity":[4,17,11,12,0,5,12,14,18,11,11,15,19,20,17,16,16,5,3,2],"Gender":"female","Rating":0,"Color":"red","dob":"22/05/1982","Driver":"true"},{"Name":"Hannah Farnsworth","Progress":30,"Activity":[1,2,5,4,1,16,10,12,14,16,13,9,7,11,10,13,4,2,1,3],"Gender":"female","Rating":1,"Color":"pink","dob":"11/02/1991","Driver":""},{"Name":"James Newman","Progress":73,"Activity":[1,20,5,3,10,13,17,15,9,11,1,2,3,4,5,4,2,5,9,8],"Gender":"male","Rating":5,"Color":"red","dob":"22/03/1998","Driver":""},{"Name":"Jamie Newhart","Progress":23,"Activity":[11,7,6,12,14,13,11,10,9,6,4,17,11,12,0,5,12,14,18,11],"Gender":"male","Rating":3,"Color":"green","dob":"14/05/1985","Driver":"true"},{"Name":"Jenny Green","Progress":56,"Activity":[11,15,19,20,17,15,11,16,9,12,14,20,12,20,17,16,16,5,3,2],"Gender":"female","Rating":4,"Color":"indigo","dob":"12/11/1998","Driver":"true"},{"Name":"John Phillips","Progress":80,"Activity":[11,7,6,12,14,1,20,5,3,10,13,17,15,9,1,13,11,10,9,6],"Gender":"male","Rating":1,"Color":"green","dob":"24/09/1950","Driver":"true"},{"Name":"Margret Marmajuke","Progress":16,"Activity":[1,3,1,3,3,1,1,3,1,3,20,17,15,11,16,9,12,14,20,12],"Gender":"female","Rating":5,"Color":"yellow","dob":"31/01/1999","Driver":""},{"Name":"Martin Barryman","Progress":20,"Activity":[1,2,3,4,5,4,11,7,6,12,14,13,11,10,9,6,2,5,9,8],"Gender":"male","Rating":5,"Color":"violet","dob":"04/04/2001","Driver":""},{"Name":"Mary May","Progress":1,"Activity":[10,12,14,16,13,9,7,11,10,13,1,2,5,4,1,16,4,2,1,3],"Gender":"female","Rating":2,"Color":"blue","dob":"14/05/1982","Driver":"true"},{"Name":"Oli Bob","Progress":12,"Activity":[1,20,5,3,10,13,17,15,9,11,10,12,14,16,13,9,7,11,10,13],"Gender":"male","Rating":1,"Color":"red","dob":"19/02/1984","Driver":1},{"Name":"Paul Branderson","Progress":60,"Activity":[1,3,1,3,3,1,11,15,19,20,17,16,16,5,3,2,1,3,1,3],"Gender":"male","Rating":5,"Color":"orange","dob":"01/01/1982","Driver":""},{"Name":"Victoria Bath","Progress":20,"Activity":[10,12,14,16,13,9,7,1,2,3,4,5,4,2,5,9,8,11,10,13],"Gender":"female","Rating":2,"Color":"purple","dob":"22/03/1986","Driver":null}]
$("#example-table").tabulator(
{
"outFile": ".\\targetout.html",
"columns": [
{
"field": "Name",
"title": "Name"
},
{
"field": "Progress",
"title": "Progress",
"formatter": "progress"
},
{
"field": "Activity",
"title": "Activity",
"formatter": lineFormatter
},
{
"field": "Gender",
"title": "Gender"
},
{
"field": "Rating",
"title": "Rating",
"formatter": "star"
},
{
"field": "Color",
"title": "Color"
},
{
"field": "dob",
"title": "dob"
},
{
"field": "Driver",
"title": "Driver",
"formatter": "tickCross"
}
],
"groupBy": "Gender"
});
$("#example-table").tabulator("setData", tabledata);
</script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
[CmdletBinding()]
param($outFile = "$PSScriptRoot\targetout.html")
$columnOptions = @()
$columnOptions += New-ColumnOption -ColumnName Progress -formatter progress
$columnOptions += New-ColumnOption -ColumnName Activity -formatter lineFormatter
ConvertFrom-Excel -ExcelFile $PSScriptRoot\test.xlsx -outFile $PSScriptRoot\targetout.html -columnOptions $columnOptions

View File

@@ -1,16 +1,20 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$file = "sales.xlsx"
$file = "$env:Temp\sales.xlsx"
Remove-Item $file -ErrorAction Ignore
#Using -Passthru with Export-Excel returns an Excel Package object.
$xlPkg = Import-Csv .\sales.csv | Export-Excel $file -PassThru
$ws = $xlPkg.Workbook.WorkSheets[1]
#We add script properties to the package so $xlPkg.Sheet1 is equivalent to $xlPkg.Workbook.WorkSheets["Sheet1"]
$ws = $xlPkg.Sheet1
#We can manipulate the cells ...
$ws.Cells["E1"].Value = "TotalSold"
$ws.Cells["F1"].Value = "Add 10%"
#This is for illustration - there are more efficient ways to do this.
2..($ws.Dimension.Rows) |
ForEach-Object {
$ws.Cells["E$_"].Formula = "=C$_+D$_"
@@ -19,7 +23,7 @@ $ws.Cells["F1"].Value = "Add 10%"
$ws.Cells.AutoFitColumns()
#You can call close-ExcelPackage $xlPkg -show, but here we will do the ssteps explicitly
$xlPkg.Save()
$xlPkg.Dispose()
Invoke-Item $file

Binary file not shown.

View File

@@ -0,0 +1,55 @@
$data = ConvertFrom-Csv @"
Region,Date,Fruit,Sold
North,1/1/2017,Pears,50
South,1/1/2017,Pears,150
East,4/1/2017,Grapes,100
West,7/1/2017,Bananas,150
South,10/1/2017,Apples,200
North,1/1/2018,Pears,100
East,4/1/2018,Grapes,200
West,7/1/2018,Bananas,300
South,10/1/2018,Apples,400
"@ | Select-Object -Property Region, @{n = "Date"; e = {[datetime]::ParseExact($_.Date, "M/d/yyyy", (Get-Culture))}}, Fruit, Sold
$xlfile = "$env:temp\multiplePivotTables.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$excel = $data | Export-Excel $xlfile -PassThru -AutoSize -TableName FruitData
$pivotTableParams = @{
PivotTableName = "ByRegion"
Address = $excel.Sheet1.cells["F1"]
SourceWorkSheet = $excel.Sheet1
PivotRows = echo Region Fruit Date
PivotData = @{'sold' = 'sum'}
PivotTableStyle = 'Light21'
GroupDateRow = "Date"
GroupDatePart = echo Years Quarters
}
$pt = Add-PivotTable @pivotTableParams -PassThru
#$pt.RowHeaderCaption ="By Region,Fruit,Date"
$pt.RowHeaderCaption = "By " + ($pivotTableParams.PivotRows -join ",")
$pivotTableParams.PivotTableName = "ByFruit"
$pivotTableParams.Address = $excel.Sheet1.cells["J1"]
$pivotTableParams.PivotRows = echo Fruit Region Date
$pt = Add-PivotTable @pivotTableParams -PassThru
$pt.RowHeaderCaption = "By Fruit,Region"
$pivotTableParams.PivotTableName = "ByDate"
$pivotTableParams.Address = $excel.Sheet1.cells["N1"]
$pivotTableParams.PivotRows = echo Date Region Fruit
$pt = Add-PivotTable @pivotTableParams -PassThru
$pt.RowHeaderCaption = "By Date,Region,Fruit"
$pivotTableParams.PivotTableName = "ByYears"
$pivotTableParams.Address = $excel.Sheet1.cells["S1"]
$pivotTableParams.GroupDatePart = echo Years
$pt = Add-PivotTable @pivotTableParams -PassThru
$pt.RowHeaderCaption = "By Years,Region"
Close-ExcelPackage $excel -Show

View File

@@ -1,15 +1,25 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
Remove-Item .\test1.xlsx -ErrorAction Ignore
$ExcelParams = @{
Path = ".\test1.xlsx"
Path = "$env:TEMP\test1.xlsx"
IncludePivotTable = $true
PivotRows = 'Company'
PivotTableName = 'MyTable'
PivotData = @{'Handles' = 'sum'}
Show = $true
Activate = $true
}
Remove-Item $ExcelParams.Path -ErrorAction Ignore
Get-Process | Select-Object Company, Handles | Export-Excel @ExcelParams
Get-Process | Select-Object Company, Handles |
Export-Excel @ExcelParams
<# Builds a pivot table that looks like this:
Sum of Handles
Row Labels Total
Adobe Systems Incorporated 3100
(blank) 214374
Apple Inc. 215
etc
etc
Grand Total 365625
#>

View File

@@ -0,0 +1,26 @@
$path = "$Env:TEMP\test.xlsx"
remove-item -path $path -ErrorAction SilentlyContinue
#Export some sales data to Excel, format it as a table and put a data-bar in. For this example we won't create the pivot table during the export
$excel = ConvertFrom-Csv @"
Product, City, Gross, Net
Apple, London , 300, 250
Orange, London , 400, 350
Banana, London , 300, 200
Orange, Paris, 600, 500
Banana, Paris, 300, 200
Apple, New York, 1200,700
"@ | Export-Excel -PassThru -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"}
#Add a pivot table, specify its address to put it on the same sheet, use the data that was just exported set the table style and number format.
#Use the "City" for the row names, and "Product" for the columnnames, and sum both the gross and net values for each City/Product combination; add grand totals to rows and columns.
# activate the sheet and add a pivot chart (defined in a hash table)
Add-PivotTable -Address $excel.Sheet1.Cells["F1"] -SourceWorkSheet $Excel.Sheet1 -SourceRange $Excel.Sheet1.Dimension.Address -PivotTableName "Sales" -PivotTableStyle "Medium12" -PivotNumberFormat "$#,##0.00" `
-PivotRows "City" -PivotColumns "Product" -PivotData @{Gross="Sum";Net="Sum"}-PivotTotals "Both" -Activate -PivotChartDefinition @{
Title="Gross and net by city and product";
ChartType="ColumnClustered";
Column=11; Width=500; Height=360;
YMajorUnit=500; YMinorUnit=100; YAxisNumberformat="$#,##0"
LegendPosition="Bottom"}
#Save and open in excel
Close-ExcelPackage $excel -Show

Binary file not shown.

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$xlFile=".\testPivot.xlsx"
$xlFile="$env:TEMP\testPivot.xlsx"
Remove-Item $xlFile -ErrorAction Ignore
$data =@"
@@ -18,4 +18,18 @@ $data |
-AutoSize -AutoFilter `
-IncludePivotTable `
-PivotRows Product `
-PivotData @{"Units"="sum"} -PivotFilter Region, Area
-PivotData @{"Units"="sum"} -PivotFilter Region, Area -Activate
<#
Creates a Pivot table that looks like
Region All^
Area All^
Sum of Units
Row Labels Total
Apple 100
Pear 240
Grape 280
Banana 160
Grand Total 780
#>

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$plt = New-Plot
$plt.Plot((Get-Range 0 5 .02|%{[math]::Cos(2*[math]::pi*$_)}))
$plt.Plot((Get-Range 0 5 .02|Foreach-Object {[math]::Cos(2*[math]::pi*$_)}))
$plt.SetChartSize(800,300)
$plt.Show()

View File

@@ -1,5 +1,7 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
#requires -modules "getSql"
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
#download f1Results from https://1drv.ms/f/s!AhfYu7-CJv4egbt5FD7Cdxi8jSz3aQ and update the path below
Get-SQL -Session f1 -Excel -Connection C:\Users\mcp\OneDrive\Public\F1\f1Results.xlsx -showtables -Verbose
Remove-Item .\demo3.xlsx

View File

@@ -1,10 +1,13 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$p = Get-Process | Select-Object Company, Handles | Export-Excel c:\temp\testBackgroundColor.xlsx -ClearSheet -KillExcel -PassThru
$path = "$env:TEMP\testBackgroundColor.xlsx"
$p = Get-Process | Select-Object Company, Handles | Export-Excel $path -ClearSheet -PassThru
$ws = $p.Workbook.WorkSheets[1]
$totalRows = $ws.Dimension.Rows
Set-Format -Address $ws.Cells["B2:B$($totalRows)"] -BackgroundColor LightBlue
#Set the range from B2 to the last active row. s
Set-ExcelRange -Range $ws.Cells["B2:B$($totalRows)"] -BackgroundColor LightBlue
Export-Excel -ExcelPackage $p -show -AutoSize

View File

@@ -3,7 +3,7 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
#. ..\New-PSItem.ps1
Remove-Item *.xlsx
Remove-Item "$env:temp\functions.xlsx" -ErrorAction SilentlyContinue
$(
New-PSItem 12001 Nails 37 3.99 =C2*D2 (echo ID Product Quantity Price Total)
@@ -11,4 +11,4 @@ $(
New-PSItem 12003 Saw 12 15.37 =C4*D4
New-PSItem 12010 Drill 20 8 =C5*D5
New-PSItem 12011 Crowbar 7 23.48 =C6*D6
) | Export-Excel functions.xlsx -AutoSize -Show
) | Export-Excel "$env:temp\functions.xlsx"-AutoSize -Show

View File

@@ -1,6 +1,6 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
Remove-Item *.xlsx
Remove-Item "$env:temp\functions.xlsx" -ErrorAction SilentlyContinue
$(
New-PSItem =2%/12 60 500000 "=pmt(rate,nper,pv)" (echo rate nper pv pmt)
@@ -9,4 +9,4 @@ $(
New-PSItem =5%/12 60 500000 "=pmt(rate,nper,pv)"
New-PSItem =6%/12 60 500000 "=pmt(rate,nper,pv)"
New-PSItem =7%/12 60 500000 "=pmt(rate,nper,pv)"
) | Export-Excel functions.xlsx -AutoNameRange -AutoSize -Show
) | Export-Excel "$env:temp\functions.xlsx" -AutoNameRange -AutoSize -Show

View File

@@ -1,10 +1,10 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
Remove-Item *.xlsx
Remove-Item "$env:temp\hyperlink.xlsx" -ErrorAction SilentlyContinue
$(
New-PSItem '=Hyperlink("http://dougfinke.com/blog","Doug Finke")' @("Link")
New-PSItem '=Hyperlink("http://blogs.msdn.com/b/powershell/","PowerShell Blog")'
New-PSItem '=Hyperlink("http://blogs.technet.com/b/heyscriptingguy/","Hey, Scripting Guy")'
) | Export-Excel hyperlink.xlsx -AutoSize -Show
) | Export-Excel "$env:temp\hyperlink.xlsx" -AutoSize -Show

View File

@@ -1,25 +1,24 @@
<#
Revisit I think yahoo deprecated their service
#>
function Get-StockInfo {
param(
$stock,
[datetime]$startDate,
[datetime]$endDate
[Parameter(Mandatory)]
$symbols,
[ValidateSet('open', 'close', 'high', 'low', 'avgTotalVolume')]
$dataPlot = "close"
)
Process {
$xlfile = "$env:TEMP\stocks.xlsx"
rm $xlfile -ErrorAction Ignore
if (!$endDate) { $endDate = $startDate}
$result = Invoke-RestMethod "https://api.iextrading.com/1.0/stock/market/batch?symbols=$($symbols)&types=quote&last=1"
$baseUrl = "http://query.yahooapis.com/v1/public/yql?q="
$q = @"
select * from yahoo.finance.historicaldata where symbol = "$($stock)" and startDate = "$($startDate.ToString('yyyy-MM-dd'))" and endDate = "$($endDate.ToString('yyyy-MM-dd'))"
"@
$suffix = "&env=store://datatables.org/alltableswithkeys&format=json"
$r = Invoke-RestMethod ($baseUrl + $q + $suffix)
$r.query.results.quote
$symbolCount = $symbols.Split(",").count
}
}
$ecd = New-ExcelChartDefinition -Row 1 -Column 1 -SeriesHeader $dataPlot `
-XRange symbol -YRange $dataPlot `
-Title "$($dataPlot)`r`n As Of $((Get-Date).ToShortDateString())"
$(foreach ($name in $result.psobject.Properties.name) {
$result.$name.quote
}) | Export-Excel $xlfile -AutoNameRange -AutoSize -Show -ExcelChartDefinition $ecd -StartRow 21 -StartColumn 2
}

View File

@@ -1,20 +0,0 @@
<#
Revisit I think yahoo deprecated their service
#>
# try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
# $Symbol = "MSFT"
# . .\Get-StockInfo.ps1
# Remove-Item *.xlsx -ErrorAction Ignore
# $chart = New-ExcelChart -XRange Date -YRange Volume `
# -ChartType ColumnStacked `
# -Column 9 -Title "$Symbol Volume"
# Get-StockInfo $Symbol 11/2 11/30 |
# Export-Excel .\stocks.xlsx -Show `
# -AutoSize -AutoNameRange `
# -ExcelChartDefinition $chart

View File

@@ -0,0 +1,3 @@
. $PSScriptRoot\Get-StockInfo.ps1
Get-StockInfo -symbols "msft,ibm,ge,xom,aapl" -dataPlot avgTotalVolume

Binary file not shown.

View File

@@ -1,7 +1,7 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
$xlfile = "testData.xlsx"
Remove-Item *.xlsx
$xlfile = "$env:Temp\testData.xlsx"
Remove-Item $xlfile -ErrorAction SilentlyContinue
$r = Get-ChildItem C:\WINDOWS\system32
@@ -23,16 +23,19 @@ $top10ByFileSize = $r |
Select-Object -First 10 Name, @{n="Size";e={$_.Length}} #,Extension,Path
$top10BySize | Export-Excel $xlfile -WorkSheetname FileInfo -TableName ExtSize
$top10ByCount | Export-Excel $xlfile -WorkSheetname FileInfo -StartRow 13 -TableName ExtCount
$top10ByFileSize | Export-Excel $xlfile -WorkSheetname FileInfo -StartRow 25 -AutoSize -TableName FileSize
$xlPkg = $top10BySize | Export-Excel -path $xlfile -WorkSheetname FileInfo -TableName ExtSize -PassThru
$xlPkg = $top10ByCount | Export-Excel -ExcelPackage $xlPkg -WorkSheetname FileInfo -StartRow 13 -TableName ExtCount -PassThru
$xlPkg = $top10ByFileSize | Export-Excel -ExcelPackage $xlPkg -WorkSheetname FileInfo -StartRow 25 -TableName FileSize -PassThru -AutoSize
#worksheets.tables["Name1","Name2"] returns 2 tables. Set-ExcelRange can process those and will set the number format over both
Set-ExcelRange -Range $xlpkg.Workbook.Worksheets[1].Tables["ExtSize","FileSize"] -NumberFormat '0,,"MB"'
$ps = Get-Process | Where-Object Company
$ps |
Sort-Object handles -Descending |
Select-Object -First 10 company, handles |
Export-Excel $xlfile -WorkSheetname Handles -AutoSize -TableName Handles
Export-Excel -ExcelPackage $xlPkg -WorkSheetname Handles -AutoSize -TableName Handles
$ps |
Sort-Object PM -Descending |

Binary file not shown.

View File

@@ -0,0 +1,90 @@
function ConvertTo-PesterTest {
param(
[parameter(Mandatory)]
$XlFilename,
$WorksheetName = 'Sheet1'
)
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss")
$records = Import-Excel $XlFilename
$params = @{}
$blocks = $(foreach ($record in $records) {
foreach ($propertyName in $record.psobject.properties.name) {
if ($propertyName -notmatch 'ExpectedResult|QueryString') {
$params.$propertyName = $record.$propertyName
}
}
if ($record.QueryString) {
$params.Uri += "?{0}" -f $record.QueryString
}
@"
it "Should have the expected result '$($record.ExpectedResult)'" {
`$target = '$($params | ConvertTo-Json -compress)' | ConvertFrom-Json
`$target.psobject.Properties.name | ForEach-Object {`$p=@{}} {`$p.`$_=`$(`$target.`$_)}
Invoke-RestMethod @p | Should Be '$($record.ExpectedResult)'
}
"@
})
@"
Describe "Tests from $($XlFilename) in $($WorksheetName)" {
$($blocks)
}
"@ | Set-Content -Encoding Ascii $testFileName
[PSCustomObject]@{
TestFileName = (Get-ChildItem $testFileName).FullName
}
}
function Show-PesterResult {
param(
[Parameter(ValueFromPipelineByPropertyName, Mandatory)]
$TestFileName
)
Begin {
$xlfilename = ".\test.xlsx"
Remove-Item $xlfilename -ErrorAction SilentlyContinue
$ConditionalText = @()
$ConditionalText += New-ConditionalText -Range "Result" -Text failed -BackgroundColor red -ConditionalTextColor black
$ConditionalText += New-ConditionalText -Range "Result" -Text passed -BackgroundColor green -ConditionalTextColor black
$ConditionalText += New-ConditionalText -Range "Result" -Text pending -BackgroundColor gray -ConditionalTextColor black
$xlParams = @{
Path = $xlfilename
WorkSheetname = 'PesterTests'
ConditionalText = $ConditionalText
PivotRows = 'Result', 'Name'
PivotData = @{'Result' = 'Count'}
IncludePivotTable = $true
AutoSize = $true
AutoNameRange = $true
AutoFilter = $true
Show = $true
}
}
End {
$(foreach ($result in (Invoke-Pester -Script $TestFileName -PassThru -Show None).TestResult) {
[PSCustomObject][Ordered]@{
Description = $result.Describe
Name = $result.Name
Result = $result.Result
Messge = $result.FailureMessage
StackTrace = $result.StackTrace
}
}) | Export-Excel @xlParams
}
}

View File

@@ -1,40 +1,32 @@
function Show-PesterResults {
$xlfilename=".\test.xlsx"
rm $xlfilename -ErrorAction Ignore
$xlfilename = ".\test.xlsx"
Remove-Item $xlfilename -ErrorAction Ignore
$ConditionalText = @()
$ConditionalText += New-ConditionalText -Range "Result" -Text failed -BackgroundColor red -ConditionalTextColor black
$ConditionalText += New-ConditionalText -Range "Result" -Text passed -BackgroundColor green -ConditionalTextColor black
$ConditionalText += New-ConditionalText -Range "Result" -Text pending -BackgroundColor gray -ConditionalTextColor black
$xlParams = @{
Path=$xlfilename
WorkSheetname = 'PesterTests'
ConditionalText=$ConditionalText
PivotRows = 'Description'
PivotColumns = 'Result'
PivotData = @{'Result'='Count'}
IncludePivotTable = $true
#IncludePivotChart = $true
#NoLegend = $true
#ShowPercent = $true
#ShowCategory = $true
AutoSize = $true
AutoNameRange = $true
AutoFilter = $true
Show = $true
Path = $xlfilename
WorkSheetname = 'PesterTests'
ConditionalText = $ConditionalText
PivotRows = 'Result', 'Name'
PivotData = @{'Result' = 'Count'}
IncludePivotTable = $true
AutoSize = $true
AutoNameRange = $true
AutoFilter = $true
Show = $true
}
$(foreach($result in (Invoke-Pester -PassThru -Show None).TestResult) {
[PSCustomObject]@{
Description = $result.Describe
Name = $result.Name
#Time = $result.Time
Result = $result.Result
Messge = $result.FailureMessage
StackTrace = $result.StackTrace
}
}) | Sort Description | Export-Excel @xlParams
$(foreach ($result in (Invoke-Pester -PassThru -Show None).TestResult) {
[PSCustomObject]@{
Description = $result.Describe
Name = $result.Name
Result = $result.Result
Messge = $result.FailureMessage
StackTrace = $result.StackTrace
}
}) | Sort-Object Description | Export-Excel @xlParams
}

View File

@@ -1,5 +1,3 @@
try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
function Test-APIReadXls {
param(
[parameter(Mandatory)]
@@ -7,6 +5,8 @@ function Test-APIReadXls {
$WorksheetName = 'Sheet1'
)
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss")
$records = Import-Excel $XlFilename
$params = @{}
@@ -35,15 +35,11 @@ function Test-APIReadXls {
"@
})
$testFileName = "{0}.tests.ps1" -f (get-date).ToString("yyyyMMddHHmmss.fff")
@"
Describe "Tests from $($XlFilename) in $($WorksheetName)" {
$($blocks)
}
"@ | Set-Content -Encoding Ascii $testFileName
#Invoke-Pester -Script (Get-ChildItem $testFileName)
Get-ChildItem $testFileName
}
(Get-ChildItem $testFileName).FullName
}

View File

@@ -2,6 +2,6 @@ try {. $PSScriptRoot\..\..\LoadPSD1.ps1} catch {}
. $PSScriptRoot\TestAPIReadXls.ps1
Test-APIReadXls $PSScriptRoot\testlist.xlsx | % {
Test-APIReadXls $PSScriptRoot\testlist.xlsx | Foreach-Object {
Invoke-Pester -Script $_.fullname -PassThru -Show None
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

28
Export-StocksToExcel.ps1 Normal file
View File

@@ -0,0 +1,28 @@
function Export-StocksToExcel {
param(
[string]$symbols,
[ValidateSet("Open", "High", "Low", "Close", "Volume")]
$measure = "Open"
)
$xl = "$env:TEMP\Stocks.xlsx"
Remove-Item $xl -ErrorAction SilentlyContinue
$r = Invoke-RestMethod "https://azfnstockdata-fn83fffd32.azurewebsites.net/api/GetQuoteChart?symbol=$($symbols)"
$chartColumn = $symbols.Split(',').count + 2
$ptd = New-PivotTableDefinition `
-SourceWorkSheet Sheet1 `
-PivotTableName result `
-PivotData @{$measure = 'sum'} `
-PivotRows date `
-PivotColumns symbol `
-ChartType Line `
-ChartTitle "Stock - $measure " `
-IncludePivotChart -NoTotalsInPivot -ChartColumn $chartColumn -ChartRow 3 -Activate
$r | Sort-Object Date, symbol | Export-Excel $xl -PivotTableDefinition $ptd -AutoSize -AutoFilter -Show
}
# Export-StocksToExcel -symbols 'ibm,aapl,msft' -measure High

View File

@@ -1,49 +1,49 @@
<#
.Synopsis
Exports the charts in an Excel spreadSheet
Exports the charts in an Excel spreadSheet
.Example
Export-Charts .\test.xlsx
Exports the charts in test.xlsx to JPEG files in the current directory.
.Example
Export-Charts -path .\test,xlsx -destination [System.Environment+SpecialFolder]::MyDocuments -outputType PNG -passthrough
Exports the charts to PNG files in MyDocuments , and returns file objects representing the newly created files
Export-Charts -path .\test,xlsx -destination [System.Environment+SpecialFolder]::MyDocuments -outputType PNG -passthrough
Exports the charts to PNG files in MyDocuments , and returns file objects representing the newly created files
#>
Param (
#Path to the Excel file whose chars we will export.
$Path = "C:\Users\public\Documents\stats.xlsx",
#If specified, output file objects representing the image files
[switch]$Passthru,
#Format to write - JPG by default
#Path to the Excel file whose chars we will export.
$Path = "C:\Users\public\Documents\stats.xlsx",
#If specified, output file objects representing the image files
[switch]$Passthru,
#Format to write - JPG by default
[ValidateSet("JPG","PNG","GIF")]
$OutputType = "JPG",
#Folder to write image files to (defaults to same one as the Excel file is in)
$OutputType = "JPG",
#Folder to write image files to (defaults to same one as the Excel file is in)
$Destination
)
#if no output folder was specified, set destination to the folder where the Excel file came from
if (-not $Destination) {$Destination = Split-Path -Path $Path -Parent }
#if no output folder was specified, set destination to the folder where the Excel file came from
if (-not $Destination) {$Destination = Split-Path -Path $Path -Parent }
#Call up Excel and tell it to open the file.
try { $excelApp = New-Object -ComObject "Excel.Application" }
catch { Write-Warning "Could not start Excel application - which usually means it is not installed." ; return }
#Call up Excel and tell it to open the file.
try { $excelApp = New-Object -ComObject "Excel.Application" }
catch { Write-Warning "Could not start Excel application - which usually means it is not installed." ; return }
try { $excelWorkBook = $excelApp.Workbooks.Open($Path) }
catch { Write-Warning -Message "Could not Open $Path." ; return }
try { $excelWorkBook = $excelApp.Workbooks.Open($Path) }
catch { Write-Warning -Message "Could not Open $Path." ; return }
#For each worksheet, for each chart, jump to the chart, create a filename of "WorksheetName_ChartTitle.jpg", and export the file.
#For each worksheet, for each chart, jump to the chart, create a filename of "WorksheetName_ChartTitle.jpg", and export the file.
foreach ($excelWorkSheet in $excelWorkBook.Worksheets) {
#note somewhat unusual way of telling excel we want all the charts.
#note somewhat unusual way of telling excel we want all the charts.
foreach ($excelchart in $excelWorkSheet.ChartObjects([System.Type]::Missing)) {
#if you don't go to the chart the image will be zero size !
#if you don't go to the chart the image will be zero size !
$excelApp.Goto($excelchart.TopLeftCell,$true)
$imagePath = Join-Path -Path $Destination -ChildPath ($excelWorkSheet.Name + "_" + ($excelchart.Chart.ChartTitle.Text -split "\s\d\d:\d\d,")[0] + ".$OutputType")
if ( $excelchart.Chart.Export($imagePath, $OutputType, $false) ) { # Export returs true/false for success/failure
if ($Passthru) {Get-Item -Path $imagePath } # when succesful return a file object (-Passthru) or print a verbose message, write warning for any failures
if ( $excelchart.Chart.Export($imagePath, $OutputType, $false) ) { # Export returs true/false for success/failure
if ($Passthru) {Get-Item -Path $imagePath } # when succesful return a file object (-Passthru) or print a verbose message, write warning for any failures
else {Write-Verbose -Message "Exported $imagePath"}
}
else {Write-Warning -Message "Failure exporting $imagePath" }
}
else {Write-Warning -Message "Failure exporting $imagePath" }
}
}
$excelApp.DisplayAlerts = $false

View File

@@ -29,7 +29,7 @@ Function Get-ExcelSheetInfo {
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path,'Open','Read','ReadWrite'
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
$workbook = $xl.Workbook
if ($workbook -and $workbook.Worksheets) {
$workbook.Worksheets |
Select-Object -Property name,index,hidden,@{

View File

@@ -1,8 +1,8 @@
Function Get-ExcelWorkbookInfo {
<#
.SYNOPSIS
<#
.SYNOPSIS
Retrieve information of an Excel workbook.
.DESCRIPTION
.DESCRIPTION
The Get-ExcelWorkbookInfo cmdlet retrieves information (LastModifiedBy, LastPrinted, Created, Modified, ...) fron an Excel workbook. These are the same details that are visible in Windows Explorer when right clicking the Excel file, selecting Properties and check the Details tabpage.
.PARAMETER Path
Specifies the path to the Excel file. This parameter is required.
@@ -10,22 +10,22 @@
Get-ExcelWorkbookInfo .\Test.xlsx
CorePropertiesXml : #document
Title :
Subject :
Title :
Subject :
Author : Konica Minolta User
Comments :
Keywords :
Comments :
Keywords :
LastModifiedBy : Bond, James (London) GBR
LastPrinted : 2017-01-21T12:36:11Z
Created : 17/01/2017 13:51:32
Category :
Status :
Category :
Status :
ExtendedPropertiesXml : #document
Application : Microsoft Excel
HyperlinkBase :
HyperlinkBase :
AppVersion : 14.0300
Company : Secret Service
Manager :
Manager :
Modified : 10/02/2017 12:45:37
CustomPropertiesXml : #document
@@ -35,8 +35,8 @@
.LINK
https://github.com/dfinke/ImportExcel
#>
#>
[CmdletBinding()]
Param (
[Alias('FullName')]
@@ -52,12 +52,12 @@
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
$workbook = $xl.Workbook
$workbook.Properties
$stream.Close()
$stream.Dispose()
$xl.Dispose()
$xl = $null
}
}
Catch {
throw "Failed retrieving Excel workbook information for '$Path': $_"
}

View File

@@ -1,3 +1,5 @@
# https://www.leeholmes.com/blog/2015/01/05/extracting-tables-from-powershells-invoke-webrequest/
# tweaked from the above code
function Get-HtmlTable {
param(
[Parameter(Mandatory=$true)]
@@ -9,7 +11,7 @@ function Get-HtmlTable {
)
$r = Invoke-WebRequest $url -UseDefaultCredentials: $UseDefaultCredentials
$table = $r.ParsedHtml.getElementsByTagName("table")[$tableIndex]
$propertyNames=$Header
$totalRows=@($table.rows).count
@@ -17,16 +19,16 @@ function Get-HtmlTable {
for ($idx = $FirstDataRow; $idx -lt $totalRows; $idx++) {
$row = $table.rows[$idx]
$cells = @($row.cells)
$cells = @($row.cells)
if(!$propertyNames) {
if($cells[0].tagName -eq 'th') {
$propertyNames = @($cells | foreach {$_.innertext -replace ' ',''})
$propertyNames = @($cells | ForEach-Object {$_.innertext -replace ' ',''})
} else {
$propertyNames = @(1..($cells.Count + 2) | % { "P$_" })
$propertyNames = @(1..($cells.Count + 2) | Foreach-Object { "P$_" })
}
continue
}
}
$result = [ordered]@{}
@@ -39,4 +41,4 @@ function Get-HtmlTable {
[PSCustomObject]$result
}
}
}

View File

@@ -1,7 +1,7 @@
function Get-XYRange {
param($targetData)
$record = $targetData| select -First 1
$record = $targetData | Select-Object -First 1
$p=$record.psobject.Properties.name
$infer = for ($idx = 0; $idx -lt $p.Count; $idx++) {
@@ -20,7 +20,7 @@ function Get-XYRange {
}
[PSCustomObject]@{
XRange = $infer | ? {$_.datatype -match 'string'} | select -First 1 excelcolumn, name
YRange = $infer | ? {$_.datatype -match 'int|double'} |select -First 1 excelcolumn, name
XRange = $infer | Where-Object -FilterScript {$_.datatype -match 'string'} | Select-Object -First 1 -Property excelcolumn, name
YRange = $infer | Where-Object -FilterScript {$_.datatype -match 'int|double'} | Select-Object -First 1 -Property excelcolumn, name
}
}

View File

@@ -25,7 +25,7 @@ Function Get-ExcelTableName {
$Stream.Close()
$Stream.Dispose()
$Excel.Dispose()
$Excel = $null
$Excel = $null
}
Function Get-ExcelTable {
@@ -66,7 +66,7 @@ Function Get-ExcelTable {
$propertyNames = for($col=$startCol; $col -lt ($startCol+$colCount); $col+= 1) {
$Worksheet.Cells[$startRow, $col].value
}
$startRow++
for($row=$startRow; $row -lt ($startRow+$rowCount); $row += 1) {
$nr=[ordered]@{}
@@ -89,16 +89,14 @@ function ConvertFrom-ExcelColumnName {
$sum=0
$columnName.ToCharArray() |
ForEach {
ForEach-Object {
$sum*=26
$sum+=[char]$_.tostring().toupper()-[char]'A'+1
}
}
$sum
}
cls
Import-Module .\ImportExcel.psd1 -Force
ipmo .\ImportExcel.psd1 -Force
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
#Get-ExcelTableName .\testTable.xlsx | Get-ExcelTable .\testTable.xlsx
Get-ExcelTable .\testTable.xlsx Table3

View File

@@ -2,19 +2,19 @@
function Import-Html {
[CmdletBinding()]
param(
$url,
$url,
$index,
$Header,
[int]$FirstDataRow=0,
[Switch]$UseDefaultCredentials
)
$xlFile = [System.IO.Path]::GetTempFileName() -replace "tmp","xlsx"
rm $xlFile -ErrorAction Ignore
Remove-Item $xlFile -ErrorAction Ignore
Write-Verbose "Exporting to Excel file $($xlFile)"
$data = Get-HtmlTable -url $url -tableIndex $index -Header $Header -FirstDataRow $FirstDataRow -UseDefaultCredentials: $UseDefaultCredentials
$data | Export-Excel $xlFile -Show -AutoSize
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,120 +1,188 @@
@{
# Script module or binary module file associated with this manifest.
RootModule = 'ImportExcel.psm1'
# Script module or binary module file associated with this manifest.
RootModule = 'ImportExcel.psm1'
# Version number of this module.
ModuleVersion = '5.1.1'
# Version number of this module.
ModuleVersion = '6.1.0'
# ID used to uniquely identify this module
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
# ID used to uniquely identify this module
GUID = '60dd4136-feff-401a-ba27-a84458c57ede'
# Author of this module
Author = 'Douglas Finke'
# Author of this module
Author = 'Douglas Finke'
# Company or vendor of this module
CompanyName = 'Doug Finke'
# Company or vendor of this module
CompanyName = 'Doug Finke'
# Copyright statement for this module
Copyright = 'c 2015 All rights reserved.'
# Copyright statement for this module
Copyright = 'c 2015 All rights reserved.'
# Description of the functionality provided by this module
Description = @'
# Description of the functionality provided by this module
Description = @'
PowerShell module to import/export Excel spreadsheets, without Excel.
Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5uoqS92stXioZw-u-ze_NtvSo0k0K0kq
'@
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of Microsoft .NET Framework required by this module
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Minimum version of the common language runtime (CLR) required by this module
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module
FunctionsToExport = '*'
# Functions to export from this module
FunctionsToExport = @(
'Add-ConditionalFormatting',
'Add-ExcelChart',
'Add-ExcelDataValidationRule',
'Add-ExcelName',
'Add-ExcelTable',
'Add-PivotTable',
'Add-WorkSheet',
'BarChart',
'Close-ExcelPackage',
'ColumnChart',
'Compare-WorkSheet',
'Convert-XlRangeToImage',
'ConvertFrom-ExcelData',
'ConvertFrom-ExcelSheet',
'ConvertFrom-ExcelToSQLInsert',
'ConvertTo-ExcelXlsx',
'Copy-ExcelWorkSheet',
'DoChart',
'Expand-NumberFormat',
'Export-Excel',
'Export-ExcelSheet',
'Export-MultipleExcelSheets',
'Get-ExcelColumnName',
'Get-ExcelSheetInfo',
'Get-ExcelWorkbookInfo',
'Get-HtmlTable',
'Get-Range',
'Get-XYRange',
'Import-Excel',
'Import-Html',
'Import-UPS',
'Import-USPS',
'Invoke-AllTests',
'Invoke-Sum',
'Join-Worksheet',
'LineChart',
'Merge-MultipleSheets',
'Merge-Worksheet',
'New-ConditionalFormattingIconSet',
'New-ConditionalText',
'New-ExcelChartDefinition',
'New-PivotTableDefinition',
'New-Plot',
'New-PSItem',
'NumberFormatCompletion',
'Open-ExcelPackage',
'PieChart',
'Pivot',
'Remove-WorkSheet'
'Select-Worksheet',
'Send-SQLDataToExcel',
'Set-CellStyle',
'Set-ExcelColumn',
'Set-ExcelRange',
'Set-ExcelRow',
'Test-Boolean',
'Test-Date',
'Test-Integer',
'Test-Number',
'Test-String',
'Update-FirstObjectProperties'
)
# Cmdlets to export from this module
CmdletsToExport = '*'
# Cmdlets to export from this module
#CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# Variables to export from this module
#VariablesToExport = '*'
# Aliases to export from this module
AliasesToExport = '*'
# Aliases to export from this module
AliasesToExport = @(
'New-ExcelChart',
'Set-Column',
'Set-Format',
'Set-Row',
'Use-ExcelData'
)
# List of all modules packaged with this module
# ModuleList = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess
PrivateData = @{
# PSData is module packaging and gallery metadata embedded in PrivateData
# It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
# We had to do this because it's the only place we're allowed to extend the manifest
# https://connect.microsoft.com/PowerShell/feedback/details/421837
PSData = @{
# The primary categorization of this module (from the TechNet Gallery tech tree).
Category = "Scripting Excel"
# Private data to pass to the module specified in RootModule/ModuleToProcess
PrivateData = @{
# PSData is module packaging and gallery metadata embedded in PrivateData
# It's for rebuilding PowerShellGet (and PoshCode) NuGet-style packages
# We had to do this because it's the only place we're allowed to extend the manifest
# https://connect.microsoft.com/PowerShell/feedback/details/421837
PSData = @{
# The primary categorization of this module (from the TechNet Gallery tech tree).
Category = "Scripting Excel"
# Keyword tags to help users find this module via navigations and search.
Tags = @("Excel","EPPlus","Export","Import")
# Keyword tags to help users find this module via navigations and search.
Tags = @("Excel", "EPPlus", "Export", "Import")
# The web address of an icon which can be used in galleries to represent this module
#IconUri = "http://pesterbdd.com/images/Pester.png"
# The web address of an icon which can be used in galleries to represent this module
#IconUri = "http://pesterbdd.com/images/Pester.png"
# The web address of this module's project or support homepage.
ProjectUri = "https://github.com/dfinke/ImportExcel"
# The web address of this module's project or support homepage.
ProjectUri = "https://github.com/dfinke/ImportExcel"
# The web address of this module's license. Points to a page that's embeddable and linkable.
LicenseUri = "https://github.com/dfinke/ImportExcel/blob/master/LICENSE.txt"
# The web address of this module's license. Points to a page that's embeddable and linkable.
LicenseUri = "https://github.com/dfinke/ImportExcel/blob/master/LICENSE.txt"
# Release notes for this particular version of the module
#ReleaseNotes = $True
# Release notes for this particular version of the module
#ReleaseNotes = $True
# If true, the LicenseUrl points to an end-user license (not just a source license) which requires the user agreement before use.
# RequireLicenseAcceptance = ""
# If true, the LicenseUrl points to an end-user license (not just a source license) which requires the user agreement before use.
# RequireLicenseAcceptance = ""
# Indicates this is a pre-release/testing version of the module.
IsPrerelease = 'False'
# Indicates this is a pre-release/testing version of the module.
IsPrerelease = 'False'
}
}
}
# HelpInfo URI of this module
# HelpInfoURI = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

View File

@@ -1,74 +1,84 @@
#region import everything we need
Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
. $PSScriptRoot\AddConditionalFormatting.ps1
. $PSScriptRoot\Charting.ps1
. $PSScriptRoot\ColorCompletion.ps1
. $PSScriptRoot\ConvertExcelToImageFile.ps1
. $PSScriptRoot\Compare-WorkSheet.ps1
. $PSScriptRoot\ConvertFromExcelData.ps1
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
. $PSScriptRoot\ConvertToExcelXlsx.ps1
. $PSScriptRoot\Copy-ExcelWorkSheet.ps1
. $PSScriptRoot\Export-Excel.ps1
. $PSScriptRoot\Export-ExcelSheet.ps1
. $PSScriptRoot\Get-ExcelColumnName.ps1
. $PSScriptRoot\Get-ExcelSheetInfo.ps1
. $PSScriptRoot\Get-ExcelWorkbookInfo.ps1
. $PSScriptRoot\Get-HtmlTable.ps1
. $PSScriptRoot\Get-Range.ps1
. $PSScriptRoot\Get-XYRange.ps1
. $PSScriptRoot\Import-Html.ps1
. $PSScriptRoot\InferData.ps1
. $PSScriptRoot\Invoke-Sum.ps1
. $PSScriptRoot\Join-WorkSheet.ps1
. $PSScriptRoot\Merge-Worksheet.ps1
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
. $PSScriptRoot\New-ConditionalText.ps1
. $PSScriptRoot\New-ExcelChart.ps1
. $PSScriptRoot\New-PSItem.ps1
. $PSScriptRoot\Open-ExcelPackage.ps1
. $PSScriptRoot\Pivot.ps1
. $PSScriptRoot\Send-SQLDataToExcel.ps1
. $PSScriptRoot\Set-CellStyle.ps1
. $PSScriptRoot\Set-Column.ps1
. $PSScriptRoot\Set-Row.ps1
. $PSScriptRoot\SetFormat.ps1
. $PSScriptRoot\TrackingUtils.ps1
. $PSScriptRoot\Update-FirstObjectProperties.ps1
Add-Type -Path "$($PSScriptRoot)\EPPlus.dll"
. $PSScriptRoot\AddConditionalFormatting.ps1
. $PSScriptRoot\AddDataValidation.ps1
. $PSScriptRoot\Charting.ps1
. $PSScriptRoot\ColorCompletion.ps1
. $PSScriptRoot\ConvertExcelToImageFile.ps1
. $PSScriptRoot\compare-workSheet.ps1
. $PSScriptRoot\ConvertFromExcelData.ps1
. $PSScriptRoot\ConvertFromExcelToSQLInsert.ps1
. $PSScriptRoot\ConvertToExcelXlsx.ps1
. $PSScriptRoot\Copy-ExcelWorkSheet.ps1
. $PSScriptRoot\Export-Excel.ps1
. $PSScriptRoot\Export-ExcelSheet.ps1
. $PSScriptRoot\Export-StocksToExcel.ps1
. $PSScriptRoot\Get-ExcelColumnName.ps1
. $PSScriptRoot\Get-ExcelSheetInfo.ps1
. $PSScriptRoot\Get-ExcelWorkbookInfo.ps1
. $PSScriptRoot\Get-HtmlTable.ps1
. $PSScriptRoot\Get-Range.ps1
. $PSScriptRoot\Get-XYRange.ps1
. $PSScriptRoot\Import-Html.ps1
. $PSScriptRoot\InferData.ps1
. $PSScriptRoot\Invoke-Sum.ps1
. $PSScriptRoot\Join-Worksheet.ps1
. $PSScriptRoot\Merge-worksheet.ps1
. $PSScriptRoot\New-ConditionalFormattingIconSet.ps1
. $PSScriptRoot\New-ConditionalText.ps1
. $PSScriptRoot\New-ExcelChart.ps1
. $PSScriptRoot\New-PSItem.ps1
. $PSScriptRoot\Open-ExcelPackage.ps1
. $PSScriptRoot\Pivot.ps1
. $PSScriptRoot\PivotTable.ps1
. $PSScriptRoot\RemoveWorksheet.ps1
. $PSScriptRoot\Send-SqlDataToExcel.ps1
. $PSScriptRoot\Set-CellStyle.ps1
. $PSScriptRoot\Set-Column.ps1
. $PSScriptRoot\Set-Row.ps1
. $PSScriptRoot\Set-WorkSheetProtection.ps1
. $PSScriptRoot\SetFormat.ps1
. $PSScriptRoot\TrackingUtils.ps1
. $PSScriptRoot\Update-FirstObjectProperties.ps1
New-Alias -Name Use-ExcelData -Value "ConvertFrom-ExcelData" -Force
New-Alias -Name Use-ExcelData -Value "ConvertFrom-ExcelData" -Force
if ($PSVersionTable.PSVersion.Major -ge 5) {
. $PSScriptRoot\Plot.ps1
if ($PSVersionTable.PSVersion.Major -ge 5) {
. $PSScriptRoot\plot.ps1
Function New-Plot {
Param()
[PSPlot]::new()
}
Function New-Plot {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification='New-Plot does not change system state')]
Param()
[PSPlot]::new()
}
else {
Write-Warning 'PowerShell 5 is required for plot.ps1'
Write-Warning 'PowerShell Excel is ready, except for that functionality'
}
}
else {
Write-Warning 'PowerShell 5 is required for plot.ps1'
Write-Warning 'PowerShell Excel is ready, except for that functionality'
}
#endregion
function Import-Excel {
<#
<#
.SYNOPSIS
Create custom objects from the rows in an Excel worksheet.
.DESCRIPTION
The Import-Excel cmdlet creates custom objects from the rows in an Excel worksheet. Each row represents one object. All of this is possible without installing Microsoft Excel and by using the .NET library EPPLus.dll.
By default, the property names of the objects are retrieved from the column headers. Because an object cannot have a blanc property name, only columns with column headers will be imported.
By default, the property names of the objects are retrieved from the column headers. Because an object cannot have a blank property name, only columns with column headers will be imported.
If the default behavior is not desired and you want to import the complete worksheet as is, the parameter -NoHeader can be used. In case you want to provide your own property names, you can use the parameter -HeaderName.
.PARAMETER Path
Specifies the path to the Excel file.
.PARAMETER ExcelPackage
Instead of specifying a path provides an Excel Package object (from Open-ExcelPackage)
Using this avoids re-reading the whole file when importing multiple parts of it.
To allow multiple read operations Import-Excel does NOT close the package, and you should use
Close-ExcelPackage -noSave to close it.
.PARAMETER WorksheetName
Specifies the name of the worksheet in the Excel workbook to import. By default, if no name is provided, the first worksheet will be imported.
@@ -77,19 +87,15 @@ function Import-Excel {
.PARAMETER HeaderName
Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
In case you provide less header names than there is data in the worksheet, then only the data with a corresponding header name will be imported and the data without header name will be disregarded.
In case you provide more header names than there is data in the worksheet, then all data will be imported and all objects will have all the property names you defined in the header names. As such, the last properties will be blanc as there is no data for them.
If you provide fewer header names than there are columns of data in the worksheet, then data will only be imported from that number of columns - the others will be ignored.
If you provide more header names than there are columns of data in the worksheet, it will result in blank properties being added to the objects returned.
.PARAMETER NoHeader
Automatically generate property names (P1, P2, P3, ..) instead of the ones defined in the column headers of the TopRow.
This switch is best used when you want to import the complete worksheet as is and are not concerned with the property names.
.PARAMETER StartRow
The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
When the parameters -NoHeader and -HeaderName are not provided, this row will contain the column headers that will be used as property names. When one of both parameters are provided, the property names are automatically created and this row will be treated as a regular row containing data.
.PARAMETER EndRow
@@ -220,7 +226,7 @@ function Import-Excel {
Notice that empty rows and empty columns are not imported.
.EXAMPLE
.EXAMPLE
Import data from an Excel worksheet. One object is created for each row. The property names are provided with the -HeaderName parameter. The import will start from row 2 and empty columns and rows are not imported.
----------------------------------------------------------
@@ -240,31 +246,49 @@ function Import-Excel {
Notice that only 1 object is imported with only 3 properties. Column B and row 2 are empty and have been disregarded by using the switch '-DataOnly'. The property names have been named with the values provided with the parameter '-HeaderName'. Row number 1 with Chuck Norris has not been imported, because we started the import from row 2 with the parameter -StartRow 2.
.EXAMPLE
>
PS> ,(Import-Excel -Path .\SysTables_AdventureWorks2014.xlsx) |
Write-SqlTableData -ServerInstance localhost\DEFAULT -Database BlankDB -SchemaName dbo -TableName MyNewTable_fromExcel -Force
Imports data from an Excel file and pipe the data to the Write-SqlTableData to be INSERTed into a table in a SQL Server database.
The ",( ... )" around the Import-Excel command allows all rows to be imported from the Excel file, prior to pipelining to the Write-SqlTableData cmdlet. This helps prevent a RBAR scenario and is important when trying to import thousands of rows.
The -Force parameter will be ignored if the table already exists. However, if a table is not found that matches the values provided by -SchemaName and -TableName parameters, it will create a new table in SQL Server database. The Write-SqlTableData cmdlet will inherit the column names & datatypes for the new table from the object being piped in.
NOTE: You need to install the SqlServer module from the PowerShell Gallery in oder to get the Write-SqlTableData cmdlet.
.LINK
https://github.com/dfinke/ImportExcel
.NOTES
#>
[CmdLetBinding(DefaultParameterSetName)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
[CmdLetBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
Param (
[Alias('FullName')]
[Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline, Position=0, Mandatory)]
[Parameter(ParameterSetName = "PathA", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[Parameter(ParameterSetName = "PathB", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[Parameter(ParameterSetName = "PathC", Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline, Position = 0 )]
[ValidateScript( {(Test-Path -Path $_ -PathType Leaf) -and ($_ -match '.xls$|.xlsx$|.xlsm$')})]
[String]$Path,
[Parameter(ParameterSetName = "PackageA", Mandatory)]
[Parameter(ParameterSetName = "PackageB", Mandatory)]
[Parameter(ParameterSetName = "PackageC", Mandatory)]
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
[Alias('Sheet')]
[Parameter(Position=1)]
[Parameter(Position = 1)]
[ValidateNotNullOrEmpty()]
[String]$WorksheetName,
[Parameter(ParameterSetName='B', Mandatory)]
[Parameter(ParameterSetName = 'PathB' , Mandatory)]
[Parameter(ParameterSetName = 'PackageB', Mandatory)]
[String[]]$HeaderName ,
[Parameter(ParameterSetName='C', Mandatory)]
[Parameter(ParameterSetName = 'PathC' , Mandatory)]
[Parameter(ParameterSetName = 'PackageC', Mandatory)]
[Switch]$NoHeader ,
[Alias('HeaderRow','TopRow')]
[Alias('HeaderRow', 'TopRow')]
[ValidateRange(1, 9999)]
[Int]$StartRow = 1,
[Alias('StopRow','BottomRow')]
[Alias('StopRow', 'BottomRow')]
[Int]$EndRow ,
[Alias('LeftColumn')]
[Int]$StartColumn = 1,
@@ -274,14 +298,14 @@ function Import-Excel {
[ValidateNotNullOrEmpty()]
[String]$Password
)
Begin {
begin {
$sw = [System.Diagnostics.Stopwatch]::StartNew()
Function Get-PropertyNames {
<#
.SYNOPSIS
Create objects containing the column number and the column name for each of the different header types.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification="Name would be incorrect, and command is not exported")]
Param (
[Parameter(Mandatory)]
[Int[]]$Columns,
@@ -294,75 +318,52 @@ function Import-Excel {
$i = 0
foreach ($C in $Columns) {
$i++
$C | Select-Object @{N='Column'; E={$_}}, @{N='Value'; E={'P' + $i}}
$C | Select-Object @{N = 'Column'; E = {$_}}, @{N = 'Value'; E = {'P' + $i}}
}
}
elseif ($HeaderName) {
$i = 0
foreach ($H in $HeaderName) {
$H | Select-Object @{N='Column'; E={$Columns[$i]}}, @{N='Value'; E={$H}}
$H | Select-Object @{N = 'Column'; E = {$Columns[$i]}}, @{N = 'Value'; E = {$H}}
$i++
}
}
else {
if ($StartRow -eq 0) {
throw 'The top row can never be equal to 0 when we need to retrieve headers from the worksheet.'
if ($StartRow -lt 1) {
throw 'The top row can never be less than 1 when we need to retrieve headers from the worksheet.' ; return
}
foreach ($C in $Columns) {
$Worksheet.Cells[$StartRow,$C] | Where-Object {$_.Value} | Select-Object @{N='Column'; E={$C}}, Value
$Worksheet.Cells[$StartRow, $C] | Where-Object {$_.Value} | Select-Object @{N = 'Column'; E = {$C}}, Value
}
}
}
Catch {
throw "Failed creating property names: $_"
throw "Failed creating property names: $_" ; return
}
}
}
Process {
Try {
#region Open file
$Path = (Resolve-Path $Path).ProviderPath
Write-Verbose "Import Excel workbook '$Path' with worksheet '$Worksheetname'"
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, 'Open', 'Read', 'ReadWrite'
if ($Password) {
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage
Try {
$Excel.Load($Stream,$Password)
}
Catch {
throw "Password '$Password' is not correct."
}
process {
if ($Path -and $Password) {$ExcelPackage = Open-ExcelPackage -Path $Path -Password $Password}
elseif ($Path) {$ExcelPackage = Open-ExcelPackage -Path $Path}
try {
#Select worksheet
if (-not $WorksheetName) { $Worksheet = $ExcelPackage.Workbook.Worksheets[1] }
elseif(-not ($Worksheet = $ExcelPackage.Workbook.Worksheets[$WorkSheetName])) {
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($ExcelPackage.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter." ; return
}
else {
$Excel = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
}
#endregion
#region Select worksheet
if ($WorksheetName) {
if (-not ($Worksheet = $Excel.Workbook.Worksheets[$WorkSheetName])) {
throw "Worksheet '$WorksheetName' not found, the workbook only contains the worksheets '$($Excel.Workbook.Worksheets)'. If you only wish to select the first worksheet, please remove the '-WorksheetName' parameter."
}
}
else {
$Worksheet = $Excel.Workbook.Worksheets | Select-Object -First 1
}
#endregion
Write-Debug $sw.Elapsed.TotalMilliseconds
#region Get rows and columns
#If we are doing dataonly it is quicker to work out which rows to ignore before processing the cells.
if (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row }
if (-not $EndRow ) {$EndRow = $Worksheet.Dimension.End.Row }
if (-not $EndColumn) {$EndColumn = $Worksheet.Dimension.End.Column }
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]",0,0)
$endAddress = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$EndRow]C[$EndColumn]", 0, 0)
if ($DataOnly) {
#If we are using headers startrow will be the headerrow so examine data from startRow + 1,
#If we are using headers startrow will be the header-row so examine data from startRow + 1,
if ($NoHeader) {$range = "A" + ($StartRow ) + ":" + $endAddress }
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
else {$range = "A" + ($StartRow + 1 ) + ":" + $endAddress }
#We're going to look at every cell and build 2 hash tables holding rows & columns which contain data.
#Want to Avoid 'select unique' operations & large Sorts, becuse time time taken increases with square
#of number of items (PS uses heapsort at large size). Instead keep a list of what we have seen,
@@ -370,23 +371,23 @@ function Import-Excel {
$colHash = @{}
$rowHash = @{}
foreach ($cell in $Worksheet.Cells[$range]) {
if ($null -ne $cell.Value ) {$colHash[$cell.Start.Column]=1; $rowHash[$cell.Start.row]=1 }
if ($null -ne $cell.Value ) {$colHash[$cell.Start.Column] = 1; $rowHash[$cell.Start.row] = 1 }
}
$rows = ( $StartRow..$EndRow ).Where({$rowHash[$_]})
$columns = ($StartColumn..$EndColumn).Where({$colHash[$_]})
$rows = ( $StartRow..$EndRow ).Where( {$rowHash[$_]})
$columns = ($StartColumn..$EndColumn).Where( {$colHash[$_]})
}
else {
$Columns = $StartColumn..$EndColumn ; if ($StartColumn -gt $EndColumn) {Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results."}
if ($NoHeader) {$Rows = ( $StartRow)..$EndRow ; if ($StartRow -gt $EndRow) {Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results."} }
else {$Rows = (1 + $StartRow)..$EndRow ; if ($StartRow -ge $EndRow) {Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results."}}
$Columns = $StartColumn .. $EndColumn ; if ($StartColumn -gt $EndColumn) {Write-Warning -Message "Selecting columns $StartColumn to $EndColumn might give odd results."}
if ($NoHeader) {$Rows = $StartRow..$EndRow ; if ($StartRow -gt $EndRow) {Write-Warning -Message "Selecting rows $StartRow to $EndRow might give odd results."} }
else {$Rows = (1 + $StartRow)..$EndRow ; if ($StartRow -ge $EndRow) {Write-Warning -Message "Selecting $StartRow as the header with data in $(1+$StartRow) to $EndRow might give odd results."}}
}
#endregion
#region Create property names
if ((-not $Columns) -or (-not ($PropertyNames = Get-PropertyNames -Columns $Columns -StartRow $StartRow))) {
throw "No column headers found on top row '$StartRow'. If column headers in the worksheet are not a requirement then please use the '-NoHeader' or '-HeaderName' parameter."
throw "No column headers found on top row '$StartRow'. If column headers in the worksheet are not a requirement then please use the '-NoHeader' or '-HeaderName' parameter."; return
}
if ($Duplicates = $PropertyNames | Group-Object Value | Where-Object Count -GE 2) {
throw "Duplicate column headers found on row '$StartRow' in columns '$($Duplicates.Group.Column)'. Column headers must be unique, if this is not a requirement please use the '-NoHeader' or '-HeaderName' parameter."
throw "Duplicate column headers found on row '$StartRow' in columns '$($Duplicates.Group.Column)'. Column headers must be unique, if this is not a requirement please use the '-NoHeader' or '-HeaderName' parameter."; return
}
#endregion
Write-Debug $sw.Elapsed.TotalMilliseconds
@@ -396,12 +397,13 @@ function Import-Excel {
else {
#region Create one object per row
foreach ($R in $Rows) {
Write-Verbose "Import row '$R'"
#Disabled write-verbose for speed
# Write-Verbose "Import row '$R'"
$NewRow = [Ordered]@{}
foreach ($P in $PropertyNames) {
$NewRow[$P.Value] = $Worksheet.Cells[$R, $P.Column].Value
Write-Verbose "Import cell '$($Worksheet.Cells[$R, $P.Column].Address)' with property name '$($p.Value)' and value '$($Worksheet.Cells[$R, $P.Column].Value)'."
$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
@@ -410,14 +412,9 @@ function Import-Excel {
}
Write-Debug $sw.Elapsed.TotalMilliseconds
}
Catch {
throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"
}
Finally {
$Stream.Close()
$Stream.Dispose()
$Excel.Dispose()
$Excel = $null
catch { throw "Failed importing the Excel workbook '$Path' with worksheet '$Worksheetname': $_"; return }
finally {
if ($Path) {Close-ExcelPackage -ExcelPackage $ExcelPackage -NoSave }
}
}
}
@@ -446,11 +443,11 @@ function ConvertFrom-ExcelSheet {
[String]
$OutputPath = '.\',
[String]
$SheetName="*",
[ValidateSet('ASCII', 'BigEndianUniCode','Default','OEM','UniCode','UTF32','UTF7','UTF8')]
$SheetName = "*",
[ValidateSet('ASCII', 'BigEndianUniCode', 'Default', 'OEM', 'UniCode', 'UTF32', 'UTF7', 'UTF8')]
[string]
$Encoding = 'UTF8',
[ValidateSet('.txt', '.log','.csv')]
[ValidateSet('.txt', '.log', '.csv')]
[string]
$Extension = '.csv',
[ValidateSet(';', ',')]
@@ -459,8 +456,8 @@ function ConvertFrom-ExcelSheet {
)
$Path = (Resolve-Path $Path).Path
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path,"Open","Read","ReadWrite"
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $stream
$Stream = New-Object -TypeName System.IO.FileStream -ArgumentList $Path, "Open", "Read", "ReadWrite"
$xl = New-Object -TypeName OfficeOpenXml.ExcelPackage -ArgumentList $Stream
$workbook = $xl.Workbook
$targetSheets = $workbook.Worksheets | Where-Object {$_.Name -like $SheetName}
@@ -471,8 +468,7 @@ function ConvertFrom-ExcelSheet {
$params.Remove('Extension')
$params.NoTypeInformation = $true
Foreach ($sheet in $targetSheets)
{
Foreach ($sheet in $targetSheets) {
Write-Verbose "Exporting sheet: $($sheet.Name)"
$params.Path = "$OutputPath\$($Sheet.Name)$Extension"
@@ -480,24 +476,24 @@ function ConvertFrom-ExcelSheet {
Import-Excel $Path -Sheet $($sheet.Name) | Export-Csv @params
}
$stream.Close()
$stream.Dispose()
$Stream.Close()
$Stream.Dispose()
$xl.Dispose()
}
function Export-MultipleExcelSheets {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
param(
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
$Path,
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
[hashtable]$InfoMap,
[string]$Password,
[Switch]$Show,
[Switch]$AutoSize
)
$parameters = @{}+$PSBoundParameters
$parameters = @{} + $PSBoundParameters
$parameters.Remove("InfoMap")
$parameters.Remove("Show")
@@ -505,24 +501,24 @@ function Export-MultipleExcelSheets {
foreach ($entry in $InfoMap.GetEnumerator()) {
Write-Progress -Activity "Exporting" -Status "$($entry.Key)"
$parameters.WorkSheetname=$entry.Key
$parameters.WorkSheetname = $entry.Key
& $entry.Value | Export-Excel @parameters
}
if($Show) {Invoke-Item $Path}
if ($Show) {Invoke-Item $Path}
}
Function WorksheetArgumentCompleter {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
$xlPath = $fakeBoundParameter['Path']
$xlPath = $fakeBoundParameter['Path']
if (Test-Path -Path $xlPath) {
$xlpkg = Open-ExcelPackage -Path $xlPath
$WorksheetNames = $xlPkg.Workbook.Worksheets.Name
Close-ExcelPackage -nosave -ExcelPackage $xlpkg
$WorksheetNames.where({$_ -like "*$wordToComplete*"}) | foreach-object {
$WorksheetNames.where( {$_ -like "*$wordToComplete*"}) | foreach-object {
New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList "'$_'",
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) ,$_
$_ , ([System.Management.Automation.CompletionResultType]::ParameterValue) , $_
}
}
}

View File

@@ -68,7 +68,7 @@ function Invoke-AllTests {
)
$resultCount=0
$tests.GetEnumerator() | ForEach {
$tests.GetEnumerator() | ForEach-Object {
$result=& $_.Value $target

View File

@@ -1,5 +1,5 @@
<#
.SYNOPSIS
<#
.SYNOPSIS
Download the module files from GitHub.
.DESCRIPTION
@@ -85,12 +85,12 @@ Process {
}
if (-not (Test-Path $InstallDirectory)) {
New-Item -Path $InstallDirectory -ItemType Directory -EA Stop | Out-Null
$null = New-Item -Path $InstallDirectory -ItemType Directory -EA Stop
Write-Verbose "$ModuleName created module folder '$InstallDirectory'"
}
$WebClient = New-Object System.Net.WebClient
$Files | ForEach-Object {
$WebClient.DownloadFile("$GitPath/$_","$installDirectory\$_")
Write-Verbose "$ModuleName installed module file '$_'"

View File

@@ -1,47 +1,3 @@
<#
.SYNOPSIS
Install the module in the PowerShell module folder.
$fullPath = 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel'
.DESCRIPTION
Install the module in the PowerShell module folder by copying all the files.
#>
[CmdLetBinding()]
Param (
[ValidateNotNullOrEmpty()]
[String]$ModuleName = 'ImportExcel',
[ValidateScript({Test-Path -Path $_ -Type Container})]
[String]$ModulePath = 'C:\Program Files\WindowsPowerShell\Modules'
)
Begin {
Try {
Write-Verbose "$ModuleName module installation started"
$Files = Get-Content $PSScriptRoot\filelist.txt
}
Catch {
throw "Failed installing the module '$ModuleName': $_"
}
}
Process {
Try {
$TargetPath = Join-Path -Path $ModulePath -ChildPath $ModuleName
if (-not (Test-Path $TargetPath)) {
New-Item -Path $TargetPath -ItemType Directory -EA Stop | Out-Null
Write-Verbose "$ModuleName created module folder '$TargetPath'"
}
Get-ChildItem $Files | ForEach-Object {
Copy-Item -Path $_.FullName -Destination "$($TargetPath)\$($_.Name)"
Write-Verbose "$ModuleName installed module file '$($_.Name)'"
}
Write-Verbose "$ModuleName module installation successful"
}
Catch {
throw "Failed installing the module '$ModuleName': $_"
}
}
Robocopy . $fullPath /mir /XD .vscode .git examples testimonials images spikes /XF appveyor.yml .gitattributes .gitignore

View File

@@ -18,7 +18,7 @@ function Invoke-Sum {
$h.$key=[ordered]@{}
}
foreach($m in $measure) {
foreach($m in $measure) {
$value = $item.$m
if($value -is [string] -or $value -is [System.Enum]) {
$value = 1
@@ -27,15 +27,15 @@ function Invoke-Sum {
$h.$key.$m+=$value
}
}
foreach ($entry in $h.GetEnumerator()){
$nh=[ordered]@{Name=$entry.key}
foreach ($item in $entry.value.getenumerator()) {
$nh.($item.key)=$item.value
}
}
[pscustomobject]$nh
}
}

View File

@@ -1,59 +1,72 @@
function Join-Worksheet {
[CmdletBinding(DefaultParameterSetName = 'Default')]
<#
.SYNOPSIS
Combines data on all the sheets in an Excel worksheet onto a single sheet.
.DESCRIPTION
Join worksheet can work in two main ways:
Either Combining data which has the same layout from many pages into one, or combining pages which have nothing in common.
In the former case the header row is copied from the first sheet and, by default, each row of data is labelled with the name of the sheet it came from.
In the latter case -NoHeader is specified, and each copied block can have the sheet it came from placed above it as a title.
Join-Worksheet can work in two main ways, either
Combining data which has the same layout from many pages into one, or
combining pages which have nothing in common.
In the former case the header row is copied from the first sheet and,
by default, each row of data is labelled with the name of the sheet it came from.
In the latter case -NoHeader is specified, and each copied block can have the
sheet it came from placed above it as a title.
.EXAMPLE
foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
Get-Service -ComputerName $computerName | Select-Object -Property Status, Name, DisplayName, StartType |
>
PS> foreach ($computerName in @('Server1', 'Server2', 'Server3', 'Server4')) {
Get-Service -ComputerName $computerName | Select-Object -Property Status, Name, DisplayName, StartType |
Export-Excel -Path .\test.xlsx -WorkSheetname $computerName -AutoSize
}
$ptDef =New-PivotTableDefinition -PivotTableName "Pivot1" -SourceWorkSheet "Combined" -PivotRows "Status" -PivotFilter "MachineName" -PivotData @{Status='Count'} -IncludePivotChart -ChartType BarClustered3D
Join-Worksheet -Path .\test.xlsx -WorkSheetName combined -FromLabel "MachineName" -HideSource -AutoSize -FreezeTopRow -BoldTopRow -PivotTableDefinition $pt -Show
}
PS> $ptDef =New-PivotTableDefinition -PivotTableName "Pivot1" -SourceWorkSheet "Combined" -PivotRows "Status" -PivotFilter "MachineName" -PivotData @{Status='Count'} -IncludePivotChart -ChartType BarClustered3D
PS> Join-Worksheet -Path .\test.xlsx -WorkSheetName combined -FromLabel "MachineName" -HideSource -AutoSize -FreezeTopRow -BoldTopRow -PivotTableDefinition $pt -Show
The foreach command gets the services running on four servers and exports each to its own page in Test.xlsx.
$PtDef= creates a defintion for a single Pivot table.
The Join-Worksheet command uses the same file and merges the results onto a sheet named "Combined". It sets a column header of "Machinename",
this column will contain the name of the sheet the data was copied from; after copying the data to the sheet "combined", the other sheets will be hidden.
Join-Worksheet finishes by calling export-Excel to AutoSize cells, freeze the top row and make it bold and add the Pivot table.
The foreach command gets the services running on four servers and exports each
to its own page in Test.xlsx.
$PtDef= creates a definition for a PivotTable.
The Join-Worksheet command uses the same file and merges the results into a sheet
named "Combined". It sets a column header of "Machinename", this column will
contain the name of the sheet the data was copied from; after copying the data
to the sheet "Combined", the other sheets will be hidden.
Join-Worksheet finishes by calling Export-Excel to AutoSize cells, freeze the
top row and make it bold and add thePivotTable.
.EXAMPLE
Get-WmiObject -Class win32_logicaldisk | select -Property DeviceId,VolumeName, Size,Freespace |
Export-Excel -Path "$env:computerName.xlsx" -WorkSheetname Volumes -NumberFormat "0,000"
Get-NetAdapter | Select-Object Name,InterfaceDescription,MacAddress,LinkSpeed |
Export-Excel -Path "$env:COMPUTERNAME.xlsx" -WorkSheetname NetAdapter
Join-Worksheet -Path "$env:COMPUTERNAME.xlsx" -WorkSheetName Summary -Title "Summary" -TitleBold -TitleSize 22 -NoHeader -LabelBlocks -AutoSize -HideSource -show
>
PS> Get-WmiObject -Class win32_logicaldisk | Select-Object -Property DeviceId,VolumeName, Size,Freespace |
Export-Excel -Path "$env:computerName.xlsx" -WorkSheetname Volumes -NumberFormat "0,000"
PS> Get-NetAdapter | Select-Object Name,InterfaceDescription,MacAddress,LinkSpeed |
Export-Excel -Path "$env:COMPUTERNAME.xlsx" -WorkSheetname NetAdapter
PS> Join-Worksheet -Path "$env:COMPUTERNAME.xlsx" -WorkSheetName Summary -Title "Summary" -TitleBold -TitleSize 22 -NoHeader -LabelBlocks -AutoSize -HideSource -show
The first two command get logical disk and network card information; each type is exported to its own sheet in a workbook.
The Join-worksheet command copies both onto a page named "Summary". Because the data is disimilar -NoHeader is specified, ensuring the whole of each page is copied.
Specifying -LabelBlocks causes each sheet's name to become a title on the summary page above the copied data.
The source data is hidden, a title is addded in 22 point boldface and the columns are sized to fit the data.
The first two commands get logical-disk and network-card information; each type
is exported to its own sheet in a workbook.
The Join-Worksheet command copies both onto a page named "Summary". Because
the data is dissimilar, -NoHeader is specified, ensuring the whole of each
page is copied. Specifying -LabelBlocks causes each sheet's name to become
a title on the summary page above the copied data. The source data is
hidden, a title is added in 22 point boldface and the columns are sized
to fit the data.
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
param (
# Path to a new or existing .XLSX file.
[Parameter(ParameterSetName = "Default", Position = 0)]
[Parameter(ParameterSetName = "Table" , Position = 0)]
[String]$Path ,
# An object representing an Excel Package - usually this is returned by specifying -Passthru allowing multiple commands to work on the same Workbook without saving and reloading each time.
# An object representing an Excel Package - either from Open-Excel Package or specifying -PassThru to Export-Excel.
[Parameter(Mandatory = $true, ParameterSetName = "PackageDefault")]
[Parameter(Mandatory = $true, ParameterSetName = "PackageTable")]
[OfficeOpenXml.ExcelPackage]$ExcelPackage,
# The name of a sheet within the workbook where the other sheets will be joined together - "Combined" by default.
$WorkSheetName = 'Combined',
# If specified any pre-existing target for the joined data will be deleted and re-created; otherwise data will be appended on this sheet.
# If specified ,any pre-existing target for the joined data will be deleted and re-created; otherwise data will be appended on this sheet.
[switch]$Clearsheet,
#Join-Worksheet assumes each sheet has identical headers and the headers should be copied to the target sheet, unless -NoHeader is specified.
[switch]$NoHeader,
#If -NoHeader is NOT specified, then rows of data will be labeled with the name of the sheet they came, FromLabel is the header for this column. If it is null or empty, the labels will be omitted.
$FromLabel = "From" ,
#If -NoHeader is NOT specified, then rows of data will be labeled with the name of the sheet they came from. FromLabel is the header for this column. If it is null or empty, the labels will be omitted.
[string]$FromLabel = "From" ,
#If specified, the copied blocks of data will have the name of the sheet they were copied from inserted above them as a title.
[switch]$LabelBlocks,
#Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
#Sets the width of the Excel columns to display all the data in their cells.
[Switch]$AutoSize,
#Freezes headers etc. in the top row.
[Switch]$FreezeTopRow,
@@ -63,30 +76,31 @@
[Switch]$FreezeTopRowFirstColumn,
# Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
[Int[]]$FreezePane,
#Enables the 'Filter' in Excel on the complete header row. So users can easily sort, filter and/or search the data in the select column from within Excel.
#Enables the Excel filter on the headers of the combined sheet.
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'PackageDefault')]
[Switch]$AutoFilter,
#Makes the top Row boldface.
#Makes the top row boldface.
[Switch]$BoldTopRow,
#If Specified hides the sheets that the data is copied from.
#If specified, hides the sheets that the data is copied from.
[switch]$HideSource,
#Text of a title to be placed in Cell A1.
[String]$Title,
#Sets the fill pattern for the title cell.
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'Solid',
#Sets the cell background color for the title cell.
[System.Drawing.Color]$TitleBackgroundColor,
$TitleBackgroundColor,
#Sets the title in boldface type.
[Switch]$TitleBold,
#Sets the point size for the title.
[Int]$TitleSize = 22,
#Hashtable(s) with Sheet PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values to specify a definition for one or more pivot table(s).
#Hashtable(s) with Sheet PivotRows, PivotColumns, PivotData, IncludePivotChart and ChartType values to specify a definition for one or morePivotTable(s).
[Hashtable]$PivotTableDefinition,
#A hashtable containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
[Object[]]$ExcelChartDefinition,
#One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
[Object[]]$ConditionalFormat,
#Applies a 'Conditional formatting rule' in Excel on all the cells. When specific conditions are met a rule is triggered.
#Applies a Conditional formatting rule defined with New-ConditionalText. When specific conditions are met the format is applied
[Object[]]$ConditionalText,
#Makes each column a named range.
[switch]$AutoNameRange,
@@ -104,12 +118,13 @@
})]
[Parameter(ParameterSetName = 'Table' , Mandatory = $true)]
[Parameter(ParameterSetName = 'PackageTable' , Mandatory = $true)]
# Makes the data in the worksheet a table with a name applies a style to it. Name must not contain spaces.
# Makes the data in the worksheet a table with a name and applies a style to it. Name must not contain spaces.
[String]$TableName,
[Parameter(ParameterSetName = 'Table')]
[Parameter(ParameterSetName = 'PackageTable')]
#Selects the style for the named table - defaults to "Medium6".
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
#Selects the style for the named table - defaults to 'Medium6'.
#If specified, returns the range of cells in the combined sheet, in the format "A1:Z100".
[switch]$ReturnRange,
#Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
[switch]$Show,
@@ -134,6 +149,7 @@
if ($TitleBold) {$destinationSheet.Cells[1, 1].Style.Font.Bold = $True }
#Can only set TitleBackgroundColor if TitleFillPattern is something other than None.
if ($TitleBackgroundColor -AND ($TitleFillPattern -ne 'None')) {
if ($TitleBackgroundColor -is [string]) {$TitleBackgroundColor = [System.Drawing.Color]::$TitleBackgroundColor }
$destinationSheet.Cells[1, 1].Style.Fill.PatternType = $TitleFillPattern
$destinationSheet.Cells[1, 1].Style.Fill.BackgroundColor.SetColor($TitleBackgroundColor)
}
@@ -145,6 +161,7 @@
#Assume every row has titles in row 1, copy row 1 from first sheet to new sheet.
$destinationSheet.Select("A$row")
$ExcelPackage.Workbook.Worksheets[1].cells["1:1"].Copy($destinationSheet.SelectedRange)
#fromlabel can't be an empty string
if ($FromLabel ) {
#Add a column which says where the data comes from.
$fromColumn = ($destinationSheet.Dimension.Columns + 1)
@@ -181,7 +198,7 @@
#We accept a bunch of parameters work to pass on to Export-excel ( Autosize, Autofilter, boldtopRow Freeze ); if we have any of those call export-excel otherwise close the package here.
$params = @{} + $PSBoundParameters
'Path', 'Clearsheet', 'NoHeader', 'FromLabel', 'LabelBlocks', 'HideSource',
'Title', 'TitleFillPattern', 'TitleBackgroundColor', 'TitleBold', 'TitleSize' | ForEach-Object {[void]$params.Remove($_)}
'Title', 'TitleFillPattern', 'TitleBackgroundColor', 'TitleBold', 'TitleSize' | ForEach-Object {$null = $params.Remove($_)}
if ($params.Keys.Count) {
if ($Title) { $params.StartRow = 2}
$params.WorkSheetName = $WorkSheetName

View File

@@ -1,3 +1,3 @@
if((Get-Module -list ImportExcel) -eq $null) {
if($null -eq (Get-Module -ListAvailable ImportExcel) ) {
Import-Module $PSScriptRoot\ImportExcel.psd1 -force
}

View File

@@ -1,83 +1,103 @@
Function Merge-Worksheet {
<#
.Synopsis
Merges two worksheets (or other objects) into a single worksheet with differences marked up.
Merges two Worksheets (or other objects) into a single Worksheet with differences marked up.
.Description
The Compare-Worksheet command takes two worksheets and marks differences in the source document, and optionally outputs a grid showing the changes.
By contrast the Merge-Worksheet command takes the worksheets and combines them into a single sheet showing the old and new data side by side .
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* worksheets, or a merge *to* worksheet.
The Compare-Worksheet command takes two Worksheets and marks differences in the source document, and optionally outputs a grid showing the changes.
By contrast the Merge-Worksheet command takes the Worksheets and combines them into a single sheet showing the old and new data side by side.
Although it is designed to work with Excel data it can work with arrays of any kind of object; so it can be a merge *of* Worksheets, or a merge *to* a Worksheet.
.Example
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -show
The workbooks contain audit information for two servers, one page contains a list of services. This command creates a worksheet named 54-55
in a workbook named services which shows all the services and their differences, and opens it in Excel.
Merge-Worksheet "Server54.xlsx" "Server55.xlsx" -WorksheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -show
The workbooks contain audit information for two servers, one sheet contains
a list of services. This command creates a worksheet named "54-55" in a
workbook named "services.xlsx" which shows all the services and their
differences, and opens the new workbook in Excel.
.Example
merge-worksheet "Server54.xlsx" "Server55.xlsx" -WorkSheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
This modifies the previous command to hide the equal rows in the output sheet and changes the color used to mark rows added to the second file.
Merge-Worksheet "Server54.xlsx" "Server55.xlsx" -WorksheetName services -OutputFile Services.xlsx -OutputSheetName 54-55 -HideEqual -AddBackgroundColor LightBlue -show
This modifies the previous command to hide the equal rows in the output
sheet and changes the color used to mark rows added to the second file.
.Example
merge-worksheet -OutputFile .\j1.xlsx -OutputSheetName test11 -ReferenceObject (dir .\ImportExcel\4.0.7) -DifferenceObject (dir .\ImportExcel\4.0.8) -Property Length -Show
Merge-Worksheet -OutputFile .\j1.xlsx -OutputSheetName test11 -ReferenceObject (dir .\ImportExcel\4.0.7) -DifferenceObject (dir .\ImportExcel\4.0.8) -Property Length -Show
This version compares two directories, and marks what has changed.
Because no "Key" property is given, "Name" is assumed to be the key and the only other property examined is length.
Files which are added or deleted or have changed size will be highlighed in the output sheet. Changes to dates or other attributes will be ignored.
Because no "Key" property is given, "Name" is assumed to be the key
and the only other property examined is length. Files which are added
or deleted or have changed size will be highlighed in the output sheet.
Changes to dates or other attributes will be ignored.
.Example
merge-worksheet -RefO (dir .\ImportExcel\4.0.7) -DiffO (dir .\ImportExcel\4.0.8) -Pr Length | Out-GridView
This time no file is written and the results -which include all properties, not just length, are output and sent to Out-Gridview.
This version uses aliases to shorten the parameters,
(OutputFileName can be "outFile" and the sheet "OutSheet" : DifferenceObject & ReferenceObject can be DiffObject & RefObject).
Merge-Worksheet -RefO (dir .\ImportExcel\4.0.7) -DiffO (dir .\ImportExcel\4.0.8) -Pr Length | Out-GridView
This time no file is written and the results - which include all properties,
not just length, are output and sent to Out-Gridview. This version uses
aliases to shorten the parameters, (OutputFileName can be "outFile" and
the Sheet can be"OutSheet"; DifferenceObject & ReferenceObject can be
DiffObject & RefObject respectively).
#>
[cmdletbinding(SupportsShouldProcess=$true)]
Param(
#First Excel file to compare. You can compare two Excel files or two other objects but not one of each.
[parameter(ParameterSetName='A',Mandatory=$true,Position=0)]
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)]
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)]
#First Excel file to compare. You can compare two Excel files or two other objects or a reference obhct against a difference file, but not a reference file against an object.
[parameter(ParameterSetName='A',Mandatory=$true,Position=0)] #A = Compare two files default headers
[parameter(ParameterSetName='B',Mandatory=$true,Position=0)] #B = Compare two files user supplied headers
[parameter(ParameterSetName='C',Mandatory=$true,Position=0)] #C = Compare two files headers P1, P2, P3 etc
$Referencefile ,
#Second Excel file to compare.
[parameter(ParameterSetName='A',Mandatory=$true,Position=1)]
[parameter(ParameterSetName='B',Mandatory=$true,Position=1)]
[parameter(ParameterSetName='C',Mandatory=$true,Position=1)]
[parameter(ParameterSetName='E',Mandatory=$true,Position=1)]
[parameter(ParameterSetName='E',Mandatory=$true,Position=1)] #D Compare two objects; E = Compare one object one file that uses default headers
[parameter(ParameterSetName='F',Mandatory=$true,Position=1)] #F = Compare one object one file that uses user supplied headers
[parameter(ParameterSetName='G',Mandatory=$true,Position=1)] #G Compare one object one file that uses headers P1, P2, P3 etc
$Differencefile ,
#Name(s) of worksheets to compare,
[parameter(ParameterSetName='A',Position=2)]
#Name(s) of Worksheets to compare.
[parameter(ParameterSetName='A',Position=2)] #Applies to all sets EXCEPT D which is two objects (no sheets)
[parameter(ParameterSetName='B',Position=2)]
[parameter(ParameterSetName='C',Position=2)]
[parameter(ParameterSetName='E',Position=2)]
$WorkSheetName = "Sheet1",
[parameter(ParameterSetName='F',Position=2)]
[parameter(ParameterSetName='G',Position=2)]
$WorksheetName = "Sheet1",
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
[parameter(ParameterSetName='A')]
[parameter(ParameterSetName='A')] #Applies to all sets EXCEPT D which is two objects (no sheets, so no start row )
[parameter(ParameterSetName='B')]
[parameter(ParameterSetName='C')]
[parameter(ParameterSetName='E')]
[parameter(ParameterSetName='F')]
[parameter(ParameterSetName='G')]
[int]$Startrow = 1,
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
[Parameter(ParameterSetName='B',Mandatory=$true)]
#Specifies custom property names to use, instead of the values defined in the column headers of the Start ROw.
[Parameter(ParameterSetName='B',Mandatory=$true)] #Compare object + sheet or 2 sheets with user supplied headers
[Parameter(ParameterSetName='F',Mandatory=$true)]
[String[]]$Headername,
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
[Parameter(ParameterSetName='C',Mandatory=$true)]
#Automatically generate property names (P1, P2, P3, ..) instead of using the values the top row of the sheet.
[Parameter(ParameterSetName='C',Mandatory=$true)] #Compare object + sheet or 2 sheets with headers of P1, P2, P3 ...
[Parameter(ParameterSetName='G',Mandatory=$true)]
[switch]$NoHeader,
#Object to compare if a worksheet is NOT being used.
#Reference object to compare if a Worksheet is NOT being used. Reference object can combine with a difference sheet or difference object
[parameter(ParameterSetName='D',Mandatory=$true)]
[parameter(ParameterSetName='E',Mandatory=$true)]
[parameter(ParameterSetName='F',Mandatory=$true)]
[parameter(ParameterSetName='G',Mandatory=$true)]
[Alias('RefObject')]
$ReferenceObject ,
#Object to compare if a worksheet is NOT being used.
#Difference object to compare if a Worksheet is NOT being used for either half. Can't have a reference sheet and difference object.
[parameter(ParameterSetName='D',Mandatory=$true,Position=1)]
[Alias('DiffObject')]
$DifferenceObject ,
[parameter(ParameterSetName='D',Position=2)]
[parameter(ParameterSetName='E',Position=3)]
[parameter(ParameterSetName='E',Position=2)]
[parameter(ParameterSetName='F',Position=2)]
[parameter(ParameterSetName='G',Position=2)]
#If there isn't a filename to use to label data from the "Difference" side, DiffPrefix is used, it defaults to "=>"
$DiffPrefix = "=>" ,
#File to hold merged data.
[parameter(Position=3)]
[Alias('OutFile')]
$OutputFile ,
#Name of worksheet to output - if none specified will use the reference worksheet name.
#Name of Worksheet to output - if none specified will use the reference Worksheet name.
[parameter(Position=4)]
[Alias('OutSheet')]
$OutputSheetName = "Sheet1",
@@ -88,51 +108,54 @@
#Name of a column which is unique used to pair up rows from the refence and difference side, default is "Name".
$Key = "Name" ,
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
[System.Drawing.Color]$KeyFontColor = "DarkRed",
$KeyFontColor = [System.Drawing.Color]::DarkRed ,
#Sets the background color for changed rows.
[System.Drawing.Color]$ChangeBackgroundColor = "Orange",
$ChangeBackgroundColor = [System.Drawing.Color]::Orange,
#Sets the background color for rows in the reference but deleted from the difference sheet.
[System.Drawing.Color]$DeleteBackgroundColor = "LightPink",
$DeleteBackgroundColor = [System.Drawing.Color]::LightPink,
#Sets the background color for rows not in the reference but added to the difference sheet.
[System.Drawing.Color]$AddBackgroundColor = "PaleGreen",
#if Specified hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
$AddBackgroundColor = [System.Drawing.Color]::PaleGreen,
#if specified, hides the rows in the spreadsheet that are equal and only shows changes, added or deleted rows.
[switch]$HideEqual ,
#If specified outputs the data to the pipeline (you can add -whatif so it the command only outputs to the pipeline).
#If specified, outputs the data to the pipeline (you can add -WhatIf so the command only outputs to the pipeline).
[switch]$Passthru ,
#If specified, opens the output workbook.
[Switch]$Show
)
#region Read Excel data
if ($Referencefile -and $Differencefile) {
if ($Differencefile -is [System.IO.FileInfo]) {$Differencefile = $Differencefile.FullName}
if ($Referencefile -is [System.IO.FileInfo]) {$Referencefile = $Referencefile.FullName}
if ($Referencefile -and $Differencefile) {
#if the filenames don't resolve, give up now.
try { $oneFile = ((Resolve-Path -Path $Referencefile -ErrorAction Stop).path -eq (Resolve-Path -Path $Differencefile -ErrorAction Stop).path)}
Catch { Write-Warning -Message "Could not Resolve the filenames." ; return }
#If we have one file , we must have two different worksheet names. If we have two files $worksheetName can be a single string or two strings.
if ($onefile -and ( ($WorkSheetName.count -ne 2) -or $WorkSheetName[0] -eq $WorkSheetName[1] ) ) {
Write-Warning -Message "If both the Reference and difference file are the same then worksheet name must provide 2 different names"
#If we have one file , we must have two different Worksheet names. If we have two files $WorksheetName can be a single string or two strings.
if ($onefile -and ( ($WorksheetName.count -ne 2) -or $WorksheetName[0] -eq $WorksheetName[1] ) ) {
Write-Warning -Message "If both the Reference and difference file are the same then Worksheet name must provide 2 different names"
return
}
if ($WorkSheetName.count -eq 2) {$workSheet2 = $DiffPrefix = $WorkSheetName[1] ; $worksheet1 = $WorkSheetName[0] ; }
elseif ($WorkSheetName -is [string]) {$worksheet2 = $workSheet1 = $WorkSheetName ;
if ($WorksheetName.count -eq 2) {$Worksheet2 = $DiffPrefix = $WorksheetName[1] ; $Worksheet1 = $WorksheetName[0] ; }
elseif ($WorksheetName -is [string]) {$Worksheet2 = $Worksheet1 = $WorksheetName ;
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$","" }
else {Write-Warning -Message "You must provide either a single worksheet name or two names." ; return }
else {Write-Warning -Message "You must provide either a single Worksheet name or two names." ; return }
$params= @{ ErrorAction = [System.Management.Automation.ActionPreference]::Stop }
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
try {
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $WorkSheet1 @params
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $WorkSheet2 @Params
$ReferenceObject = Import-Excel -Path $Referencefile -WorksheetName $Worksheet1 @params
$DifferenceObject = Import-Excel -Path $Differencefile -WorksheetName $Worksheet2 @Params
}
Catch {Write-Warning -Message "Could not read the worksheet from $Referencefile::$worksheet1 and/or $Differencefile::$worksheet2." ; return }
Catch {Write-Warning -Message "Could not read the Worksheet from $Referencefile::$Worksheet1 and/or $Differencefile::$Worksheet2." ; return }
if ($NoHeader) {$firstDataRow = $Startrow } else {$firstDataRow = $Startrow + 1}
}
elseif ( $Differencefile) {
if ($WorkSheetName -isnot [string]) {Write-Warning -Message "You must provide a single worksheet name." ; return }
$params = @{WorkSheetName=$WorkSheetName; Path=$Differencefile; ErrorAction = [System.Management.Automation.ActionPreference]::Stop ;}
if ($WorksheetName -isnot [string]) {Write-Warning -Message "You must provide a single Worksheet name." ; return }
$params = @{WorksheetName=$WorksheetName; Path=$Differencefile; ErrorAction=[System.Management.Automation.ActionPreference]::Stop }
foreach ($p in @("HeaderName","NoHeader","StartRow")) {if ($PSBoundParameters[$p]) {$params[$p] = $PSBoundParameters[$p]}}
try {$DifferenceObject = Import-Excel @Params }
Catch {Write-Warning -Message "Could not read the worksheet '$WorkSheetName' from $Differencefile::$WorkSheetName." ; return }
Catch {Write-Warning -Message "Could not read the Worksheet '$WorksheetName' from $Differencefile::$WorksheetName." ; return }
if ($DiffPrefix -eq "=>" ) {
$DiffPrefix = (Split-Path -Path $Differencefile -Leaf) -replace "\.xlsx$",""
}
@@ -148,7 +171,7 @@
$headings = $DifferenceObject[0].psobject.Properties.Name # This preserves the sequence - using get-member would sort them alphabetically! There may be extra properties in
if ($NoHeader -and "Name" -eq $Key) {$Key = "p1"}
if ($headings -notcontains $Key -and
('*' -ne $Key)) {Write-Warning -Message "You need to specify one of the headings in the sheet '$worksheet1' as a key." ; return }
('*' -ne $Key)) {Write-Warning -Message "You need to specify one of the headings in the sheet '$Worksheet1' as a key." ; return }
foreach ($p in $Property) { $propList += ($headings.where({$_ -like $p}) )}
foreach ($p in $ExcludeProperty) { $propList = $propList.where({$_ -notlike $p}) }
if (($propList -notcontains $Key) -and
@@ -198,19 +221,29 @@
else {$Rowhash[$row.$key] = $rowNo }
$rowNo ++
}
if ($DifferenceObject.count -gt $Rowhash.Keys.Count) {
Write-Warning -Message "Difference object has $($DifferenceObject.Count) rows; but only $($Rowhash.keys.count) unique keys"
}
if ($Key -eq '*') {$key = "_ALL"}
#endregion
#We need to know all the properties we've met on the objects we've diffed
$eDiffProps = [ordered]@{}
#When we do a compare object changes will result in two rows so we group them and join them together.
$expandedDiff = Compare-Object -ReferenceObject $ReferenceObject -DifferenceObject $DifferenceObject -Property $propList -PassThru -IncludeEqual |
Group-Object -Property $key | ForEach-Object {
#The value of the key column is the name of the group.
#The value of the key column is the name of the Group.
$keyval = $_.name
#we're going to create a custom object from a hash table. ??Might no longer need to preserve the field order
#we're going to create a custom object from a hash table.
$hash = [ordered]@{}
foreach ($result in $_.Group) {
if ($result.SideIndicator -ne "=>") {$hash["_Row"] = $result._Row }
elseif (-not $hash["$DiffPrefix Row"]) {$hash["_Row"] = "" }
#if we have already set the side, be this must the second record, so set side to indicate "changed"
if ($hash.Side) {$hash.Side = "<>"} else {$hash["Side"] = $result.SideIndicator}
#if we have already set the side, this must be the second record, so set side to indicate "changed"; if we got two "Same" indicators we may have a classh of keys
if ($hash.Side) {
if ($hash.Side -eq $result.SideIndicator) {Write-Warning -Message "'$keyval' may be a duplicate."}
$hash.Side = "<>"
}
else {$hash["Side"] = $result.SideIndicator}
switch ($hash.side) {
'==' { $hash["$DiffPrefix is"] = 'Same' }
'=>' { $hash["$DiffPrefix is"] = 'Added' }
@@ -223,7 +256,7 @@
}
'<=' { $hash["$DiffPrefix is"] = 'Removed'}
}
#find the number of the row in the the "difference" object which has this key. If it is the object is only the reference this will be blank.
#find the number of the row in the the "difference" object which has this key. If it is the object is only in the reference this will be blank.
$hash["$DiffPrefix Row"] = $Rowhash[$keyval]
$hash[$key] = $keyval
#Create FieldName and/or =>FieldName columns
@@ -235,6 +268,8 @@
elseif ($result.SideIndicator -eq "=>") { $hash[("$DiffPrefix $p")] = $result.$P}
}
}
foreach ($k in $hash.keys) {$eDiffProps[$k] = $true}
[Pscustomobject]$hash
} | Sort-Object -Property "_row"
@@ -245,35 +280,35 @@
$expandedDiff = $expandedDiff | Sort-Object -Property "$DiffPrefix Row"
for ($i = 1; $i -lt $expandedDiff.Count; $i++) {if (-not $expandedDiff[$i]."_Row") {$expandedDiff[$i]."_Row" = $expandedDiff[$i-1]."_Row" } }
$AllProps = @("_Row") + $OutputProps + $expandedDiff[0].psobject.properties.name.where({$_ -notin ($outputProps + @("_row","side","SideIndicator","_ALL" ))})
$AllProps = @("_Row") + $OutputProps + $eDiffProps.keys.where({$_ -notin ($outputProps + @("_row","side","SideIndicator","_ALL" ))})
if ($PassThru -or -not $OutputFile) {return ($expandedDiff | Select-Object -Property $allprops | Sort-Object -Property "_row", "$DiffPrefix Row" | Update-FirstObjectProperties ) }
if ($PassThru -or -not $OutputFile) {return ($expandedDiff | Select-Object -Property $allprops | Sort-Object -Property "_row", "$DiffPrefix Row" ) }
elseif ($PSCmdlet.ShouldProcess($OutputFile,"Write Output to Excel file")) {
$expandedDiff = $expandedDiff | Sort-Object -Property "_row", "$DiffPrefix Row"
$xl = $expandedDiff | Select-Object -Property $OutputProps | Update-FirstObjectProperties |
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
Export-Excel -Path $OutputFile -Worksheetname $OutputSheetName -FreezeTopRow -BoldTopRow -AutoSize -AutoFilter -PassThru
$ws = $xl.Workbook.Worksheets[$OutputSheetName]
for ($i = 0; $i -lt $expandedDiff.Count; $i++ ) {
if ( $expandedDiff[$i].side -ne "==" ) {
Set-Format -WorkSheet $ws -Range ("A" + ($i + 2 )) -FontColor $KeyFontColor
Set-ExcelRange -Worksheet $ws -Range ("A" + ($i + 2 )) -FontColor $KeyFontColor
}
elseif ( $HideEqual ) {$ws.row($i+2).hidden = $true }
if ( $expandedDiff[$i].side -eq "<>" ) {
$range = $ws.Dimension -replace "\d+", ($i + 2 )
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $ChangeBackgroundColor
}
elseif ( $expandedDiff[$i].side -eq "<=" ) {
$rangeR1C1 = "R[{0}]C[1]:R[{0}]C[{1}]" -f ($i + 2 ) , $lastRefColNo
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $DeleteBackgroundColor
}
elseif ( $expandedDiff[$i].side -eq "=>" ) {
if ($propList.count -gt 1) {
$rangeR1C1 = "R[{0}]C[{1}]:R[{0}]C[{2}]" -f ($i + 2 ) , $FirstDiffColNo , $lastDiffColNo
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1($rangeR1C1,0,0)
Set-Format -WorkSheet $ws -Range $range -BackgroundColor $AddBackgroundColor
Set-ExcelRange -Worksheet $ws -Range $range -BackgroundColor $AddBackgroundColor
}
Set-Format -WorkSheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
Set-ExcelRange -Worksheet $ws -Range ("A" + ($i + 2 )) -BackgroundColor $AddBackgroundColor
}
}
Close-ExcelPackage -ExcelPackage $xl -Show:$Show
@@ -281,135 +316,158 @@
}
Function Merge-MultipleSheets {
[cmdletbinding()]
[Alias("Merge-MulipleSheets")]
<#
.Synopsis
Merges worksheets into a single worksheet with differences marked up.
.Description
The Merge worksheet command combines 2 sheets. Merge-MultipleSheets is designed to merge more than 2.
So if asked to merge sheets A,B,C which contain Services, with a Name, Displayname and Start mode, where "name" is treated as the key
Merge-MultipleSheets calls Merge-Worksheet to merge Name, Displayname and Start mode, from sheets A and C
the result has column headings -Row, Name, DisplayName, Startmode, C-DisplayName, C-StartMode C-Is, C-Row
Merge-MultipleSheets then calls Merge-Worsheet with this result and sheet B, comparing 'Name', 'Displayname' and 'Start mode' columns on each side
which outputs _Row, Name, DisplayName, Startmode, B-DisplayName, B-StartMode B-Is, B-Row, C-DisplayName, C-StartMode C-Is, C-Row
Any columns in the "reference" side which are not used in the comparison are appended on the right, which is we compare the sheets in reverse order.
<#
.Synopsis
Merges Worksheets into a single Worksheet with differences marked up.
.Description
The Merge Worksheet command combines two sheets. Merge-MultipleSheets is
designed to merge more than two. So if asked to merge sheets A,B,C which
contain Services, with a Name, Displayname and Start mode, where "Name" is
treated as the key, Merge-MultipleSheets calls Merge-Worksheet to merge
"Name", "Displayname" and "Startmode" from sheets A and C; the result has
column headings "_Row", "Name", "DisplayName", "Startmode", "C-DisplayName",
"C-StartMode", "C-Is" and "C-Row".
Merge-MultipleSheets then calls Merge-Worksheet again passing it the
intermediate result and sheet B, comparing "Name", "Displayname" and
"Start mode" columns on each side, and gets a result with columns "_Row",
"Name", "DisplayName", "Startmode", "B-DisplayName", "B-StartMode", "B-Is",
"B-Row", "C-DisplayName", "C-StartMode", "C-Is" and "C-Row". Any columns on
the "reference" side which are not used in the comparison are added on the
right, which is why we compare the sheets in reverse order.
The "Is" column holds "Same", "Added", "Removed" or "Changed" and is used for conditional formatting in the output sheet (this is hidden by default),
and when the data is written to Excel the "reference" columns, in this case "DisplayName" and "Start" are renamed to reflect their source,
so become "A-DisplayName" and "A-Start".
The "Is" columns hold "Same", "Added", "Removed" or "Changed" and is used for
conditional formatting in the output sheet (these columns are hidden by default),
and when the data is written to Excel the "reference" columns, in this case
"DisplayName" and "Start" are renamed to reflect their source, so become
"A-DisplayName" and "A-Start".
Conditional formatting is also applied to the "key" column (name in this case) so the view can be filtered to rows with changes by filtering this column on color.
Conditional formatting is also applied to the Key column ("Name" in this
case) so the view can be filtered to rows with changes by filtering this
column on color.
Note: the processing order can affect what is seen as a change. For example if there is an extra item in sheet B in the example above,
Sheet C will be processed and that row and will not be seen to be missing. When sheet B is processed it is marked as an addition, and the conditional formatting marks
the entries from sheet A to show that a values were added in at least one sheet.
However if Sheet B is the reference sheet, A and C will be seen to have an item removed;
and if B is processed before C, the extra item is known when C is processed and so C is considered to be missing that item.
.Example
dir Server*.xlsx | Merge-MulipleSheets -WorkSheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
We are auditing servers and each one has a workbook in the current directory which contains a "Services" worksheet (the result of
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode
No key is specified so the key is assumed to be the "Name" column. The files are merged and the result is opened on completion.
.Example
dir Serv*.xlsx | Merge-MulipleSheets -WorkSheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
The server audit files in the previous example also have "Software" worksheet, but no single field on that sheet works as a key.
Specifying "*" for the key produces a compound key using all non-excluded fields (and the installation date and file location are excluded).
.Example
Merge-MulipleSheets -Path hotfixes.xlsx -WorkSheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
This time all the servers have written their hofix information to their own worksheets in a shared Excel workbook named "Hotfixes"
(the information was obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
This ignores any sheets which are not named "Serv*", and uses the HotfixID as the key ; in this version the row numbers are hidden.
#>
param (
Note: the processing order can affect what is seen as a change. For example
if there is an extra item in sheet B in the example above, Sheet C will be
processed and that row and will not be seen to be missing. When sheet B is
processed it is marked as an addition, and the conditional formatting marks
the entries from sheet A to show that a values were added in at least one
sheet. However if Sheet B is the reference sheet, A and C will be seen to
have an item removed; and if B is processed before C, the extra item is
known when C is processed and so C is considered to be missing that item.
.Example
dir Server*.xlsx | Merge-MulipleSheets -WorksheetName Services -OutputFile Test2.xlsx -OutputSheetName Services -Show
Here we are auditing servers and each one has a workbook in the current
directory which contains a "Services" Worksheet (the result of
Get-WmiObject -Class win32_service | Select-Object -Property Name, Displayname, Startmode)
No key is specified so the key is assumed to be the "Name" column.
The files are merged and the result is opened on completion.
.Example
dir Serv*.xlsx | Merge-MulipleSheets -WorksheetName Software -Key "*" -ExcludeProperty Install* -OutputFile Test2.xlsx -OutputSheetName Software -Show
The server audit files in the previous example also have "Software" worksheet,
but no single field on that sheet works as a key. Specifying "*" for the key
produces a compound key using all non-excluded fields (and the installation
date and file location are excluded).
.Example
Merge-MulipleSheets -Path hotfixes.xlsx -WorksheetName Serv* -Key hotfixid -OutputFile test2.xlsx -OutputSheetName hotfixes -HideRowNumbers -Show
This time all the servers have written their hotfix information to their own
worksheets in a shared Excel workbook named "Hotfixes.xlsx" (the information was
obtained by running Get-Hotfix | Sort-Object -Property description,hotfixid | Select-Object -Property Description,HotfixID)
This ignores any sheets which are not named "Serv*", and uses the HotfixID as
the key; in this version the row numbers are hidden.
#>
[cmdletbinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification="False positives when initializing variable in begin block")]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification="MultipleSheet would be incorrect")]
#[Alias("Merge-MulipleSheets")] #There was a spelling error in the first release. This was there to ensure things didn't break but intelisense gave the alias first.
param (
#Paths to the files to be merged. Files are also accepted
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string[]]$Path ,
#The row from where we start to import data, all rows above the StartRow are disregarded. By default this is the first row.
$Path ,
#The row from where we start to import data, all rows above the Start row are disregarded. By default this is the first row.
[int]$Startrow = 1,
#Specifies custom property names to use, instead of the values defined in the column headers of the TopRow.
#Specifies custom property names to use, instead of the values defined in the column headers of the Start row.
[String[]]$Headername,
#Automatically generate property names (P1, P2, P3, ..) instead of the using the values the top row of the sheet.
#If specified, property names will be automatically generated (P1, P2, P3, ..) instead of using the values from the start row.
[switch]$NoHeader,
#Name(s) of worksheets to compare,
$WorkSheetName = "Sheet1",
#File to write output to
#Name(s) of Worksheets to compare.
$WorksheetName = "Sheet1",
#File to write output to.
[Alias('OutFile')]
$OutputFile = ".\temp.xlsx",
#Name of worksheet to output - if none specified will use the reference worksheet name.
#Name of Worksheet to output - if none specified will use the reference Worksheet name.
[Alias('OutSheet')]
$OutputSheetName = "Sheet1",
#Properties to include in the DIFF - supports wildcards, default is "*".
#Properties to include in the comparison - supports wildcards, default is "*".
$Property = "*" ,
#Properties to exclude from the the search - supports wildcards.
#Properties to exclude from the the comparison - supports wildcards.
$ExcludeProperty ,
#Name of a column which is unique used to pair up rows from the refence and difference side, default is "Name".
#Name of a column which is unique used to pair up rows from the reference and difference sides, default is "Name".
$Key = "Name" ,
#Sets the font color for the "key" field; this means you can filter by color to get only changed rows.
[System.Drawing.Color]$KeyFontColor = "Red",
#Sets the font color for the Key field; this means you can filter by color to get only changed rows.
$KeyFontColor = [System.Drawing.Color]::Red,
#Sets the background color for changed rows.
[System.Drawing.Color]$ChangeBackgroundColor = "Orange",
$ChangeBackgroundColor = [System.Drawing.Color]::Orange,
#Sets the background color for rows in the reference but deleted from the difference sheet.
[System.Drawing.Color]$DeleteBackgroundColor = "LightPink",
$DeleteBackgroundColor = [System.Drawing.Color]::LightPink,
#Sets the background color for rows not in the reference but added to the difference sheet.
[System.Drawing.Color]$AddBackgroundColor = "Orange",
#if Specified hides the columns in the spreadsheet that contain the row numbers
$AddBackgroundColor = [System.Drawing.Color]::Orange,
#If specified, hides the columns in the spreadsheet that contain the row numbers.
[switch]$HideRowNumbers ,
#If specified outputs the data to the pipeline (you can add -whatif so it the command only outputs to the command)
#If specified, outputs the data to the pipeline (you can add -whatif so it the command only outputs to the pipeline).
[switch]$Passthru ,
#If specified, opens the output workbook.
[Switch]$Show
)
begin { $filestoProcess = @() }
process { $filestoProcess += $Path}
end {
if ($filestoProcess.Count -eq 1 -and $WorkSheetName -match '\*') {
begin { $filestoProcess = @() }
process { $filestoProcess += $Path}
end {
if ($filestoProcess.Count -eq 1 -and $WorksheetName -match '\*') {
Write-Progress -Activity "Merging sheets" -CurrentOperation "Expanding * to names of sheets in $($filestoProcess[0]). "
$excel = Open-ExcelPackage -Path $filestoProcess
$WorksheetName = $excel.Workbook.Worksheets.Name.where({$_ -like $WorkSheetName})
$WorksheetName = $excel.Workbook.Worksheets.Name.where({$_ -like $WorksheetName})
Close-ExcelPackage -NoSave -ExcelPackage $excel
}
#Merge indentically named sheets in different work books;
if ($filestoProcess.Count -ge 2 -and $WorkSheetName -is "string" ) {
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorkSheetName' -ErrorAction SilentlyContinue |
#Merge identically named sheets in different work books;
if ($filestoProcess.Count -ge 2 -and $WorksheetName -is "string" ) {
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty','WorksheetName' -ErrorAction SilentlyContinue |
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($filestoProcess[-1]) against $($filestoProcess[0]). "
Write-Progress -Activity "Merging sheets" -CurrentOperation "comparing '$WorksheetName' in $($filestoProcess[-1]) against $($filestoProcess[0]). "
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[-1]
$nextFileNo = 2
while ($nextFileNo -lt $filestoProcess.count -and $merged) {
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($filestoProcess[-$nextFileNo]) against $($filestoProcess[0]). "
Write-Progress -Activity "Merging sheets" -CurrentOperation "comparing '$WorksheetName' in $($filestoProcess[-$nextFileNo]) against $($filestoProcess[0]). "
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[-$nextFileNo]
$nextFileNo ++
}
}
#Merge different sheets from one workbook
elseif ($filestoProcess.Count -eq 1 -and $WorkSheetName.Count -ge 2 ) {
elseif ($filestoProcess.Count -eq 1 -and $WorksheetName.Count -ge 2 ) {
Get-Variable -Name 'HeaderName','NoHeader','StartRow','Key','Property','ExcludeProperty' -ErrorAction SilentlyContinue |
Where-Object {$_.Value} | ForEach-Object -Begin {$params= @{} } -Process {$params[$_.Name] = $_.Value}
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-1]) against $($WorkSheetName[0]). "
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[0] -WorkSheetName $WorkSheetName[0,-1]
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorksheetName[-1]) against $($WorksheetName[0]). "
$merged = Merge-Worksheet @params -Referencefile $filestoProcess[0] -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[0,-1]
$nextSheetNo = 2
while ($nextSheetNo -lt $WorkSheetName.count -and $merged) {
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorkSheetName[-$nextSheetNo]) against $($WorkSheetName[0]). "
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[0] -WorkSheetName $WorkSheetName[-$nextSheetNo] -DiffPrefix $WorkSheetName[-$nextSheetNo]
while ($nextSheetNo -lt $WorksheetName.count -and $merged) {
Write-Progress -Activity "Merging sheets" -CurrentOperation "Comparing $($WorksheetName[-$nextSheetNo]) against $($WorksheetName[0]). "
$merged = Merge-Worksheet @params -ReferenceObject $merged -Differencefile $filestoProcess[0] -WorksheetName $WorksheetName[-$nextSheetNo] -DiffPrefix $WorksheetName[-$nextSheetNo]
$nextSheetNo ++
}
}
#We either need one worksheet name and many files or one file and many sheets.
#We either need one Worksheet name and many files or one file and many sheets.
else { Write-Warning -Message "Need at least two files to process" ; return }
#if the process didn't return data then abandon now.
if (-not $merged) {Write-Warning -Message "The merge operation did not return any data."; return }
$orderByProperties = $merged[0].psobject.properties.where({$_.name -match "row$"}).name
Write-Progress -Activity "Merging sheets" -CurrentOperation "Creating output sheet '$OutputSheetName' in $OutputFile"
$excel = $merged | Sort-Object -Property $orderByProperties | Update-FirstObjectProperties |
Export-Excel -Path $OutputFile -WorkSheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
Write-Progress -Activity "Merging sheets" -CurrentOperation "creating output sheet '$OutputSheetName' in $OutputFile"
$excel = $merged | Sort-Object -Property $orderByProperties |
Export-Excel -Path $OutputFile -Worksheetname $OutputSheetName -ClearSheet -BoldTopRow -AutoFilter -PassThru
$sheet = $excel.Workbook.Worksheets[$OutputSheetName]
#We will put in a conditional format for "if all the others are not flagged as 'same'" to mark rows where something is added, removed or changed
@@ -423,8 +481,8 @@ Function Merge-MultipleSheets {
if ($filesToProcess.Count -ge 2) {
$refPrefix = (Split-Path -Path $filestoProcess[0] -Leaf) -replace "\.xlsx$"," "
}
else {$refPrefix = $WorkSheetName[0] }
Write-Progress -Activity "Merging sheets" -CurrentOperation "Applying formatting to sheet '$OutputSheetName' in $OutputFile"
else {$refPrefix = $WorksheetName[0] }
Write-Progress -Activity "Merging sheets" -CurrentOperation "applying formatting to sheet '$OutputSheetName' in $OutputFile"
#Find the column headings which are in the form "diffFile is"; which will hold 'Same', 'Added' or 'Changed'
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -match "\sIS$"}) ) {
#Work leftwards across the headings applying conditional formatting which says
@@ -433,7 +491,7 @@ Function Merge-MultipleSheets {
$columnNo = $cell.start.Column -1
$cellAddr = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R1C$columnNo",1,$columnNo)
while ($sheet.cells[$cellAddr].value -match $prefix) {
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='None'; WorkSheet=$sheet; Range=$([OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[1]C[$columnNo]:R[1048576]C[$columnNo]",0,0)) }
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='Solid'; Worksheet=$sheet; StopIfTrue=$true; Range=$([OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[1]C[$columnNo]:R[1048576]C[$columnNo]",0,0)) }
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Added"' ) -BackgroundColor $AddBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Changed"') -BackgroundColor $ChangeBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ($cell.Address + '="Removed"') -BackgroundColor $DeleteBackgroundColor
@@ -449,15 +507,16 @@ Function Merge-MultipleSheets {
$nameRegex = $colNames -Join '|'
foreach ($cell in $sheet.Cells[($sheet.Dimension.Address -replace "\d+$","1")].Where({$_.value -Notmatch $nameRegex}) ) {
$cell.Value = $refPrefix + $cell.Value
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='None'; WorkSheet=$sheet; Range=[OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[2]C[$($cell.start.column)]:R[1048576]C[$($cell.start.column)]",0,0)}
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("OR(" +(($sameChecks -join ",") -replace '<>"Same"','="Added"') +")" ) -BackgroundColor $DeleteBackgroundColor
$condFormattingParams = @{RuleType='Expression'; BackgroundPattern='Solid'; Worksheet=$sheet; StopIfTrue=$true; Range=[OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[2]C[$($cell.start.column)]:R[1048576]C[$($cell.start.column)]",0,0)}
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("OR(" +(($sameChecks -join ",") -replace '<>"Same"','="Added"' ) +")" ) -BackgroundColor $DeleteBackgroundColor
Add-ConditionalFormatting @condFormattingParams -ConditionValue ("AND(" +(($sameChecks -join ",") -replace '<>"Same"','="Changed"') +")" ) -BackgroundColor $ChangeBackgroundColor
}
#We've made a bunch of things wider so now is the time to autofit columns. Any hiding has to come AFTER this, because it unhides things
$sheet.Cells.AutoFitColumns()
#if we have a key field (we didn't concatenate all fields) use what we built up in $sameChecks to apply conditional formatting to it (Row no will be in column A, Key in Column B)
if ($Key -ne '*') {
Add-ConditionalFormatting -WorkSheet $sheet -Range "B2:B1048576" -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ("OR(" +($sameChecks -join ",") +")" )
Add-ConditionalFormatting -Worksheet $sheet -Range "B2:B1048576" -ForeGroundColor $KeyFontColor -BackgroundPattern 'None' -RuleType Expression -ConditionValue ("OR(" +($sameChecks -join ",") +")" )
$sheet.view.FreezePanes(2, 3)
}
else {$sheet.view.FreezePanes(2, 2) }
@@ -472,8 +531,8 @@ Function Merge-MultipleSheets {
$sheet.Column($cell.start.Column).HIDDEN = $true
}
}
Close-ExcelPackage -ExcelPackage $excel -Show:$Show
if ($Passthru) {$excel}
else {Close-ExcelPackage -ExcelPackage $excel -Show:$Show}
Write-Progress -Activity "Merging sheets" -Completed
}
}
}

View File

@@ -1,4 +1,33 @@
function New-ConditionalFormattingIconSet {
<#
.SYNOPSIS
Creates an object which describes a conditional formatting rule a for 3,4 or 5 icon set.
.DESCRIPTION
Export-Excel takes a -ConditionalFormat parameter which can hold one or more descriptions for conditional formats;
this command builds the defintion of a Conditional formatting rule for an icon set.
.PARAMETER Range
The range of cells that the conditional format applies to.
.PARAMETER ConditionalFormat
The type of rule: one of "ThreeIconSet","FourIconSet" or "FiveIconSet"
.PARAMETER IconType
The name of an iconSet - different icons are available depending on whether 3,4 or 5 icon set is selected.
.PARAMETER Reverse
Use the icons in the reverse order.
.Example
$cfRange = [OfficeOpenXml.ExcelAddress]::new($topRow, $column, $lastDataRow, $column)
$cfdef = New-ConditionalFormattingIconSet -Range $cfrange -ConditionalFormat ThreeIconSet -IconType Arrows
Export-Excel -ExcelPackage $excel -ConditionalFormat $cfdef -show
The first line creates a range - one column wide in the column $column, running
from $topRow to $lastDataRow.
The second line creates a definition object using this range
and the third uses Export-Excel with an open package to apply the format and
save and open the file.
.Link
Add-Add-ConditionalFormatting
New-ConditionalText
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
param(
[Parameter(Mandatory=$true)]
$Range,

View File

@@ -1,35 +1,84 @@
function New-ConditionalText {
<#
.SYNOPSIS
Creates an object which describes a conditional formatting rule for single valued rules.
.DESCRIPTION
Some Conditional formatting rules don't apply styles to a cell (IconSets and Databars).
Some take two parameters (Between).
Some take none (ThisWeek, ContainsErrors, AboveAverage etc).
The others take a single parameter (Top, BottomPercent, GreaterThan, Contains etc).
This command creates an object to describe the last two categories, which can then be passed to Export-Excel.
.PARAMETER Range
The range of cells that the conditional format applies to; if none is specified the range will be apply to all the data in the sheet.
.PARAMETER ConditionalType
One of the supported rules; by default "ContainsText" is selected.
.PARAMETER Text
The text (or other value) to use in the rule. Note that Equals, GreaterThan/LessThan rules require text to wrapped in double quotes.
.PARAMETER ConditionalTextColor
The font color for the cell - by default: "DarkRed".
.PARAMETER BackgroundColor
The fill color for the cell - by default: "LightPink".
.PARAMETER PatternType
The background pattern for the cell - by default: "Solid"
.EXAMPLE
>
$ct = New-ConditionalText -Text 'Ferrari'
Export-Excel -ExcelPackage $excel -ConditionalTest $ct -show
The first line creates a definition object which will highlight the word
"Ferrari" in any cell. and the second uses Export-Excel with an open package
to apply the format and save and open the file.
.EXAMPLE
>
$ct = New-ConditionalText -Text "Ferrari"
$ct2 = New-ConditionalText -Range $worksheet.Names["FinishPosition"].Address -ConditionalType LessThanOrEqual -Text 3 -ConditionalTextColor Red -BackgroundColor White
Export-Excel -ExcelPackage $excel -ConditionalText $ct,$ct2 -show
This builds on the previous example, and specifies a condition of <=3 with
a format of red text on a white background; this applies to a named range
"Finish Position". The range could be written -Range "C:C" to specify a
named column, or -Range "C2:C102" to specify certain cells in the column.
.Link
Add-Add-ConditionalFormatting
New-ConditionalFormattingIconSet
#>
[cmdletbinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
param(
#[Parameter(Mandatory=$true)]
[Alias("ConditionValue")]
$Text,
[System.Drawing.Color]$ConditionalTextColor="DarkRed",
[System.Drawing.Color]$BackgroundColor="LightPink",
[Alias("ForeGroundColor")]
$ConditionalTextColor=[System.Drawing.Color]::DarkRed,
$BackgroundColor=[System.Drawing.Color]::LightPink,
[String]$Range,
[OfficeOpenXml.Style.ExcelFillStyle]$PatternType=[OfficeOpenXml.Style.ExcelFillStyle]::Solid,
[ValidateSet(
"LessThan","LessThanOrEqual","GreaterThan","GreaterThanOrEqual",
"NotEqual","Equal","ContainsText","NotContainsText","BeginsWith","EndsWith",
"Last7Days","LastMonth","LastWeek",
"NextMonth","NextWeek",
"ThisMonth","ThisWeek",
"Today","Tomorrow","Yesterday",
"DuplicateValues",
"AboveOrEqualAverage","BelowAverage","AboveAverage",
"Top", "TopPercent", "ContainsBlanks"
"LessThan", "LessThanOrEqual", "GreaterThan", "GreaterThanOrEqual",
"Equal", "NotEqual",
"Top", "TopPercent", "Bottom", "BottomPercent",
"ContainsText", "NotContainsText", "BeginsWith", "EndsWith",
"ContainsBlanks", "NotContainsBlanks", "ContainsErrors", "NotContainsErrors",
"DuplicateValues", "UniqueValues",
"Tomorrow", "Today", "Yesterday", "Last7Days",
"NextWeek", "ThisWeek", "LastWeek",
"NextMonth", "ThisMonth", "LastMonth",
"AboveAverage", "AboveOrEqualAverage", "BelowAverage", "BelowOrEqualAverage"
)]
[Alias("RuleType")]
$ConditionalType="ContainsText"
)
$obj = [PSCustomObject]@{
Text = $Text
ConditionalTextColor = $ConditionalTextColor
ConditionalType = $ConditionalType
PatternType = $PatternType
ConditionalType = $ConditionalType
PatternType = $PatternType
Range = $Range
BackgroundColor = $BackgroundColor
BackgroundColor = $BackgroundColor
}
$obj.pstypenames.Clear()
$obj.pstypenames.Add("ConditionalText")
$obj
$obj
}

View File

@@ -1,6 +1,103 @@
function New-ExcelChartDefinition {
[cmdletbinding()]
function New-ExcelChartDefinition {
<#
.SYNOPSIS
Creates a Definition of a chart which can be added using Export-Excel, or Add-PivotTable
.DESCRIPTION
All the parameters which are passed to Add-ExcelChart can be added to an object and
passed to Export-Excel with the -ExcelChartDefinition parameter,
or to Add-PivotTable with the -PivotChartDefinition parameter.
This command sets up those definitions.
.PARAMETER Title
The title for the chart.
.PARAMETER TitleBold
Sets the title in bold face.
.PARAMETER TitleSize
Sets the point size for the title.
.PARAMETER ChartType
One of the built-in chart types, such as Pie, ClusteredColumn, Line etc. Defaults to "ColumnStacked".
.PARAMETER XRange
The range of cells containing values for the X-Axis - usually labels.
.PARAMETER YRange
The range(s) of cells holding values for the Y-Axis - usually "data".
.PARAMETER Width
Width of the chart in pixels. Defaults to 500.
.PARAMETER Height
Height of the chart in pixels. Defaults to 350.
.PARAMETER Row
Row position of the top left corner of the chart. 0 places at the top of the sheet, 1 below row 1 and so on.
.PARAMETER RowOffSetPixels
Offset to position the chart by a fraction of a row.
.PARAMETER Column
Column position of the top left corner of the chart. 0 places at the edge of the sheet 1 to the right of column A and so on.
.PARAMETER ColumnOffSetPixels
Offset to position the chart by a fraction of a column.
.PARAMETER NoLegend
If specified, turns off display of the key. If you only have one data series it may be preferable to use the title to say what the chart is.
.PARAMETER SeriesHeader
Specifies explicit name(s) for the data series, which will appear in the legend/key
.PARAMETER LegendPosition
Location of the key, either "Left", "Right", "Top", "Bottom" or "TopRight".
.PARAMETER LegendSize
Font size for the key.
.PARAMETER LegendBold
Sets the key in bold type.
.PARAMETER ShowCategory
Attaches a category label in charts which support this.
.PARAMETER ShowPercent
Attaches a percentage label in charts which support this.
.PARAMETER XAxisTitleText
Specifies a title for the X-axis.
.PARAMETER XAxisTitleBold
Sets the X-axis title in bold face.
.PARAMETER XAxisTitleSize
Sets the font size for the axis title.
.PARAMETER XAxisNumberformat
A number formatting string, like "#,##0.00", for numbers along the X-axis.
.PARAMETER XMajorUnit
Spacing for the major gridlines / tick marks along the X-axis.
.PARAMETER XMinorUnit
Spacing for the minor gridlines / tick marks along the X-axis.
.PARAMETER XMaxValue
Maximum value for the scale along the X-axis.
.PARAMETER XMinValue
Minimum value for the scale along the X-axis.
.PARAMETER xAxisPosition
Position for the X-axis ("Top" or" Bottom").
.PARAMETER YAxisTitleText
Specifies a title for the Y-axis.
.PARAMETER YAxisTitleBold
Sets the Y-axis title in bold face.
.PARAMETER YAxisTitleSize
Sets the font size for the Y-axis title.
.PARAMETER YAxisNumberformat
A number formatting string, like "#,##0.00", for numbers on the Y-axis
.PARAMETER YMajorUnit
Spacing for the major gridlines / tick marks on the Y-axis.
.PARAMETER YMinorUnit
Spacing for the minor gridlines / tick marks on the Y-axis.
.PARAMETER YMaxValue
Maximum value on the Y-axis.
.PARAMETER YMinValue
Minimum value on the Y-axis.
.PARAMETER YAxisPosition
Position for the Y-axis ("Left" or "Right").
.PARAMETER Header
No longer used. This may be removed in future versions.
.Example
>
PS> $cDef = New-ExcelChartDefinition -ChartType line -XRange "X" -YRange "Sinx" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
-SeriesHeader "Sin(x)" -LegendSize 8 -legendBold -LegendPosition Bottom
0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -now -WorkSheetname SinX -ExcelChartDefinition $cDef -Show
This reworks an example from Add-Excel-Chart but here the chart is defined
and the defintion stored in $cDef and then Export-Excel uses $cDef .
#>
[Alias("New-ExcelChart")] #This was the former name. The new name reflects that we are defining a chart, not making one in the workbook.
[cmdletbinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',Justification='Does not change system State')]
param(
$Title = "Chart Title",
$Header,
@@ -13,8 +110,9 @@ function New-ExcelChartDefinition {
$RowOffSetPixels = 10,
$Column = 6,
$ColumnOffSetPixels = 5,
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
$LegendSize,
[Switch]$legendBold,
[Switch]$LegendBold,
[Switch]$NoLegend,
[Switch]$ShowCategory,
[Switch]$ShowPercent,
@@ -53,12 +151,15 @@ function New-ExcelChartDefinition {
RowOffSetPixels = $RowOffSetPixels
Column = $Column
ColumnOffSetPixels = $ColumnOffSetPixels
LegendPosition = $LegendPosition
LegendSize = $LegendSize
Legendbold = $LegendBold
NoLegend = $NoLegend -as [Boolean]
ShowCategory = $ShowCategory -as [Boolean]
ShowPercent = $ShowPercent -as [Boolean]
SeriesHeader = $SeriesHeader
TitleBold = $TitleBold -as [Boolean]
TitleSize = $TitleSize
SeriesHeader = $SeriesHeader
XAxisTitleText = $XAxisTitleText
XAxisTitleBold = $XAxisTitleBold -as [Boolean]
XAxisTitleSize = $XAxisTitleSize
@@ -78,4 +179,280 @@ function New-ExcelChartDefinition {
YMinValue = $YMinValue
YAxisPosition = $YAxisPosition
}
}
}
function Add-ExcelChart {
<#
.SYNOPSIS
Creates a chart in an existing Excel worksheet.
.DESCRIPTION
Creates a chart. It is possible to configure the type of chart, the range of X values (labels) and Y values.
the title, the legend, the ranges for both axes, the format and position of the axes.
Normally the command does not return anything, but if -passthru is specified the chart is returned so that it can be customized.
.PARAMETER Worksheet
An existing Sheet where the chart will be created.
.PARAMETER Title
The title for the chart.
.PARAMETER TitleBold
Sets the title in bold face.
.PARAMETER TitleSize
Sets the point size for the title.
.PARAMETER ChartType
One of the built-in chart types, such as Pie, ClusteredColumn, Line etc. Defaults to "ColumnStacked".
.PARAMETER XRange
The range of cells containing values for the X-Axis - usually labels.
.PARAMETER YRange
The range(s) of cells holding values for the Y-Axis - usually "data".
.PARAMETER PivotTable
Instead of specify X and Y ranges, get data from a PivotTable by passing a PivotTable Object.
.PARAMETER Width
Width of the chart in Pixels. Defaults to 500.
.PARAMETER Height
Height of the chart in Pixels. Defaults to 350.
.PARAMETER Row
Row position of the top left corner of the chart. 0 places at the top of the sheet, 1 below row 1 and so on.
.PARAMETER RowOffSetPixels
Offset to position the chart by a fraction of a row.
.PARAMETER Column
Column position of the top left corner of the chart. 0 places at the edge of the sheet 1 to the right of column A and so on.
.PARAMETER ColumnOffSetPixels
Offset to position the chart by a fraction of a column.
.PARAMETER NoLegend
If specified, turns of display of the key. If you only have one data series it may be preferable to use the title to say what the chart is.
.PARAMETER SeriesHeader
Specify explicit name(s) for the data series, which will appear in the legend/key. The contents of a cell can be specified in the from =Sheet9!Z10 .
.PARAMETER LegendPosition
Location of the key, either left, right, top, bottom or TopRight.
.PARAMETER LegendSize
Font size for the key.
.PARAMETER LegendBold
Sets the key in bold type.
.PARAMETER ShowCategory
Attaches a category label in charts which support this.
.PARAMETER ShowPercent
Attaches a percentage label in charts which support this.
.PARAMETER XAxisTitleText
Specifies a title for the X-axis.
.PARAMETER XAxisTitleBold
Sets the X-axis title in bold face.
.PARAMETER XAxisTitleSize
Sets the font size for the axis title.
.PARAMETER XAxisNumberformat
A number formatting string, like "#,##0.00", for numbers along the X-axis.
.PARAMETER XMajorUnit
Spacing for the major gridlines / tick marks along the X-axis.
.PARAMETER XMinorUnit
Spacing for the minor gridlines / tick marks along the X-axis.
.PARAMETER XMaxValue
Maximum value for the scale along the X-axis.
.PARAMETER XMinValue
Minimum value for the scale along the X-axis.
.PARAMETER xAxisPosition
Position for the X-axis (Top or Bottom).
.PARAMETER YAxisTitleText
Specifies a title for the Y-axis.
.PARAMETER YAxisTitleBold
Sets the Y-axis title in bold face.
.PARAMETER YAxisTitleSize
Sets the font size for the Y-axis title
.PARAMETER YAxisNumberformat
A number formatting string, like "#,##0.00", for numbers on the Y-axis.
.PARAMETER YMajorUnit
Spacing for the major gridlines / tick marks on the Y-axis.
.PARAMETER YMinorUnit
Spacing for the minor gridlines / tick marks on the Y-axis.
.PARAMETER YMaxValue
Maximum value on the Y-axis.
.PARAMETER YMinValue
Minimum value on the Y-axis.
.PARAMETER YAxisPosition
Position for the Y-axis (Left or Right).
.PARAMETER PassThru
Add-Excel chart doesn't normally return anything, but if -PassThru is specified it returns the newly created chart to allow it to be fine tuned.
.EXAMPLE
>
PS> $Excel = ConvertFrom-Csv @"
Product, City, Sales
Apple, London , 300
Orange, London , 400
Banana, London , 300
Orange, Paris, 600
Banana, Paris, 300
Apple, New York, 1200
"@ | Export-Excel -Path test.xlsx -PassThru
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -ChartType "Doughnut" -XRange "A2:B7" -YRange "C2:C7" -width 500
Close-ExcelPackage -Show $Excel
The first command expands a multi-line string into 6 rows of data which is exported to new Excel file; leaving an ExcelPackage object in $excel
The second command adds a chart - the cell ranges are explicitly specified. Note that the XRange (labels) is TWO columns wide and the chart will
combine the name of the product and the name of the City to create the label.
The width of the chart is set explictly, the default legend is used and there is no Chart title.
.EXAMPLE
>
PS> $Excel = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize | Export-Excel $path -AutoSize -ExcelChartDefinition $c -AutoNameRange -PassThru
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -Title "VM use" -ChartType PieExploded3D -XRange "Name" -YRange "VirtualMemorySize" -NoLegend -ShowCategory
Close-ExcelPackage $Excel -Show
The first line exports information and creates named ranges for each column.
The Second line uses the ranges to specify a chart - the labels come from the range "Name" and the data from the range "VirtualMemorySize"
The chart is specified as a 3D exploded PIE chart, with a title of "VM Use" and instead of a legend the the pie slices are identified with a label.
.EXAMPLE
>
PS> $Excel = Invoke-Sum (Get-Process) Company Handles, PM, VirtualMemorySize | Export-Excel test.xlsx -TableName Processes -PassThru
Add-ExcelChart -Worksheet $Excel.Workbook.Worksheets[1] -Title Stats -ChartType LineMarkersStacked -XRange "Processes[Name]" -YRange "Processes[PM]", "Processes[VirtualMemorySize]" -SeriesHeader 'PM', 'VMSize'
Close-ExcelPackage $Excel -Show
The first line exports information to a table in new file; and captures the excel Package object in $Excel
The second line creates a chart on the first page of the work sheet, using the notation "TableName[ColumnnName]" to refer to the data,
the labels come Name column in the table, and the data series from its PM and VirtualMemorySize columns. The display names for these in the header are set to PM and VMSize
.EXAMPLE
>
PS> $excel = 0..360 | ForEach-Object {[pscustomobject][ordered]@{x = $_; Sinx = "=Sin(Radians(x)) "}} | Export-Excel -AutoNameRange -Path Text.xlsx -WorkSheetname SinX -PassThru
Add-ExcelChart -Worksheet $excel.Workbook.Worksheets["Sinx"] -ChartType line -XRange "X" -YRange "Sinx" -Title "Graph of Sine X" -TitleBold -TitleSize 14 `
-Column 2 -ColumnOffSetPixels 35 -Width 800 -XAxisTitleText "Degrees" -XAxisTitleBold -XAxisTitleSize 12 -XMajorUnit 30 -XMinorUnit 10 -XMinValue 0 -XMaxValue 361 -XAxisNumberformat "000" `
-YMinValue -1.25 -YMaxValue 1.25 -YMajorUnit 0.25 -YAxisNumberformat "0.00" -YAxisTitleText "Sine" -YAxisTitleBold -YAxisTitleSize 12 `
-SeriesHeader "Sin(x)" -LegendSize 8 -legendBold -LegendPosition Bottom
Close-ExcelPackage $Excel -Show
The first line puts numbers from 0 to 360 into a sheet, as the first column, and
a formula to calculate the Sine of that number of number of degrees in the second column.
It creates named-ranges for the two columns - "X" and "SinX" respectively
The Add-ExcelChart command adds a chart to that worksheet, specifying a line chart
with the X values coming from named-range "X" and the Y values coming from named-range "SinX".
The chart has a title, and is positioned to the right of column 2 and sized 800 pixels wide
The X-axis is labelled "Degrees", in bold 12 point type and runs from 0 to 361 with labels every 30,
and minor tick marks every 10. Degrees are shown padded to 3 digits.
The Y-axis is labelled "Sine" and to allow some room above and below its scale runs from -1.25 to 1.25,
and is marked off in units of 0.25 shown to two decimal places.
The key will for the chart will be at the bottom in 8 point bold type and the line will be named "Sin(x)".
#>
[cmdletbinding(DefaultParameterSetName='Worksheet')]
[OutputType([OfficeOpenXml.Drawing.Chart.ExcelChart])]
param(
[Parameter(ParameterSetName='Workshet',Mandatory=$true)]
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
[Parameter(ParameterSetName='PivotTable',Mandatory=$true)]
[OfficeOpenXml.Table.PivotTable.ExcelPivotTable]$PivotTable ,
[String]$Title,
#$Header, Not used but referenced previously
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
$XRange,
$YRange,
[int]$Width = 500,
[int]$Height = 350,
[int]$Row = 0,
[int]$RowOffSetPixels = 10,
[int]$Column = 6,
[int]$ColumnOffSetPixels = 5,
[OfficeOpenXml.Drawing.Chart.eLegendPosition]$LegendPosition,
$LegendSize,
[Switch]$LegendBold,
[Switch]$NoLegend,
[Switch]$ShowCategory,
[Switch]$ShowPercent,
[String[]]$SeriesHeader,
[Switch]$TitleBold,
[Int]$TitleSize ,
[String]$XAxisTitleText,
[Switch]$XAxisTitleBold,
$XAxisTitleSize ,
[string]$XAxisNumberformat,
$XMajorUnit,
$XMinorUnit,
$XMaxValue,
$XMinValue,
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$XAxisPosition ,
[String]$YAxisTitleText,
[Switch]$YAxisTitleBold,
$YAxisTitleSize,
[string]$YAxisNumberformat,
$YMajorUnit,
$YMinorUnit,
$YMaxValue,
$YMinValue,
[OfficeOpenXml.Drawing.Chart.eAxisPosition]$YAxisPosition,
[Switch]$PassThru
)
try {
if ($PivotTable) {
$Worksheet = $PivotTable.WorkSheet
$chart = $Worksheet.Drawings.AddChart(("Chart" + $PivotTable.Name ),$ChartType,$PivotTable)
}
else {
$ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', ''
$chart = $Worksheet.Drawings.AddChart($ChartName, $ChartType)
$chartDefCount = @($YRange).Count
if ($chartDefCount -eq 1) {
$Series = $chart.Series.Add($YRange, $XRange)
if ($SeriesHeader) { $Series.Header = $SeriesHeader}
else { $Series.Header = 'Series 1'}
}
else {
for ($idx = 0; $idx -lt $chartDefCount; $idx += 1) {
if ($Yrange.count -eq $xrange.count) {
$Series = $chart.Series.Add($YRange[$idx], $XRange[$idx])
}
else {
$Series = $chart.Series.Add($YRange[$idx], $XRange)
}
if ($SeriesHeader.Count -gt 0) {
if ($SeriesHeader[$idx] -match '^=') {$Series.HeaderAddress = $SeriesHeader[$idx] -replace '^=',''}
else {$Series.Header = $SeriesHeader[$idx] }
}
else { $Series.Header = "Series $($idx)"}
}
}
}
if ($Title) {
$chart.Title.Text = $Title
if ($TitleBold) {$chart.Title.Font.Bold = $true}
if ($TitleSize) {$chart.Title.Font.Size = $TitleSize}
}
if ($NoLegend) { $chart.Legend.Remove() }
else {
if ($PSBoundParameters.ContainsKey('LegendPosition')) {$chart.Legend.Position = $LegendPosition}
if ($PSBoundParameters.ContainsKey('LegendBold')) {$chart.Legend.Font.Bold = [boolean]$LegendBold}
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
}
if ($XAxisTitleText) {
$chart.XAxis.Title.Text = $XAxisTitleText
if ($PSBoundParameters.ContainsKey('XAxisTitleBold')) {
$chart.XAxis.Title.Font.Bold = [boolean]$XAxisTitleBold
}
if ($XAxisTitleSize) {$chart.XAxis.Title.Font.Size = $XAxisTitleSize}
}
if ($XAxisPosition) {Write-Warning "X-axis position is not being set propertly at the moment, parameter ignored" }
#$chart.ChartXml.chartSpace.chart.plotArea.catAx.axPos.val = $XAxisPosition.ToString().substring(0,1)}
if ($XMajorUnit) {$chart.XAxis.MajorUnit = $XMajorUnit}
if ($XMinorUnit) {$chart.XAxis.MinorUnit = $XMinorUnit}
if ($null -ne $XMinValue) {$chart.XAxis.MinValue = $XMinValue}
if ($null -ne $XMaxValue) {$chart.XAxis.MaxValue = $XMaxValue}
if ($XAxisNumberformat) {$chart.XAxis.Format = (Expand-NumberFormat $XAxisNumberformat)}
if ($YAxisTitleText) {
$chart.YAxis.Title.Text = $YAxisTitleText
if ($PSBoundParameters.ContainsKey('YAxisTitleBold')) {
$chart.YAxis.Title.Font.Bold = [boolean]$YAxisTitleBold
}
if ($YAxisTitleSize) {$chart.YAxis.Title.Font.Size = $YAxisTitleSize}
}
if ($YAxisPosition) {Write-Warning "Y-axis position is not being set propertly at the moment, parameter ignored" }
#$chart.ChartXml.chartSpace.chart.plotArea.valAx.axPos.val= $YAxisPosition.ToString().substring(0,1)}
if ($YMajorUnit) {$chart.YAxis.MajorUnit = $YMajorUnit}
if ($YMinorUnit) {$chart.YAxis.MinorUnit = $YMinorUnit}
if ($null -ne $YMinValue){$chart.YAxis.MinValue = $YMinValue}
if ($null -ne $YMaxValue){$chart.YAxis.MaxValue = $YMaxValue}
if ($YAxisNumberformat) {$chart.YAxis.Format = (Expand-NumberFormat $YAxisNumberformat)}
if ($null -ne $chart.Datalabel) {
$chart.Datalabel.ShowCategory = [boolean]$ShowCategory
$chart.Datalabel.ShowPercent = [boolean]$ShowPercent
}
$chart.SetPosition($Row, $RowOffsetPixels, $Column, $ColumnOffsetPixels)
$chart.SetSize($Width, $Height)
if ($PassThru) {return $chart}
}
catch {Write-Warning -Message "Failed adding Chart to worksheet '$($WorkSheet).name': $_"}
}

View File

@@ -1,3 +1,5 @@
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function', Target='New*', Justification='Does not change system State')]
param()
function New-PSItem {
$totalArgs = $args.Count

Some files were not shown because too many files have changed in this diff Show More