Créer des documents Word depuis R avec officer

Construire et mettre en forme des rapports .docx — titres, paragraphes, tableaux et graphiques — depuis R

Programming

Apprenez à créer des documents Word depuis R avec le package officer — ajoutez des titres, des paragraphes mis en forme, des tableaux via flextable, des images et des graphiques ggplot2, des sauts de page, et démarrez même à partir d’un modèle, puis générez un rapport .docx par programmation. Le remplacement moderne de ReporteRs, désormais abandonné.

Auteur·rice
Date de publication

8 juillet 2026

Modifié

17 juillet 2026

AstuceCe que vous allez construire
  • Un vrai fichier .docx généré entièrement depuis R — titres, paragraphes, tableaux et graphiques, sans copier-coller manuel.
  • Du texte mis en forme (gras, couleur, taille de police) et des hyperliens via fpar() / ftext().
  • Des tableaux de qualité professionnelle avec flextable et des graphiques ggplot2 déposés directement dans le document.
  • Des sauts de page, une table des matières qui se met à jour automatiquement, et comment démarrer à partir de votre propre modèle d’entreprise.
  • Chaque commande est du R réel, à copier-coller — il vous suffit d’officer et de flextable.

Besoin de remettre un rapport Word à un collègue — pas un PDF, pas une page HTML — directement depuis votre analyse ? Le package officer écrit des fichiers Microsoft Word (.docx) et PowerPoint (.pptx) natifs depuis R. Vous construisez le document sous forme d’objet en mémoire, ajoutez le contenu bloc par bloc, puis l’écrivez sur le disque. Comme c’est du R pur, le rapport se reconstruit tout seul à chaque changement de vos données — aucune remise en forme à la main.

Si vous avez suivi l’ancien tutoriel SThDA/Datanovia qui utilisait ReporteRs, sachez que ReporteRs est abandonné (retiré du CRAN, dépendant de Java, plus installable). officer est son successeur moderne et multiplateforme — du même auteur, David Gohel — sans Java, activement maintenu, et le standard actuel de la communauté. Ce billet refait tout le flux de travail sur officer + flextable.

De ReporteRs à officer

Si vous avez du vieux code ReporteRs, les concepts se transposent presque un pour un — il suffit d’échanger les noms de fonctions :

ReporteRs (abandonné) officer (moderne)
docx() read_docx()
addTitle() body_add_par(style = "heading 1")
addParagraph() body_add_par(style = "Normal")
pot() + textProperties() fpar() + ftext() + fp_text()
addFlexTable() body_add_flextable() (construit avec flextable)
addPlot() body_add_gg()
addImage() body_add_img()
addPageBreak() body_add_break()
addTOC() body_add_toc()
writeDoc() print(doc, target = ...)

Le schéma est toujours le même : créer un document, y faire passer du contenu, l’imprimer dans un fichier.

Installer et charger officer

Installez officer (pour le document) et flextable (pour les tableaux) depuis le CRAN :

install.packages(c("officer", "flextable"))

Puis chargez-les. Nous utiliserons aussi ggplot2 pour les graphiques plus loin.

library(officer)
library(flextable)
library(ggplot2)

Construire votre premier document Word

Chaque document commence par read_docx(), qui ouvre un document vierge basé sur le modèle intégré d’officer. Vous ajoutez ensuite du contenu avec body_add_par(), en passant un nom de style issu du modèle — "heading 1", "heading 2", et "Normal" pour le corps de texte. Enfin, print() avec une cible (target) écrit le .docx sur le disque.

Le code ci-dessous construit un rapport en deux sections : un titre, un paragraphe d’introduction et une sous-section « Background ».

library(officer)

doc <- read_docx()

doc <- body_add_par(doc, "Monthly analysis report", style = "heading 1")
doc <- body_add_par(
  doc,
  "This report is generated from R with the officer package. Every heading, paragraph, table, and chart below is written programmatically.",
  style = "Normal"
)

doc <- body_add_par(doc, "Background", style = "heading 2")
doc <- body_add_par(
  doc,
  "officer writes native Microsoft Word (.docx) files. It is the modern, cross-platform replacement for the retired ReporteRs package.",
  style = "Normal"
)

print(doc, target = "first-report.docx")

Ouvrez first-report.docx dans Word et vous obtenez un document correctement mis en forme — les niveaux de titre sont de vrais styles Word, ils apparaissent donc dans le volet de navigation et dans toute table des matières. Voici la page rendue :

