Public/Export-GlookoZipToXlsx.ps1
|
function Export-GlookoZipToXlsx { <# .SYNOPSIS Converts a Glooko zip file to an Excel (XLSX) file with each dataset in a separate worksheet. .DESCRIPTION This advanced function imports data from a Glooko zip file using Import-GlookoZip and exports it to an Excel file. A Summary worksheet is created as the first tab, containing an overview of all datasets with their name, record count, and date range information. Each dataset is then placed in a separate worksheet, with the worksheet name corresponding to the dataset value from the metadata. The XLSX file is created with the same name and location as the ZIP file (unless a custom output path is specified). This function requires the ImportExcel module to be installed. If not installed, it will provide instructions on how to install it. .PARAMETER Path The path to the zip file to convert. .PARAMETER OutputPath Optional. The full path for the output XLSX file. If not specified, the XLSX file will be created in the same folder as the ZIP file with the same name but .xlsx extension. .PARAMETER Force Optional. If specified, overwrites the existing XLSX file if it exists. If not specified and the file exists, a timestamp will be appended to the filename (e.g., export_311225_143022.xlsx). .EXAMPLE Export-GlookoZipToXlsx -Path "C:\data\export.zip" Converts the zip file to C:\data\export.xlsx with a Summary worksheet as the first tab, followed by each dataset in a separate worksheet. .EXAMPLE Export-GlookoZipToXlsx -Path "C:\data\export.zip" -Force Converts the zip file to C:\data\export.xlsx, overwriting if it exists. .EXAMPLE Export-GlookoZipToXlsx -Path "C:\data\export.zip" -OutputPath "C:\output\mydata.xlsx" Converts the zip file to the specified output path. .EXAMPLE "C:\data\export.zip" | Export-GlookoZipToXlsx Converts the zip file via pipeline input. .OUTPUTS System.IO.FileInfo Returns the FileInfo object for the created XLSX file. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateScript({ if (Test-Path $_ -PathType Leaf) { if ($_ -match '\.zip$') { $true } else { throw "File must have .zip extension: $_" } } else { throw "File not found: $_" } })] [string]$Path, [Parameter(Mandatory = $false)] [string]$OutputPath, [Parameter(Mandatory = $false)] [switch]$Force ) begin { Write-Verbose "Starting Export-GlookoZipToXlsx function" # Check if ImportExcel module is available (either already loaded or can be loaded) $importExcelLoaded = $null -ne (Get-Module -Name ImportExcel) $importExcelAvailable = $null -ne (Get-Module -ListAvailable -Name ImportExcel) if (-not $importExcelLoaded -and -not $importExcelAvailable) { $errorMessage = @" The ImportExcel module is required but not installed. To install it, run one of the following commands: Install-Module -Name ImportExcel -Scope CurrentUser Or clone it from GitHub: git clone https://github.com/dfinke/ImportExcel.git Import-Module ./ImportExcel/ImportExcel.psd1 For more information, visit: https://github.com/dfinke/ImportExcel "@ Write-Error $errorMessage throw "ImportExcel module not found" } # Import the ImportExcel module if not already loaded if (-not $importExcelLoaded) { Import-Module ImportExcel -ErrorAction Stop -Verbose:$false Write-Verbose "ImportExcel module loaded successfully" } else { Write-Verbose "ImportExcel module already loaded" } } process { try { Write-Verbose "Processing zip file: $Path" # Resolve to absolute path $zipPath = Resolve-Path -Path $Path Write-Verbose "Resolved zip path: $zipPath" # Determine output path if (-not $OutputPath) { $zipDirectory = Split-Path -Path $zipPath -Parent $zipBaseName = [System.IO.Path]::GetFileNameWithoutExtension($zipPath) $OutputPath = Join-Path -Path $zipDirectory -ChildPath "$zipBaseName.xlsx" Write-Verbose "Using default output path: $OutputPath" } else { $OutputPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputPath) Write-Verbose "Using specified output path: $OutputPath" } # Import data from zip file Write-Verbose "Importing data from zip file" $datasets = Import-GlookoZip -Path $zipPath if (-not $datasets -or $datasets.Count -eq 0) { Write-Warning "No data found in zip file: $zipPath" return } Write-Verbose "Found $($datasets.Count) dataset(s) to export" # Handle existing file if (Test-Path $OutputPath) { if ($Force) { Write-Verbose "Removing existing file: $OutputPath" Remove-Item -Path $OutputPath -Force } else { # Append timestamp to filename $timestamp = Get-Date -Format 'ddMMyy_HHmmss' $directory = Split-Path -Path $OutputPath -Parent $baseName = [System.IO.Path]::GetFileNameWithoutExtension($OutputPath) $extension = [System.IO.Path]::GetExtension($OutputPath) $OutputPath = Join-Path -Path $directory -ChildPath "${baseName}_${timestamp}${extension}" Write-Verbose "File exists, creating new file with timestamp: $OutputPath" } } # Create summary data for all datasets Write-Verbose "Creating summary data for $($datasets.Count) dataset(s)" $summaryData = @() foreach ($dataset in $datasets) { $datasetName = if ($dataset.Metadata.Dataset) { $dataset.Metadata.Dataset } else { 'Unknown' } $summaryData += [PSCustomObject]@{ Dataset = $datasetName Records = $dataset.Data.Count Name = $dataset.Metadata.Name StartDate = $dataset.Metadata.StartDate EndDate = $dataset.Metadata.EndDate } } # Export summary worksheet first if ($summaryData.Count -gt 0) { Write-Verbose "Exporting Summary worksheet with $($summaryData.Count) dataset(s)" $summaryData | Export-Excel -Path $OutputPath -WorksheetName 'Summary' -AutoSize -TableName 'Summary' -TableStyle Medium2 } # Export each dataset to a separate worksheet $sheetCounter = 1 foreach ($dataset in $datasets) { $worksheetName = if ($dataset.Metadata.Dataset) { $dataset.Metadata.Dataset } else { # If no dataset name, use a generic name "Sheet$sheetCounter" } # Excel worksheet names must be 31 characters or less and cannot contain: \ / ? * [ ] : $worksheetName = $worksheetName -replace '[\\\/\?\*\[\]:]', '_' if ($worksheetName.Length -gt 31) { $worksheetName = $worksheetName.Substring(0, 31) } Write-Verbose "Exporting dataset '$worksheetName' with $($dataset.Data.Count) rows" if ($dataset.Data -and $dataset.Data.Count -gt 0) { $dataset.Data | Export-Excel -Path $OutputPath -WorksheetName $worksheetName -AutoSize -TableName $worksheetName -TableStyle Medium2 } else { Write-Warning "Dataset '$worksheetName' has no data, skipping" } $sheetCounter++ } Write-Verbose "Successfully created Excel file: $OutputPath" # Return the file info return Get-Item -Path $OutputPath } catch { Write-Error "Error converting zip to XLSX: $($_.Exception.Message)" throw } } end { Write-Verbose "Export-GlookoZipToXlsx function completed" } } # Export the function if this script is being dot-sourced Export-ModuleMember -Function Export-GlookoZipToXlsx |