src/Excel/Write-XrmExcelSheet.ps1
<# .SYNOPSIS Write Excel Sheet. .DESCRIPTION Push Microsoft Dataverse rows / entity records to Excel file on a specific sheet. .PARAMETER ExcelFilePath Full path to Excel file. .PARAMETER SheetName Excel sheet name. .PARAMETER Records Rows / Entity records array. .PARAMETER HeaderMappings Key value pair collection that map Excel column name to record column (attribute logicalname) .PARAMETER ColumnsSize Array that specify columns width. .PARAMETER TableStyle Specify table template name. (Default: TableStyleMedium15) More information : https://docs.devexpress.com/OfficeFileAPI/DevExpress.Spreadsheet.BuiltInTableStyleId #> function Write-XrmExcelSheet { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $ExcelFilePath, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $SheetName, [Parameter(Mandatory = $true)] [PsObject[]] $Records, [Parameter(Mandatory = $true)] [System.Collections.Specialized.OrderedDictionary] $HeaderMappings, [Parameter(Mandatory = $false)] [int[]] $ColumnsSize = @(), [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $TableStyle = "TableStyleMedium15" ) begin { $StopWatch = [System.Diagnostics.Stopwatch]::StartNew(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters); } process { $excelApplication = New-Object -ComObject Excel.Application; try { $excelApplication.Visible = $false; $excelApplication.ScreenUpdating = $false; $excelApplication.DisplayAlerts = 'False'; $workbook = $excelApplication.Workbooks.Add(); Write-HostAndLog "Adding Excel Sheet '$SheetName' ..." -ForegroundColor Gray; $sheet = $workbook.Sheets.Add(); if ($SheetName.Length -gt 30) { $SheetName = $SheetName.Remove(31); } $sheet.Name = $SheetName; Write-HostAndLog "Adding Excel Sheet '$SheetName' done!" -ForegroundColor Green; $rowCount = $Records.Count + 1; $columnCount = $HeaderMappings.Count; $excelData = [string[, ]]::new($rowCount, $columnCount); $rowNumber = 0; $columnNumber = 0; foreach ($headerMappingKey in $HeaderMappings.Keys) { $excelData[$rowNumber, $columnNumber] = $HeaderMappings[$headerMappingKey]; $columnNumber++; } $current = 0; $total = $Records.Count; foreach ($object in $Records) { $current++; $percent = ($current / $total) * 100; Write-Progress -Activity "Provisioning Excel data" -Status "Processing record ...[$current/$total]" -PercentComplete $percent -Id 1051; $rowNumber ++; $columnNumber = 0; $record = $object.Record; foreach ($headerMappingKey in $HeaderMappings.Keys) { if ($record.FormattedValues.ContainsKey($headerMappingKey)) { $value = $record.FormattedValues[$headerMappingKey]; } else { $value = $record[$headerMappingKey]; } $excelData[$rowNumber, $columnNumber] = $value; $columnNumber++; } } Write-Progress -Activity "Provisioning Excel data" -Id 1051 -Completed; # Push data to Excel Write-HostAndLog "Writing data to Excel ..." -ForegroundColor Gray; $startCell = $sheet.Cells[1, 1]; $endCell = $sheet.Cells[($rowCount), $columnCount]; $sheetContentRange = $sheet.Range($startCell, $endCell); $sheetContentRange.Value2 = $excelData; Write-HostAndLog "Writing data to Excel done!" -ForegroundColor Green; # Apply table format Write-HostAndLog "Formatting Excel table ..." -ForegroundColor Gray; $tableName = "Table$SheetName"; $sheetContentRange.Worksheet.ListObjects.Add([Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, $sheetContentRange, [System.Type]::Missing, [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes, [System.Type]::Missing).Name = $tableName; $sheetContentRange.Select() | Out-Null; $sheetContentRange.Worksheet.ListObjects[$tableName].TableStyle = $tableStyle; Write-HostAndLog "Formatting Excel table done!" -ForegroundColor Green; # Resize columns if ($ColumnsSize.Length -gt 0) { Write-HostAndLog "Resizing columns ..." -ForegroundColor Gray; for ($i = 0; $i -lt $ColumnsSize.Count; $i++) { $columnIndex = $i + 1; if ($full) { $columnIndex ++; } $sheet.Columns($columnIndex).ColumnWidth = $ColumnsSize[$i]; } Write-HostAndLog "Resizing columns done!" -ForegroundColor Green; } Write-HostAndLog "Saving Excel file to '$ExcelFilePath' ..." -ForegroundColor Gray; if (Test-Path -Path $ExcelFilePath) { Remove-Item -Path $ExcelFilePath -Force; } $workbook.SaveAs($ExcelFilePath); $workbook.Close(); Write-HostAndLog "Saving Excel file to '$ExcelFilePath' done!" -ForegroundColor Green; } finally { try { $workbook.Close(); } catch { # Ignore } try { $excelApplication.DisplayAlerts = 'False'; $excelProcess = Get-Process Excel | Where-Object { $_.MainWindowHandle -eq $excelApplication.Hwnd } $excelApplication.Quit(); [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheetContentRange); [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet); [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook); [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelApplication); [GC]::Collect(); [GC]::WaitForPendingFinalizers(); Stop-Process -Id $excelProcess.Id; } catch { # Ignore } } } end { $StopWatch.Stop(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch; } } Export-ModuleMember -Function Write-XrmExcelSheet -Alias *; |