如何使用 R 和 COM (RDCOMClient) 将 UTF-8 单元格值和文件名指定为 Excel?
How can I specify UTF-8 cell values and filenames to Excel using R and COM (RDCOMClient)?
我正在使用 library(RDCOMClient)
成功修改多个 Excel 文件。
但是,将单元格值设置为非 ascii 字符串会导致 å
变为 Ã¥
等。
我也无法将 UTF-8 文件名传递给 Excel 的 Open() 和 Save() 方法。
希望这两个问题都有一个解决方案。
这是一个使用 Save() 的简单可重现示例:
创建一个空工作簿并尝试将其另存为 å.xlsx
结果 Ã¥.xlsx
。
相同的操作适用于 a.xlsx
.
# install.packages("RDCOMServer", repos = "http://www.omegahat.net/R")
library(RDCOMClient)
xlApp <- COMCreate("Excel.Application")
wb <- xlApp$Workbooks()$Add()
path1 <- normalizePath("a.xlsx", mustWork = FALSE)
path2 <- normalizePath("å.xlsx", mustWork = FALSE)
wb$SaveAs(path1)
#> [1] TRUE
wb$SaveAs(path2)
#> [1] TRUE
wb$Close()
#> [1] TRUE
xlApp$Quit()
#> NULL
dir(pattern = "xlsx")
#> [1] "a.xlsx" "Ã¥.xlsx"
devtools::session_info()
#> - Session info ---------------------------------------------------------------
#> setting value
#> version R version 4.0.0 (2020-04-24)
#> os Windows 10 x64
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United States.1252
#> ctype English_United States.1252
#> tz Europe/Berlin
#> date 2020-05-10
#>
#> - Packages -------------------------------------------------------------------
#> package * version date lib source
#> assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.0)
#> backports 1.1.6 2020-04-05 [1] CRAN (R 4.0.0)
#> callr 3.4.3 2020-03-28 [1] CRAN (R 4.0.0)
#> cli 2.0.2 2020-02-28 [1] CRAN (R 4.0.0)
#> crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.0)
#> desc 1.2.0 2018-05-01 [1] CRAN (R 4.0.0)
#> devtools 2.3.0 2020-04-10 [1] CRAN (R 4.0.0)
#> digest 0.6.25 2020-02-23 [1] CRAN (R 4.0.0)
#> ellipsis 0.3.0 2019-09-20 [1] CRAN (R 4.0.0)
#> evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.0)
#> fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.0)
#> fs 1.4.1 2020-04-04 [1] CRAN (R 4.0.0)
#> glue 1.4.0 2020-04-03 [1] CRAN (R 4.0.0)
#> highr 0.8 2019-03-20 [1] CRAN (R 4.0.0)
#> htmltools 0.4.0 2019-10-04 [1] CRAN (R 4.0.0)
#> knitr 1.28 2020-02-06 [1] CRAN (R 4.0.0)
#> magrittr 1.5 2014-11-22 [1] CRAN (R 4.0.0)
#> memoise 1.1.0 2017-04-21 [1] CRAN (R 4.0.0)
#> pkgbuild 1.0.7 2020-04-25 [1] CRAN (R 4.0.0)
#> pkgload 1.0.2 2018-10-29 [1] CRAN (R 4.0.0)
#> prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.0)
#> processx 3.4.2 2020-02-09 [1] CRAN (R 4.0.0)
#> ps 1.3.2 2020-02-13 [1] CRAN (R 4.0.0)
#> R6 2.4.1 2019-11-12 [1] CRAN (R 4.0.0)
#> Rcpp 1.0.4.6 2020-04-09 [1] CRAN (R 4.0.0)
#> RDCOMClient * 0.94-0 2020-04-13 [1] local
#> remotes 2.1.1 2020-02-15 [1] CRAN (R 4.0.0)
#> rlang 0.4.5 2020-03-01 [1] CRAN (R 4.0.0)
#> rmarkdown 2.1 2020-01-20 [1] CRAN (R 4.0.0)
#> rprojroot 1.3-2 2018-01-03 [1] CRAN (R 4.0.0)
#> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.0)
#> stringi 1.4.6 2020-02-17 [1] CRAN (R 4.0.0)
#> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.0.0)
#> testthat 2.3.2 2020-03-02 [1] CRAN (R 4.0.0)
#> usethis 1.6.1 2020-04-29 [1] CRAN (R 4.0.0)
#> withr 2.2.0 2020-04-20 [1] CRAN (R 4.0.0)
#> xfun 0.13 2020-04-13 [1] CRAN (R 4.0.0)
#> yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.0)
#>
#> [1] C:/R-library
#> [2] C:/Program Files/R/R-4.0.0/library
由 reprex package (v0.3.0)
于 2020-05-10 创建
Encoding(path2) <- "UTF-8"
和 似乎都没有任何效果。 ("OS reports request to set locale to "en_US.UTF-8"无法兑现"。)
我无法弄清楚 Excel COM 如何处理来自 docs 的 Unicode。
This Visual Basic-related question 可能相关,但我不知道如何将其应用于我的问题。
编辑:我通过 opening/saving 临时副本解决了文件名问题,通过数字而不是名称来引用工作表名称问题,通过重新措辞来解决单元格值问题。仍然对合适的解决方案感兴趣 8-)
stringi::stri_enc_tonative()
正是我所需要的。
我有 readxl::read_excel()
和 readxl::excel_sheets()
返回的 UTF-8 字符串 text
和 sheets
,因此 Encoding(text)
是 "UTF-8" 而Excel 显然需要 "latin1" 在我的系统上。
用 stringi::stri_enc_tonative(text)
替换 text
解决了我所有的问题:xlApp$Open()
的文件名、wb$Open()
的工作表名和 rng[["Value"]] <-
.
的值
可以使用 stringi::stri_enc_toutf8()
转换为 UTF-8。
我正在使用 library(RDCOMClient)
成功修改多个 Excel 文件。
但是,将单元格值设置为非 ascii 字符串会导致 å
变为 Ã¥
等。
我也无法将 UTF-8 文件名传递给 Excel 的 Open() 和 Save() 方法。
希望这两个问题都有一个解决方案。
这是一个使用 Save() 的简单可重现示例:
创建一个空工作簿并尝试将其另存为 å.xlsx
结果 Ã¥.xlsx
。
相同的操作适用于 a.xlsx
.
# install.packages("RDCOMServer", repos = "http://www.omegahat.net/R")
library(RDCOMClient)
xlApp <- COMCreate("Excel.Application")
wb <- xlApp$Workbooks()$Add()
path1 <- normalizePath("a.xlsx", mustWork = FALSE)
path2 <- normalizePath("å.xlsx", mustWork = FALSE)
wb$SaveAs(path1)
#> [1] TRUE
wb$SaveAs(path2)
#> [1] TRUE
wb$Close()
#> [1] TRUE
xlApp$Quit()
#> NULL
dir(pattern = "xlsx")
#> [1] "a.xlsx" "Ã¥.xlsx"
devtools::session_info()
#> - Session info ---------------------------------------------------------------
#> setting value
#> version R version 4.0.0 (2020-04-24)
#> os Windows 10 x64
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate English_United States.1252
#> ctype English_United States.1252
#> tz Europe/Berlin
#> date 2020-05-10
#>
#> - Packages -------------------------------------------------------------------
#> package * version date lib source
#> assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.0)
#> backports 1.1.6 2020-04-05 [1] CRAN (R 4.0.0)
#> callr 3.4.3 2020-03-28 [1] CRAN (R 4.0.0)
#> cli 2.0.2 2020-02-28 [1] CRAN (R 4.0.0)
#> crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.0)
#> desc 1.2.0 2018-05-01 [1] CRAN (R 4.0.0)
#> devtools 2.3.0 2020-04-10 [1] CRAN (R 4.0.0)
#> digest 0.6.25 2020-02-23 [1] CRAN (R 4.0.0)
#> ellipsis 0.3.0 2019-09-20 [1] CRAN (R 4.0.0)
#> evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.0)
#> fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.0)
#> fs 1.4.1 2020-04-04 [1] CRAN (R 4.0.0)
#> glue 1.4.0 2020-04-03 [1] CRAN (R 4.0.0)
#> highr 0.8 2019-03-20 [1] CRAN (R 4.0.0)
#> htmltools 0.4.0 2019-10-04 [1] CRAN (R 4.0.0)
#> knitr 1.28 2020-02-06 [1] CRAN (R 4.0.0)
#> magrittr 1.5 2014-11-22 [1] CRAN (R 4.0.0)
#> memoise 1.1.0 2017-04-21 [1] CRAN (R 4.0.0)
#> pkgbuild 1.0.7 2020-04-25 [1] CRAN (R 4.0.0)
#> pkgload 1.0.2 2018-10-29 [1] CRAN (R 4.0.0)
#> prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.0)
#> processx 3.4.2 2020-02-09 [1] CRAN (R 4.0.0)
#> ps 1.3.2 2020-02-13 [1] CRAN (R 4.0.0)
#> R6 2.4.1 2019-11-12 [1] CRAN (R 4.0.0)
#> Rcpp 1.0.4.6 2020-04-09 [1] CRAN (R 4.0.0)
#> RDCOMClient * 0.94-0 2020-04-13 [1] local
#> remotes 2.1.1 2020-02-15 [1] CRAN (R 4.0.0)
#> rlang 0.4.5 2020-03-01 [1] CRAN (R 4.0.0)
#> rmarkdown 2.1 2020-01-20 [1] CRAN (R 4.0.0)
#> rprojroot 1.3-2 2018-01-03 [1] CRAN (R 4.0.0)
#> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.0)
#> stringi 1.4.6 2020-02-17 [1] CRAN (R 4.0.0)
#> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.0.0)
#> testthat 2.3.2 2020-03-02 [1] CRAN (R 4.0.0)
#> usethis 1.6.1 2020-04-29 [1] CRAN (R 4.0.0)
#> withr 2.2.0 2020-04-20 [1] CRAN (R 4.0.0)
#> xfun 0.13 2020-04-13 [1] CRAN (R 4.0.0)
#> yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.0)
#>
#> [1] C:/R-library
#> [2] C:/Program Files/R/R-4.0.0/library
由 reprex package (v0.3.0)
于 2020-05-10 创建Encoding(path2) <- "UTF-8"
和
我无法弄清楚 Excel COM 如何处理来自 docs 的 Unicode。 This Visual Basic-related question 可能相关,但我不知道如何将其应用于我的问题。
编辑:我通过 opening/saving 临时副本解决了文件名问题,通过数字而不是名称来引用工作表名称问题,通过重新措辞来解决单元格值问题。仍然对合适的解决方案感兴趣 8-)
stringi::stri_enc_tonative()
正是我所需要的。
我有 readxl::read_excel()
和 readxl::excel_sheets()
返回的 UTF-8 字符串 text
和 sheets
,因此 Encoding(text)
是 "UTF-8" 而Excel 显然需要 "latin1" 在我的系统上。
用 stringi::stri_enc_tonative(text)
替换 text
解决了我所有的问题:xlApp$Open()
的文件名、wb$Open()
的工作表名和 rng[["Value"]] <-
.
可以使用 stringi::stri_enc_toutf8()
转换为 UTF-8。