林海雪原

email | about | tags

ReporteRs与中文docx模板

29 Apr 2014     tags:  R |  ReporteRs |  Word |  问题 |  办公自动化

问题:中文docx文件中的样式无法识别

前文中已经对ReporteRs的一些问题做了探讨,但是作为一个刚刚开始不久的项目,仍会有一些问题,其实其Github上的issues也不算多。

我在使用中发现一个问题,作者也曾提到过:

Do not use styles names that contains special character. In France for example, the default style named “Legend” becomes “L?gende” and is returned as “Lgende” by the styles R function. The workaround is to create a new style based on “L?gende” and to name it “Legende”. It will be then a valid name to use with ReporteRs

但在实际工作中,这个问题不太可能被彻底回避,比如我们用一个中文的Word文档作为template,再使用styles函数的话得到的样式名称如下:

doc <- docx(template = docx.file)  # 文件名在不可见R区块中给出
styles(doc)
##  [1] "a0" "1"  "20" "3"  "4"  "5"  "a4" "a5" "a6" "a7" "a8"
## [12] "a9" "a"  "2"  "aa" "ac" "ad" "ae" "10"

谁能告诉我这些都是神马样式呢?我们还不如前面提到的法语中的情况,可以猜出来哪个是哪个,差别不大,但是显然中文这个完全不行。

是否可以修改Word内建样式名称?

如果了解Word并且经常使用其样式功能的人一定会经常修改内建样式或创建自己需要的样式。关于前面提到的问题,这里有两件事要放在一起说一下:

样式名称

因此,简单来说就是既要尽量使用内建样式,又无法更改样式名称。

暂时的解决方案

关于这个问题我已经向作者提出,看看作者能否有什么好办法改善一下这个情况,因为我们真的没办法在那里瞎猜。如果就确定使用很少数的几个模板还好,如果模板经常换就麻烦了,再说这也算个缺陷吧。

其实暂时的解决方案也很简单:

  1. declareTitlesStyles函数声明一下标题样式,这个可以出来,前面代码运行结果中"1""2"等等就是了。
  2. 新建一些样式用英文命名供自己使用。
  3. 一下这些样式都是什么。

上面提到的对标题进行重新声明,可以参考项目主页上的方法来做:

doc <- declareTitlesStyles(doc,
       stylenames=c("1", "2", "3", "4", "5",
                    "6", "7", "8", "9" ) )
## Error: Some of the stylenames are not in available styles
## (run styles on your object to list available styles.

注意,一定要看一下目前模板中的目录到底到第几层,Word当中最多有9层目录,但是如果styles没有显示那么多就会出错,上面代码中给出的信息正是这个意思,两者一定要匹配才行。

关于上面提到的第3点,实在是一种很不爽的办法,或者说是“没办法的办法”,算是个小Hack吧:

options('ReporteRs-default-font'='Arial')
sty_list <- styles(doc)
par_list <- paste("这一段的样式名称是:", sty_list)
for (i in 1:length(sty_list)) {
  doc <- addParagraph(doc, value=par_list[i],
                      stylename=sty_list[i])
}
writeDoc(doc, file=output) # output文件名在不可见区块中给出

得到的结果就是如下图所示了,可以看到styles给出的样式实际对应的样式名称,然后根据这种方法做好自己的模板。应当说这样的方法有利于制作很常用的模板和自动化报告的程序,磨刀不误砍柴工,否则就有点儿费事儿,但愿作者能做些修改。

样式名称