Wie Text aus .docx-Datei in Tabellen finden und ersetzen?
Verfasst: Montag 12. Dezember 2022, 03:11
Ich habe im folgenden ein Skript, dass formatierten Text aus HTML Dateien liest, dann eine präparierte docx Datei öffnet
und bestimmte Wörter durch den HTML-Text der HTML-Dateien ersetzt und es als neue docx-Datei speichert.
Also wenn in der Word-Datei das Wort "{{ENTRY_1}}" steht, wird es durch den Inhalt der HTML-Datei "entry_1.html" ersetzt usw.
Soweit funktioniert das Skript ersteinmal.
Aber sobald die "Tags" wie "{{ENTRY_1}}","{{ENTRY_2}}" und "{{ENTRY_3}}" innerhalb einer Tabelle stehen, ist die "output.docx" nach dem Speichern leer!
Hier der Code, welcher für docx Dokumente funktioniert, wenn der Text nicht in Tabellen steht:
Wie ich mittlerweile rausgefunden habe, verarbeitet der Code nur die Abschnitte, die als Absätze markiert sind, nicht jedoch, wenn es innerhalb einer Tabelle im docx-Dokument vorkommt.Entsprechend werden die Tag-Wörter auch nicht in der "template.docx" Datei durch die Inhalte der HTML-Dateien ersetzt:
Ich habe versucht dafür den Code auf Folgendes zu ändern, jedoch leider ohne Erfolg:
Ich habe im "template.docx" Dokument, Text innerhalb als auch außerhalb von Tabellen stehen und möchte das er gefunden wird, dann ersetzt durch den HTML-Text und als "output.docx" gespeichert wird. Natürlich soll auch alles andere was im "template.docx" Dokument steht und nichts mit Tag-Wörtern zu tun hat in die "output.docx" übernommen werden. Also irgendein Text der normal, in fett, unterstrichen, kursiv oder farblich markiert ist.
Mir ist nämlich außerdem auch aufgefallen, dass jegliche Art von Formatierungen im "template.docx" nicht in die "output.docx" übernommen werden.
In dem Fall habe ich:
-farblich markierten Text
-Text der mit dem Effekt "Texthervorherbungsfarbe" markiert ist
-und Text in fett, kursiv, oder unterstrichen
In der Output-Datei ist der zuvor formartierte Text aus der "template.docx" Datei dann leider nur noch unformartiert.
Das einzige was funktioniert ist:
-dass formatierter Text aus den HTML-Dateien auch in die "output.docx" Datei formartiert übernommen wird
-und dass Tags wie "{{ENTRY_1}}" erfolgreich ersetzt werden, solange sie nicht in einer Tabelle stehen.
Wie muss der Code aussehen, damit das alles funktioniert?
Liebe Grüße,
Marlon
und bestimmte Wörter durch den HTML-Text der HTML-Dateien ersetzt und es als neue docx-Datei speichert.
Also wenn in der Word-Datei das Wort "{{ENTRY_1}}" steht, wird es durch den Inhalt der HTML-Datei "entry_1.html" ersetzt usw.
Soweit funktioniert das Skript ersteinmal.
Aber sobald die "Tags" wie "{{ENTRY_1}}","{{ENTRY_2}}" und "{{ENTRY_3}}" innerhalb einer Tabelle stehen, ist die "output.docx" nach dem Speichern leer!
Hier der Code, welcher für docx Dokumente funktioniert, wenn der Text nicht in Tabellen steht:
Code: Alles auswählen
import docx
from html.parser import HTMLParser
from tkinter import Button, Tk
#HTMLParser to parse the html files
class TKinterHTMLParser2(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.doc = docx.Document()
self.paragraph = self.doc.add_paragraph()
self.bold = False
self.italic = False
self.underline = False
def handle_starttag(self, tag, attrs):
if tag == 'b':
self.bold = True
if tag == 'i':
self.italic = True
if tag == 'u':
self.underline = True
def handle_endtag(self, tag):
if tag == 'b':
self.bold = False
if tag == 'i':
self.italic = False
if tag == 'u':
self.underline = False
def handle_data(self, data):
run = self.paragraph.add_run(data)
run.bold = self.bold
run.italic = self.italic
run.underline = self.underline
def save(self, filename):
self.doc.save(filename)
class MyApp:
def __init__(self, root):
#button to start the conversion
self.button = Button(root, text="Konvertieren", command=self.convert)
self.button.pack()
#function to convert the html files to docx
def convert_html_to_docx(self):
# variables for the template and output document
template_doc = docx.Document('template.docx')
output_doc = docx.Document()
parser = TKinterHTMLParser2()
# open the html files and parse them
with open('entry_1.html') as f:
parser.feed(f.read())
entry1_doc = parser.doc
parser = TKinterHTMLParser2()
with open('entry_2.html') as f:
parser.feed(f.read())
entry2_doc = parser.doc
parser = TKinterHTMLParser2()
with open('entry_3.html') as f:
parser.feed(f.read())
entry3_doc = parser.doc
# copy the template document to the output document
for paragraph in template_doc.paragraphs:
output_doc.add_paragraph(paragraph.text)
# replace the placeholders with the parsed html files
for paragraph in output_doc.paragraphs:
if "{{ENTRY_1}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_1}}", "")
# copy the formatting from the parsed html file
for p in entry1_doc.paragraphs:
for run in p.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
if "{{ENTRY_2}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_2}}", "")
# copy the formatting from the parsed html file
for p in entry2_doc.paragraphs:
for run in p.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
if "{{ENTRY_3}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_3}}", "")
# copy the formatting from the parsed html file
for p in entry3_doc.paragraphs:
for run in p.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
# save the output document
output_doc.save('output.docx')
# button command
def convert(self):
self.convert_html_to_docx()
root = Tk()
myapp = MyApp(root)
root.mainloop()
Ich habe versucht dafür den Code auf Folgendes zu ändern, jedoch leider ohne Erfolg:
Code: Alles auswählen
import docx
from html.parser import HTMLParser
from tkinter import Button, Tk
#class that converts the html to docx
class TKinterHTMLParser2(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.doc = docx.Document()
self.paragraph = self.doc.add_paragraph()
self.bold = False
self.italic = False
self.underline = False
def handle_starttag(self, tag, attrs):
if tag == 'b':
self.bold = True
if tag == 'i':
self.italic = True
if tag == 'u':
self.underline = True
def handle_endtag(self, tag):
if tag == 'b':
self.bold = False
if tag == 'i':
self.italic = False
if tag == 'u':
self.underline = False
def handle_data(self, data):
run = self.paragraph.add_run(data)
run.bold = self.bold
run.italic = self.italic
run.underline = self.underline
def save(self, filename):
self.doc.save(filename)
class MyApp:
def __init__(self, root):
#button to start the conversion
self.button = Button(root, text="Konvertieren", command=self.convert)
self.button.pack()
#function to convert the html to docx
def convert_html_to_docx(self):
parser = TKinterHTMLParser2()
with open('entry_1.html') as f:
parser.feed(f.read())
entry1_doc = parser.doc
parser = TKinterHTMLParser2()
with open('entry_2.html') as f:
parser.feed(f.read())
entry2_doc = parser.doc
parser = TKinterHTMLParser2()
with open('entry_3.html') as f:
parser.feed(f.read())
entry3_doc = parser.doc
template_doc = docx.Document('template.docx')
output_doc = docx.Document()
#copy the template docx to the output docx
for paragraph in template_doc.paragraphs:
output_doc.add_paragraph(paragraph.text)
for table in template_doc.tables:
for row in table.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
if "{{ENTRY_1}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_1}}", "")
for paragraph in entry1_doc.paragraphs:
for run in paragraph.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
elif "{{ENTRY_2}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_2}}", "")
for paragraph in entry2_doc.paragraphs:
for run in paragraph.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
elif "{{ENTRY_3}}" in paragraph.text:
paragraph.text = paragraph.text.replace("{{ENTRY_3}}", "")
for paragraph in entry3_doc.paragraphs:
for run in paragraph.runs:
new_run = paragraph.add_run(run.text)
new_run.bold = run.bold
new_run.italic = run.italic
new_run.underline = run.underline
new_run.font.name = run.font.name
new_run.font.size = run.font.size
new_run.font.color.rgb = run.font.color.rgb
output_doc.save('output.docx')
#function to start the conversion
def convert(self):
self.convert_html_to_docx()
root = Tk()
myapp = MyApp(root)
root.mainloop()
Mir ist nämlich außerdem auch aufgefallen, dass jegliche Art von Formatierungen im "template.docx" nicht in die "output.docx" übernommen werden.
In dem Fall habe ich:
-farblich markierten Text
-Text der mit dem Effekt "Texthervorherbungsfarbe" markiert ist
-und Text in fett, kursiv, oder unterstrichen
In der Output-Datei ist der zuvor formartierte Text aus der "template.docx" Datei dann leider nur noch unformartiert.
Das einzige was funktioniert ist:
-dass formatierter Text aus den HTML-Dateien auch in die "output.docx" Datei formartiert übernommen wird
-und dass Tags wie "{{ENTRY_1}}" erfolgreich ersetzt werden, solange sie nicht in einer Tabelle stehen.
Wie muss der Code aussehen, damit das alles funktioniert?
Liebe Grüße,
Marlon