如何用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
相关产品推荐
相关产品推荐

