Automatisierte Verzeichnisstruktur und Dokument Anpassungen
Hallo zusammen
Ich soll für folgendes Szenario eine halb automatisierte Lösung finden.
1. Projektnummer und Name wird durch ein bestehendes Tool erfasst
2. Dieses Tool erstellt ein Verzeichnis auf einem Share mit Projektnummer und Namen
3. Das Tool kopiert eine Vorlagen-Ordner mit diversen Unterverzeichnissen, Word und Excel Dokumente in das neu erstellte Verzeichnis auf dem Share
4. Nun sollen in allen Word und Excel Dokumenten gewisse Platzhalter ersetzt werden. Die Werte die in den Platzhaltern eingefügt werden sollen, müssen natürlich irgendwie vorher definiert werden.
Mein Vorgänger wollte dies alles mit einem Frage/Antwort Powershell Script lösen. Unsere Anwender die das Script bedienen, sollen aber selber Anpassungen machen können, was die Lösung für mich unbrauchbar macht. Außerdem verzeiht das Script keine Schreibfehler und mann muss von vorne beginnen. Des weiteren möchte ich nicht zu viel Zeit aufwenden und ein riesiges Script schreiben. Wir reden von ca. 50 Eingaben und entsprechend vielen Platzhaltern in den Dokumenten verteilt.
Ich dachte mir sowas wie eine Excel Tabelle wo unsere Anwender alle Werte für die Platzhalter eintragen können. Auf irgendeine Art und weise sollen diese Werte nun in die Dokumente geschrieben werden, dabei ging mir der Serienbrief von Word durch den Kopf. Jedoch soll es bei mir ja mehrere Dokumente anpassen und unter anderem auch Excel.
Mein weiteres Vorgehen wäre eine Lösung mit Serienbrief und Powershell gemischt aber ich wollte mich zuerst erkundigen ob es nicht einen einfacheren Weg gibt. Evtl. kennt ihr ja sogar eine fertige Lösung, ohne dass ich das Rad neu erfinden muss.
Grüsse
Ich soll für folgendes Szenario eine halb automatisierte Lösung finden.
1. Projektnummer und Name wird durch ein bestehendes Tool erfasst
2. Dieses Tool erstellt ein Verzeichnis auf einem Share mit Projektnummer und Namen
3. Das Tool kopiert eine Vorlagen-Ordner mit diversen Unterverzeichnissen, Word und Excel Dokumente in das neu erstellte Verzeichnis auf dem Share
4. Nun sollen in allen Word und Excel Dokumenten gewisse Platzhalter ersetzt werden. Die Werte die in den Platzhaltern eingefügt werden sollen, müssen natürlich irgendwie vorher definiert werden.
Mein Vorgänger wollte dies alles mit einem Frage/Antwort Powershell Script lösen. Unsere Anwender die das Script bedienen, sollen aber selber Anpassungen machen können, was die Lösung für mich unbrauchbar macht. Außerdem verzeiht das Script keine Schreibfehler und mann muss von vorne beginnen. Des weiteren möchte ich nicht zu viel Zeit aufwenden und ein riesiges Script schreiben. Wir reden von ca. 50 Eingaben und entsprechend vielen Platzhaltern in den Dokumenten verteilt.
Ich dachte mir sowas wie eine Excel Tabelle wo unsere Anwender alle Werte für die Platzhalter eintragen können. Auf irgendeine Art und weise sollen diese Werte nun in die Dokumente geschrieben werden, dabei ging mir der Serienbrief von Word durch den Kopf. Jedoch soll es bei mir ja mehrere Dokumente anpassen und unter anderem auch Excel.
Mein weiteres Vorgehen wäre eine Lösung mit Serienbrief und Powershell gemischt aber ich wollte mich zuerst erkundigen ob es nicht einen einfacheren Weg gibt. Evtl. kennt ihr ja sogar eine fertige Lösung, ohne dass ich das Rad neu erfinden muss.
Grüsse
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 383727
Url: https://administrator.de/forum/automatisierte-verzeichnisstruktur-und-dokument-anpassungen-383727.html
Ausgedruckt am: 23.12.2024 um 00:12 Uhr
12 Kommentare
Neuester Kommentar
Mein Vorgänger wollte dies alles mit einem Frage/Antwort Powershell Script lösen.
Frage-Antwort ist doof. Da hast du recht.
Was du machen kannst wäre folgendes:
- Zuerst nimmst du alle deine Word- und Excel-Dokumente und baust dir daraus Kopiervorlagen. In den Dokumenten schreibst du überall wo irgendwas ausgefüllt werden soll deine Platzhalter (bspw: [Kunde], [Projekt], ...)
- Dann erstellst du das Excel-Sheet mit den Quellangaben. In einer der Spalten muss deine Projektnummer stehen.
- Jetzt schreibst du ein Script - Powershell bietet sich da an - das zuerst in dem Excel-Sheet die Zeile sucht in der die Projektnummer steht. Danach holt es in dieser Zeile alle notwendigen Informationen
- Mit diesen Informationen machst du jetzt in jeder deiner Vorlagen ein Suchen-Ersetzen und tauschst Platzhalter durch die echte Info.
- Zum guten Schluss dann die Vorlagendokumente unter neuem Namen im Projektverzeichnis speichern.
- Fertig.
Ich würde allerdings die Projektinformationen nicht in einem Excel-Sheet ablegen sondern eine Datenbank (geht auch mit Access) dafür nehmen.
Des weiteren möchte ich nicht zu viel Zeit aufwenden und ein riesiges Script schreiben.
So ganz ohne Zeitaufwand wird es aber nichts werden. Solche Scripte/Tools fallen nicht vom Himmel und ich kennen auch keinen Generator, der das mal eben zusammenklicken lässt.
Manuel
Naja, die User müssen es ja nicht "live" in die Konsole eingeben, sondern die können es in eine "Eingabedatei" machen, die dann das Powershellskript auswertet.
Was du dazu brauchst steht in dem Artikel:
https://kevinmarquette.github.io/2016-11-06-powershell-hashtable-everyth ...
1. Reading directly from a file
2. Splatting hashtables at cmdlets
Dabei muss dein PS Skript natürlich die eingabeparameter richtig intepretieren, also über "ValueFromPipelineByPropertyName" die Werte einlesen.
Die Word/Excel dokumente kannst du mit Powershell über "Com Objekte" editieren
Was du dazu brauchst steht in dem Artikel:
https://kevinmarquette.github.io/2016-11-06-powershell-hashtable-everyth ...
1. Reading directly from a file
2. Splatting hashtables at cmdlets
Dabei muss dein PS Skript natürlich die eingabeparameter richtig intepretieren, also über "ValueFromPipelineByPropertyName" die Werte einlesen.
Die Word/Excel dokumente kannst du mit Powershell über "Com Objekte" editieren
Servus.
Grüße Uwe
Zitat von @NetzwerkDude:
Die Word/Excel dokumente kannst du mit Powershell über "Com Objekte" editieren
Oder schneller geht's bei Bedarf auch ohne das lahme COM .Die Word/Excel dokumente kannst du mit Powershell über "Com Objekte" editieren
function Replace-StringsInOfficeFiles {
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)][string[]]$FullName,
[Parameter(Mandatory=$true)][hashtable]$replacements
)
Begin{
# Benötigt wird mindestens NET-Framework 4.5 und Powershell 3.0
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.Filesystem
}
Process{
foreach($file in $fullname){
try{
write-verbose "Working on file '$($file)'..."
# Word-Dokument als ZIP-Datei im Update-Modus öffnen
$zipfile = [System.IO.Compression.ZipFile]::Open($file,[System.IO.Compression.ZipArchiveMode]::Update)
$entries = $null
$remove = @()
# Zu durchsuchende XML-Files des Office Dokumentes selektieren
switch -regex ([IO.Path]::GetExtension($file)){
'^\.doc[xm]$' {
$entries = $zipfile.Entries | ?{$_.FullName -match '^(word/(document|footnotes|endnotes)\.xml|word/(header|footer)\d*\.xml)$'}
break
}
'^\.xls[xm]$' {
$entries = $zipfile.Entries | ?{$_.FullName -match '^xl/(worksheets/|sharedStrings).*\.xml$'}
break
}
default{
throw "Extension of file '$file' not supported."
}
}
foreach($entry in $entries){
$tmp = "$env:TEMP\$($entry.Name)"
Remove-Item $tmp -Force -EA SilentlyContinue | out-null
# *.xml extrahieren
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry,$tmp)
# Datei als XML Object laden
$xml = new-object xml
$xml.Load($tmp)
$found = $false
foreach($searchitem in $replacements.GetEnumerator()){
if ($xml.DocumentElement.InnerText -match [regex]::Escape($searchitem.Key)){
$found = $true
# Einträge in Nodes ersetzen
$xml.SelectNodes("//*/text()") | ?{$_.InnerText -match [regex]::Escape($searchitem.Key)} | %{
write-verbose "Replacement found in text '$($_.InnerText)' => Replacing : $($searchitem.Key) => $($searchitem.Value)"
$_.InnerText = $_.InnerText -replace [regex]::Escape($searchitem.Key),$searchitem.Value
}
}
}
if ($found){
$xml.Save($tmp)
# geänderte Datei wieder hinzufügen
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipfile,$tmp,$entry.FullName) | out-null
$remove += $entry
}
# Temporäre Files löschen
del $tmp -Force -ErrorAction SilentlyContinue
}
# lösche ersetzte Dokumentteile im ZIP
$remove | %{$_.Delete()}
write-verbose "Done => '$file'."
}catch{
Write-Error -Message $_.Exception.Message
}finally{
# Zipfile-Resourcen freigeben
$zipfile.Dispose()
}
}
}
End{
}
}
# Ordner der zu verarbeiten ist
$folder = 'D:\Ordner'
<# Datei mit folgendem Aufbau(Format) erstellen und ins Skriptverzeichnis als 'parameters.txt' speichern
Search1 = Replace1
Search2 = Replace2
Search3 = Replace3
#>
$parameterfile = "$PSScriptRoot\parameters.txt"
# Parameter-Datei als Hashtable einlesen
[hashtable]$parametertable = gc $parameterfile -raw | ConvertFrom-StringData
# In einem Ordner rekursiv *.xlsx und *.docx verarbeiten
gci $folder -Include *.xlsx,*.docx -File -Recurse | Replace-StringsInOfficeFiles -replacements $parametertable -Verbose
Die machen nichts wenn du beim Import der Textdatei das richtige Encoding verwendest. Der Rest wird alles intern in UTF8 erledigt.
Das Skript ist für einfache Ersetzungen gedacht ohne dabei komplexe Formatierungen mit einzubeziehen.
Oder -Encoding Default wenn es sich um Standard ANSI handelt. Das Encoding erkennt Powershell normalerweise automatisch, aber nur sofern die Datei es im Header auch definiert.
Wenn ich das Script richtig verstehe ersetzt es die Platzhalter nicht direkt im Word, sondern das Dokument wird in reiner Textform geöffnet.
Nein, das Dokument wird als ZIP-Archiv geöffnet und die entsprechenden XML-Parts als XML-Document eingelesen, dann die Nodes auf die Platzhalter durchsucht, ersetzt, gespeichert und das ganze wieder dem ZIP hinzugefügt.Sollte ich bei den Platzhaltern auf eine spezielle Schreibweise oder Formatierung achten?
Ja deine Platzhalter nutzen leider größer und kleiner Zeichen (<>), das ist gerade bei XML ein Problem da müsste man noch aufwendiger eingreifen da diese im Dokument in < und > gewandelt werden und in separaten XML-Knoten landen. Also am besten keine XML oder HTML spezifischen Sonderzeichen nutzen, sondern z.B. doppelte Hashes (##Platzhalter##) oder ähnliches.Das Skript ist für einfache Ersetzungen gedacht ohne dabei komplexe Formatierungen mit einzubeziehen.
Noch eine andere Frage, habe bisher keine Lösung dazu gefunden... Kann ich Powershell irgendwie beibringen, dass es in den zu ersetzenden Texten (z.B. oben Replace1) Umlaute benutzen kann/soll?
Klar das Encoding beim Import (Get-Content) mit dem Parameter -Encoding anpassen. bei UTF8 Datei so[hashtable]$parametertable = gc $parameterfile -raw -Encoding UTF8 | ConvertFrom-StringData
Im XML werden Änderungen separat geschrieben
Wie oben geschrieben für "einfache" Platzhalter ohne einzelne separate Formatierungen von einzelnen Wörtern oder Zeichen des Platzhalters klappt das noch. Sobald du also auf den Platzhaltertext unterschiedliche Formatierungen vornimmst Rechtschreibung anwendest etc. geht es nicht mehr. Wie sollte der Algorithmus also jetzt die Formatierung die du auf den Platzhalter angewendet hast auf deinen ersetzten Text anwenden ? Dafür bräuchte man schon eine Glaskugel.