R: قراءة وكتابة ملفات Excel

آخر تحديث: 2026-08-26

في الدرس السابق، تعرفنا على صيغة CSV، لكن 60% من البيانات في المشاريع العملية يتم تخزينها في Excel — فالمديرون وموظفو المبيعات والمتخصصون في الشؤون المالية جميعهم يفضلون مشاركة ملفات Excel. في هذا الدرس، سنتعرف على الطريقة القياسية لقراءة وكتابة ملفات Excel في R: readxl + writexl، والتي لا تعتمد على Java (على عكس حزمة xlsx، التي تتطلب JDK).

بعد الانتهاء من هذا الدرس، ستتمكن من قراءة البيانات المالية الموزعة على أوراق متعددة وإنشاء تقارير Excel منسقة.

1. ما ستتعلمه



2. قصة التقرير المالي الشهري

(1) المشكلة: هناك 30 مهمة في برنامج Excel تدفعني إلى الجنون

تعمل أليس في مجال الشؤون المالية، وتضطر في بداية كل شهر إلى تجميع «تقارير المبيعات الشهرية» الواردة من 30 فرعًا:

إذا كنت تستخدم أداة «Power Query» المدمجة في برنامج Excel، فإن المعالجة عبر الملفات تكون معقدة؛ كما أن استخدام لغة Python openpyxl يكون بطيئًا؛ أما استخدام لغة R xlsx فيتطلب تثبيت Java—

(2) الحل باستخدام لغة R

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.

100%
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. ثلاثة تنسيقات لملفات إكسل

100%
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() عرض قائمة بأسماء جميع الأوراق
R
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) تدريب عملي: المعلمات الشائعة

R
# 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

R
# 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 على عناوين وتعليقات وصفوف فارغة. حدد نطاقًا لقراءة دقيقة:

R
# 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

R
# 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

(2) قواعد النحو الأساسية

R
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) التطبيق العملي

R
# 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")
⚠️ ملاحظة: لا يدعم برنامج writexl تنسيق الخلايا (اللون، الخط، الصيغ). لتطبيق التنسيق، استخدم openxlsx:

R
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 فرعًا

R 📖 للعرض فقط
# ============================================
# 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)
84 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

النتائج المتوقعة (مقتطف):

TEXT 📖 للعرض فقط
=== 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. 


❓ أسئلة شائعة

س ماذا أفعل إذا عرضت أداة readxl أحرفًا مشوشة؟
ج تتعامل أداة readxl تلقائيًّا مع ترميزات UTF-8 و GBK. إذا كنت ترى بالفعل أحرفًا مشوشة، فاستخدم iconv لتحويل ترميز الملف قبل قراءته.
س كيف يمكنني الاطلاع على ورقة معينة؟
ج read_excel("file.xlsx", sheet = "Sales Details") أو sheet = 1 (حسب الرقم). excel_sheets(file) يعرض قائمة بجميع أسماء الأوراق.
س كيف يمكنني قراءة نطاق معين فقط؟
ج استخدم range = "A1:D100" لتحديد نطاق الخلايا. أو استخدم range = "A1:D1" لتثبيت النطاق على العنوان وتوسيعه تلقائيًا.
س كيف يمكنني قراءة ملف Excel يحتوي على خلايا مدمجة؟
ج تحتوي الخلايا المدمجة على قيم في الزاوية العلوية اليسرى فقط؛ أما المواضع الأخرى فهي فارغة. تعالج مكتبة readxl هذه الخلايا على أنها «غير مدمجة»، لذا فإن المواضع «غير العلوية اليسرى» في المناطق المدمجة تُظهر كـ NA. للتعامل مع هذا الأمر، استخدم المعلمتين openxlsx وmergeCells.
R
library(openxlsx)
wb <- loadWorkbook("existing.xlsx")
addWorksheet(wb, "newsheet")
writeData(wb, "newsheet", new_df)
saveWorkbook(wb, "existing.xlsx")

📖 ملخص


📝 تمارين

  1. تمرين أساسي: أنشئ ملف Excel يحتوي على ثلاث أوراق عمل (المبيعات، الذمم المدينة، والمخزون) وقم بتصديره باستخدام write_xlsx(). استخدم excel_sheets() للتحقق من صحة أسماء أوراق العمل، واستخدم read_excel() لقراءة ورقة العمل «المبيعات» والتحقق من صحة البيانات.

  2. تمرين أساسي: افتح ملف Excel من السؤال السابق واستخدم range = "A1:B5" لقراءة العمودين A و B فقط من الصفوف 1–5. تأكد من أنه تم قراءة عمودين و5 صفوف فقط.

  3. تمرين أساسي: اقرأ ورقة «المبيعات» من السؤال السابق، واستخدم col_types = c("numeric", "date", "text", "numeric") لتحديد نوع العمود بشكل صريح، وتأكد من صحة هذا النوع.

  4. تمرين متقدم: قم بمحاكاة ثلاثة فروع في برنامج Excel (ثلاث أوراق عمل لكل فرع). استخدم lapply لقراءة جميع أوراق العمل دفعة واحدة، واستخدم bind_rows لدمج البيانات من نفس النوع. احسب إجمالي المبيعات لكل مدينة.

  5. التحدي: استخدم openxlsx لإنشاء ملف Excel منسق: ① اجعل صف العناوين باللون الأحمر وبخط عريض؛ ② قم بمحاذاة عمود الأرقام إلى اليمين؛ ③ قم بتنسيق عمود الأرقام باستخدام فواصل الآلاف؛ ④ اضبط عرض الأعمدة بحيث يتم تعديله تلقائيًا. احفظه باسم formatted_report.xlsx، وافتحه في Excel للتحقق من النتائج (التقط لقطة شاشة واحفظها).

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%