You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:05:21