R导出可编辑Excel图表遇dml_xlsx报错,求解决方案
修复R导出可编辑Excel图表的错误及实现方案
问题背景
昨日已实现从R导出可编辑PowerPoint图表,今日尝试用同一数据集导出可编辑Excel图表时遇到两个问题:
- 按教程操作后生成的是不可编辑的图片
- 使用
dml_xlsx时触发错误:Error: Expecting a single string value: [type=list; extent=9]
错误原因
dml_xlsx参数误用:该函数的file参数需传入文件路径字符串,你却传入了ggplot对象xplot,导致类型不匹配报错。- 工作流混淆:
xl_add_vg是officer包的函数,需配合officer的Excel工作簿对象,而非openxlsx创建的对象。 - 未定义对象与空参数:
read_xlsx()未指定文件路径,且xl_add_vg中引用了未定义的gg对象。
修复后的完整代码
library(tidyverse) library(ggplot2) library(officer) library(rvg) library(readxl) library(here) # 读取数据集 Project_stages <- read_excel("/Users/giang/Library/CloudStorage/OneDrive-GCF/Documents/R/Test w R/Project stages 131122.xlsx") # 数据预处理(保留原业务逻辑) Project_stages_1 <- Project_stages %>% filter(Stage %in% c("00. PI received", "01. Stage 3: CN received", "04. Stage 4: FP received", "14. Stage 6: Approved")) %>% spread(key = Stage, value = 'Day of Stage Date') %>% select(`Approved Ref`, Index, PI = `00. PI received`, CN = `01. Stage 3: CN received`, FP = `04. Stage 4: FP received`, Approved = '14. Stage 6: Approved') %>% mutate(Project_received = as.Date(ifelse(!is.na(PI), as.character(PI), ifelse(!is.na(CN), as.character(CN), ifelse(!is.na(FP), as.character(FP), NA)))), duration = as.numeric(difftime(Approved, Project_received, units = "days")), Sub_Year = as.numeric(format(Project_received, format= "%Y"))) %>% filter(Index == 1) # 生成统计汇总表 xcel_stages <- Project_stages_1 %>% select(duration, Sub_Year) %>% group_by(Sub_Year) %>% summarise(Avrg = round(mean(duration, na.rm = TRUE)), Mdn = round(median(duration, na.rm = TRUE))) # 创建officer兼容的Excel工作簿 wb <- create_xlsx() # 添加工作表并写入数据 wb <- wb %>% add_worksheet("analysis2") %>% xl_add_data(x = xcel_stages, sheet = "analysis2", start_col = 1, start_row = 1) # 生成ggplot可视化图表 xplot <- ggplot(xcel_stages, aes(x = Sub_Year, y = Avrg)) + geom_bar(stat = "identity", fill = "#2f8c80") + theme_minimal() + ggtitle("Duration of project submission to GCF") # 插入可编辑图表到Excel wb <- wb %>% xl_add_vg( sheet = "analysis2", code = print(xplot), # 传入图表生成代码,直接生成可编辑DrawingML元素 width = 6, height = 4, left = 1, top = 5 # 调整位置避免覆盖数据 ) # 保存最终文件 print(wb, target = here("results.xlsx"))
关键修改说明
- 移除
openxlsx相关依赖,统一使用officer处理Excel工作流,避免包冲突。 - 用
create_xlsx()创建officer兼容的工作簿,替代openxlsx::createWorkbook()。 - 用
xl_add_data()写入数据,替代openxlsx::writeDataTable()。 - 删除错误的
dml_xlsx调用,直接在xl_add_vg的code参数中传入print(xplot),这是生成可编辑图表的标准方式。 - 为统计函数添加
na.rm=TRUE,避免缺失值导致计算失败。 - 调整图表位置,防止覆盖工作表中的数据。
Mac环境注意事项
- 确保安装最新版本的依赖包:
install.packages(c("officer", "rvg"))。 - 若导出仍异常,检查Java环境(
rvg依赖Java生成DrawingML),确保Java与R均为64位架构。
内容的提问来源于stack exchange,提问作者user133737
相关产品推荐
相关产品推荐

