Création, édition et analyse de fichiers DOCX
Un .docx est une archive ZIP de fichiers XML. Choisissez votre approche en fonction de la tâche :
| Tâche | Approche |
|---|---|
| Créer un nouveau document | Écrire un script docx (npm) — voir les pièges ci-dessous |
| Éditer un document existant | unzip → modifier word/document.xml → zip (docx-js ne peut pas ouvrir les fichiers existants) |
| Lire le contenu | pandoc -t markdown file.docx |
Les chemins de scripts ci-dessous sont relatifs au répertoire de cette compétence.
Création avec docx-js — pièges
docx est préinstallé — n'exécutez pas npm install d'abord ; écrivez le script et utilisez require('docx') directement. Seulement si ce require échoue : npm install docx. Le modèle connaît l'API ; voici les pièges :
- La taille de page par défaut est A4. Pour du US Letter, définissez
page: { size: { width: 12240, height: 15840 } }(en DXA ; 1440 = 1″). - Paysage : passez les dimensions portrait et
orientation: PageOrientation.LANDSCAPE— docx-js échange la largeur et la hauteur en interne. - Les tableaux nécessitent des largeurs doubles : définissez
columnWidthssur le tableau ETwidthsur chaque cellule, tous deux enWidthType.DXA(PERCENTAGE ne fonctionne pas dans Google Docs). Les largeurs de colonnes doivent totaliser la largeur du tableau. - Fond de tableau : utilisez
ShadingType.CLEAR, jamaisSOLID(rendu en noir). - Listes : n'insérez jamais
•littéralement ; utilisez une configurationnumberingavecLevelFormat.BULLET. ImageRunnécessitetype:("png","jpg", …).PageBreakdoit être à l'intérieur d'unParagraph.- N'utilisez jamais
\n— utilisez des élémentsParagraphséparés. - TOC : les titres doivent utiliser les
HeadingLevel.*intégrés ; les styles de titre personnalisés nécessitentoutlineLevelpour apparaître. - N'utilisez pas un tableau comme filet horizontal — utilisez plutôt une bordure inférieure de paragraphe.
- Points de suite / aligné à droite sur la même ligne : utilisez
PositionalTab(alignment: PositionalTabAlignment.RIGHT,leader: PositionalTabLeader.DOT) à l'intérieur d'unTextRun, pas de.littéraux ou de remplissage d'espaces.
Vérifier la sortie
Après avoir écrit un .docx, convertissez-le et examinez-le :
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg # puis lisez les images
pdftoppm complète les numéros de page avec des zéros sur la largeur du nombre total de pages (page-01.jpg…page-12.jpg).
Éditer des documents existants
Les fichiers .doc hérités doivent d'abord être convertis : python scripts/office/soffice.py --headless --convert-to docx file.doc.
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete # supprimer les entrées de liens symboliques — les docx de sources externes ne sont pas fiables
python scripts/merge_runs.py unpacked/ # fusionner les fragments de texte pour rendre le texte trouvable
# modifier unpacked/word/document.xml sur place — ne PAS reformater ni pretty-print
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx # vérifications XSD ; --auto-repair corrige les problèmes courants
# suivi des modifications ? ajoutez --author "<le nom sous lequel vous avez fait le suivi>" pour vérifier que chaque modification est suivie
Word répartit le texte sur de nombreuses balises <w:r> (identifiants de révision, marqueurs de vérification orthographique), donc une phrase que vous voyez dans le document n'existe souvent pas en tant que chaîne contiguë dans le XML. merge_runs.py fusionne les fragments adjacents formatés de manière identique dans word/document.xml sans modifier le contenu ni le rendu ; il accepte aussi directement un .docx (python scripts/merge_runs.py doc.docx -o merged.docx).
Modifications suivies : lors du suivi des modifications, validez avec --author "<le nom sous lequel vous avez fait le suivi>" (nécessite --original) — il signale tout texte que vous avez modifié sans <w:ins>/<w:del> autour, ce qui est facile à faire accidentellement et invisible dans la vue acceptée. Encapsulez les fragments dans <w:ins>/<w:del> avec les attributs w:id, w:author, w:date. À l'intérieur de <w:del>, l'élément de texte est <w:delText>, pas <w:t>. Une marque de paragraphe supprimée (<w:pPr><w:rPr><w:del w:id=".." w:author=".." w:date=".."/></w:rPr></w:pPr>) signifie "fusionner ce paragraphe dans le suivant" — donc supprimer un paragraphe carrément, c'est cela plus un <w:del> autour de chaque fragment. <w:del/> doit précéder les autres enfants de rPr ; leur ordre est imposé par le schéma.
Pour produire une copie propre avec toutes les modifications suivies acceptées : python scripts/accept_changes.py in.docx out.docx.
Accepter une marque de paragraphe supprimée devrait joindre ce paragraphe à celui du dessous, donc un paragraphe dont tous les fragments sont tous supprimés disparaît. Word fait cela ; accept_changes.py et pandoc --track-changes=accept ne le font pas toujours. Les deux échouent de la même manière — ils suppriment le texte supprimé mais laissent le paragraphe vidé derrière, qui apparaît comme une puce vide parasite lorsqu'il était numéroté automatiquement :
pandoc --track-changes=acceptne joint jamais les paragraphes.accept_changes.py(LibreOffice) les joint correctement, sauf lorsque le paragraphe supprimé est suivi d'un paragraphe d'espacement vide.
Une puce vide dans l'une ou l'autre vue est un artefact de cette vue, pas un défaut du document. Vérifiez les suppressions de paragraphes dans le XML.
Commentaires
Les commentaires nécessitent six fichiers interconnectés. Utilisez l'assistant — mode répertoire lorsque vous allez aussi modifier document.xml (évite un cycle de décompression/recompression), mode .docx direct sinon :
# Contre un répertoire déjà décompressé (préféré lors du placement de marqueurs)
python scripts/comment.py unpacked/ "Le plafond des frais est trop bas"
python scripts/comment.py unpacked/ "D'accord" --parent 0
# Contre un .docx directement
python scripts/comment.py contract.docx "Ce plafond est trop bas" -o annotated.docx
Le script écrit comments.xml, commentsExtended.xml, commentsIds.xml, commentsExtensible.xml, les relations et les remplacements de type de contenu. Les ID de commentaires sont attribués automatiquement. Il imprime ensuite l'extrait <w:commentRangeStart>/<w:commentRangeEnd>/<w:commentReference> à ajouter à word/document.xml pour que le commentaire soit ancré à un texte spécifique — jusqu'à ce que vous placiez ces marqueurs, le commentaire existe mais n'est pas visible.
Dépendances
docx (npm, préinstallé — installez seulement si require('docx') échoue) · pandoc · LibreOffice (soffice) · pdftoppm (Poppler)
Cette compétence est créée et maintenue par Anthropic. Incluse ici sans modification, à l'exception des métadonnées de préambule ; voir LICENSE.txt pour les conditions.