在 officer 中插入自定义目录的最佳方法
Best way to insert a custom TOC in officer
我需要将自定义目录插入到 officer
文档中。在这种情况下,我需要插入使用级别 6 headers 创建的 table 列表。我需要插入的目录字段是:
{TOC \o "6-6" \* MERGEFORMAT}
block_toc
函数似乎不允许我这样做。所以想做的是使用该函数中的内部函数(例如,run_seqfield
、to_wml
等)来完成此操作。我想知道是否有人有任何其他利用更标准的官员功能的想法。
在下面的示例中,我尝试使用带有 block_toc 的样式选项来创建 table 的列表。当我 运行 时,它给我“找不到 table 的内容条目。”
library(officer)
library(flextable)
library(magrittr)
tab_seq_id = "Table"
# empty report
rpt = read_docx()
bt <- block_toc(style = "Table Caption")
out <- to_wml(bt, add_ns = TRUE)
rpt <- body_add_xml(rpt, str = out, pos = "after")
mytxt = paste(rep("The quick brown fox jumped over the lazy dog.", 30), collapse=" ")
# Making a table
ft = flextable(head(mtcars))
# Creating some sections with text
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."
#-------------------------------------------------------
# Normal table
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)
#-------------------------------------------------------
# Table with the section number in it
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")
# Creating some sections with text
rpt = body_add_fpar(rpt, fpar("A third section"), style="heading 1")
#-------------------------------------------------------
# Table with the section number in it
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")
print(rpt, "fig_sec_num.docx")
这应该有帮助(还记得在 Word 中刷新目录):
library(officer)
library(flextable)
library(magrittr)
mytxt <- paste(rep("The quick brown fox jumped over the lazy dog.", 30), collapse = " ")
long_cap <- "This is my table caption. It can span many lines and take up much space on the page."
tab_seq_id <- "Table"
ft <- flextable(head(mtcars))
get_caption <- function(bookmark){
par <- list(
ftext("Table "),
run_word_field("STYLEREF 1 \s"),
ftext("-"),
run_word_field("SEQ Table \u005C* Arabic")
)
run_bookmark(bookmark, par)
}
fptxt <- fpar(
"This is a cross reference to the first table (",
run_reference("my_table1"),
") and this is a reference to the second table (",
run_reference("my_table2"), ").",
") and a third table in a new section (",
run_reference("my_table3"), ")."
)
rpt <- read_docx() %>%
body_add_toc(style = "Table Caption") %>%
body_add_par("A section", style = "heading 1") %>%
body_add_par(value = mytxt, style = "Normal") %>%
body_add_par("Another section", style = "heading 1") %>%
body_add_fpar(fptxt) %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table1"), " ", long_cap), style = "Table Caption") %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table2"), " ", long_cap), style = "Table Caption") %>%
body_add_par("A third section", style = "heading 1") %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table3"), " ", long_cap), style = "Table Caption")
print(rpt, "fig_sec_num.docx")
TLDR;我需要将 separator="," 添加到上面的 body_add_toc() 调用
我开始查看指定词样式时生成的目录域代码。 David 提供的示例可以在他的计算机上运行,但我无法让它在我这边生成 TOC。我开始使用生成的字段代码来尝试解决问题。在 Davids 解决方案中由官员为我生成的字段代码是:
{TOC \h \z \t "Table Caption;1"}
那对我不起作用。然后我发现,如果我将字段代码更改为以下之一,它将正确生成 TOC:
{TOC \h \z \t "Table Caption"}
{TOC \h \z \t "Table Caption,1"}
在第一个示例中,我完全省略了“;1”,在第二个示例中,我更改了“;”到 ”,”。所以我开始谷歌搜索,如果我没看错的话,可能是某种区域设置导致了这个问题:
然后我阅读了 body_add_toc 的文档,意识到有一个选项可以解决这个问题。我以前见过它,但我不知道它为什么在那里,但这为我解决了所有问题。
感谢大卫的耐心等待。
我需要将自定义目录插入到 officer
文档中。在这种情况下,我需要插入使用级别 6 headers 创建的 table 列表。我需要插入的目录字段是:
{TOC \o "6-6" \* MERGEFORMAT}
block_toc
函数似乎不允许我这样做。所以想做的是使用该函数中的内部函数(例如,run_seqfield
、to_wml
等)来完成此操作。我想知道是否有人有任何其他利用更标准的官员功能的想法。
在下面的示例中,我尝试使用带有 block_toc 的样式选项来创建 table 的列表。当我 运行 时,它给我“找不到 table 的内容条目。”
library(officer)
library(flextable)
library(magrittr)
tab_seq_id = "Table"
# empty report
rpt = read_docx()
bt <- block_toc(style = "Table Caption")
out <- to_wml(bt, add_ns = TRUE)
rpt <- body_add_xml(rpt, str = out, pos = "after")
mytxt = paste(rep("The quick brown fox jumped over the lazy dog.", 30), collapse=" ")
# Making a table
ft = flextable(head(mtcars))
# Creating some sections with text
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."
#-------------------------------------------------------
# Normal table
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)
#-------------------------------------------------------
# Table with the section number in it
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")
# Creating some sections with text
rpt = body_add_fpar(rpt, fpar("A third section"), style="heading 1")
#-------------------------------------------------------
# Table with the section number in it
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")
print(rpt, "fig_sec_num.docx")
这应该有帮助(还记得在 Word 中刷新目录):
library(officer)
library(flextable)
library(magrittr)
mytxt <- paste(rep("The quick brown fox jumped over the lazy dog.", 30), collapse = " ")
long_cap <- "This is my table caption. It can span many lines and take up much space on the page."
tab_seq_id <- "Table"
ft <- flextable(head(mtcars))
get_caption <- function(bookmark){
par <- list(
ftext("Table "),
run_word_field("STYLEREF 1 \s"),
ftext("-"),
run_word_field("SEQ Table \u005C* Arabic")
)
run_bookmark(bookmark, par)
}
fptxt <- fpar(
"This is a cross reference to the first table (",
run_reference("my_table1"),
") and this is a reference to the second table (",
run_reference("my_table2"), ").",
") and a third table in a new section (",
run_reference("my_table3"), ")."
)
rpt <- read_docx() %>%
body_add_toc(style = "Table Caption") %>%
body_add_par("A section", style = "heading 1") %>%
body_add_par(value = mytxt, style = "Normal") %>%
body_add_par("Another section", style = "heading 1") %>%
body_add_fpar(fptxt) %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table1"), " ", long_cap), style = "Table Caption") %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table2"), " ", long_cap), style = "Table Caption") %>%
body_add_par("A third section", style = "heading 1") %>%
body_add_flextable(value = ft) %>%
body_add_fpar(value = fpar(get_caption(bookmark = "my_table3"), " ", long_cap), style = "Table Caption")
print(rpt, "fig_sec_num.docx")
TLDR;我需要将 separator="," 添加到上面的 body_add_toc() 调用
我开始查看指定词样式时生成的目录域代码。 David 提供的示例可以在他的计算机上运行,但我无法让它在我这边生成 TOC。我开始使用生成的字段代码来尝试解决问题。在 Davids 解决方案中由官员为我生成的字段代码是:
{TOC \h \z \t "Table Caption;1"}
那对我不起作用。然后我发现,如果我将字段代码更改为以下之一,它将正确生成 TOC:
{TOC \h \z \t "Table Caption"}
{TOC \h \z \t "Table Caption,1"}
在第一个示例中,我完全省略了“;1”,在第二个示例中,我更改了“;”到 ”,”。所以我开始谷歌搜索,如果我没看错的话,可能是某种区域设置导致了这个问题:
然后我阅读了 body_add_toc 的文档,意识到有一个选项可以解决这个问题。我以前见过它,但我不知道它为什么在那里,但这为我解决了所有问题。
感谢大卫的耐心等待。