2016-04-27 11 views
2

Gibt es eine Möglichkeit, auf Text in einem vorhandenen docx-Dokument in einem Textfeld mit python-docx zuzugreifen und es zu bearbeiten?Python-docx-Absatz in Textfeld

Ich habe versucht, ein Schlüsselwort in allen Absätzen in einem Dokument von Iteration zu finden:

doc = Document('test.docx') 

for paragraph in doc.paragraphs: 
    if '<DATE>' in paragraph.text: 
     print('found date: ', paragraph.text) 

Es wird gefunden, wenn in normalen Text platziert, aber nicht in einer Textbox.

+0

In Word-Dateien leben TextBoxen in einem separaten Objekt. Vom flüchtigen googlen hat 'python-docx' Zugriff auf InlineShapes, aber nicht auf TextBoxes. – usr2564301

Antwort

2

Nicht über die API, noch nicht mindestens. Sie müssten die XML-Struktur, in der sie sich befinden, aufdecken und auf die Ebene lxml und vielleicht XPath gehen, um sie zu finden. So etwas wie dies könnte ein Anfang sein:

body = doc._body 
# assuming differentiating container element is w:textBox 
text_box_p_elements = body.xpath('.//w:textBox//w:p') 

Ich habe keine Ahnung, ob textBox ist der eigentliche Element Name hier, würden Sie, dass aus mit dem Rest der XPath-Pfad Details sortieren müssen, aber dieser Ansatz wird wahrscheinlich Arbeit. Ich verwende häufig ähnliche Ansätze, um Features zu umgehen, die noch nicht in die API integriert sind.

opc-diag ist ein nützliches Werkzeug zur Überprüfung der XML. Der grundlegende Ansatz besteht darin, eine minimal kleine .docx-Datei zu erstellen, die den Typ der Sache enthält, die Sie suchen möchten. Dann opc-Diag verwenden, um die XML-Wort erzeugt zu inspizieren, wenn Sie die Datei speichern:

$ opc browse test.docx document.xml 

http://opc-diag.readthedocs.org/en/latest/index.html

+0

Vielen Dank für die Einsicht in diesen allgemeinen Ansatz. Das aktuelle Projekt ist nicht befriedigend, sich in diesem speziellen Teil zu vertiefen - also fand ich einen Weg, alles in einen schwebenden Tisch anstatt in ein Textfeld zu stellen. Übrigens: Tolle Arbeit mit dem docx-Projekt. Vielen Dank und bitte halten Sie diese Arbeit am Laufen. – Stefan

+0

Dies könnte durch Hinzufügen einer Textrahmen (framePr) -Eigenschaft zu einem Absatz erreicht werden: http://officeopenxml.com/WPparagraph-textFrames.php –

2

Eine Abhilfe für Textfelder, die nur formatierten Text enthalten ist eine schwebende, formatierte Tabelle zu verwenden. Es kann fast wie eine Textbox (Rahmen, Farben, etc.) gestaltet werden und ist leicht zugänglich durch die docx API.

doc = Document('test.docx') 

for table in doc.tables: 
    for row in table.rows: 
     for cell in row.cells: 
      for paragraph in cell.paragraphs: 
       if '<DATE>' in paragraph.text: 
        print('found date: ', paragraph.text)