A rendered Word page with a level-1 heading 'Monthly analysis report', an intro paragraph, and a 'Background' subheading, generated from R by officer.

Note

Quels noms de style puis-je utiliser ? Les styles disponibles proviennent du modèle sous-jacent. Listez-les avec styles_info(doc) — le modèle par défaut fournit "heading 1""heading 3" et "Normal". Pour obtenir "Title", "List Bullet" ou vos styles de marque, partez d’un modèle qui les définit (voir Démarrer à partir d’un modèle Word plus bas).

Mettre en forme le texte : gras, couleur et taille de police

Pour un paragraphe à mise en forme mixte, construisez-le à partir de fragments (runs) de texte stylé plutôt que d’une seule chaîne. Trois fonctions travaillent ensemble :

  • fp_text() définit un format de texte (couleur, taille, gras, italique, souligné).
  • ftext() associe un morceau de texte à un format.
  • fpar() assemble les fragments en un paragraphe mis en forme, ajouté avec body_add_fpar().

L’exemple ci-dessous définit deux formats réutilisables, puis construit une phrase qui les mélange et ajoute un hyperlien stylé avec hyperlink_ftext().

library(officer)

# Reusable text formats
blue_bold   <- fp_text(color = "#3a86d4", bold = TRUE, font.size = 12)
orange_ital <- fp_text(color = "#e8590c", italic = TRUE, font.size = 14)
plain       <- fp_text(font.size = 12)

# A paragraph assembled from formatted runs
para <- fpar(
  ftext("This Word document is created using ", plain),
  ftext("R software", orange_ital),
  ftext(" and the ", plain),
  ftext("officer", blue_bold),
  ftext(" package.", plain)
)

doc <- read_docx()
doc <- body_add_par(doc, "Formatted text", style = "heading 1")
doc <- body_add_fpar(doc, para)

# A styled hyperlink
doc <- body_add_fpar(doc, fpar(
  hyperlink_ftext(
    href = "https://www.datanovia.com",
    text = "Visit Datanovia",
    prop = fp_text(color = "#3a86d4", underlined = TRUE, bold = TRUE)
  )
))

print(doc, target = "formatted-report.docx")

Chaque fragment conserve sa propre couleur, taille et graisse — exactement ce que faisait pot() dans ReporteRs, mais de façon composable. Le résultat rendu :

A rendered Word page showing a sentence with 'R software' in orange italics and 'officer' in blue bold, plus a blue underlined 'Visit Datanovia' hyperlink.

Listes à puces et numérotées

Les rapports s’appuient sur les listes — une liste d’étapes à cocher, un ensemble de résultats. Vous n’avez pas besoin d’un modèle spécial pour cela : officer construit de vraies listes Word à partir de block_list_items(), puis les insère avec body_add_list(). Chaque élément est un fpar() enveloppé dans list_item() ; définissez list_type = "bullet" pour une liste non ordonnée ou list_type = "decimal" pour une liste numérotée, et utilisez level pour imbriquer.

library(officer)

# A bulleted (unordered) list
todo <- block_list_items(
  list_item(fpar("Summarize the data")),
  list_item(fpar("Visualize the distribution")),
  list_item(fpar("Check the assumptions")),
  list_type = "bullet"
)

# A numbered (ordered) list, with one nested sub-step
steps <- block_list_items(
  list_item(fpar("Import the raw data"),        level = 1),
  list_item(fpar("Fit the model"),              level = 1),
  list_item(fpar("Inspect the diagnostics"),    level = 2),
  list_item(fpar("Export the report"),          level = 1),
  list_type = "decimal"
)

doc <- read_docx()
doc <- body_add_fpar(doc, fpar(ftext("Analysis checklist", fp_text(bold = TRUE))))
doc <- body_add_list(doc, todo)
doc <- body_add_fpar(doc, fpar(ftext("Workflow steps", fp_text(bold = TRUE))))
doc <- body_add_list(doc, steps)

print(doc, target = "lists-report.docx")

Comme chaque élément est un fpar(), vous pouvez mélanger les formats à l’intérieur d’une puce exactement comme dans la section texte mis en forme ci-dessus — list_item(fpar(ftext("Critical", fp_text(color = "#e8590c", bold = TRUE)))). Le résultat rendu :

A rendered Word page with a bold 'Analysis checklist' caption over a three-item bulleted list, then a bold 'Workflow steps' caption over a numbered list whose second item has a nested numbered sub-step.

Note

