knitr::opts_chunk$set(warning = TRUE, message = TRUE)
# 必要なパッケージを読み込み
library(officer)
## Warning: パッケージ 'officer' はバージョン 4.3.3 の R の下で造られました
library(tidyverse)
## Warning: パッケージ 'tidyverse' はバージョン 4.3.3 の R の下で造られました
## Warning: パッケージ 'ggplot2' はバージョン 4.3.3 の R の下で造られました
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(flextable)
## Warning: パッケージ 'flextable' はバージョン 4.3.3 の R の下で造られました
##
## 次のパッケージを付け加えます: 'flextable'
##
## 以下のオブジェクトは 'package:purrr' からマスクされています:
##
## compose
# 1. データ準備 ----
tbl_data1_raw <- tibble(
name = c("山田", "佐藤", "田中"),
age = c(28, 34, 23),
department = c("営業", "経理", "開発")
)
tbl_data2_raw <- tibble(
product = c("A", "B", "C", "D", "E"),
sales = c(120, 140, 100, 160, 180),
profit = c(30, 40, 20, 50, 60),
inventory = c(10, 15, 5, 20, 25)
)
# 2. スタイリング関数定義 ----
# tbl_data1 用のスタイリング関数 (列数を引数に追加)
custom_style_ft1 <- function(ft_combined, num_cols_ft1, num_row1) {
ft_combined <- bg(ft_combined, j = 1:num_cols_ft1, bg = "lightblue", part = "header")
ft_combined <- bold(ft_combined, j = 1:num_cols_ft1, bold = TRUE, part = "header")
ft_combined <- fontsize(ft_combined, j = 1:num_cols_ft1, size = 12, part = "header")
ft_combined <- border(ft_combined, j = 1:num_cols_ft1, border = fp_border(color = "black", width = 2), part = "header")
for (row in 1:num_row1) {
for (col in 1:(num_cols_ft1)) {
ft_combined <- bg(ft_combined, i = row, j = col, bg = ifelse(col %% 2 == 1, "lightgray", "white"), part = "body")
ft_combined <- border(ft_combined, i = row, j = col, border = fp_border(color = "black", width = 1), part = "body")
}
}
return(ft_combined)
}
# tbl_data2 用のスタイリング関数 (開始列を引数に追加)
custom_style_ft2 <- function(ft_combined, start_col, num_cols_data2, num_row2) {
ft_combined <- bg(ft_combined, j = start_col:num_cols_data2, bg = "lightgreen", part = "header")
ft_combined <- bold(ft_combined, j = start_col:num_cols_data2, bold = TRUE, part = "header")
ft_combined <- fontsize(ft_combined, j = start_col:start_col, size = 12, part = "header")
ft_combined <- border(ft_combined, j = start_col:num_cols_data2, border = fp_border(color = "black", width = 1), part = "header")
for (row in 1:num_row2) {
for (col in start_col:num_cols_data2) {
ft_combined <- bg(ft_combined, i = row, j = col, bg = ifelse((col - start_col + 1) %% 2 == 1, "lightgray", "white"), part = "body")
ft_combined <- border(ft_combined, i = row, j = col, border = fp_border(color = "black", width = 0.5), part = "body")
}
}
return(ft_combined)
}
# 結合後のスタイル適用を行う関数
apply_combined_style <- function(tbl_data1, tbl_data2) {
max_rows <- max(nrow(tbl_data1_raw), nrow(tbl_data2_raw))
tbl_data1 <- bind_rows(tbl_data1_raw, tibble(name = rep("", max_rows - nrow(tbl_data1_raw)), age = rep(NA, max_rows - nrow(tbl_data1_raw)), department = rep("", max_rows - nrow(tbl_data1_raw))))
tbl_data2 <- bind_rows(tbl_data2_raw, tibble(product = rep("", max_rows - nrow(tbl_data2_raw)), sales = rep(NA, max_rows - nrow(tbl_data2_raw)), profit = rep(NA, max_rows - nrow(tbl_data2_raw)), inventory = rep(NA, max_rows - nrow(tbl_data2_raw))))
# 空白の列を追加してデータを横に結合
empty_col <- tibble(blank = rep("", max_rows))
combined_data <- bind_cols(tbl_data1, empty_col, tbl_data2)
# 結合データを使用して flextable を作成
ft_combined <- flextable(combined_data) |>
border_remove()
ft_combined <- set_header_labels(ft_combined, blank = NA)
# 空白列のヘッダーを削除
# ft_combined <- delete_part(ft_combined, part = "header", j = ncol(tbl_data1) + 1)
# tbl_data1とtbl_data2にスタイル適用
ft_combined <- custom_style_ft1(ft_combined, ncol(tbl_data1), nrow(tbl_data1_raw))
ft_combined <- custom_style_ft2(ft_combined,
start_col = ncol(tbl_data1) + 2,
num_cols_data2 = ncol(tbl_data1) + 1 + ncol(tbl_data2),
nrow(tbl_data2_raw)
)
# フォントスタイルの一括設定
ft_combined <- font(ft_combined, fontname = "Arial", part = "all")
ft_combined
return(ft_combined)
}
# 3. スタイル適用と Word ドキュメントへの保存 ----
ft_combined <- apply_combined_style(tbl_data1_raw, tbl_data2_raw)
# flextable を HTML 出力用に変換して表示
ft_combined <- apply_combined_style(tbl_data1_raw, tbl_data2_raw)
flextable::htmltools_value(ft_combined)
name | age | department | product | sales | profit | inventory | |
|---|---|---|---|---|---|---|---|
山田 | 28 | 営業 | A | 120 | 30 | 10 | |
佐藤 | 34 | 経理 | B | 140 | 40 | 15 | |
田中 | 23 | 開発 | C | 100 | 20 | 5 | |
D | 160 | 50 | 20 | ||||
E | 180 | 60 | 25 |
# Wordドキュメントの作成と保存
doc <- read_docx() |>
body_add_par("2つの表を横に並べた表示", style = "heading 1") |>
body_add_flextable(ft_combined) |>
body_add_par(" ", style = "Normal")
print(doc, target = "two_tables_side_by_side2.docx")