R语言officer包插入自定义TOC(表格目录)的最优实现方法
需求说明
- 需要在officer生成的Word文档中插入自定义目录,提取6级标题内容生成表格目录,目标TOC域代码为
{TOC \o "6-6" \* MERGEFORMAT} - 现有
block_toc函数无法直接实现该配置,希望找到标准的officer通用函数实现,而非调用内部函数 - 尝试通过
block_toc的style参数生成表格目录时,返回No table of contents entries found.报错
报错原因
你提供的测试代码中,目录插入顺序错误:先插入了TOC域,再添加Table Caption样式的表格标题,Word扫描内容时找不到符合要求的条目,因此触发报错。
解决方案
1. 插入仅提取6级标题的自定义TOC
使用officer公开函数run_word_field直接插入自定义域代码即可,属于官方支持的标准用法,无需调用内部函数,代码示例:
# 插入自定义6级标题目录 rpt <- body_add_fpar( x = rpt, value = fpar(run_word_field(field = 'TOC \\o "6-6" \\* MERGEFORMAT')) )
2. 基于Table Caption样式生成表格目录
将目录插入代码调整到所有表格标题添加完成之后即可,修改后的代码逻辑如下:
library(officer) library(flextable) library(magrittr) tab_seq_id = "Table" # 新建空白文档 rpt = read_docx() mytxt = paste(rep("The quick brown fox jumped over the lazy dog.", 30), collapse=" ") ft = flextable(head(mtcars)) # 添加第一节内容 rpt = body_add_fpar(rpt, fpar("A section"), style="heading 1") fptxt = fpar(mytxt) rpt = officer::body_add_fpar(rpt, fptxt) # 添加第二节内容 rpt = body_add_fpar(rpt, fpar("Another section"), style="heading 1") fptxt = fpar("This is a cross reference to the first table (Table ", run_reference("my_table"), ") and this is a reference to the second table (Table ", run_reference("my_second_table"), ")." , ") and a third table in a new section (Table ", run_reference("my_third_table"), ")." ) long_cap = "This is my table caption. It can span many lines and take up much space on the page." # 添加第一张表格及标题 run_num = officer::run_autonum(seq_id = tab_seq_id, pre_label = "Table ", post_label = ".", bkm = "my_table") caption = officer::block_caption(long_cap, style = "Table Caption", autonum = run_num ) rpt = officer::body_add_fpar(rpt, fptxt) rpt = flextable::body_add_flextable(rpt, value=ft) rpt = officer::body_add_caption(rpt, caption) # 添加第二张表格及标题 runs = list( run_word_field("STYLEREF 1 \\s"), ftext("-"), officer::run_autonum(pre_label = "", seq_id = tab_seq_id, post_label="")) rb_res = run_bookmark("my_second_table", runs) rpt = flextable::body_add_flextable(rpt, value=ft) rpt = officer::body_add_fpar(rpt, fpar("Table ", rb_res, ". ", long_cap), style = "Table Caption") # 添加第三节内容 rpt = body_add_fpar(rpt, fpar("A third section"), style="heading 1") # 添加第三张表格及标题 runs = list( run_word_field("STYLEREF 1 \\s"), ftext("-"), officer::run_autonum(pre_label = "", seq_id = tab_seq_id, start_at = 1, post_label="")) rb_res = run_bookmark("my_third_table", runs) rpt = flextable::body_add_flextable(rpt, value=ft) rpt = officer::body_add_fpar(rpt, fpar("Table ", rb_res, ". ", long_cap), style = "Table Caption") # 所有内容添加完成后,在文档开头插入表格目录 bt <- block_toc(style = "Table Caption") out <- to_wml(bt, add_ns = TRUE) rpt <- cursor_begin(rpt) %>% body_add_xml(str = out, pos = "before") print(rpt, "fig_sec_num.docx")
注意事项
生成的Word文档打开后会提示更新域,选择「更新整个目录」即可正常显示所有TOC条目,属于Word的常规机制。
内容的提问来源于stack exchange,提问作者John Harrold
相关产品推荐
相关产品推荐

