如何在 Officer 中获取 Word 文档中的样式格式?

How to get formatting of styles in Word document in officer?

我想用 officer 写一些文档,我的 word 文档中有一些预定义的样式,我用 read_docx() 加载。现在我可以查看样式,但我特别想知道每种样式的字体类型或字体大小,但我找不到。 这是我能找到的所有内容:

Document <- read_docx(FILEPATH)
head(Document$styles)
  style_type style_id style_name is_custom is_default
1  paragraph   Normal     Normal     FALSE       TRUE
2  paragraph Heading1  heading 1     FALSE      FALSE
3  paragraph Heading2  heading 2     FALSE      FALSE
4  paragraph Heading3  heading 3     FALSE      FALSE
5  paragraph Heading4  heading 4     FALSE      FALSE
6  paragraph Heading5  heading 5     FALSE      FALSE

很遗憾,没有包含字体大小或字体类型的列。 我真的需要 R 中标题 1 的字体大小(例如 10)和字体类型(例如 "Times New Roman"),因为函数 body_add_par 的参数 style不足以满足我的目的。有办法得到这个吗?

编辑:如果解决方案不是来自 officer

也很好

我找不到在 officer 中执行此操作的方法。事实上,最后我不得不解析 docx 的 xml 内容来获取字体。

原来并不是所有的样式都有字体集。有的继承自其他样式,有的只是取Word给定的默认值。无论如何,解析 xml 非常复杂,所以这有点复杂/混乱。

首先您需要解压 docx 以获得其样式 xml。如果你有 officer,你也会有所需的 zip 包,所以我们将使用这个:

library(zip)
doc_path <- "my_file_path.docx"
unzip(doc_path, files = "word/styles.xml", exdir = path.expand("~/"))

现在我们需要解析 xml:


编辑

正如@TobiSonne 在评论中指出的那样,sz 值是半磅,而不是磅,因此我们需要将它们减半以获得字体的磅值。


read_xml(path.expand("~/word/styles.xml")) %>%
xml_nodes(xpath = "//w:style")             %>%
lapply(xml_new_root)                       %>%
lapply(function(x) data.frame(
  name = x %>% xml_node(xpath = "//w:name") %>% xml_attr("val"),
  based_on = x %>% xml_node(xpath = "//w:basedOn") %>% xml_attr("val"),
  font = x %>% xml_node(xpath = "//w:rFonts") %>% xml_attr("ascii"),
  size = x %>% xml_node(xpath = "//w:sz") %>% xml_attr("val") %>% as.numeric() %>% `/`(2),
  stringsAsFactors = F)) %>%
{do.call("rbind", .)} -> font_table

这给了我们字体 table,但是有很多缺失值可以从继承等方面推断出来:


read_xml(path.expand("~/word/styles.xml")) %>%
xml_node(xpath = "//w:docDefaults//w:rPr") %>% 
xml_new_root -> defaults

default_size <- xml_node(defaults, xpath = "//w:sz") %>% 
                xml_attr("val") %>%
                as.numeric() %>%
                `/`(2)
default_font <- xml_node(defaults, xpath = "//w:rFonts") %>% xml_attr("ascii")
if(is.na(default_font))
  default_font <- xml_node(defaults, xpath = "//w:rFonts") %>% xml_attr("asciiTheme")

font_table$size[is.na(font_table$size) & is.na(font_table$based_on)] <- default_size
font_table$font[is.na(font_table$font)] <- default_font
font_table$based_on[is.na(font_table$based_on)] <- "default"

现在我们有:

font_table
#>                      name             based_on            font size
#> 1                  Normal              default      minorHAnsi   12
#> 2               heading 2               Normal      minorHAnsi   13
#> 3  Default Paragraph Font              default      minorHAnsi   12
#> 4            Normal Table              default      minorHAnsi   12
#> 5                 No List              default      minorHAnsi   12
#> 6              Table Grid          TableNormal      minorHAnsi <NA>
#> 7          List Paragraph               Normal      minorHAnsi <NA>
#> 8            Normal (Web)               Normal Times New Roman <NA>
#> 9            Balloon Text               Normal          Tahoma    8
#> 10      Balloon Text Char DefaultParagraphFont          Tahoma    8
#> 11         Heading 2 Char DefaultParagraphFont      minorHAnsi   13