R: قراءة وكتابة ملفات Excel
آخر تحديث: 2026-08-26
في الدرس السابق، تعرفنا على صيغة CSV، لكن 60% من البيانات في المشاريع العملية يتم تخزينها في Excel — فالمديرون وموظفو المبيعات والمتخصصون في الشؤون المالية جميعهم يفضلون مشاركة ملفات Excel. في هذا الدرس، سنتعرف على الطريقة القياسية لقراءة وكتابة ملفات Excel في R:
readxl+writexl، والتي لا تعتمد على Java (على عكس حزمةxlsx، التي تتطلب JDK).
بعد الانتهاء من هذا الدرس، ستتمكن من قراءة البيانات المالية الموزعة على أوراق متعددة وإنشاء تقارير Excel منسقة.
1. ما ستتعلمه
- التنسيقات الثلاثة لملفات Excel (.xlsx / .xls / .xlsm)
- تثبيت حزمة readxl ووظائفها الأساسية الأربع
- قراءة أوراق متعددة والمعالجة المجمعة
- 8 معلمات مشتركة لـ
read_excel(sheet،range،col_types،na) - writexl: كتابة ملفات Excel
- الاختلافات عن openxlsx
- تجربة عملية: المعالجة المجمعة للتقارير المالية الشهرية
2. قصة التقرير المالي الشهري
(1) المشكلة: هناك 30 مهمة في برنامج Excel تدفعني إلى الجنون
تعمل أليس في مجال الشؤون المالية، وتضطر في بداية كل شهر إلى تجميع «تقارير المبيعات الشهرية» الواردة من 30 فرعًا:
- يحتوي كل ملف Excel على 3 أوراق (تفاصيل المبيعات، والإيصالات، والمخزون)
- كل ملف Excel له نفس التنسيق
- يلزم استيراد ما مجموعه 90 جدولًا إلى برنامج R لتحليلها
إذا كنت تستخدم أداة «Power Query» المدمجة في برنامج Excel، فإن المعالجة عبر الملفات تكون معقدة؛ كما أن استخدام لغة Python openpyxl يكون بطيئًا؛ أما استخدام لغة R xlsx فيتطلب تثبيت Java—
(2) الحل باستخدام لغة R
# 1. Packing(Not dependent on Java)
install.packages("readxl")
install.packages("writexl")
# 2. List all Excel Documents
files <- list.files("reports/", pattern = "\\.xlsx$", full.names = TRUE)
# 3. Read all in bulk sheet
library(readxl)
all_data <- lapply(files, function(f) {
list(
sales = read_excel(f, sheet = "Sales Details"),
payment = read_excel(f, sheet = "Payment"),
stock = read_excel(f, sheet = "Inventory")
)
})
# 4. Consolidated Analysis
library(dplyr)
combined <- bind_rows(lapply(all_data, function(d) d$sales))
5 أسطر فقط من التعليمات البرمجية لمعالجة 30 ملفًا من ملفات Excel × 3 أوراق = 90 ورقة عمل. هذه هي قوة readxl.
graph TB
A[30 branch offices Excel Documents] --> B[list.files List]
B --> C[lapply Batch Read]
C --> D[excel_sheets check sheet]
D --> E[read_excel Each sheet]
E --> F[bind_rows Merge]
F --> G[group_by + summarise Summarize]
G --> H[write_xlsx Generate Report]
style A fill:#cce5ff
style B fill:#d4edda
style C fill:#fff3cd
style D fill:#f8d7da
style E fill:#e1d4ff
style F fill:#ffe1d4
style G fill:#cce5ff
style H fill:#d4edda
3. ثلاثة تنسيقات لملفات إكسل
mindmap
root((Excel Documents<br/>3 Type of Format))
.xlsx
Excel 2007+
Maximum @,000 rows of
Modern Standards
Tools: readxl / openxlsx
.xls
Excel 97-2003
Maximum 65536 row
Old Format
Tools: readxl
.xlsm
Enable Macros
Contains VBA
Tools: readxl Do not read macros
Select
New Project: .xlsx
Old data: .xls
Han Hong: .xlsm
(1) مقارنة التنسيقات
| التنسيق | امتداد الملف | الحد الأقصى لعدد الصفوف والأعمدة | التوافق | قابلية القراءة |
|---|---|---|---|---|
| Excel 2007 وما بعده | .xlsx |
1048576 × 16384 | المعيار الحديث | readxl / openxlsx |
| Excel 97-2003 | .xls |
65536 × 256 | التنسيق القديم | readxl |
| تمكين الماكرو في Excel | .xlsm |
مثل xlsx | يحتوي على VBA | readxl (لا يتم تحميل الماكرو) |
(2) مقارنة بين 3 حزم برمجية في لغة R لقراءة ملفات Excel
| الحزمة | التبعيات | السرعة | الميزات | التوصية |
|---|---|---|---|---|
| readxl | لغة R الخالصة (C++) | سريع | للقراءة فقط | ⭐⭐⭐ الخيار الأفضل للقراءة |
| writexl | لغة R خالصة (C++) | سريع | للكتابة فقط | ⭐⭐⭐ الخيار الأفضل للكتابة |
| openxlsx | لغة R الخالصة | الصينية | القراءة/الكتابة + التنسيق | ⭐⭐ يُستخدم عند الحاجة إلى التنسيق |
| xlsx | يتطلب Java | بطيء | القراءة/الكتابة + الصيغ | ❌ غير موصى به (اعتماد كبير) |
readxl + writexl (الطريقة الأبسط)؛ بالنسبة للبيانات التي تتطلب تنسيق الخلايا أو الصيغ، استخدم openxlsx؛ تجنب استخدام حزمة xlsx (تتطلب Java).
4. الوظائف الأساسية الأربع لـ readxl
(1) جدول مرجعي سريع للوظائف
| الوظيفة | الغرض |
|---|---|
read_excel() |
قراءة ملفات .xlsx أو .xls (يتم الكشف عنها تلقائيًا) |
read_xlsx() |
ملف .xlsx للقراءة فقط (أسرع) |
read_xls() |
ملف .xls للقراءة فقط (تنسيق قديم) |
excel_sheets() |
عرض قائمة بأسماء جميع الأوراق |
library(readxl)
# 1. List all sheet
sheets <- excel_sheets("report.xlsx")
print(sheets)
# [1] "Sales Details" "Payment" "Inventory"
# 2. Read as Specified sheet
sales <- read_excel("report.xlsx", sheet = "Sales Details")
# or press sheet Number
sales <- read_excel("report.xlsx", sheet = 1)
# 3. Read All sheet(Back list)
all_sheets <- lapply(excel_sheets("file.xlsx"), function(name) {
read_excel("file.xlsx", sheet = name)
})
names(all_sheets) <- excel_sheets("file.xlsx")
(2) 8 معلمات شائعة لـ read_excel
| المعلمة | الوظيفة | مثال |
|---|---|---|
path |
مسار الملف | "data/sales.xlsx" |
sheet |
اسم الورقة أو رقمها | 1 أو "Sales Details" |
range |
نطاق القراءة | "A1:D100" أو "A1:D100" |
col_names |
TRUE / متجه مخصص | TRUE |
col_types |
نوع القائمة | "text"، "numeric"، "date" |
na |
علامة NA | c("", "NA") |
skip |
تخطي الأسطر | 2 (تخطي صف العناوين) |
n_max |
الحد الأقصى لعدد الصفوف المراد قراءتها | 1000 |
(3) تدريب عملي: المعلمات الشائعة
# 1. Specification sheet
df <- read_excel("data.xlsx", sheet = "Sales Details")
# 2. Specified Range(Avoid reading comments outside the table header)
df <- read_excel("data.xlsx", range = "A1:D1000")
# 3. Skip the header row
df <- read_excel("data.xlsx", skip = 2)
# 4. Read-only 1000 row
df <- read_excel("data.xlsx", n_max = 1000)
# 5. Specify Column Type
df <- read_excel("data.xlsx", col_types = c("text", "numeric", "date"))
# 6. Custom NA
df <- read_excel("data.xlsx", na = c("", "NA", "N/A"))
5. شرح تفصيلي لمعلمة read_excel
(1) المعلمة sheet
# Method 1:sheet name(Recommendations)
df <- read_excel("data.xlsx", sheet = "Sales Details")
# Method 2:sheet number(Starting from 1)
df <- read_excel("data.xlsx", sheet = 1)
# Method 3:NULL(By default, read the first one)
df <- read_excel("data.xlsx")
(2) المعلمة range (الأكثر فائدة)
غالبًا ما يحتوي برنامج Excel على عناوين وتعليقات وصفوف فارغة. حدد نطاقًا لقراءة دقيقة:
# 1. String Range
df <- read_excel("data.xlsx", range = "A1:D100")
# 2. Anchor Cell(Automatically expand to non-empty areas)
df <- read_excel("data.xlsx", range = "A1:D1") # Read-only 1 row(Automatic Scaling)
# 3. Complete A1 Quote
df <- read_excel("data.xlsx", range = "A1:Z1000")
# 4. Naming Area(Excel as defined in Named Range)
df <- read_excel("data.xlsx", range = "SalesTable")
(3) المعلمة col_types
# Method 1:String Shorthand
col_types = c("text", "numeric", "date", "guess", "skip")
# Method 2:List
col_types = list(
text, # Character
numeric, # Numbers
date, # Date
guess, # Automatic Inference
skip # Skip
)
# Skip All(Do not read the data)
col_types = c("skip", "skip", "skip")
# All characters
col_types = c("text")
الأنواع المتاحة: "guess" (الاستدلال الافتراضي)، "logical"، "numeric"، "date"، "text"، "skip"، "list" (الجداول المتداخلة)
6. كتابة في Excel: writexl
(1) مزايا برنامج writexl
- تنفيذ بلغة R الخالصة (لا يعتمد على Java أو LibreOffice)
- سريع (نظام أساسي بلغة C++)
- واجهة برمجة تطبيقات بسيطة (فقط
write_xlsx())
(2) قواعد النحو الأساسية
library(writexl)
# 1. Single sheet Output
write_xlsx(df, "output.xlsx")
# 2. Multiple sheet Output(Use list)
write_xlsx(
list(
"Sales Details" = sales_df,
"Payment" = payment_df,
"Inventory" = stock_df
),
"output.xlsx"
)
# 3. Append to the existing file
# writexl Does not directly support additional entries,Required openxlsx
(3) التطبيق العملي
# Export R data frames in batch
list_of_dfs <- list(
Sales = sales_df,
Payment = payment_df,
Inventory = stock_df
)
write_xlsx(list_of_dfs, "monthly_report.xlsx")
cat("=== The report has been generated:monthly_report.xlsx ===\n")
openxlsx:
library(openxlsx)
# Write formatted text Excel
wb <- createWorkbook()
addWorksheet(wb, "Sales")
writeData(wb, "Sales", sales_df)
addStyle(wb, "Sales", style = createStyle(fontColour = "red"),
rows = 2:10, cols = 5)
saveWorkbook(wb, "formatted_report.xlsx")
7. تدريب عملي: القراءة الجماعية لعدة أوراق في البيانات المالية
فيما يلي مثال على مسار عمل كامل يوضح كيفية معالجة عدة ملفات تحتوي على أوراق متعددة بشكل مجمَّع.
▶ مثال: ملخص التقارير المالية الشهرية من 30 فرعًا
# ============================================
# 30 Summary of Monthly Financial Reports from Each Branch
# Features:Batch Read 30 ea Excel × 3 ea sheet
# ============================================
library(readxl)
library(dplyr)
library(purrr)
library(writexl)
# 1. Preparing Sample Data
set.seed(42)
make_sales <- function(city) {
tibble(
order_id = 1:5,
date = as.Date("2024-01-01") + 0:4,
product = sample(c("A", "B", "C"), 5, replace = TRUE),
amount = sample(1000:5000, 5)
)
}
make_payment <- function(city) {
tibble(
order_id = 1:5,
paid = sample(c(TRUE, FALSE), 5, replace = TRUE),
paid_date = as.Date("2024-01-15") + 0:4
)
}
make_stock <- function(city) {
tibble(
product = c("A", "B", "C"),
stock = sample(50:200, 3)
)
}
# Simulation 3 Each branch's Excel(Each 3 sheet)
dir.create("temp_reports", showWarnings = FALSE)
for (city in c("Beijing", "Shanghai", "Guangzhou")) {
write_xlsx(
list(
"Sales Details" = make_sales(city),
"Payment" = make_payment(city),
"Inventory" = make_stock(city)
),
file.path("temp_reports", paste0(city, ".xlsx"))
)
}
# 2. List all Excel Documents
files <- list.files("temp_reports", pattern = "\\.xlsx$", full.names = TRUE)
cat("Found", length(files), "ea Excel Documents:\n")
print(files)
# 3. View each file's sheet name
for (f in files) {
cat("\nDocuments:", basename(f), "\n")
cat(" Sheet:", paste(excel_sheets(f), collapse = ", "), "\n")
}
# 4. Read all in bulk sheet
cat("\n=== Bulk reading in progress ===\n")
all_reports <- lapply(files, function(f) {
city <- tools::file_path_sans_ext(basename(f))
list(
sales = read_excel(f, sheet = "Sales Details") |> mutate(city = !!city),
payment = read_excel(f, sheet = "Payment") |> mutate(city = !!city),
stock = read_excel(f, sheet = "Inventory") |> mutate(city = !!city)
)
})
names(all_reports) <- tools::file_path_sans_ext(basename(files))
# 5. Consolidate all sales data
all_sales <- bind_rows(lapply(all_reports, function(d) d$sales))
cat("\n=== Sales Summary ===\n")
print(all_sales)
# 6. Consolidate all payment receipt data
all_payment <- bind_rows(lapply(all_reports, function(d) d$payment))
cat("\n=== Summary of Receivables ===\n")
print(all_payment)
# 7. Merge all inventory data
all_stock <- bind_rows(lapply(all_reports, function(d) d$stock))
cat("\n=== Inventory Summary ===\n")
print(all_stock)
# 8. Comprehensive Analysis
cat("\n=== Sales Analysis by City ===\n")
city_stats <- all_sales |>
group_by(city) |>
summarise(
Number of Orders = n(),
Total Sales = sum(amount),
Average Order = round(mean(amount), 2)
) |>
arrange(desc(Total Sales))
print(city_stats)
# 9. Generate a Summary Report
write_xlsx(
list(
"Sales Summary" = all_sales,
"Summary of Receivables" = all_payment,
"Inventory Summary" = all_stock,
"City Statistics" = city_stats
),
"summary_report.xlsx"
)
cat("\n=== The summary report has been generated.:summary_report.xlsx ===\n")
# 10. Clear Temporary Files
unlink("temp_reports", recursive = TRUE)
النتائج المتوقعة (مقتطف):
=== Sales Analysis by City ===
# A tibble: 3 × 4
city Number of Orders Total Sales Average Order
<chr> <int> <int> <dbl>
1 Shanghai 5 14325 2865
2 Beijing 5 12289 2458.
3 Guangzhou 5 11234 2247.
❓ أسئلة شائعة
iconv لتحويل ترميز الملف قبل قراءته.read_excel("file.xlsx", sheet = "Sales Details") أو sheet = 1 (حسب الرقم). excel_sheets(file) يعرض قائمة بجميع أسماء الأوراق.range = "A1:D100" لتحديد نطاق الخلايا. أو استخدم range = "A1:D1" لتثبيت النطاق على العنوان وتوسيعه تلقائيًا.NA. للتعامل مع هذا الأمر، استخدم المعلمتين openxlsx وmergeCells.library(openxlsx)
wb <- loadWorkbook("existing.xlsx")
addWorksheet(wb, "newsheet")
writeData(wb, "newsheet", new_df)
saveWorkbook(wb, "existing.xlsx")
📖 ملخص
- readxl هو الخيار الأفضل — يعتمد على مكتبات R فقط، وسريع، ويتعامل تلقائيًا مع أوراق عمل متعددة
- 3 تنسيقات لبرنامج Excel:
.xlsx(حديث)،.xls(قديم)،.xlsm(مع ماكرو) - 4 وظائف أساسية:
read_excel/read_xlsx/read_xls/excel_sheets - 8 معلمات شائعة:
sheetrangecol_typescol_namesnaskipn_maxpath - writexl: الخيار الأفضل للكتابة في Excel — مكتوب بلغة R الخالصة، سريع، ولا يدعم التنسيق
- استخدم openxlsx للتنسيق/الصيغ — برنامج قوي لكنه يتميز بواجهة برمجة تطبيقات معقدة؛ تجنب استخدام حزمة xlsx (تتطلب Java)
- المعالجة المجمعة لملفات متعددة تحتوي على أوراق متعددة: قم بالتكرار عبر
lapply+bind_rowsللدمج
📝 تمارين
-
تمرين أساسي: أنشئ ملف Excel يحتوي على ثلاث أوراق عمل (المبيعات، الذمم المدينة، والمخزون) وقم بتصديره باستخدام
write_xlsx(). استخدمexcel_sheets()للتحقق من صحة أسماء أوراق العمل، واستخدمread_excel()لقراءة ورقة العمل «المبيعات» والتحقق من صحة البيانات. -
تمرين أساسي: افتح ملف Excel من السؤال السابق واستخدم
range = "A1:B5"لقراءة العمودين A و B فقط من الصفوف 1–5. تأكد من أنه تم قراءة عمودين و5 صفوف فقط. -
تمرين أساسي: اقرأ ورقة «المبيعات» من السؤال السابق، واستخدم
col_types = c("numeric", "date", "text", "numeric")لتحديد نوع العمود بشكل صريح، وتأكد من صحة هذا النوع. -
تمرين متقدم: قم بمحاكاة ثلاثة فروع في برنامج Excel (ثلاث أوراق عمل لكل فرع). استخدم
lapplyلقراءة جميع أوراق العمل دفعة واحدة، واستخدمbind_rowsلدمج البيانات من نفس النوع. احسب إجمالي المبيعات لكل مدينة. -
التحدي: استخدم
openxlsxلإنشاء ملف Excel منسق: ① اجعل صف العناوين باللون الأحمر وبخط عريض؛ ② قم بمحاذاة عمود الأرقام إلى اليمين؛ ③ قم بتنسيق عمود الأرقام باستخدام فواصل الآلاف؛ ④ اضبط عرض الأعمدة بحيث يتم تعديله تلقائيًا. احفظه باسمformatted_report.xlsx، وافتحه في Excel للتحقق من النتائج (التقط لقطة شاشة واحفظها).