Neulich musste ich für ein Kundenprojekt eine Excel Datei auslesen. Beim Suchen im Internet fand ich viele Libaries und auch natürlich die Application Com-Object Variante von Microsoft. Da ich aber auf dem Server jetzt kein Excel installieren wollte, fiel die Com-Object Variante aber gleich wieder raus aus der Recherche.
Ich hab mich dann erstmal auf epplus konzentriet und siehe da, es hat einfach nur bestens funktioniert. Im folgenden Powershell Skript, hab ich versucht keine Businesslogik einzubauen, sondern einfach die im Excel enthaltenen Daten in einer XML Datei zu schreiben. Und die Businesslogik dann entsprechend auf das XML anzuwenden:
param( #path to the epplus.dll $p_epp_plus="C:\Excel\EPPlus.dll", #path to the input excel file $p_input="C:\Excel\test.xlsm", #path to write the xml output to $p_output="C:\Excel\test.xml" ) #isolate the column letter from the address function get_column($str){ $str = [regex]::Matches($str, "[a-zA-Z]*") $str = $str.groups[0].value return $str } #isolate the row number from address function get_row($str){ $str = [regex]::Matches($str, "[0-9]+") $str = $str.groups[0].value return $str } try{ #adding the libary Add-Type -Path $p_epp_plus #creating the excel object and open the file $obj = New-Object OfficeOpenXML.ExcelPackage($p_input) #creating the xml object [System.XML.XMLDocument]$xml=New-Object System.XML.XMLDocument $xml = [xml] "<!--?xml version='1.0' encoding='utf-8'?-->" [System.XML.XMLElement]$xml_root=$xml.CreateElement("root") #going thru each of the worksheets foreach($ws in $obj.Workbook.Worksheets){ #create an xml node for each worksheet [System.XML.XMLElement]$xml_worksheet=$xml.CreateElement("worksheet") $xml_worksheet.SetAttribute("index",$ws.index) $xml_worksheet.SetAttribute("name",$ws.name) #going thru each cell of the current worksheet foreach($cell in $ws.cells){ #only is a field is not empty if($cell.text -ne ""){ #create an xml node for each cell [System.XML.XMLElement]$xml_cell=$xml.CreateElement("cell") #getting the address $xml_cell.SetAttribute("Address",$cell.Address) #getting the column $column = get_column($cell.Address) $xml_cell.SetAttribute("column", $column) #getting the row $row = get_row($cell.Address) $xml_cell.SetAttribute("row", $row) #content of the cell $xml_cell.SetAttribute("text",$cell.text) #finally adding the row nodes to the worksheet $xml_worksheet.appendChild($xml_cell) | out-null } } #finally adding the row nodes to the worksheet $xml_root.appendChild($xml_worksheet) | out-null } #adding everything to the root xml node $xml.appendChild($xml_root) | out-null #save to given output path and filename $xml.Save($p_output) } catch{ write-host $_.Exception.Message } |
Das Skript liest einfach alle Felder in allen Tabellenblätter (worksheet) und legt alle gefüllten Felder in einem eigenen XML Knoten ab. Zusätzlich wird die Koordinate als Attribute gespeichert, damit man den Inhalt jeweils der gelesenen Postionen auch später noch zuordnen kann.
Der Output sieht im Grunde so aus:
Viel Spaß beim Excel Daten auslesen 🙂