web-dev-qa-db-fra.com

Création d'en-tête et pied de page dans les versions antérieures à 0.8.8

Existe-t-il une solution de contournement pour ajouter des en-têtes et des pieds de page dans un fichier Microsoft Word (docx)?

Ceux-ci ne sont pas implémentés dans les versions de python-docxavant à 0.8.8.

Plus précisément, je voudrais ajouter:

  1. Numéro de page aux pieds de page
  2. Du texte aléatoire dans les en-têtes

Le code idéal se présente comme suit:

from docx import Document

document = Document()

# Add header and footer on all pages

document.save("demo.docx")
9
ReKx

L'approche par modèle fonctionne et son principal avantage est qu'il s'agit d'une véritable solution multiplateforme. Cependant, cela nécessite qu'un style ait déjà été appliqué une fois dans le document.

Prenons une version (simplifiée) de l'exemple de jouet du python-docxpage de documentation .

La première étape consiste à créer le modèle de document:

from docx import Document

document = Document()

document.add_heading('Document Title', 0)

p = document.add_paragraph('A plain paragraph having some ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True

document.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='IntenseQuote')

document.add_paragraph(
    'first item in unordered list', style='ListBullet'
)
document.add_paragraph(
    'first item in ordered list', style='ListNumber'
)

document.save('demo.docx')

(Notez que vous pouvez également appliquer les styles manuellement dans cette première étape sans utiliser python-docx, c'est-à-dire depuis Word.)

Ensuite, vous ouvrez ce demo.docx dans Microsoft Word où vous:

  1. ajoutez l'en-tête souhaité
  2. insérer les numéros de page dans le menu
  3. enregistrer le document

Une fois que vous avez fait ce qui précède, vous supprimez simplement le contenu principal du demo.docx document (mais pas le contenu de l'en-tête et du pied de page!) et enregistrez à nouveau le fichier.

Dans la deuxième étape, vous appelez demo.docx en utilisant python-docx pour effectuer les modifications dont vous avez besoin:

from docx import Document

document = Document('demo.docx')

document.add_heading('A New Title for my Document', 0)

p = document.add_paragraph('A new paragraph having some plain ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True

document.add_heading('New Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='IntenseQuote')

document.add_paragraph(
    'first new item in unordered list', style='ListBullet'
)
document.add_paragraph(
    'first new item in ordered list', style='ListNumber'
)

document.save('demo.docx')

Vous pouvez même ajouter d'autres éléments de contenu, comme un tableau avec un style de tableau existant:

from docx import Document

document = Document('demo.docx')

document.add_page_break()

recordset = [ [1, "101", "Spam"], [2, "42", "Eggs"], [3, "631", "Spam, spam, eggs, and spam"]]

table = document.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'

for item in recordset:
    row_cells = table.add_row().cells
    row_cells[0].text = str(item[0])
    row_cells[1].text = str(item[1])
    row_cells[2].text = item[2]

table.style = 'ColorfulShading'

document.save('demo.docx')

Bien sûr, on peut éviter de répéter la première étape tout le temps, en copiant le fichier personnalisé puis en y apportant les modifications nécessaires (par exemple demo_copy.docx) sans affecter le modèle:

import shutil
shutil.copyfile('demo.docx', 'demo_copy.docx')

Enfin, il convient de mentionner que vous pouvez également utiliser personnalisé styles! Pour un exemple de procédure à suivre en utilisant python-docx et styles de tableau voir ici .

6
Pearly Spencer

Ce n'est pas le plus élégant (il vous oblige à naviguer entre VBA et Python), mais vous pouvez utiliser la bibliothèque win32com pour exploiter la fonctionnalité MS Word. Cela nécessite bien sûr une machine Windows avec MS Office installé.

import win32com.client as win32
msword = win32.gencache.EnsureDispatch('Word.Application')
doc = msword.Documents.Add
doc.Sections(1).Footers(1).Range.Text = r'Text to be included'
doc.Sections(1).Footers(1).PageNumbers.Add()
1
Eliot K

L'une des solutions de contournement que vous pourriez utiliser consiste à utiliser un modèle de document créé dans Word. Créez un document vierge, ajoutez l'en-tête avec le texte souhaité et le pied de page avec les numéros de page et enregistrez le document. Utilisez ensuite:

from docx import Document
document = Document("template.docx")
# Do your editing
document.save("demo.docx")

... et vous devriez pouvoir modifier tout le reste tout en préservant l'en-tête et le pied de page.

En fin de compte, je pense que cette solution fonctionnerait très bien pour le problème des numéros de page. Si vous avez besoin d'un texte d'en-tête unique pour chaque document, les choses pourraient devenir un peu délicates. Si tel est le cas, vous souhaiterez peut-être essayer de modifier directement le XML du fichier docx. Vous pouvez l'utiliser dans le terminal:

unzip template.docx

... pour récupérer les fichiers XML docx dans le répertoire. Vous pouvez également utiliser zipfile pour le faire en python:

import zipfile

document = zipfile.ZipFile("template.docx")
for xml in document.filelist:
    if "header" in xml.filename:
        read = document.read(xml.filename)
        print(read.decode())

L'instruction print imprimera l'intégralité du fichier XML, mais vous devriez pouvoir trouver ce petit morceau:

<w:r><w:t>ThisIsMyHeader</w:t></w:r>

Quel sera le texte dans votre en-tête. Tout ce que vous aurez à faire est de modifier le fichier XML, de regrouper les fichiers, puis de modifier le type de fichier en docx.

C'est évidemment une solution de rechange super hacky et malheureusement je n'ai pas pu le faire fonctionner pleinement, mais ce serait au moins un bon pas dans la bonne direction si vous en avez absolument besoin.

Bonne chance!

0
Kush