You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用save_as_docx将多个flextable表格保存到单个.docx文件

问题背景与需求

我已通过以下代码生成一系列Excel文件,并将这些文件读取整理为嵌套列表list3:

require(writexl)
write_xlsx(mtcars, 'PQ_ele_com.xlsx')

dir = c('com', 'set', 'rit')
init = c('PQ', 'MG')
inpst = c('_ele_', '_mel_', '_col_')

for (i in dir) {
  for (j in init) {
    for (k in inpst){
      write_xlsx(mtcars[3,], paste0(j, k, i, '.xlsx')) 
    }
  }
}

setwd("C:/Users/PC/Desktop/my_folder")
files = list.files("C:/Users/PC/Desktop/my_folder", recursive= FALSE, full.names= FALSE)

init = c('PQ', 'MG')
dir = c('com', 'set', 'rit')

files = list.files(recursive= FALSE, full.names= FALSE)
init = c('PQ', 'MG')
dir = c('com', 'set', 'rit')

list3 = NULL
for (j in init){
  for (k in dir){
    df=c()
    for (i in files){
      if(str_detect(i, pattern = j) & str_detect(i, pattern = k) == TRUE) {
        df=rbind(df,read_excel(i))}
    }
    list3[[j]][[k]] = df
  }
}

我希望将list3中所有数据通过flextable生成表格,并保存到单个.docx文件中。但尝试的以下代码仅能重复打印表格到不同页面,现需修改现有代码,同时求一个使用save_as_docx的替代方案:

library(flextable)
library(officer)
write_word_table <- function(var, doc){
  doc %>%
    body_add_flextable(var) %>% 
    body_add_break() }

my_doc <- read_docx()

lapply(list3, function(x) walk(x, write_word_table , my_doc))
print(my_doc, target = "C:/Users/PC/Desktop/D1.docx") %>% invisible() 
解决方案

一、修改现有officer代码

原代码问题在于:officer的文档对象是不可变的,每次调用body_add_flextable后需要重新赋值才能保留修改。之前的代码没有更新文档对象,所有操作都在初始空文档上执行,导致最终结果异常。

修改后的代码:

library(flextable)
library(officer)
library(purrr)

# 修改函数,返回更新后的文档对象
write_word_table <- function(doc, var){
  doc %>%
    body_add_flextable(var) %>% 
    body_add_break() # 若不需要表格间分页,可删除此行
}

my_doc <- read_docx()

# 用reduce逐层迭代嵌套列表,累加更新文档
my_doc <- reduce(list3, function(current_doc, sub_list) {
  reduce(sub_list, write_word_table, .init = current_doc)
}, .init = my_doc)

# 保存文档
print(my_doc, target = "C:/Users/PC/Desktop/D1.docx") %>% invisible()

二、使用save_as_docx的替代方案

save_as_docx支持直接传入多个flextable对象,只需先将嵌套列表中的数据框批量转换为表格,再统一保存:

library(flextable)
library(purrr)
library(readxl) # 确保已加载readxl

# 扁平化嵌套列表,将每个数据框转为带标题的flextable
all_tables <- flatten(list3) %>% 
  imap(function(df, table_name) {
    flextable(df) %>% 
      add_header_lines(paste("分组:", table_name)) %>% # 添加分组标题区分表格
      theme_booktabs() %>% # 可选,美化表格样式
      set_table_properties(layout = "autofit")
  })

# 一次性保存所有表格到单个docx
save_as_docx(!!!all_tables, path = "C:/Users/PC/Desktop/D2.docx")

说明

  • flatten(list3)将嵌套列表转为一维列表,方便批量处理
  • imap同时获取数据框和对应的命名,用于生成表格标题
  • !!!用于解包列表,将每个flextable作为独立参数传入save_as_docx

内容的提问来源于stack exchange,提问作者12666727b9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:05:42