Question [fonction] Lire un fichier xlsx sans Excel

Plus d'informations
il y a 10 ans 9 mois #15266 par Laurent Dardenne
L'objet de cette fonction est de lire un classeur d'un fichier Xlsx sans nécessité la présence d'Office 2010. En revanche la présence d'un provider OLEDB spécifique est nécessaire.

La fonction :
[code:1]
function ConvertFrom-Xlsx {
#Traite un fichier XL
#renvoie un tableau de PSObject.
#Chaque PSObjet possédera des propriétés identique aux noms de colonnes du fichier XL
#
#La routine utilise des API OLEDB afin de s'affranchir de
#l'installation d'Excel sur le poste utilisant cette fonction

# Installer les providers OLEDB 32 bits et/ou* 64 bits:
# www.microsoft.com/fr-fr/download/details.aspx?id=13255
#
# * Le host PS d'Orchestrator 2012 est en 32 bits

param (
[ValidateNotNullOrEmpty()]
[Parameter(Position=0, Mandatory=$True)]
[string] $FileName,
[Parameter(Position=1)]
[string] $XLSheetName='Feuil1'
)

if (-not (Test-path $FileName))
{Throw (New-Object System.ArgumentException(\"Le fichier n'existe pas : $FileName\"«»)) }
try {
$objDS = New-Object System.Data.DataSet
#Provider pour Office 2010
$strConn = \"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=$FileName;Extended Properties='Excel 12.0'\"
#Lit par défaut la première feuille
$objOLE = New-Object System.Data.OleDb.OleDbDataAdapter(\"SELECT * FROM [${XLSheetName}$]\", $strConn)

try {
$LinesNumber=$objOLE.Fill($objDS)
if ($objDS.Tables.Count -eq 0)
{Throw (New-Object System.ApplicationException (\"Il n'existe pas de table dans le fichier '$FileName'\"«»)) }

if ($LinesNumber -le 1) #aucune ligne ou seulement celles du header ( noms de colonne)
{Throw (New-Object System.IndexOutOfRangeException (\"Il n'existe aucune ligne de donnée dans le fichier '$FileName'\"«»)) }

#Sélectionne seulement les propriétés référençant une colonne XL
$Names=$objDS.Tables[0].Columns| Foreach {$_.ColumnName}
$objDS.Tables[0].Rows|
Select -Property $Names
}
catch [System.Management.Automation.MethodInvocationException]
{
if ( ($_.Exception.InnerException -ne $null) -And (
$_.Exception.InnerException -is [System.InvalidOperationException]) -And (
$_.Exception.InnerException.Message -match 'Microsoft\.ACE\.OLEDB\.12\.0')
)
{ Throw (New-Object System.Exception (\"Le provider OLEDB n'est pas installé.\",$_.Exception.InnerException)) }
# Peut être System.Data.OleDb.OleDbException :
# si le classeur ne contient pas la feuille dont le nom est précisé,
# si le fichier est verrouillé dans une autre session XL
# ...
else
{Throw (New-Object System.Exception (\"Erreur lors de la lecture des données du fichier '$FileName'.`r`n $($_.Exception.InnerException)\",$_.Exception.InnerException)) }
}
catch
{ Throw (New-Object System.Exception (\"Erreur inconnue lors de la conversion du fichier '$FileName'.`r`n $($_.Exception)\",$_.Exception)) }
}
finally {
if ($objOLE -ne $null)
{$objOLE.Dispose()}
}
} #ConvertFrom-Xlsx
[/code:1]
Un usage :
[code:1]
$FileName=\"C:\temp\Datas.xlsx\"
$Donnees=ConvertFrom-Xlsx $FileName
[/code:1]
Soyez attentif au fait que :
- Les types des membres des objets retournés(DataRow) nécessiteront des transformations,

- La collection renvoyée peut contenir des \&quot;objets vide\&quot;.<br><br>Message édité par: Laurent Dardenne, à: 27/06/13 22:03

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.063 secondes
Propulsé par Kunena