Aucun modèle nécessaire pour les listes. body_add_list() (officer ≥ 0.7) écrit les définitions de puces et de numérotation dans le document lui-même, il fonctionne donc à partir du document vierge par défaut — contrairement à l’ancienne voie body_add_par(style = "List Bullet"), qui ne fonctionne que lorsque votre modèle fournit déjà ces styles de paragraphe.

Ajouter des tableaux avec flextable

Les tableaux sont la raison pour laquelle la plupart des gens se tournent vers un rapport Word. Construisez-les avec flextable, qui vous donne un contrôle total sur les bordures, les trames de fond et les polices, puis déposez le résultat dans le document avec body_add_flextable().

Commencez par transformer un data frame en flextable. theme_zebra() donne les lignes zébrées que produisait l’ancien setZebraStyle(), et autofit() dimensionne les colonnes selon leur contenu. Un flextable s’affiche directement en HTML, vous pouvez donc le prévisualiser ici même :

library(flextable)

ft <- flextable(head(iris, 5))
ft <- theme_zebra(ft)
ft <- autofit(ft)
ft

Sepal.Length

Sepal.Width

Petal.Length

Petal.Width

Species

5.1

3.5

1.4

0.2

setosa

4.9

3.0

1.4

0.2

setosa

4.7

3.2

1.3

0.2

setosa

4.6

3.1

1.5

0.2

setosa

5.0

3.6

1.4

0.2

setosa

C’est exactement l’objet qui va dans Word. L’ajouter à un document tient en une ligne :

doc <- read_docx()
doc <- body_add_par(doc, "Iris measurements", style = "heading 2")
doc <- body_add_flextable(doc, ft)
print(doc, target = "table-report.docx")

Tout ce que vous pouvez styliser dans flextable — cellules fusionnées, couleur conditionnelle, format des nombres, légendes — se répercute dans le .docx. Pour un résumé de données, flextable est bien plus puissant que l’ancien vanilla.table().

Ajouter des graphiques ggplot2 et des images

officer intègre les graphiques sous forme d’images de haute qualité. Pour un graphique ggplot2, body_add_gg() prend directement l’objet graphique et vous laisse définir la taille en pouces. Voici une boîte à moustaches maison — points en jitter et un marqueur de moyenne par-dessus les boîtes, dans l’azur de la marque :

library(ggplot2)

