Exports Excel depuis PowerShell avec ImportExcel
Introduction
Export-Faitza_Export_Excel encapsule le module
ImportExcel pour produire des fichiers .xlsx
directement depuis PowerShell — sans Excel installé. La fonction gère deux modes :
export simple (une table, un onglet) et export multi-onglets via un tableau de
configurations -liste. Une fonction interne Get-Sanitize_ExcelData
nettoie automatiquement les données avant l'écriture : suppression de caractères
invisibles, échappement des formules injection et troncature à 32 700 caractères.
Le module ImportExcel doit être installé :
Install-Module -Name ImportExcel -Scope CurrentUser
Export-Faitza_Export_Excel
Génère un fichier .xlsx depuis un objet PowerShell ou une liste d'onglets.
Supporte la désactivation de la date dans le nom de fichier (-nodate),
la conservation d'un fichier existant (-keep) et le nommage personnalisé
de la table Excel (-nametable).
function Export-Faitza_Export_Excel {
[CmdletBinding()]
param(
[switch]$nodate,
[bool]$keep,
[string]$name,
$data,
[string]$nametable,
$liste
)
try {
Write-Host "$($PSStyle.Background.Red)>>> Export-Faitza_Export_Excel <<<$($PSStyle.Reset)"
if (-not $name) { throw "Il manque le nom du fichier (-name)." }
if (-not $data -and -not $liste) { throw "Il manque les donnees a exporter (-data ou -liste)." }
Import-Module ImportExcel
if ($nametable) {
$nametable = $nametable.Replace("-", "_")
} else {
$nametable = "Table_$($name.Replace("-", "_"))"
}
if ($nodate) {
$file_xlsx = "$env:TEMP\$name.xlsx"
} else {
$file_xlsx = "$env:TEMP\$((Get-Date).tostring('yyyyMMdd'))-$name.xlsx"
}
# ... Get-Sanitize_ExcelData définie ici (voir ci-dessous)
if ((Test-Path -Path $file_xlsx -PathType Leaf) -and -not $keep) {
Remove-Item -Path $file_xlsx -Force -ErrorAction SilentlyContinue
}
if ($liste) {
$liste | ForEach-Object {
Write-Host "Export_Excel : $($_.nametable)"
Get-Sanitize_ExcelData -InputData $_.data
$_.data | Export-Excel -Path $file_xlsx -Worksheetname $_.nametable -Tablename $_.nametable -AutoFilter -AutoSize -TableStyle Medium1 -Append
}
} else {
Write-Host "Export_Excel : $($file_xlsx.split('\')[-1]) $nametable"
Get-Sanitize_ExcelData -InputData $data
$data | Export-Excel -Path $file_xlsx -Worksheetname $nametable -Tablename $nametable -AutoFilter -AutoSize -TableStyle Medium1 -Append
}
return $file_xlsx
} catch {
$ErrorMessage = $_.Exception.Message
$InnerError = if ($null -ne $_.Exception.InnerException) { $_.Exception.InnerException.Message } else { "Aucune" }
Write-Host "CRASH EXPORT EXCEL" -ForegroundColor Red
Write-Host "Fichier cible : $(if ($file_xlsx) { $file_xlsx.split('\')[-1] } else { 'Non defini' })" -ForegroundColor Yellow
Write-Host "Onglet cible : $(if ($nametable) { $nametable } else { 'Non defini' })" -ForegroundColor Yellow
Write-Host "Erreur brute : $ErrorMessage" -ForegroundColor Yellow
Write-Host "Cause reelle : $InnerError" -ForegroundColor Cyan
throw "Erreur fatale lors de l'export Excel vers '$($name)' : $ErrorMessage | Cause Profonde: $InnerError"
} finally {
Write-Host "$($PSStyle.Background.Red)<<< Export-Faitza_Export_Excel >>>$($PSStyle.Reset)"
}
}
Get-Sanitize_ExcelData (imbriquée)
Fonction interne définie à l'intérieur de Export-Faitza_Export_Excel.
Elle parcourt chaque ligne de données et applique trois corrections automatiques sur les
valeurs de type [string] :
- Suppression des caractères de contrôle invisibles (
\x00–\x08,\x0B–\x1F) - Échappement des débuts de formule (
=,-,+) par un apostrophe - Troncature à 32 700 caractères (limite cellule Excel)
function Get-Sanitize_ExcelData {
param($InputData)
if ($null -eq $InputData) { return }
$RowIndex = 1
foreach ($row in $InputData) {
if ($null -eq $row -or $row -isnot [psobject]) { continue }
foreach ($prop in $row.psobject.properties) {
$val = $prop.value
if ($null -ne $val -and $val -is [string]) {
$isModified = $false
if ($val -match '[\x00-\x08\x0B\x0C\x0E-\x1F]') {
Write-Host "[AUTO-FIX] Ligne $RowIndex, Col '$($prop.name)' : caracteres invisibles supprimes." -ForegroundColor Yellow
$val = $val -replace '[\x00-\x08\x0B\x0C\x0E-\x1F]', ''
$isModified = $true
}
if ($val -match "^[=\-\+]") {
Write-Host "[AUTO-FIX] Ligne $RowIndex, Col '$($prop.name)' : signe '$($val.Substring(0,1))' echappe." -ForegroundColor Yellow
$val = "'" + $val
$isModified = $true
}
if ($val.Length -gt 32700) {
Write-Host "[AUTO-FIX] Ligne $RowIndex, Col '$($prop.name)' : texte tronque."
$val = $val.Substring(0, 32700) + "... [TRONQUE]"
$isModified = $true
}
if ($isModified) { $prop.value = $val }
}
}
$RowIndex++
}
}
Exemples d'utilisation
Export simple — un onglet
$data = Get-ADUser -Filter * -Properties DisplayName, EmailAddress, Enabled |
Select-Object DisplayName, EmailAddress, Enabled
$file = Export-Faitza_Export_Excel -name "Utilisateurs-AD" -data $data
Write-Host "Fichier genere : $file"
Export multi-onglets — liste de tables
$liste = @(
@{ nametable = "Utilisateurs"; data = $data_users },
@{ nametable = "Groupes"; data = $data_groups },
@{ nametable = "Licences"; data = $data_licences }
)
$file = Export-Faitza_Export_Excel -name "Rapport-Mensuel" -liste $liste
Write-Host "Export multi-onglets : $file"
Sans date dans le nom de fichier
# Nom fixe sans préfixe de date
$file = Export-Faitza_Export_Excel -name "Inventaire" -data $data -nodate
# Conserver un fichier existant au lieu de le supprimer
$file = Export-Faitza_Export_Excel -name "Log" -data $data -keep $true
// Commentaires
Aucun commentaire pour l'instant.