Improved tests for conversions, added quick chart support, and extended Send-SQLData

This commit is contained in:
jhoneill
2018-07-12 10:49:29 +01:00
parent de72cfe8cd
commit 90942e4084
6 changed files with 430 additions and 149 deletions

View File

@@ -16,14 +16,14 @@
If specified data will be added to the end of an existing sheet, using the same column headings.
.PARAMETER TargetData
Data to insert onto the worksheet - this is often provided from the pipeline.
.PARAMETER DisplayPropertySet
Many (but not all) objects have a hidden property named psStandardmembers with a child property DefaultDisplayPropertySet ; this parameter reduces the properties exported to those in this set.
.PARAMETER NoAliasOrScriptPropeties
Some objects duplicate existing properties by adding aliases, or have Script properties which take a long time to return a value and slow the export down, if specified this removes these properties
.PARAMETER ExcludeProperty
Specifies properties which may exist in the target data but should not be placed on the worksheet.
.PARAMETER NoAliasOrScriptPropeties
Some objects duplicate properties with aliases, or have Script properties which take a long time to return a value and slow the export down, if specified this removes these properties
.PARAMETER DisplayPropertySet,
Many (but not all) objects have a hidden property named psStandardmembers with a child property DefaultDisplayPropertySet ; this parameter reduces the properties exported to those in this set.
.PARAMETER Title
Text of a title to be placed in Cell A1.
Text of a title to be placed in the top left cell.
.PARAMETER TitleBold
Sets the title in boldface type.
.PARAMETER TitleSize
@@ -36,22 +36,33 @@
Sets password protection on the workbook.
.PARAMETER IncludePivotTable
Adds a Pivot table using the data in the worksheet.
.PARAMETER PivotTableName
If a Pivot table is created from command line parameters, specificies the name of the new sheet holding the pivot. If Omitted this will be "WorksheetName-PivotTable"
.PARAMETER PivotRows
Name(s) columns from the spreadhseet which will provide the row name(s) in the pivot table.
Name(s) columns from the spreadhseet which will provide the Row name(s) in a pivot table created from command line parameters.
.PARAMETER PivotColumns
Name(s) columns from the spreadhseet which will provide the Column name(s) in the pivot table.
Name(s) columns from the spreadhseet which will provide the Column name(s) in a pivot table created from command line parameters.
.PARAMETER PivotFilter
Name(s) columns from the spreadhseet which will provide the Filter name(s) in a pivot table created from command line parameters.
.PARAMETER PivotData
Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP to provide the data in the Pivot table.
.PARAMETER PivotTableDefinition,
HashTable(s) with Sheet PivotTows, PivotColumns, PivotData, IncludePivotChart and ChartType values to make it easier to specify a definition or multiple Pivots.
.PARAMETER IncludePivotChart,
Include a chart with the Pivot table - implies Include Pivot Table.
In a pivot table created from command line parameters, the fields to use in the table body is given as a Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP .
.PARAMETER NoTotalsInPivot
In a pivot table created from command line parameters, prevents the addition of totals to rows and columns.
.PARAMETER PivotTableDefinition
Instead of describing a single pivot table with mutliple commandline paramters; you can use a HashTable in the form PivotTableName = Definition;
Definition is itself a hashtable with Sheet PivotTows, PivotColumns, PivotData, IncludePivotChart and ChartType values.
.PARAMETER IncludePivotChart
Include a chart with the Pivot table - implies -IncludePivotTable.
.PARAMETER ChartType
The type for Pivot chart (one of Excel's defined chart types)
.PARAMETER NoLegend
Exclude the legend from the pivot chart.
.PARAMETER ShowCategory
Add category labels to the pivot chart.
.PARAMETER ShowPercent
Add Percentage labels to the pivot chart.
.PARAMETER ConditionalFormat
One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
.PARAMETER ConditionalText
Applies a 'Conditional formatting rule' in Excel on all the cells. When specific conditions are met a rule is triggered.
.PARAMETER NoNumberConversion
@@ -66,6 +77,14 @@
Makes the data in the worksheet a table with a name applies a style to it. Name must not contain spaces.
.PARAMETER TableStyle
Selects the style for the named table - defaults to 'Medium6'.
.PARAMETER BarChart
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
.PARAMETER ColumnChart
Creates a "quick" column chart using the first text column as labels and the first numeric column as values
.PARAMETER LineChart
Creates a "quick" line chart using the first text column as labels and the first numeric column as values
.PARAMETER PieChart
Creates a "quick" pie chart using the first text column as labels and the first numeric column as values
.PARAMETER ExcelChartDefinition
A hash table containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
.PARAMETER HideSheet
@@ -99,7 +118,7 @@
.PARAMETER FreezePane
Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
.PARAMETER AutoFilter
Enables the 'Filter' in Excel on the complete header row. So users can easily sort, filter and/or search the data in the select column from within Excel.
Enables the 'Filter' in Excel on the complete header row. So users can easily sort, filter and/or search the data in the selected column from within Excel.
.PARAMETER AutoSize
Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
.PARAMETER Now
@@ -132,8 +151,12 @@
# Blue color for positive numbers and a red color for negative numbers. All numbers will be proceeded by a dollar sign '$'.
'[Blue]$#,##0.00;[Red]-$#,##0.00'
.PARAMETER ReZip
If specified, Export-Excel will expand the contents of the .XLSX file (which is multiple files in a zip archive) and rebuilt it.
.PARAMETER Show
Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
.PARAMETER ReturnRange
If specified, Export-Excel returns the range of added cells in the format "A1:Z100"
.PARAMETER PassThru
If specified, Export-Excel returns an object representing the Excel package without saving the package first. To save it you need to call the save or Saveas method or send it back to Export-Excel.
@@ -396,6 +419,10 @@
[Parameter(ParameterSetName = 'Table')]
[Parameter(ParameterSetName = 'PackageTable')]
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
[Switch]$Barchart,
[Switch]$PieChart,
[Switch]$LineChart ,
[Switch]$ColumnChart ,
[Object[]]$ExcelChartDefinition,
[String[]]$HideSheet,
[Switch]$MoveToStart,
@@ -438,8 +465,8 @@
#>
Param (
[Object]$TargetCell,
[Object]$CellValue
$TargetCell,
$CellValue
)
#The write-verbose commands have been commented out below - even if verbose is silenced they cause a significiant performance impact and if it's on they will cause a flood of messages.
Switch ($CellValue) {
@@ -824,6 +851,30 @@
Add-ExcelChart -Worksheet $ws @params
}
if ($Barchart -or $PieChart -or $LineChart -or $ColumnChart) {
if ($NoHeader) {$FirstDataRow = $startRow}
else {$FirstDataRow = $startRow + 1 }
$range = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$startColumn]:R[$FirstDataRow]C[$lastCol]",0,0)
$xCol = $ws.cells[$range] | Where-Object {$_.value -is [string] } | ForEach-Object {$_.start.column} | Sort-Object | Select-Object -first 1
$yCol = $ws.cells[$range] | Where-Object {$_.value -is [valueType] } | ForEach-Object {$_.start.column} | Sort-Object | Select-Object -first 1
$params = @{
xrange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$xcol]:R[$($lastrow)]C[$xcol]",0,0) ;
yrange = [OfficeOpenXml.ExcelAddress]::TranslateFromR1C1("R[$FirstDataRow]C[$ycol]:R[$($lastrow)]C[$ycol]",0,0) ;
title = "";
Column = ($lastCol +1) ;
Width = 1200
}
if ($NoHeader) {$params["NoHeader"] = $true}
else {$Params["SeriesHeader"] = $ws.Cells[$startRow, $YCol].Value}
if ($ColumnChart) {$Params["chartType"] = "ColumnStacked" }
elseif ($Barchart) {$Params["chartType"] = "BarStacked" }
elseif ($PieChart) {$Params["chartType"] = "PieExploded3D" }
elseif ($LineChart) {$Params["chartType"] = "Line" }
Add-ExcelChart -Worksheet $ws @params
}
foreach ($ct in $ConditionalText) {
try {
$cfParams = @{RuleType = $ct.ConditionalType; ConditionValue = $ct.text ;
@@ -872,7 +923,7 @@
}
try {
$TempZipPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
[io.compression.zipfile]::ExtractToDirectory($pkg.File, $TempZipPath) | Out-Null
[io.compression.zipfile]::ExtractToDirectory($pkg.File, $TempZipPath) | Out-Null
Remove-Item $pkg.File -Force
[io.compression.zipfile]::CreateFromDirectory($TempZipPath, $pkg.File) | Out-Null
}
@@ -890,7 +941,7 @@
function New-PivotTableDefinition {
<#
.Synopsis
Creates Pivot table definitons for export excel
Creates Pivot table definitons for Export-Excel
.Description
Export-Excel allows a single Pivot table to be defined using the parameters -IncludePivotTable, -PivotColumns -PivotRows,
=PivotData, -PivotFilter, -NoTotalsInPivot, -PivotDataToColumn, -IncludePivotChart and -ChartType.
@@ -961,6 +1012,13 @@ function New-PivotTableDefinition {
@{$PivotTableName = $parameters}
}
function Add-WorkSheet {
<#
.Synopsis
Adds a workshet to an existing workbook.
.Description
If the named worksheet already exists, the -clearsheet parameter decides whether it should be deleted and a new one returned,
or if not specified the existing sheet will be returned.
#>
[cmdletBinding()]
[OutputType([OfficeOpenXml.ExcelWorksheet])]
param(
@@ -1038,15 +1096,21 @@ function Add-WorkSheet {
return $ws
}
function Add-PivotTable {
<#
.Synopsis
Adds a Pivot table (and optional pivot chart) to a workbook
.Description
If the pivot table already exists, the source data will be updated.
#>
param (
# Parameter help description
#Name for the new Pivot table - this will be the name of a sheet in the workbook
[Parameter(Mandatory = $true)]
$PivotTableName,
#An excel package object for the workbook.
$ExcelPackage,
#Worksheet where the data is found
$SourceWorkSheet,
#Address range in the worksheet e.g "A10:F20" - the first row must be column names: if not specified the whole sheet will be used/
#Address range in the worksheet e.g "A10:F20" - the first row must be column names: if not specified the whole sheet will be used.
$SourceRange,
#Fields to set as rows in the Pivot table
$PivotRows,
@@ -1162,11 +1226,17 @@ function Add-PivotTable {
}
}
function Add-ExcelChart {
<#
.Synopsis
Creates a chart in an Existing excel worksheet
#>
[cmdletbinding()]
param(
#An object representing the worksheet where the chart should be added.
[OfficeOpenXml.ExcelWorksheet]$Worksheet,
[String]$Title = "Chart Title",
#$Header, Not used but referenced previously
#The Type of chart (Area, Line, Pie etc)
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = "ColumnStacked",
$XRange,
$YRange,
@@ -1206,12 +1276,13 @@ function Add-ExcelChart {
try {
$ChartName = 'Chart' + (Split-Path -Leaf ([System.IO.path]::GetTempFileName())) -replace 'tmp|\.', ''
$chart = $Worksheet.Drawings.AddChart($ChartName, $ChartType)
$chart.Title.Text = $Title
if ($TitleBold) {$chart.Title.Font.Bold = $true}
if ($TitleSize) {$chart.Title.Font.Size = $TitleSize}
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 {
else {
if ($LegendPostion) {$Chart.Legend.Position = $LegendPostion}
if ($LegendSize) {$chart.Legend.Font.Size = $LegendSize}
if ($legendBold) {$chart.Legend.Font.Bold = $true}

View File

@@ -13,12 +13,35 @@ function New-ExcelChartDefinition {
$RowOffSetPixels = 10,
$Column = 6,
$ColumnOffSetPixels = 5,
$LegendSize,
[Switch]$legendBold,
[Switch]$NoLegend,
[Switch]$ShowCategory,
[Switch]$ShowPercent,
$SeriesHeader
$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
)
if ( $Header ) {Write-Warning "The header parameter is ignored."} #Nothing was done with it when creating a chart.
#might be able to do [PSCustomObject]$PsboundParameters, the defaults here match those in Add-Excel Chart
[PSCustomObject]@{
Title = $Title
ChartType = $ChartType
@@ -30,9 +53,29 @@ function New-ExcelChartDefinition {
RowOffSetPixels = $RowOffSetPixels
Column = $Column
ColumnOffSetPixels = $ColumnOffSetPixels
NoLegend = $NoLegend -as [Boolean]
ShowCategory = $ShowCategory-as [Boolean]
ShowPercent = $ShowPercent -as [Boolean]
NoLegend = $NoLegend -as [Boolean]
ShowCategory = $ShowCategory -as [Boolean]
ShowPercent = $ShowPercent -as [Boolean]
TitleBold = $TitleBold -as [Boolean]
TitleSize = $TitleSize
SeriesHeader = $SeriesHeader
XAxisTitleText = $XAxisTitleText
XAxisTitleBold = $XAxisTitleBold -as [Boolean]
XAxisTitleSize = $XAxisTitleSize
XAxisNumberformat = $XAxisNumberformat
XMajorUnit = $XMajorUnit
XMinorUnit = $XMinorUnit
XMaxValue = $XMaxValue
XMinValue = $XMinValue
XAxisPosition = $XAxisPosition
YAxisTitleText = $YAxisTitleText
YAxisTitleBold = $YAxisTitleBold -as [Boolean]
YAxisTitleSize = $YAxisTitleSize
YAxisNumberformat = $YAxisNumberformat
YMajorUnit = $YMajorUnit
YMinorUnit = $YMinorUnit
YMaxValue = $YMaxValue
YMinValue = $YMinValue
YAxisPosition = $YAxisPosition
}
}

View File

@@ -31,18 +31,21 @@ To install to your personal modules folder (e.g. ~\Documents\WindowsPowerShell\M
iex (new-object System.Net.WebClient).DownloadString('https://raw.github.com/dfinke/ImportExcel/master/Install.ps1')
```
# What's new to 7th July 18
# What's new to 11th July 18
- Moved chart creatation into its own function (Add-Excel chart) within Export-Excel.ps1. Renamed New-Excelchart to New-ExcelChartDefinition to make it clearer that it is not making anything in the workbook (but for compatiblity put an alias of New-ExcelChart in so existing code does not break). Found that -Header does nothing, so it isn't Add-Excel chart and there is a message that does nothing in New-ExcelChartDefinition .
- Added paramters for managing Axes and legend (these are currently in Add-ExcelChart but not new-ExcelChartDefinition)
- Fixed a bug introduced into Compare-Worksheet by the change descibed in the June changes below, this meant the font color was only being set in one sheet, when a row was changed. Also found that the PowerShell ISE and shell return Compare-Object resuls in different sequences which broke some tests. Applied a sort to ensure things are in a predictable order. (#375)
- Added -BarChart -ColumnChart -LineChart -PieChart parameters to Export-Excel for quick charts without giving a full chart definition.
- Added parameters for managing chart Axes and legend
- Added some chart tests to Export-Excel.tests.ps1. (but tests & examples for quick charts , axes or legends still on the to do list )
- Fixed some bad code which had been checked-in in-error and caused adding charts to break. (This was not seen outside Github #377)
- Added chart tests to Export-Excel.tests.ps1.
- Fixed a bug introduced into Compare-Worksheet by the change descibed in the June changes below, this meant the font color was only being set in one sheet, when a row was changed. Also found that the PowerShell ISE and shell return Compare-Object resuls in different sequences which broke some tests. Applied a sort to ensure things are in a predictable order. (#375)
- Removed (2) calls to Get-ExcelColumnName
- Fixed an issue in Export-Excel where formulas were inserted as strings if "NoNumberConversion" is applied (#374), and made sure formatting is applied to formula cells
- Fixed an issue with parameter sets in Export-Excel not being determined correctly in some case (I think this has been resolved before and might have regressed)
- Reverted the [double]::tryParse in export excel to the previous way, as the shorter way was not behaving correctly with with the number formats in certain regions. (also #374)
- Fixed an issue with parameter sets in Export-Excel not being determined correctly in some cases (I think this had been resolved before and might have regressed)
- Reverted the [double]::tryParse in export excel to the previous (longer) way, as the shorter way was not behaving correctly with with the number formats in certain regions. (also #374)
- Changed Table, Range and AutoRangeNames to apply to whole data area if no data has been inserted OR to inserted data only if it has.(#376) This means that if there are multiple inserts only inserted data is touched, rather than going as far down and/or right as the furthest used cell. Added a test for this.
- Added more of the Parameters from Export-Excel to Join-worksheet, join just calls export with these parameters so there is no code behind them (#383)
- Added more of the Parameters from Export-Excel to Join-worksheet, join just calls export-excel with these parameters so there is no code behind them (#383)
- Added more of the Parameters from Export-Excel to Send-SQLDataToExcel, send just calls export-excel with these parameters...
- Added support for passing a System.Data.DataTable directly to Send-SQLDataToExcel
# New in June 18
- New commands - Diff , Merge and Join

View File

@@ -1,55 +1,174 @@
Function Send-SQLDataToExcel {
[CmdLetBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
<#
.Synopsis
Runs a SQL query and inserts the results into an ExcelSheet, more efficiently than sending it via Export-Excel
.Description
This command takes either an object representing a session with a SQL server or ODBC database, or a connection String to make one.
It the runs a SQL command, and inserts the rows of data returned into a worksheet.
It takes most of the parameters of Export-Excel, but it is more efficient than getting dataRows and piping them into Export-Excel,
data-rows have additional properties which need to be stripped off.
.Example
C:\> Send-SQLDataToExcel -MsSQLserver -Connection localhost -SQL "select name,type,type_desc from [master].[sys].[all_objects]" -Path .\temp.xlsx -WorkSheetname master -AutoSize -FreezeTopRow -AutoFilter -BoldTopRow
Connects to the local SQL server and selects 3 columns from [Sys].[all_objects] and exports then to a sheet named master with some basic header manager
.Example
<#
.SYNOPSIS
Inserts a DataTable - returned by SQL query into an ExcelSheet, more efficiently than sending it via Export-Excel
.DESCRIPTION
This command can accept a data table object or take a SQL command and run it against a database connection.
If running the SQL command, it accepts an object representing a session with a SQL server or ODBC database, or a connection String to make a session.
It the DataTable is inserted into the Excel sheet
It takes most of the parameters of Export-Excel, but it is more efficient than getting dataRows and piping them into Export-Excel,
data-rows have additional properties which need to be stripped off.
.PARAMETER DataTable
A System.Data.DataTable object containing the data to be inserted into the spreadsheet without running a query.
.PARAMETER Session
An active ODBC Connection or SQL connection object representing a session with a database which will be queried to get the data .
.PARAMETER Connection
Database connection string; either DSN=ODBC_Data_Source_Name, a full odbc or SQL Connection string, or the name of a SQL server. This is used to create a database session.
.PARAMETER MSSQLServer
Specifies the connection string is for SQL server, not ODBC .
.PARAMETER SQL
The SQL query to run against the session which was passed in -Session or set up from $Connection.
.PARAMETER Database
Switches to a specific database on a SQL server.
.PARAMETER QueryTimeout
Override the default query time of 30 seconds.
.PARAMETER Path
Path to a new or existing .XLSX file.
.PARAMETER WorkSheetName
The name of a sheet within the workbook - "Sheet1" by default .
.PARAMETER KillExcel
Closes Excel - prevents errors writing to the file because Excel has it open
.PARAMETER Title
Text of a title to be placed in the top left cell.
.PARAMETER TitleBold
Sets the title in boldface type.
.PARAMETER TitleSize
Sets the point size for the title.
.PARAMETER TitleBackgroundColor
Sets the cell background color for the title cell.
.PARAMETER TitleFillPattern
Sets the fill pattern for the title cell.
.PARAMETER Password
Sets password protection on the workbook.
.PARAMETER IncludePivotTable
Adds a Pivot table using the data in the worksheet.
.PARAMETER PivotTableName
If a Pivot table is created from command line parameters, specificies the name of the new sheet holding the pivot. If Omitted this will be "WorksheetName-PivotTable"
.PARAMETER PivotRows
Name(s) columns from the spreadhseet which will provide the Row name(s) in a pivot table created from command line parameters.
.PARAMETER PivotColumns
Name(s) columns from the spreadhseet which will provide the Column name(s) in a pivot table created from command line parameters.
.PARAMETER PivotFilter
Name(s) columns from the spreadhseet which will provide the Filter name(s) in a pivot table created from command line parameters.
.PARAMETER PivotData
In a pivot table created from command line parameters, the fields to use in the table body is given as a Hash table in the form ColumnName = Average|Count|CountNums|Max|Min|Product|None|StdDev|StdDevP|Sum|Var|VarP .
.PARAMETER NoTotalsInPivot
In a pivot table created from command line parameters, prevents the addition of totals to rows and columns.
.PARAMETER IncludePivotChart
Include a chart with the Pivot table - implies -IncludePivotTable.
.PARAMETER ChartType
The type for Pivot chart (one of Excel's defined chart types)
.PARAMETER NoLegend
Exclude the legend from the pivot chart.
.PARAMETER ShowCategory
Add category labels to the pivot chart.
.PARAMETER ShowPercent
Add Percentage labels to the pivot chart.
.PARAMETER PivotTableDefinition
Instead of describing a single pivot table with mutliple commandline paramters; you can use a HashTable in the form PivotTableName = Definition;
Definition is itself a hashtable with Sheet PivotTows, PivotColumns, PivotData, IncludePivotChart and ChartType values.
.PARAMETER ConditionalFormat
One or more conditional formatting rules defined with New-ConditionalFormattingIconSet.
.PARAMETER ConditionalText
Applies a 'Conditional formatting rule' in Excel on all the cells. When specific conditions are met a rule is triggered.
.PARAMETER BoldTopRow
Makes the top Row boldface.
.PARAMETER NoHeader
Does not put field names at the top of columns.
.PARAMETER RangeName
Makes the data in the worksheet a named range.
.PARAMETER AutoNameRange
Makes each column a named range.
.PARAMETER TableName
Makes the data in the worksheet a table with a name applies a style to it. Name must not contain spaces.
.PARAMETER TableStyle
Selects the style for the named table - defaults to 'Medium6'.
.PARAMETER BarChart
Creates a "quick" bar chart using the first text column as labels and the first numeric column as values
.PARAMETER ColumnChart
Creates a "quick" column chart using the first text column as labels and the first numeric column as values
.PARAMETER LineChart
Creates a "quick" line chart using the first text column as labels and the first numeric column as values
.PARAMETER PieChart
Creates a "quick" pie chart using the first text column as labels and the first numeric column as values
.PARAMETER ExcelChartDefinition
A hash table containing ChartType, Title, NoLegend, ShowCategory, ShowPercent, Yrange, Xrange and SeriesHeader for one or more [non-pivot] charts.
.PARAMETER StartRow
Row to start adding data. 1 by default. Row 1 will contain the title if any. Then headers will appear (Unless -No header is specified) then the data appears.
.PARAMETER StartColumn
Column to start adding data - 1 by default.
.PARAMETER FreezeTopRow
Freezes headers etc. in the top row.
.PARAMETER FreezeFirstColumn
Freezes titles etc. in the left column.
.PARAMETER FreezeTopRowFirstColumn
Freezes top row and left column (equivalent to Freeze pane 2,2 ).
.PARAMETER FreezePane
Freezes panes at specified coordinates (in the form RowNumber , ColumnNumber).
.PARAMETER AutoFilter
Enables the 'Filter' in Excel on the complete header row. So users can easily sort, filter and/or search the data in the select column from within Excel.
.PARAMETER AutoSize
Sizes the width of the Excel column to the maximum width needed to display all the containing data in that cell.
.PARAMETER Show
Opens the Excel file immediately after creation. Convenient for viewing the results instantly without having to search for the file first.
.PARAMETER ReturnRange
If specified, Export-Excel returns the range of added cells in the format "A1:Z100"
.PARAMETER PassThru
If specified, Export-Excel returns an object representing the Excel package without saving the package first. To save it you need to call the save or Saveas method or send it back to Export-Excel.
.EXAMPLE
C:\> Send-SQLDataToExcel -MsSQLserver -Connection localhost -SQL "select name,type,type_desc from [master].[sys].[all_objects]" -Path .\temp.xlsx -WorkSheetname master -AutoSize -FreezeTopRow -AutoFilter -BoldTopRow
Connects to the local SQL server and selects 3 columns from [Sys].[all_objects] and exports then to a sheet named master with some basic header manager
.EXAMPLE
C:\> $SQL="SELECT top 25 DriverName, Count(RaceDate) as Races, Count(Win) as Wins, Count(Pole) as Poles, Count(FastestLap) as Fastlaps FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
C:\> $Connection = 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DriverId=790;ReadOnly=0;Dbq=C:\users\James\Documents\f1Results.xlsx;'
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo4.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange
C:\> Send-SQLDataToExcel -Connection $connection -SQL $sql -path .\demo1.xlsx -WorkSheetname "Winners" -AutoSize -AutoNameRange
This declares a SQL statement and creates an ODBC connection string to read from an Excel file, it then runs the statement and outputs the resulting data to a new spreadsheet.
.Example
C:\> Send-SQLDataToExcel -path .\demo4.xlsx -WorkSheetname "LR" -Connection "DSN=LR" -sql "SELECT name AS CollectionName FROM AgLibraryCollection Collection ORDER BY CollectionName"
This declares a SQL statement and creates an ODBC connection string to read from an Excel file, it then runs the statement and outputs the resulting data to a new spreadsheet.
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
.EXAMPLE
C:\> $SQL = "SELECT top 25 DriverName, Count(RaceDate) as Races, Count(Win) as Wins, Count(Pole) as Poles, Count(FastestLap) as Fastlaps FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
C:\> Get-SQL -Session F1 -excel -Connection "C:\Users\mcp\OneDrive\public\f1\f1Results.xlsx" -sql $sql -OutputVariable Table | out-null
C:\> Send-SQLDataToExcel -DataTable $Table -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -TableName winners -TableStyle Light6 -show
This uses Get-SQL (at least V1.1 download from the gallery with Install-Module -Name GetSQL - note the function is get-SQL the module is GetSQL without the "-" )
to simplify making database connections and building /submitting SQL statements.
Here it uses the same SQL statement as before; -OutputVariable leaves a System.Data.DataTable object in $table
and Send-SQLDataToExcel puts $table into the worksheet and sets it as an Excel table.
(the F1 results database is available from https://1drv.ms/x/s!AhfYu7-CJv4ehNdZWxJE9LMAX_N5sg )
.EXAMPLE
C:\> $SQL = "SELECT top 25 DriverName, Count(Win) as Wins FROM Results GROUP BY DriverName ORDER BY (count(win)) DESC"
C:\> Send-SQLDataToExcel -Session $DbSessions["f1"] -SQL $sql -Path ".\demo3.xlsx" -WorkSheetname Gpwinners -autosize -ColumnChart
Like the previous example, this uses Get-SQL (download from the gallery with Install-Module -Name GetSQL).It uses the connection which Get-SQL made rather than an ODFBC connection string
Here the data is presented as a quick chart.
.EXAMPLE
C:\> Send-SQLDataToExcel -path .\demo3.xlsx -WorkSheetname "LR" -Connection "DSN=LR" -sql "SELECT name AS CollectionName FROM AgLibraryCollection Collection ORDER BY CollectionName"
This example uses an Existing ODBC datasource name "LR" which maps to an adobe lightroom database and gets a list of collection names into a worksheet
#>
param (
#Database connection string; either DSN=ODBC_Data_Source_Name, a full odbc or SQL Connection string, or the name of a SQL server
#>
[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword","")]
param (
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
[Parameter(ParameterSetName="ODBCConnection",Mandatory=$true)]
$Connection,
#A pre-existing database session object
[Parameter(ParameterSetName="ExistingSession",Mandatory=$true)]
[System.Data.Common.DbConnection]$Session,
#Specifies the connection string is for SQL server not ODBC
[Parameter(ParameterSetName="SQLConnection",Mandatory=$true)]
[switch]$MsSQLserver,
#Switches to a specific database on a SQL server
[Parameter(ParameterSetName="SQLConnection")]
[String]$DataBase,
#The SQL query to run
[Parameter(Mandatory=$true)]
[Parameter(ParameterSetName="SQLConnection", Mandatory=$true)]
[Parameter(ParameterSetName="ODBCConnection",Mandatory=$true)]
[Parameter(ParameterSetName="ExistingSession",Mandatory=$true)]
[string]$SQL,
#Override the default query time of 30 seconds.
[int]$QueryTimeout,
#File name for the Excel File
[int]$QueryTimeout,
[Parameter(ParameterSetName="Pre-FetchedData",Mandatory=$true)]
[System.Data.DataTable]$DataTable,
$Path,
[String]$WorkSheetname = 'Sheet1',
[Switch]$KillExcel,
#If Specified, open the file created.
[Switch]$Show,
[String]$Title,
[OfficeOpenXml.Style.ExcelFillStyle]$TitleFillPattern = 'None',
@@ -57,11 +176,14 @@
[Int]$TitleSize = 22,
[System.Drawing.Color]$TitleBackgroundColor,
[String]$Password,
[Hashtable]$PivotTableDefinition,
[Switch]$IncludePivotTable,
[String[]]$PivotRows,
[String[]]$PivotColumns,
$PivotData,
[Switch]$PivotDataToColumn,
[Hashtable]$PivotTableDefinition,
[String[]]$PivotFilter,
[Switch]$PivotDataToColumn,
[Switch]$NoTotalsInPivot,
[Switch]$IncludePivotChart,
[OfficeOpenXml.Drawing.Chart.eChartType]$ChartType = 'Pie',
[Switch]$NoLegend,
@@ -78,6 +200,10 @@
[String]$RangeName,
[String]$TableName,
[OfficeOpenXml.Table.TableStyles]$TableStyle = 'Medium6',
[Switch]$Barchart,
[Switch]$PieChart,
[Switch]$LineChart ,
[Switch]$ColumnChart ,
[Object[]]$ExcelChartDefinition,
[Switch]$AutoNameRange,
[Object[]]$ConditionalFormat,
@@ -85,55 +211,58 @@
[ScriptBlock]$CellStyleSB,
[Int]$StartRow = 1,
[Int]$StartColumn = 1,
#If Specified, return an ExcelPackage object to allow further work to be done on the file.
[Switch]$ReturnRange,
[Switch]$Passthru
)
if ($KillExcel) {
Get-Process excel -ErrorAction Ignore | Stop-Process
while (Get-Process excel -ErrorAction Ignore) {}
while (Get-Process excel -ErrorAction Ignore) {Start-Sleep -Milliseconds 250}
}
#We were either given a session object or a connection string (with, optionally a MSSQLServer parameter)
# If we got -MSSQLServer, create a SQL connection, if we didn't but we got -Connection create an ODBC connection
if ($MsSQLserver) {
if ($MsSQLserver -and $Connection) {
if ($Connection -notmatch "=") {$Connection = "server=$Connection;trusted_connection=true;timeout=60"}
$Session = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $Connection
$Session = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $Connection
if ($Session.State -ne 'Open') {$Session.Open()}
if ($DataBase) {$Session.ChangeDatabase($DataBase) }
}
elseif ($Connection) {
$Session = New-Object -TypeName System.Data.Odbc.OdbcConnection -ArgumentList $Connection ; $Session.ConnectionTimeout = 30
$Session = New-Object -TypeName System.Data.Odbc.OdbcConnection -ArgumentList $Connection ; $Session.ConnectionTimeout = 30
}
#A session was either passed in or just created. If it's a SQL one make a SQL DataAdapter, otherwise make an ODBC one
if ($Session.GetType().name -match "SqlConnection") {
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
If ($session) {
#A session was either passed in or just created. If it's a SQL one make a SQL DataAdapter, otherwise make an ODBC one
if ($Session.GetType().name -match "SqlConnection") {
$dataAdapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter -ArgumentList (
New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SQL, $Session)
}
else {
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
}
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $ServerTimeout}
#Both adapter types output the same kind of table, create one and fill it from the adapter
$DataTable = New-Object -TypeName System.Data.DataTable
$rowCount = $dataAdapter.fill($dataTable)
Write-Verbose -Message "Query returned $rowCount row(s)"
}
else {
$dataAdapter = New-Object -TypeName System.Data.Odbc.OdbcDataAdapter -ArgumentList (
New-Object -TypeName System.Data.Odbc.OdbcCommand -ArgumentList $SQL, $Session )
if ($DataTable.Rows) {
#ExportExcel user a -NoHeader parameter so that's what we use here, but needs to be the other way around.
$printHeaders = -not $NoHeader
if ($Title) {$r = $StartRow +1 }
else {$r = $StartRow}
#Get our Excel sheet and fill it with the data
$excelPackage = Export-Excel -Path $Path -WorkSheetname $WorkSheetname -PassThru
$excelPackage.Workbook.Worksheets[$WorkSheetname].Cells[$r,$StartColumn].LoadFromDataTable($dataTable, $printHeaders ) | Out-Null
#Call export-excel with any parameters which don't relate to the SQL query
"Connection", "Database" , "Session", "MsSQLserver", "Destination" , "SQL" , "DataTable", "Path" | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
Export-Excel -ExcelPackage $excelPackage @PSBoundParameters
}
if ($QueryTimeout) {$dataAdapter.SelectCommand.CommandTimeout = $ServerTimeout}
#Both adapter types output the same kind of table, create one and fill it from the adapter
$dataTable = New-Object -TypeName System.Data.DataTable
$rowCount = $dataAdapter.fill($dataTable)
Write-Verbose -Message "Query returned $rowCount row(s)"
#ExportExcel user a -NoHeader parameter so that's what we use here, but needs to be the other way around.
$printHeaders = -not $NoHeader
if ($Title) {$r = $StartRow +1 }
else {$r = $StartRow}
#Get our Excel sheet and fill it with the data
$excelPackage = Export-Excel -Path $Path -WorkSheetname $WorkSheetname -PassThru
$excelPackage.Workbook.Worksheets[$WorkSheetname].Cells[$r,$StartColumn].LoadFromDataTable($dataTable, $printHeaders ) | Out-Null
#Call export-excel with any parameters which don't relate to the SQL query
"Connection", "Database" , "Session", "MsSQLserver", "Destination" , "SQL" ,"Path" | ForEach-Object {$null = $PSBoundParameters.Remove($_) }
Export-Excel -ExcelPackage $excelPackage @PSBoundParameters
#If we were not passed a session close the session we created.
else {Write-Warning -Message "No Data to insert."}
#If we were passed a connection and opened a session, close that session.
if ($Connection) {$Session.close() }
}

View File

@@ -1,4 +1,9 @@
- [ ] Create an autocomplete for WorkSheetName param on ImportExcel
- [ ] Add help text for parmaters which don't have it in Export Excel
- [ ] Add help text for parmaters which don't have it ( PivotDataToColumn , NoClobber and CellStyleSB ) in Export Excel, copy to Send-SQLDataToExcel
- [ ] Add checks for valid worksheet names (also check pivot names, range names and table names are valid)
- [ ] Investigate regional support for number conversion
- [ ] Investigate regional support for number conversion
- [ ] Add help in ConvertToExcelXLSx.ps1, Copy-ExcelWorkSheet.ps1 (probably re-write copy)
- [ ] Add Help (continued) in Get-HTMLTable.ps1, GetRange.PS1, GetExcelTable.Ps1, Import-HTML.PS1, New-ConditionalFormattingIconSet.Ps1, NewConditionalText.PS1, New-Psitem.PS1, Remove-Worksheet.ps1
[ ] Copy parameter help from function Add-ExcelChart into New-ExcelChart.ps1
- [ ] Examples and tests for new "Quick charts" in Export Excel
- [ ] Charting.ps1,GetXYRange.ps1, InferData.PS1 move to deprecated. (replace examples)

View File

@@ -81,7 +81,7 @@ Describe ExportExcel {
$ws.Dimension.Columns | Should be $propertyNames.Count
$ws.Dimension.Rows | Should be ($rowcount + 1 ) # +1 for the header.
}
it "Created a Range - even though the name given was invalid. " {
it "Created a Range - even though the name given was invalid. " {
$ws.Names["No_spaces"] | Should not beNullOrEmpty
$ws.Names["No_spaces"].End.Column | Should be $propertyNames.Count
$ws.names["No_spaces"].End.Row | Should be ($rowcount + 1 ) # +1 for the header.
@@ -146,60 +146,92 @@ Describe ExportExcel {
Context "#Examples 3 & 4 # Setting cells for different data types Also added test for URI type" {
if ((Get-Culture).NumberFormat.CurrencySymbol -eq "£") {$OtherCurrencySymbol = "$"}
else {$OtherCurrencySymbol = "£"}
$path = "$env:TEMP\Test.xlsx"
Remove-item -Path $path -ErrorAction SilentlyContinue
[PSCustOmobject][Ordered]@{
Date = Get-Date
Formula1 = '=SUM(F2:G2)'
String1 = 'My String'
String2 = 'a'
IPAddress = '10.10.25.5'
Number1 = '07670'
Number2 = '0,26'
Number3 = '1.555,83'
Number4 = '1.2'
Number5 = '-31'
PhoneNr1 = '+32 44'
PhoneNr2 = '+32 4 4444 444'
PhoneNr3 = '+3244444444'
Link = [uri]"https://github.com/dfinke/ImportExcel"
} | Export-Excel -NoNumberConversion IPAddress, Number1 -Path $path
Date = Get-Date
Formula1 = '=SUM(F2:G2)'
String1 = 'My String'
Float = [math]::pi
IPAddress = '10.10.25.5'
StrLeadZero = '07670'
StrComma = '0,26'
StrEngThousand = '1,234.56'
StrEuroThousand = '1.555,83'
StrDot = '1.2'
StrNegInt = '-31'
StrTrailingNeg = '31-'
StrParens = '(123)'
strLocalCurrency = ('{0}123.45' -f (Get-Culture).NumberFormat.CurrencySymbol )
strOtherCurrency = ('{0}123.45' -f $OtherCurrencySymbol )
StrE164Phone = '+32 (444) 444 4444'
StrAltPhone1 = '+32 4 4444 444'
StrAltPhone2 = '+3244444444'
StrLeadSpace = ' 123'
StrTrailSpace = '123 '
Link1 = [uri]"https://github.com/dfinke/ImportExcel" #2,15
Link2 = "https://github.com/dfinke/ImportExcel" #2, 16
} | Export-Excel -NoNumberConversion IPAddress, StrLeadZero, StrAltPhone2 -Path $path
it "Created a new file " {
Test-Path -Path $path -ErrorAction SilentlyContinue | Should be $true
}
$Excel = Open-ExcelPackage -Path $path
it "Created 1 worksheet " {
$Excel.Workbook.Worksheets.count | Should be 1
}
$ws = $Excel.Workbook.Worksheets[1]
it "Created the worksheet with the expected name, number of rows and number of columns " {
$ws.Name | Should be "sheet1"
$ws.Dimension.Columns | Should be 14
$ws.Dimension.Columns | Should be 22
$ws.Dimension.Rows | Should be 2
}
it "Set a date in Cell A2 " {
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
it "Set a date in Cell A2 " {
$ws.Cells[2, 1].Value.Gettype().name | Should be 'DateTime'
}
it "Set a formula in Cell B2 " {
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
it "Set a formula in Cell B2 " {
$ws.Cells[2, 2].Formula | Should be '=SUM(F2:G2)'
}
it "Set strings in Cells E2 and F2 " {
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
it "Set strings in Cells E2, F2 and R2 (no number conversion) " {
$ws.Cells[2, 5].Value.GetType().name | Should be 'String'
$ws.Cells[2, 6].Value.GetType().name | Should be 'String'
$ws.Cells[2, 18].Value.GetType().name | Should be 'String'
}
it "Set a number in Cell I2 " {
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
it "Set numbers in Cells K2,L2,M2 (diferent Negative integer formats) " {
($ws.Cells[2, 11].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 12].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 13].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 11].Value | Should beLessThan 0
$ws.Cells[2, 12].Value | Should beLessThan 0
$ws.Cells[2, 13].Value | Should beLessThan 0
}
it "Set a hyperlink in Cell N2 " {
$ws.Cells[2, 14].Hyperlink | Should be "https://github.com/dfinke/ImportExcel"
it "Set hyperlinks in Cells U2 and V2 " {
$ws.Cells[2, 21].Hyperlink | Should be "https://github.com/dfinke/ImportExcel"
$ws.Cells[2, 22].Hyperlink | Should be "https://github.com/dfinke/ImportExcel"
}
it "Processed thousands according to local settings (Cells H2 and I2) " {
if ((Get-Culture).NumberFormat.NumberGroupSeparator = ",") {
($ws.Cells[2, 8].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 9].Value.GetType().name | Should be 'String'
}
elseif ((Get-Culture).NumberFormat.NumberGroupSeparator = ".") {
($ws.Cells[2, 9].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 8].Value.GetType().name | Should be 'String'
}
}
it "Processed local currency as a number and other currency as a string (N2 & O2) " {
($ws.Cells[2, 14].Value -is [valuetype] ) | Should be $true
$ws.Cells[2, 15].Value.GetType().name | Should be 'String'
}
it "Processed numbers with spaces between digits as strings (P2 & Q2) " {
$ws.Cells[2, 16].Value.GetType().name | Should be 'String'
$ws.Cells[2, 17].Value.GetType().name | Should be 'String'
}
it "Processed numbers leading or trailing speaces as Numbers (S2 & T2) " {
($ws.Cells[2, 19].Value -is [valuetype] ) | Should be $true
($ws.Cells[2, 20].Value -is [valuetype] ) | Should be $true
}
}
Context "# # Setting cells for different data types with -noHeader" {
@@ -438,7 +470,7 @@ Describe ExportExcel {
$excel.Workbook.Worksheets[6].Name | Should be "Sheet1"
}
it "Cloned 'Sheet1' to 'NewSheet' " {
it "Cloned 'Sheet1' to 'NewSheet' " {
$newWs = $excel.Workbook.Worksheets["NewSheet"]
$newWs.Dimension.Address | Should be ($excel.Workbook.Worksheets["Sheet1"].Dimension.Address)
$newWs.ConditionalFormatting.Count | Should be ($excel.Workbook.Worksheets["Sheet1"].ConditionalFormatting.Count)
@@ -692,13 +724,13 @@ Describe ExportExcel {
$r = Get-ChildItem -path C:\WINDOWS\system32 -File
"Biggest files" | Export-Excel -Path $path -StartRow 1 -StartColumn 7
$r | Sort-Object length -Descending | Select -First 14 Name, @{n="Size";e={$_.Length}} |
$r | Sort-Object length -Descending | Select-Object -First 14 Name, @{n="Size";e={$_.Length}} |
Export-Excel -Path $path -TableName FileSize -StartRow 2 -StartColumn 7 -TableStyle Medium2
$r.extension | Group-Object | Sort-Object -Property count -Descending | Select-Object -First 12 Name, Count |
Export-Excel -Path $path -TableName ExtSize -Title "Frequent Extensions" -TitleSize 11
$r | Group-Object -Property extension | Select-Object Name, @{n="Size"; e={($_.group | measure -property length -sum).sum}} |
$r | Group-Object -Property extension | Select-Object Name, @{n="Size"; e={($_.group | Measure-Object -property length -sum).sum}} |
Sort-Object -Property size -Descending | Select-Object -First 10 |
Export-Excel -Path $path -TableName ExtCount -Title "Biggest extensions" -TitleSize 11 -StartColumn 4 -AutoSize
@@ -707,17 +739,15 @@ Describe ExportExcel {
it "Created 3 tables " {
$ws.tables.count | should be 3
}
it "Created the FileSize table in the right places with the right size " {
it "Created the FileSize table in the right place with the right size and style " {
$ws.Tables["FileSize"].Address.Address | should be "G2:H16" #Insert at row 2, Column 7, 14 rows x 2 columns of data
$ws.Tables["FileSize"].StyleName | should be "TableStyleMedium2"
}
it "Created the ExtSize table in the right places with the right size " {
it "Created the ExtSize table in the right place with the right size " {
$ws.Tables["ExtSize"].Address.Address | should be "A2:B14" #tile, then 12 rows x 2 columns of data
$ws.Tables["ExtSize"].TableStyle.tostring() | should be "medium6"
}
it "Created the ExtSize table in the right places with the right size " {
$ws.Tables["ExtSize"].Address.Address | should be "A2:B14" #tile, then 12 rows x 2 columns of data
$ws.Tables["ExtSize"].TableStyle.tostring() | should be "medium6"
it "Created the ExtCount table in the right place with the right size " {
$ws.Tables["ExtCount"].Address.Address | should be "D2:E12" #title, then 10 rows x 2 columns of data
}
}