【问题标题】:How to get formatting of styles in Word document in officer?如何在官员的Word文档中获取样式格式?
【发布时间】:2020-04-30 08:43:03
【问题描述】:

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

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,那也很好。

【问题讨论】:

    标签: r fonts officer


    【解决方案1】:

    我在军官中找不到这样做的方法。事实上,最后我不得不解析 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 在 cmets 中指出的那样,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
    
    

    这给了我们字体表,但是有很多缺失值需要从继承等中推断出来:

    
    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
    

    【讨论】:

    • 我现在对其进行了测试,效果很好,但是您知道为什么每个字体大小都比我预期的大 10 吗?在我的文档中,我希望默认为 12,但我得到的结果是 22(在原始 xml 中它实际上是 22)。
    • 我也想不通@TobiSonne。我的理解是默认字体和大小是实现定义的,但我无法通过对该主题的简短搜索来确认这一点。
    • 好的,谢谢!你也有字体大小的“问题”?
    • 看来minorHAnsi 是“word/themes 子文件夹中的xml 文件中标记为minorFont 的任何字体”的同义词。您可以解析此 xml 以获取默认的次要字体并将其插入表中。我不确定默认字体大小。我在 xml 中找不到。
    • @TobiSonne 这更有意义。谢谢你让我知道。我会更新答案以反映这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    相关资源
    最近更新 更多