From 3ff59907ff3a734a8287715ae99b54fd72e6cb16 Mon Sep 17 00:00:00 2001 From: jhoneill Date: Tue, 11 Sep 2018 14:05:23 +0100 Subject: [PATCH] Improvements to help --- Examples/PivotTable/TableAndPivotTable.ps1 | 14 ++++----- Export-Excel.ps1 | 9 +++--- New-ConditionalFormattingIconSet.ps1 | 2 +- New-ConditionalText.ps1 | 10 ++----- New-ExcelChart.ps1 | 34 ++++++++++++++++++++++ Open-ExcelPackage.ps1 | 11 +++++-- Set-Column.ps1 | 18 +++++++----- Set-Row.ps1 | 31 +++++++++++++++++--- SetFormat.ps1 | 11 +++++-- ToDo.md | 4 +-- __tests__/ExtraLongCmd.tests.ps1 | 1 + 11 files changed, 108 insertions(+), 37 deletions(-) diff --git a/Examples/PivotTable/TableAndPivotTable.ps1 b/Examples/PivotTable/TableAndPivotTable.ps1 index 0d5c0dc..97f6e0f 100644 --- a/Examples/PivotTable/TableAndPivotTable.ps1 +++ b/Examples/PivotTable/TableAndPivotTable.ps1 @@ -1,8 +1,7 @@ $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 - +#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 @@ -11,12 +10,13 @@ Banana, London , 300, 200 Orange, Paris, 600, 500 Banana, Paris, 300, 200 Apple, New York, 1200,700 -"@ | Export-Excel -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"} -PassThru +"@ | Export-Excel -PassThru -Path $path -TableStyle Medium13 -tablename "RawData" -ConditionalFormat @{Range="C2:C7"; DataBarColor="Green"} -#Add a pivot table on the same sheet, using this data. set the table style and number format. Use the "City" as row names, and "Product" for columnnames, and total both the gross and net columns -#Add a pivot chart (defined in a hash table) -Add-PivotTable -Address $excel.Sheet1.Cells["F1"] -SourceWorkSheet $Excel.Sheet1 -SourceRange $Excel.Sheet1.Dimension.Address -PivotTableName "Sales" -PivotTableSyle "Medium12" -Activate ` - -PivotRows "City" -PivotColumns "Product" -PivotData @{Gross="Sum";Net="Sum"} -PivotNumberFormat "$#,##0.00" -PivotTotals "Both" -PivotChartDefinition @{ +#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" -PivotTableSyle "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; diff --git a/Export-Excel.ps1 b/Export-Excel.ps1 index a768737..13470be 100644 --- a/Export-Excel.ps1 +++ b/Export-Excel.ps1 @@ -1211,7 +1211,7 @@ Function Add-ExcelName { It is often helpful to be able to refer to sets of cells with a name rather than using their co-ordinates; Add-ExcelName sets up these names. .EXAMPLE Add-ExcelName -Range $ws.Cells[$dataRange] -RangeName $rangeName - $WS is a worksheet, and $dataRange holds a range of cells - e.g. "A1:Z10" + $WS is a worksheet, and $dataRange is a string describing a range of cells - e.g. "A1:Z10" which will become a named range, using the name in $rangeName. #> [CmdletBinding()] @@ -1252,9 +1252,10 @@ function Add-ExcelTable { Unlike named ranges, where the name only needs to be unique within a sheet, Table names must be unique in the workbook Tables carry formatting by default have a filter. The filter, header, Totals, first and last column highlights .EXAMPLE - Add-ExcelName -Range $ws.Cells[$dataRange] -RangeName $rangeName - $WS is a worksheet, and $dataRange holds a range of cells - e.g. "A1:Z10" - which will become a named range, using the name in $rangeName. + Add-ExcelTable -Range $ws.Cells[$dataRange] -TableName $TableName + + $WS is a worksheet, and $dataRange is a string describing a range of cells - e.g. "A1:Z10" + this range which will become a table, named $TableName .EXAMPLE Add-ExcelTable -Range $ws.cells[$($ws.Dimension.address)] -TableStyle Light1 -TableName Musictable -ShowFilter:$false -ShowTotal -ShowFirstColumn Again $ws is a worksheet, range here is the whole of the active part of the worksheet. The table style and name are set, diff --git a/New-ConditionalFormattingIconSet.ps1 b/New-ConditionalFormattingIconSet.ps1 index 842bc45..4d903a1 100644 --- a/New-ConditionalFormattingIconSet.ps1 +++ b/New-ConditionalFormattingIconSet.ps1 @@ -14,7 +14,7 @@ function New-ConditionalFormattingIconSet { .PARAMETER Reverse Use the icons in the reverse order. .Example - $cfRange = [OfficeOpenXml.ExcelAddress]::new($topRow,$column,$lastDataRow,$column) + $cfRange = [OfficeOpenXml.ExcelAddress]::new($topRow, $column, $lastDataRow, $column) $cfdef = New-ConditionalFormattingIconSet -Range $cfrange -ConditionalFormat ThreeIconSet -IconType Arrows Export-Excel -ExcelPackage $excel -ConditionalFormat $cfdef -show diff --git a/New-ConditionalText.ps1 b/New-ConditionalText.ps1 index d97aae2..cdd4810 100644 --- a/New-ConditionalText.ps1 +++ b/New-ConditionalText.ps1 @@ -25,17 +25,11 @@ function New-ConditionalText { 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 third uses Export-Excel with an open package to apply the format and save and open the file. + and the secind uses Export-Excel with an open package to apply the format and save and open the file. .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 third 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 -ConditionalTest $ct,$c2 -show + Export-Excel -ExcelPackage $excel -ConditionalText $ct,$ct2 -show This builds on the previous example, and specifies a condition of <=3 with a format of Red text on a white background; this applies to a named range "Finish Position" the range could be written "C:C" to specify a named column, or "C2:C102" to specify certain cells in the column. diff --git a/New-ExcelChart.ps1 b/New-ExcelChart.ps1 index 605ace3..0691784 100644 --- a/New-ExcelChart.ps1 +++ b/New-ExcelChart.ps1 @@ -264,12 +264,46 @@ function Add-ExcelChart { Postion 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 + $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 explitly specified. Note the at 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 table. + The width of the chart is set explictly, the default legend is used and there is no Chart title. + .EXAMPLE + $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 + $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 $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 -LegendPostion 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 ranges for the two columns - "X" and "SinX" respectively diff --git a/Open-ExcelPackage.ps1 b/Open-ExcelPackage.ps1 index 8e1931f..4a5dc72 100644 --- a/Open-ExcelPackage.ps1 +++ b/Open-ExcelPackage.ps1 @@ -8,12 +8,19 @@ It takes a KillExcel switch to make sure Excel is not holding the file open; a password parameter for existing protected files, and a create switch to set-up a new file if no file already exists. .Example - $excel = Open-ExcelPackage -path $xlPath + $excel = Open-ExcelPackage -Path "$env:TEMP\test99.xlsx" -Create + $ws = Add-WorkSheet -ExcelPackage $excel + + This will create a new file in the temp folder if it doesn't already exist. It then adds a worksheet - + because no name is specified it will use the default name of "Sheet1" +.Example + $excel = Open-ExcelPackage -path "$xlPath" -Password $password $sheet1 = $excel.Workbook.Worksheets["sheet1"] Set-ExcelRange -Range $sheet1.Cells["E1:S1048576"], $sheet1.Cells["V1:V1048576"] -NFormat ([cultureinfo]::CurrentCulture.DateTimeFormat.ShortDatePattern) Close-ExcelPackage $excel -Show - This will open the file at $xlPath, select sheet1 apply formatting to two blocks of the sheet and save the package, and launch it in Excel. + This will open the password protected file at $xlPath using the password stored in $Password. + Sheet1 is selected and formatting applied to two blocks of the sheet; then the file is and saved and loaded into Excel. #> [CmdLetBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")] diff --git a/Set-Column.ps1 b/Set-Column.ps1 index 56eb56b..b508433 100644 --- a/Set-Column.ps1 +++ b/Set-Column.ps1 @@ -3,24 +3,28 @@ .SYNOPSIS Adds a column to the existing data area in an Excel sheet, fills values and sets formatting .DESCRIPTION - Set-ExcelColumn takes a value which is either string containing a value or formula or a scriptblock + Set-ExcelColumn takes a value which is either a string containing a value or formula or a scriptblock which evaluates to a string, and optionally a column number and fills that value down the column. - A column name can be specified and the new column can be made a named range. - The column can be formatted. + A column heading can be specified and the new column can be made a named range. + The column can be formatted in the same operation. .EXAMPLE C:\> Set-ExcelColumn -Worksheet $ws -Column 5 -NumberFormat 'Currency' + $ws contains a worksheet object - and column E is set to use the local currecy format. - Intelisense will complete predefined number formats. Expand-NumberFormat currency will show you how currency is interpreted on the local computer. + Intelisense will complete predefined number formats. You can see how currency is interpreted on the local computer with the command + Expand-NumberFormat currency .EXAMPLE C:\> Set-ExcelColumn -Worksheet $ws -Heading "WinsToFastLaps" -Value {"=E$row/C$row"} -Column 7 -AutoSize -AutoNameRange + Here $WS already contains a worksheet which contains counts of races won and fastest laps recorded by racing drivers (in columns C and E) - Set-ExcelColumn specifies that Column 7 should have a heading of "WinsToFastLaps" and the data cells should contain =E2/C2 , =E3/C3 + Set-ExcelColumn specifies that Column 7 should have a heading of "WinsToFastLaps" and the data cells should contain =E2/C2 , =E3/C3 etc the data cells should become a named range, which will also be "WinsToFastLaps" the column width will be set automatically .EXAMPLE C:\> Set-ExcelColumn -Worksheet $ws -Heading "Link" -Value {"https://en.wikipedia.org" + $worksheet.cells["B$Row"].value } -AutoSize + In this example, the worksheet in $ws has partial links to wikipedia pages in column B. - Value is is a script block and it outputs a string which begins https... and ends with the value of cell at column B in the current row. - When given a valid URI Set-ExcelColumn makes it a hyperlink The column will be autosized to fit the links. + The Value parameter is is a script block and it outputs a string which begins https... and ends with the value of cell at column B in the current row. + When given a valid URI, Set-ExcelColumn makes it a hyperlink. The column will be autosized to fit the links. #> [cmdletbinding()] [Alias(" Set-Column")] diff --git a/Set-Row.ps1 b/Set-Row.ps1 index 827da00..b290dcf 100644 --- a/Set-Row.ps1 +++ b/Set-Row.ps1 @@ -6,7 +6,7 @@ Set-ExcelRow accepts either a Worksheet object or an Excel package object returned by Export-Excel and the name of a sheet, and inserts the chosen contents into a row of the sheet. The contents can be a constant "42" , a formula or a script block which is converted into a constant or formula. - The first cell of the row can optional be given a heading. + The first cell of the row can optionally be given a heading. .Example Set-ExcelRow -Worksheet $ws -Heading Total -Value {"=sum($columnName`2:$columnName$endrow)" } @@ -15,6 +15,12 @@ =Sum(xx2:xx99) - where xx is the column name, and 99 is the last row of data. Note the use of `2 to Prevent 2 becoming part of the variable "ColumnName" The script block can use $row, $column, $ColumnName, $startRow/Column $endRow/Column + .Example + Set-ExcelRow -Worksheet $ws -Heading Total -HeadingBold -Value {"=sum($columnName`2:$columnName$endrow)" } -NumberFormat 'Currency' -StartColumn 2 -Bold -BorderTop Double -BorderBottom Thin + + This builds on the previous example, but this time the label "Total" appears in column 2 and the formula fills from column 3 onwards; + the formula and heading are set in bold face, and the formula is formatted for the local currency, + and given a double line border above and single line border below. #> [cmdletbinding()] [Alias(" Set-Row")] @@ -37,11 +43,25 @@ $Value, #Optional Row heading $Heading , + #Set the heading in bold type + [Switch]$HeadingBold, + #Change the size of the heading type + [Int]$HeadingSize , #Number format to apply to cells e.g. "dd/MM/yyyy HH:mm", "£#,##0.00;[Red]-£#,##0.00", "0.00%" , "##/##" , "0.0E+0" etc [Alias("NFormat")] $NumberFormat, #Style of border to draw around the row [OfficeOpenXml.Style.ExcelBorderStyle]$BorderAround, + #Color of the border + [System.Drawing.Color]$BorderColor=[System.Drawing.Color]::Black, + #Style for the bottom border + [OfficeOpenXml.Style.ExcelBorderStyle]$BorderBottom, + #Style for the top border + [OfficeOpenXml.Style.ExcelBorderStyle]$BorderTop, + #Style for the left border + [OfficeOpenXml.Style.ExcelBorderStyle]$BorderLeft, + #Style for the right border + [OfficeOpenXml.Style.ExcelBorderStyle]$BorderRight, #Colour for the text - if none specified it will be left as it it is [System.Drawing.Color]$FontColor, #Make text bold; use -Bold:$false to remove bold @@ -99,8 +119,10 @@ Write-Verbose -Message "Updating Row $Row" #Add a row label if ($Heading) { - $Worksheet.Cells[$Row, $StartColumn].Value = $Heading - $StartColumn ++ + $Worksheet.Cells[$Row, $StartColumn].Value = $Heading + if ($HeadingBold) {$Worksheet.Cells[$Row, $StartColumn].Style.Font.Bold = $true} + if ($HeadingSize) {$Worksheet.Cells[$Row, $StartColumn].Style.Font.Size = $HeadingSize} + $StartColumn ++ } #Fill in the data if ($PSBoundParameters.ContainsKey('Value')) {foreach ($column in ($StartColumn..$endColumn)) { @@ -133,7 +155,8 @@ $params = @{} foreach ($p in @('Underline','Bold','Italic','StrikeThru','FontSize', 'FontShift','NumberFormat','TextRotation', 'WrapText', 'HorizontalAlignment','VerticalAlignment', 'Height', 'FontColor' - 'BorderAround', 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) { + 'BorderAround', 'BorderBottom', 'BorderTop', 'BorderLeft', 'BorderRight', 'BorderColor', + 'BackgroundColor', 'BackgroundPattern', 'PatternColor')) { if ($PSBoundParameters.ContainsKey($p)) {$params[$p] = $PSBoundParameters[$p]} } $theRange = [OfficeOpenXml.ExcelAddress]::New($Row, $StartColumn, $Row, $endColumn) diff --git a/SetFormat.ps1 b/SetFormat.ps1 index b538a87..cc65b56 100644 --- a/SetFormat.ps1 +++ b/SetFormat.ps1 @@ -9,11 +9,18 @@ It has been extended to set Values, Formulas and set ArrayFormulas (sometimes called Ctrl-shift-Enter [CSE] formulas); because of this the name has become Set-ExcelRange - but the old name of Set-Format is preserved as an alias name may swapped. .EXAMPLE - $sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NumberFormat "#,###" - Selects column 3 from a sheet object (within a workbook object, which is a child of the ExcelPackage object) and passes it to Set-ExcelRange which formats as an integer with comma seperated groups + $sheet.Column(3) | Set-ExcelRange -HorizontalAlignment Right -NumberFormat "#,###" -AutoFit + + Selects column 3 from a sheet object (within a workbook object, which is a child of the ExcelPackage object) and passes it to Set-ExcelRange + which formats as an integer with comma seperated groups, aligns it right, and auto-fits the column to the contents. .EXAMPLE Set-ExcelRange -Range $sheet.Cells["E1:H1048576"] -HorizontalAlignment Right -NumberFormat "#,###" + Instead of piping the address in this version specifies a block of cells and applies similar formatting + .EXAMPLE + Set-ExcelRange $excel.Workbook.Worksheets[1].Tables["Processes"] -Italic + + This time instead of specifying a range of cells, a table is selected by name and formatted as italic. #> [cmdletbinding()] [Alias("Set-Format")] diff --git a/ToDo.md b/ToDo.md index 01f877b..128fe40 100644 --- a/ToDo.md +++ b/ToDo.md @@ -1,4 +1,4 @@ -- [ ] Add Examples and tests for new "Quick charts" in Export Excel (replace examples) that use Charting.ps1, GetXYRange.ps1, InferData.PS1 (move these to deprecated). - [ ] Investigate regional support for number conversion & possible date conversion. Also investigate feasablity of preserving number format when converting string to number - [ ] Add help to ConvertToExcelXLSx.ps1, Get-HTMLTable.ps1, GetRange.PS1, GetExcelTable.Ps1, Import-HTML.PS1, New-Psitem.PS1 and Remove-Worksheet.ps1 -- [ ] Increase Test code-covereage for import-excel \ No newline at end of file +- [ ] Add Examples and tests for new "Quick charts" in Export Excel (is it possible to replace examples that use Charting.ps1, GetXYRange.ps1, InferData.PS1 ? ). +- [ ] Increase Test code-covereage for import-excel diff --git a/__tests__/ExtraLongCmd.tests.ps1 b/__tests__/ExtraLongCmd.tests.ps1 index 73b68f3..9edb3c2 100644 --- a/__tests__/ExtraLongCmd.tests.ps1 +++ b/__tests__/ExtraLongCmd.tests.ps1 @@ -1,4 +1,5 @@ + $path = "$Env:TEMP\test.xlsx" remove-item -path $path -ErrorAction SilentlyContinue ConvertFrom-Csv @"