writexl
基于 libxlsxwriter 的便携式、轻量级数据框转 xlsx 导出工具。 无需 Java 或 Excel。
封装 libxlsxwriter 库以创建 Microsoft Excel 'xlsx' 格式的文件。
安装
install.packages("writexl")
快速入门
library(writexl)
library(readxl)
tmp <- write_xlsx(iris)
read_xlsx(tmp)
# A tibble: 150 × 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <chr>
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5 3.6 1.4 0.2 setosa
# ℹ 145 more rows
命名列表为每个元素写入一个工作表:
write_xlsx(list(Flowers = iris, Cars = mtcars))
这就是常见情况的全部内容。以下所有内容均为可选。
它还能做什么
每一项都有一个示例;编写工作簿时均无需使用。
| 单元格格式化 | 字体、填充、边框、数字格式和对齐方式,由可与 + 组合的组构造器构建。同一个格式对象可应用于单元格、列、图表系列或条件规则。条件格式、色阶、数据条和图标集。 |
| 工作表和工作簿 | 以字符或像素为单位的列宽和行高,冻结和拆分窗格,选项卡颜色和可见性,大纲,保护,页面设置和打印,文档属性,以及用于大型工作簿的行流式处理模式。 |
| 图表和图片 | Excel 提供的所有 22 种图表类型,包括坐标轴、标记、数据标签、趋势线、误差线、图例和数据表;图表工作表;以及放置在表格上、单元格内、页眉中或平铺在网格背后的图片。 |
| 公式、表格及其他 | 公式(包括数组公式和动态数组公式)、超链接、批注、富文本字符串、混合类型列、数据验证、实际隐藏行的自动筛选、工作表表格和合并单元格。 |
| 一次性全部展示 | 一个可运行的脚本,将整套功能应用于两个工作簿——这是在不阅读其他四个部分的情况下了解其功能的最快方式。 |
以下是它们如何协同工作的示例:
sheet <- xl_sheet(
sales,
cols = xl_col_spec("revenue", format = xl_num_format("$#,##0")),
freeze = "A2",
chart = xl_chart("column", xl_chart_series(values = list(cols = "revenue")))
)
write_xlsx(list(Sales = sheet), "report.xlsx")
往返转换
每种列类型在经过 readxl 的往返后均保持不变,但有一个
例外是有意为之的:
library(nycflights13)
out <- readxl::read_xlsx(writexl::write_xlsx(flights))
keep <- setdiff(names(flights), "time_hour")
all.equal(out[keep], flights[keep])
## TRUE
time_hour 是 America/New_York 中的 POSIXct,并且 Excel 没有时区的概念。writexl 不会静默地将所有内容转换为 UTC,而是针对每个工作簿做出一次决定:当所有日期时间共享同一时区时,它写入本地墙上时钟读数,并从默认日期时间格式中移除 " UTC" 后缀,以确保没有内容被错误标记;当时区不同时,它转换为 UTC 并发出警告。无论哪种情况,时区本身都不在文件中,供 readxl 返回。
性能
写入 nycflights13::flights —— 336,776 行乘以 19 列 —— 比
openxlsx2 实现更快,对于相同大小的文件:
library(nycflights13)
bench <- function(f) median(replicate(2, {
p <- tempfile(fileext = ".xlsx")
on.exit(unlink(p))
system.time(f(p))[["elapsed"]]
}))
bench(function(p) writexl::write_xlsx(flights, p))
## 12.3
bench(function(p) openxlsx2::write_xlsx(flights, p))
## 19.6
输出文件之间的差异在舍入误差范围内:
file.size(writexl::write_xlsx(flights, tempfile(fileext = ".xlsx")))
## 29132216 (27.8 MB)
p <- tempfile(fileext = ".xlsx"); openxlsx2::write_xlsx(flights, p); file.size(p)
## 29297097 (27.9 MB)
在 R 4.6.1、writexl 2.0.0、openxlsx2 1.28 上测量。
内存
constant_memory = TRUE 将每一行流式写入磁盘,而不是将整个
工作表保留在内存中,这正是工作簿能否装入内存的区别所在。整个 R 进程的峰值常驻内存,写入相同的
336,776 行:
| 峰值内存 | 文件 | 时间 | |
|---|---|---|---|
constant_memory = FALSE | 894 MB | 26.8 MB | 7.4 s |
constant_memory = TRUE | 208 MB | 27.8 MB | 7.7 s |
内存减少四分之一,文件大 3.5%,时间大致相同。 流式写入产生的文件稍大,因为无法为已刷新到磁盘的行构建共享字符串表。
保持默认设置时,writexl 按工作簿进行选择:仅当预计节省值得时 才启用流式写入,对于无法在流式写入期间写入的功能——工作表表格、 多单元格数组公式、合并区域和嵌入图像——会自动禁用。参见 工作表和工作簿。