p <- ggplot(ToothGrowth, aes(factor(dose), len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.5) +
  stat_summary(fun = mean, geom = "point", shape = 18, size = 3, color = "#e8590c") +
  labs(x = "Vitamin C dose (mg/day)", y = "Tooth length") +
  theme_minimal()
p

A ggplot2 boxplot of guinea pig tooth length by vitamin C dose (0.5, 1, 2 mg/day) in blue, with jittered points and an orange diamond marking each group mean.

Déposez ce même p dans un document Word :

doc <- read_docx()
doc <- body_add_par(doc, "Tooth growth by dose", style = "heading 2")
doc <- body_add_gg(doc, value = p, width = 6, height = 3.4)
print(doc, target = "chart-report.docx")

Pour une image externe — un graphique enregistré, un logo, une capture d’écran — utilisez body_add_img() avec un chemin et une taille :

ggsave("chart.png", p, width = 6, height = 3.4, dpi = 150)
doc <- body_add_img(doc, src = "chart.png", width = 6, height = 3.4)

body_add_gg() fonctionne avec tout graphique basé sur grid (ggplot2, lattice) ; body_add_img() accepte les formats PNG, JPEG et similaires.

Sauts de page et table des matières

Les longs rapports ont besoin de structure. body_add_break() insère un saut de page, et body_add_toc() dépose une table des matières que Word construit à partir de vos styles de titre.

doc <- read_docx()

doc <- body_add_par(doc, "Report contents", style = "heading 1")
doc <- body_add_toc(doc)          # placeholder — Word fills it in
doc <- body_add_break(doc)        # start the body on a new page

doc <- body_add_par(doc, "Introduction", style = "heading 1")
doc <- body_add_par(doc, "Study background and objectives.", style = "Normal")
doc <- body_add_break(doc)

doc <- body_add_par(doc, "Results", style = "heading 1")
doc <- body_add_par(doc, "Findings and figures.", style = "Normal")

print(doc, target = "toc-report.docx")
Note

La table des matières se met à jour dans Word, pas dans R. body_add_toc() écrit un champ, pas la liste finie. La première fois que vous ouvrez le fichier, Word demande à mettre à jour les champs — cliquez sur Oui (ou clic droit sur la table des matières → Mettre à jour les champs). Enregistrez ensuite pour que les entrées restent.

En-têtes, pieds de page et numéros de page

Les rapports professionnels portent le même titre en haut de chaque page et un numéro de page en bas. Dans officer, ces éléments résident dans une section du document : vous construisez un en-tête et un pied de page sous forme de paragraphes block_list() et les attachez avec prop_section(). Un numéro de page n’est pas une chaîne statique — c’est un champ Word que Word recalcule, ajouté avec run_word_field() ("PAGE" pour la page courante, "NUMPAGES" pour le total).

library(officer)

# A footer with an automatic "Page X of Y"
footer <- block_list(fpar(
  ftext("Confidential  |  Page "),
  run_word_field(field = "PAGE"),
  ftext(" of "),
  run_word_field(field = "NUMPAGES")
))

# A header with the report title
header <- block_list(fpar(
  ftext("Tooth growth report", fp_text(bold = TRUE, color = "#3a86d4"))
))

doc <- read_docx()
doc <- body_add_par(doc, "Introduction", style = "heading 1")
doc <- body_add_par(doc, "Body text on a portrait page.", style = "Normal")

# Attach the header + footer to the document's default section
doc <- body_set_default_section(doc, prop_section(
  header_default = header,
  footer_default = footer,
  page_size      = page_size(orient = "portrait")
))

print(doc, target = "furniture-report.docx")

prop_section() prend aussi header_first = et header_even = (avec les footer_* correspondants) lorsque vous avez besoin d’une première page différente ou de pages paires/impaires en miroir — la même astuce de champ s’applique à chacune.

Note

Les numéros de page, comme la table des matières, se résolvent dans Word. run_word_field("PAGE") écrit un champ, pas un numéro fini. Il se remplit quand vous ouvrez le fichier (ou clic droit sur le pied de page → Mettre à jour les champs) — exactement le comportement de la table des matières ci-dessus.

Pages en paysage pour les tableaux larges

Un tableau large ou un graphique étendu a souvent besoin que la page soit tournée sur le côté. officer gère l’orientation par section : tout ce que vous ajoutez avant un appel à body_end_section_landscape() devient sa propre section paysage, et le contenu qui suit continue en portrait.

doc <- read_docx()
doc <- body_add_par(doc, "Portrait intro", style = "heading 1")
doc <- body_add_par(doc, "This page stays portrait.", style = "Normal")

# The wide content that should sit sideways
doc <- body_add_par(doc, "A very wide table sits better sideways.", style = "Normal")
doc <- body_end_section_landscape(doc, w = 11, h = 8.5)   # close the landscape block

# Back to the default portrait orientation
doc <- body_add_par(doc, "Back to portrait for the discussion.", style = "Normal")

print(doc, target = "landscape-report.docx")

Les w/h sont la largeur et la hauteur de la page en pouces (US Letter tournée sur le côté ici). Pour un contrôle plus fin — marges personnalisées, colonnes, ou un saut portrait explicite — passez un prop_section() complet à body_end_section_portrait() / body_end_section_continuous().

Démarrer à partir d’un modèle Word

Le vrai coup de maître pour un rapport professionnel : partir de votre propre modèle — un modèle avec votre logo, vos polices, vos couleurs et vos styles de paragraphe personnalisés. Passez son chemin à read_docx() et chaque style qu’il définit devient disponible.

# Open your branded template instead of the blank default
doc <- read_docx(path = "corporate-template.docx")

# Discover the style names your template defines
styles_info(doc)

# Now use those styles by name
doc <- body_add_par(doc, "Quarterly Report", style = "Title")
doc <- body_add_par(doc, "Key point", style = "List Bullet")

Concevez le modèle une fois dans Word (en-têtes, pieds de page, page de couverture, styles de marque), puis laissez R le remplir de nouveaux chiffres à chaque exécution — le rapport a toujours l’air conforme à la marque, sans aucune mise en forme manuelle.

Tout assembler : un rapport complet

Voici le schéma complet de bout en bout — un titre, une introduction, un graphique et un tableau récapitulatif, écrits dans un seul .docx. C’est l’image de couverture de ce billet : une page Word finie, générée entièrement depuis R.

library(officer)
library(flextable)
library(ggplot2)

# A chart
p <- ggplot(ToothGrowth, aes(factor(dose), len)) +
  geom_boxplot(fill = "#3a86d4", alpha = 0.7, outlier.shape = NA) +
  geom_jitter(width = 0.15, alpha = 0.5) +
  stat_summary(fun = mean, geom = "point", shape = 18, size = 3, color = "#e8590c") +
  labs(x = "Vitamin C dose (mg/day)", y = "Tooth length") +
  theme_minimal()

# A summary table: mean length per dose
tg <- aggregate(len ~ dose, data = ToothGrowth, FUN = mean)
names(tg) <- c("Dose (mg/day)", "Mean length")
ft <- autofit(theme_zebra(flextable(tg)))

# Assemble the document
doc <- read_docx()
doc <- body_add_par(doc, "Tooth growth report", style = "heading 1")
doc <- body_add_par(
  doc,
  "Guinea pig odontoblast length by vitamin C dose. Generated from R with officer.",
  style = "Normal"
)
doc <- body_add_par(doc, "Distribution by dose", style = "heading 2")
doc <- body_add_gg(doc, value = p, width = 6, height = 3.1)
doc <- body_add_par(doc, "Mean length by dose", style = "heading 2")
doc <- body_add_flextable(doc, ft)

print(doc, target = "report.docx")

A finished Word page generated from R with officer: a title 'Tooth growth report', an intro line, a blue boxplot of tooth length by dose, and a small zebra-striped table of mean length per dose.

Relancez le script après un changement de vos données et tout le rapport — graphique, tableau, chiffres — se reconstruit tout seul. C’est tout l’intérêt : des rapports sous forme de code.

Foire aux questions

Oui. ReporteRs a été retiré du CRAN et n’est plus installable (il dépendait de Java et de rJava). officer, du même auteur, David Gohel, est son successeur moderne, multiplateforme et sans Java, et le standard actuel de la communauté pour générer des fichiers Word et PowerPoint depuis R. Chaque capacité de ReporteRs — titres, texte mis en forme, tableaux, graphiques, sauts de page, table des matières — a un équivalent officer (plus flextable), listé dans le tableau de correspondance ci-dessus.

Utilisez body_add_list() avec un objet block_list_items() — il écrit les définitions de puces ou de numérotation dans le document lui-même, donc aucun modèle n’est requis (voir Listes à puces et numérotées ci-dessus). Définissez list_type = "bullet" ou "decimal" et utilisez level pour imbriquer. (L’ancienne voie body_add_par(doc, "item", style = "List Bullet") fonctionne toujours, mais seulement lorsque votre modèle définit déjà ces styles de paragraphe — vérifiez avec styles_info(doc).)

Utilisez officer lorsque vous construisez un document par programmation dans un script R — l’approche bloc par bloc de ce billet. Utilisez officedown lorsque vous rédigez en R Markdown ou Quarto et voulez que la sortie Word générée par knit gagne les fonctionnalités d’officer (légendes, renvois, sections paysage). officedown repose sur officer ; choisissez officer pour la génération de rapports par script, officedown pour les documents axés sur la prose.

Oui. read_pptx() ouvre une présentation et la famille add_slide() / ph_with() place du texte, des tableaux et des graphiques sur les dispositions de diapositives — le même schéma objet-puis-impression. Un seul package couvre à la fois les rapports Word et PowerPoint depuis R.

Non. officer écrit directement le fichier .docx — il ne lance jamais Word, et il fonctionne sur Windows, macOS et Linux (y compris les serveurs sans interface graphique et l’intégration continue). Vous n’avez besoin de Word (ou d’un lecteur compatible comme LibreOffice ou Google Docs) que pour ouvrir le fichier fini.

Pour aller plus loin dans /learn

C’est la recette ciblée pour faire passer la sortie R dans Word. Pour les leçons complètes, pas à pas, sur la construction des graphiques que vous incorporerez :

Voir aussi

🟢 Avec un agent IA

Demandez à Prova « transforme mon analyse en rapport Word avec officer — un titre, mon tableau récapitulatif et un graphique ggplot » — elle répond avec du code que vous pouvez exécuter sur vos propres données. The runtime is the judge. Demander à Prova →

Cette page vous a-t-elle été utile ?

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN

Citation

BibTeX
@online{kassambara2026,
  author = {Kassambara, Alboukadel},
  title = {Créer des documents Word depuis R avec officer},
  date = {2026-07-08},
  url = {https://www.datanovia.com/blog/word-documents-in-r-officer},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
Kassambara, Alboukadel. 2026. “Créer des documents Word depuis R avec officer.” July 8. https://www.datanovia.com/blog/word-documents-in-r-officer.