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

求助:基于R脚本生成指定格式Word参会人员卡片

问题描述

我尝试用R脚本生成Word文档,为64位参会人员制作符合指定样式的卡片,需求如下:

  • 卡片规格:宽2cm、高8cm
  • 卡片内容从上至下依次为:黑色加粗日期、蓝色粗分隔线、红色加粗院校名称、黑色加粗姓名、Logo、蓝色加粗职位
  • Word文档中每行放置3-4张卡片

当前脚本未实现预期布局,原脚本、参考样式图及Logo图如下:

原R脚本

# Sample Test_cards dataset (should contain 64 rows in your actual data)
Test_cards <- tibble::tibble(
  ID = 1:64,
  Name = paste0("Name_", 1:64),
  Role = rep(c("Radiation Officer", "Radiologist", "Senior Manager", "Senior Technologist", "Technologist"), length.out = 64),
  Date = rep("Q3-2024", 64),
  School = rep("World’s College Hospital Here (Radiology)", 64),
  Logo = NA  # Assuming the same logo for simplicity
)
# Load necessary libraries
library(readxl)
library(officer)   # For creating Word documents
library(flextable) # For advanced table layout and styling
library(magick)    # For image handling
library(tibble)    # For tibble data structure


# Path to logo image (ensure the correct path)
logo_path <- "logo.png"

# Define the custom styling with fp_text() for school name (red) and other fields
school_fp <- fp_text(color = "red", bold = TRUE)
date_fp <- fp_text(color = "black", bold = TRUE)
name_fp <- fp_text(color = "black", bold = TRUE)
role_fp <- fp_text(color = "blue", bold = TRUE)

# Function to create a box for each entry with correct colors and formatting
create_box <- function(date, school, name, role, logo_path) {
  # Create a flextable for the card content
  box_table <- flextable(data.frame(Card = rep(NA, 5))) %>%
    
    # Date (first row) in black, bold, centered
    compose(i = 1, j = 1, value = as_paragraph(as_chunk(date, props = date_fp))) %>%
    
    # Add thicker blue horizontal line after the date
    hline(i = 1, j = 1, border = fp_border(color = "blue", width = 3)) %>%
    
    # School (second row) in red, bold, centered
    compose(i = 2, j = 1, value = as_paragraph(as_chunk(school, props = school_fp))) %>%
    
    # Name (third row) in black, bold, centered
    compose(i = 3, j = 1, value = as_paragraph(as_chunk(name, props = name_fp))) %>%
    
    # Insert the logo in the fourth row
    compose(i = 4, j = 1, value = as_paragraph(as_image(src = logo_path, width = 1.3, height = 1.5))) %>%
    
    # Role (fifth row) in blue, bold, centered
    compose(i = 5, j = 1, value = as_paragraph(as_chunk(role, props = role_fp))) %>%
    
    # Align all content to the center
    align(align = "center", part = "all")
  
  # Set the column width to 2.5 cm and adjust row heights for a total height of 5 cm
  box_table <- width(box_table, j = 1, width = 2.5)  # Set the width to 2.5 cm
  box_table <- height_all(box_table, height = 1)  # Adjust each row's height
  
  # Add black borders around the table (box)
  box_table <- border_outer(box_table, border = fp_border(color = "black", width = 2))
  
  return(box_table)
}

# Create a new Word document
doc <- read_docx()

# Loop over each row in Test_cards and generate a card for each entry
for (i in seq_len(nrow(Test_cards))) {
  # Extract the data for the current row
  date <- Test_cards$Date[i]
  school <- Test_cards$School[i]
  name <- Test_cards$Name[i]
  role <- Test_cards$Role[i]
  
  # Create the card (box) for this row
  box <- create_box(date, school, name, role, logo_path)
  
  # Add the box to the document
  doc <- body_add_flextable(doc, value = box)
  
  # Add a page break after each card except the last one
  if (i < nrow(Test_cards)) {
    doc <- body_add_break(doc)
  }
}

# Save the document
print(doc, target = "Test_cards_output.docx")

参考样式图

卡片样式参考图

Logo图

Logo图


修正后的解决方案

以下是实现需求的修正版脚本,关键调整包括卡片尺寸适配、多行排列布局、样式细节优化:

# 加载所需库
library(officer)
library(flextable)
library(tibble)

