Как получить форматирование стилей в документе Word в офицерском? - PullRequest
0 голосов
/ 13 января 2020

Я хочу написать несколько документов с officer, и у меня есть несколько предопределенных стилей в моем текстовом документе, которые я загружаю с 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

К сожалению, нет столбца с размером шрифта или тип шрифта. Мне действительно нужно иметь размер шрифта (например, 10) и тип шрифта (например, «Times New Roman») заголовка 1 в R, потому что аргумент style функции body_add_par недостаточно для моих целей , Есть ли способ получить это?

Редактировать: Было бы также здорово, если бы решение не из officer.

1 Ответ

1 голос
/ 14 января 2020

Я не мог найти способ сделать это в офицере. Фактически, в конце мне пришлось проанализировать содержимое 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

Это дает нам таблицу шрифтов, но есть много пропущенных значений, которые можно извлечь из наследования и т. Д. c:


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
...