使用purrr输出多文件多工作表时,如何应用openxlsx格式化?
问题修正与解决方案
你的代码存在几个关键问题:
openxlsx的调用逻辑错误,不能直接嵌套addStyle和writeData到write.xlsx中- 美元格式的数字代码写错(误用了百分比格式
0.0%) - 客户名称的写入位置错误(要求A1却设置了
startRow=3) - 固定列索引
cols=3:4不可靠,remove_empty可能改变列顺序 - 变量引用错误(应使用
iwalk中的nm参数指代客户名称,而非customer)
以下是修正后的代码:
library(tidyverse) library(openxlsx) library(janitor) df.1 <- tribble( ~customer ,~period, ~cost1, ~cost2 , ~prod, 'cust1', '202201', 5, 10, 'online', 'cust1', '202202', 5, 10, 'online', 'cust1', '202203', 5, 10, 'in-person', 'cust1', '202204', 5, 10, 'in-person', 'cust2', '202203', 5, 10,'online', 'cust2', '202204', 5, 10, 'in-person', 'cust2', '202202', 5, 10, 'online', 'cust3', '202204', 5, 10, 'online', 'cust4', '202101', NA, NA, 'online', 'cust4', '202102', NA,10, 'online' ) # 按客户拆分并生成对应Excel文件 df.1 %>% split(.$customer) %>% iwalk(function(df, cust_name) { # 创建空工作簿 wb <- createWorkbook() # 清理空列 df_clean <- df %>% janitor::remove_empty(which = 'cols') # 按产品类型拆分,每个类型生成独立工作表 df_clean %>% split(.$prod) %>% iwalk(function(prod_df, prod_name) { # 添加工作表 addWorksheet(wb, sheetName = prod_name) # 从第6行开始写入数据 writeData(wb, sheet = prod_name, x = prod_df, startRow = 6) # 定义美元格式样式 dollar_style <- createStyle(numFmt = "$#,##0.00") # 动态定位cost1和cost2的列索引 cost_cols <- which(colnames(prod_df) %in% c("cost1", "cost2")) # 给cost列添加格式 if(length(cost_cols) > 0) { addStyle(wb, sheet = prod_name, style = dollar_style, cols = cost_cols, rows = 6:(6 + nrow(prod_df) - 1), gridExpand = TRUE) } }) # 在每个工作表的A1单元格写入客户名称 walk(names(wb), function(sheet) { writeData(wb, sheet = sheet, x = paste0('Client Name: ', cust_name), startCol = 1, startRow = 1) }) # 保存工作簿 saveWorkbook(wb, file = paste0(cust_name, ".xlsx"), overwrite = TRUE) })
关键修正说明:
- 采用
openxlsx标准流程:创建工作簿→添加工作表→写入数据→设置样式→保存 - 美元格式使用
$#,##0.00,自动添加美元符号并保留两位小数 - 通过列名动态获取cost列索引,避免列顺序变化导致的错误
- 明确在每个工作表的A1位置写入客户名称,覆盖已有文件时需确认
overwrite=TRUE
内容的提问来源于stack exchange,提问作者cowboy
相关产品推荐
相关产品推荐