# 示例数据(实际为64行)
Test_cards <- tibble::tibble(
  ID = 1:64,
  Name = paste0("Name_", 1:64),
  Role = rep(c("Radiation Officer", "Radiologist", "Senior Manager", "Senior Technologist", "Technologist"), length.out = 64),
  Date = rep("Q3-2024", 64),
  School = rep("World’s College Hospital Here (Radiology)", 64)
)

# Logo路径(请替换为实际路径)
logo_path <- "logo.png"

# 定义文本样式
date_fp <- fp_text(color = "black", bold = TRUE, font.size = 10)
school_fp <- fp_text(color = "red", bold = TRUE, font.size = 10)
name_fp <- fp_text(color = "black", bold = TRUE, font.size = 12)
role_fp <- fp_text(color = "blue", bold = TRUE, font.size = 10)

# 创建单张卡片的函数
create_single_card <- function(date, school, name, role, logo_path) {
  # 构建卡片内容的表格(6行对应6个元素)
  card_content <- data.frame(
    content = c(date, "", school, name, "", role),
    row_height = c(0.8, 0.2, 1, 1.2, 3.5, 1.3)  # 行高总和8cm,适配卡片高度
  )
  
  card <- flextable(card_content) %>%
    # 隐藏表头
    delete_part(part = "header") %>%
    # 设置列宽为2cm
    width(j = 1, width = 2) %>%
    # 设置各行高度
    height(i = 1:6, height = card_content$row_height) %>%
    # 日期行样式
    compose(i = 1, j = 1, value = as_paragraph(as_chunk(content, props = date_fp))) %>%
    # 蓝色粗分隔线(第二行)
    hline(i = 1, j = 1, border = fp_border(color = "blue", width = 2)) %>%
    # 院校名称行样式
    compose(i = 3, j = 1, value = as_paragraph(as_chunk(content, props = school_fp))) %>%
    # 姓名行样式
    compose(i = 4, j = 1, value = as_paragraph(as_chunk(content, props = name_fp))) %>%
    # Logo行(第五行)
    compose(i = 5, j = 1, value = as_paragraph(as_image(src = logo_path, width = 1.8, height = 3))) %>%
    # 职位行样式
    compose(i = 6, j = 1, value = as_paragraph(as_chunk(content, props = role_fp))) %>%
    # 所有内容居中对齐
    align(align = "center", part = "body") %>%
    # 添加卡片外边框
    border_outer(border = fp_border(color = "black", width = 1)) %>%
    # 去除内部边框
    border_inner(border = fp_border(width = 0))
  
  return(card)
}

# 将卡片按每行4张分组
cards_per_row <- 4
card_groups <- split(Test_cards, ceiling(seq_len(nrow(Test_cards))/cards_per_row))

# 创建Word文档
doc <- read_docx()

# 遍历每组,生成一行卡片
for (group in card_groups) {
  # 创建当前行的空表格(1行,列数=每行卡片数)
  row_table <- flextable(data.frame(matrix(ncol = cards_per_row, nrow = 1))) %>%
    delete_part(part = "header") %>%
    width(j = 1:cards_per_row, width = 2) %>%
    height(i = 1, height = 8)
  
  # 为每列插入卡片
  for (col in 1:nrow(group)) {
    card <- create_single_card(
      date = group$Date[col],
      school = group$School[col],
      name = group$Name[col],
      role = group$Role[col],
      logo_path = logo_path
    )
    row_table <- compose(row_table, i = 1, j = col, value = as_paragraph(as_flextable(card)))
  }
  
  # 添加当前行到文档
  doc <- body_add_flextable(doc, row_table)
  # 添加换行(可选,控制行间距)
  doc <- body_add_par(doc, value = "", style = "Normal")
}

# 保存文档
print(doc, target = "参会卡片_输出.docx")

关键修改说明

  • 卡片尺寸精准控制:设置卡片宽2cm、高8cm,通过分配各行高度实现内容区域的合理布局
  • 多行排列布局:将卡片按每行4张分组,用表格嵌套实现同行排列,避免每页仅一张卡片
  • 样式细节优化:调整分隔线宽度、文本字号,适配参考样式;优化Logo尺寸,填充卡片中间区域
  • 批量处理效率:通过分组循环生成整行卡片,减少文档操作次数,提升生成效率

内容的提问来源于stack exchange,提问作者firmo23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:05:09