איך להמיר תגובות API לדוחות Excel ב-C#

איך להמיר תגובות API לדוחות Excel ב-C#

בעולם המונע על ידי נתונים של היום, עסקים מסתמכים במידה רבה על API-ים מסוג REST להעברת נתונים. עם זאת, רבים מהמעורבים מעדיפים לצרוך נתונים אלו בפורמט Excel לצורך ניתוח ודיווח. מדריך זה מדגים כיצד לבנות אפליקציה מלאה ב-C# אשר:

  1. מתחברת ל-API-ים מסוג REST
  2. שולפת נתוני תגובת JSON
  3. ממירה את הנתונים לדו"ח Excel מעוצב מקצועית
  4. מוסיפה ויזואליזציה עם גרפים וטבלאות

ערך עסקי

פתרון זה מספק ערך משמעותי על ידי:

  • אוטומציה של תהליכי חילוץ נתונים ידניים ויצירת דוחות
  • הבטחת דיוק הנתונים על ידי חיסול העתקות ידניות
  • מתן עיצוב דוחות עקבי
  • אפשרות ליצירת דוחות מתוזמנים

מדריך יישום שלב-אחר-שלב

שלב 1: צור אפליקציית C# חדשה

התחל ביצירת אפליקציה קונסול חדשה:

dotnet new console -n ApiToExcelReporter
cd ApiToExcelReporter

שלב 2: התקן חבילות נדרשות

הוסף את חבילות NuGet הנדרשות:

dotnet add package Aspose.Cells
dotnet add package Newtonsoft.Json
dotnet add package RestSharp

שלב 3: יישם את לקוח ה-API

צור שירות לתקשורת עם ה-API:

using RestSharp;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;

public class ApiService
{
    private readonly RestClient _client;
    
    public ApiService(string baseUrl)
    {
        _client = new RestClient(baseUrl);
    }
    
    public async Task<T> GetApiDataAsync<T>(string endpoint, string apiKey = null)
    {
        var request = new RestRequest(endpoint, Method.Get);
        
        // הוסף אימות אם נדרש
        if (!string.IsNullOrEmpty(apiKey))
        {
            request.AddHeader("Authorization", $"Bearer {apiKey}");
        }
        
        var response = await _client.ExecuteAsync(request);
        
        if (response.IsSuccessful)
        {
            return JsonConvert.DeserializeObject<T>(response.Content);
        }
        
        throw new Exception($"שיחת ה-API נכשלה: {response.ErrorMessage}");
    }
}

שלב 4: עבד את נתוני תגובת JSON

הוסף מחלקה לעיבוד נתוני JSON:

using Newtonsoft.Json.Linq;
using System.Collections.Generic;

public class DataProcessor
{
    public List<Dictionary<string, object>> FlattenJsonData(string jsonData)
    {
        var results = new List<Dictionary<string, object>>();
        JToken token = JToken.Parse(jsonData);
        
        // טיפול במבנים שונים של JSON
        if (token is JArray array)
        {
            foreach (var item in array)
            {
                results.Add(FlattenObject(item));
            }
        }
        else if (token is JObject obj)
        {
            // עבור נתונים מקוננים כמו {"data": [{...}, {...}]}
            var dataToken = obj["data"] as JArray;
            if (dataToken != null)
            {
                foreach (var item in dataToken)
                {
                    results.Add(FlattenObject(item));
                }
            }
            else
            {
                results.Add(FlattenObject(obj));
            }
        }
        
        return results;
    }
    
    private Dictionary<string, object> FlattenObject(JToken token)
    {
        var result = new Dictionary<string, object>();
        FillDictionary(result, token, "");
        return result;
    }
    
    private void FillDictionary(Dictionary<string, object> dict, JToken token, string prefix)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                foreach (var prop in token.Children<JProperty>())
                {
                    FillDictionary(dict, prop.Value, 
                        string.IsNullOrEmpty(prefix) ? prop.Name : $"{prefix}.{prop.Name}");
                }
                break;
                
            case JTokenType.Array:
                int index = 0;
                foreach (var item in token.Children())
                {
                    FillDictionary(dict, item, $"{prefix}[{index}]");
                    index++;
                }
                break;
                
            default:
                dict[prefix] = ((JValue)token).Value;
                break;
        }
    }
}

שלב 5: המרה ל-Excel עם Aspose.Cells

יישם את המרת ה-Excel:

using Aspose.Cells;
using Aspose.Cells.Utility;
using System;
using System.Collections.Generic;
using System.IO;

public class ExcelReportGenerator
{
    public void GenerateReport(string jsonData, string outputPath)
    {
        // צור חוברת עבודה חדשה
        Workbook workbook = new Workbook();
        Worksheet sheet = workbook.Worksheets[0];
        
        // הגדר אפשרויות פריסת JSON
        JsonLayoutOptions options = new JsonLayoutOptions
        {
            ArrayAsTable = true,
            ConvertNumericOrDate = true,
            IgnoreNull = true
        };
        
        // עשה את הכותרות בולטות
        options.TitleStyle = new CellsFactory().CreateStyle();
        options.TitleStyle.Font.IsBold = true;
        
        // ייבא נתוני JSON
        JsonUtility.ImportData(jsonData, sheet.Cells, 0, 0, options);
        
        // אוטו-התאם עמודות
        sheet.AutoFitColumns();
        
        // שמור את חוברת העבודה
        workbook.Save(outputPath);
    }
    
    public void GenerateReportFromObjects(List<Dictionary<string, object>> data, string outputPath)
    {
        Workbook workbook = new Workbook();
        Worksheet sheet = workbook.Worksheets[0];
        
        // הוסף כותרות אם יש נתונים
        if (data.Count > 0)
        {
            int col = 0;
            foreach (var key in data[0].Keys)
            {
                // הוסף כותרת עם עיצוב
                Cell cell = sheet.Cells[0, col];
                cell.PutValue(key);
                
                Style style = cell.GetStyle();
                style.Font.IsBold = true;
                cell.SetStyle(style);
                
                col++;
            }
            
            // הוסף שורות נתונים
            for (int row = 0; row < data.Count; row++)
            {
                col = 0;
                foreach (var value in data[row].Values)
                {
                    sheet.Cells[row + 1, col].PutValue(value);
                    col++;
                }
            }
        }
        
        // עיצוב כטבלה
        if (data.Count > 0)
        {
            int lastRow = data.Count;
            int lastCol = data[0].Count - 1;
            
            var tableRange = sheet.Cells.CreateRange(0, 0, lastRow + 1, lastCol + 1);
            sheet.ListObjects.Add(tableRange, "DataTable");
        }
        
        // אוטו-התאם עמודות
        sheet.AutoFitColumns();
        
        // שמור את חוברת העבודה
        workbook.Save(outputPath);
    }
}

שלב 6: הוסף עיצוב מקצועי

שפר את פלט ה-Excel עם עיצוב מקצועי:

public void ApplyProfessionalFormatting(Workbook workbook)
{
    Worksheet sheet = workbook.Worksheets[0];
    
    // צור סגנון עבור הכותרת
    Style titleStyle = workbook.CreateStyle();
    titleStyle.Font.Size = 14;
    titleStyle.Font.IsBold = true;
    titleStyle.HorizontalAlignment = TextAlignmentType.Center;
    
    // הוסף כותרת לדו"ח
    sheet.Cells.Merge(0, 0, 1, sheet.Cells.MaxColumn + 1);
    Cell titleCell = sheet.Cells[0, 0];
    titleCell.PutValue("דו"ח נתוני API - " + DateTime.Now.ToString("yyyy-MM-dd"));
    titleCell.SetStyle(titleStyle);
    
    // הכנס שורה ריקה לאחר הכותרת
    sheet.Cells.InsertRow(1);
    
    // החל צבעים לסירוגין על השורות בנתונים
    Style evenRowStyle = workbook.CreateStyle();
    evenRowStyle.ForegroundColor = Color.FromArgb(240, 240, 240);
    evenRowStyle.Pattern = BackgroundType.Solid;
    
    int dataStartRow = 3; // בהתחשב בכותרת ובשורה הריקה
    int lastRow = sheet.Cells.MaxRow;
    
    for (int row = dataStartRow; row <= lastRow; row += 2)
    {
        for (int col = 0; col <= sheet.Cells.MaxColumn; col++)
        {
            sheet.Cells[row, col].SetStyle(evenRowStyle);
        }
    }
    
    // הוסף כותרת ותחתית לדף
    sheet.PageSetup.SetHeader(1, "&\"Arial,Bold\"&14דו"ח API");
    sheet.PageSetup.SetFooter(1, "עמוד &P מתוך &N");
    
    // הגדר אפשרויות הדפסה
    sheet.PageSetup.Orientation = PageOrientationType.Landscape;
    sheet.PageSetup.FitToPagesWide = 1;
    sheet.PageSetup.TopMargin = 0.5;
    sheet.PageSetup.LeftMargin = 0.5;
    sheet.PageSetup.RightMargin = 0.5;
    sheet.PageSetup.BottomMargin = 0.5;
}

שלב 7: הוסף ויזואליזציה של נתונים

שפר את הדו"ח עם גרפים:

public void AddChartVisualization(Workbook workbook, int dataColumn)
{
    Worksheet sheet = workbook.Worksheets[0];
    Worksheet chartSheet = workbook.Worksheets.Add("ניתוח גרפים");
    
    // קבל את טווח הנתונים (דלג על שורת הכותרת)
    int lastRow = sheet.Cells.MaxRow;
    int nameColumn = 0; // מניח שהעמודה הראשונה מכילה שמות/קטגוריות
    
    // הוסף גרף
    int chartIndex = chartSheet.Charts.Add(ChartType.Column, 2, 2, 20, 10);
    Chart chart = chartSheet.Charts[chartIndex];
    
    // הגדר את טווח הנתונים עבור הגרף
    chart.NSeries.Add($"Sheet1!B2:B{lastRow + 1}", true);
    chart.NSeries.CategoryData = $"Sheet1!A2:A{lastRow + 1}";
    
    // הגדר את כותרת הגרף ושאר המאפיינים
    chart.Title.Text = "ניתוח נתונים";
    chart.Legend.Position = LegendPositionType.Bottom;
    
    // התאמה נוספת של הגרף
    chart.NSeries[0].Area.ForegroundColor = Color.FromArgb(79, 129, 189);
    chart.PlotArea.Area.ForegroundColor = Color.White;
    
    // הוסף תוויות נתונים
    chart.NSeries[0].DataLabels.IsValueShown = true;
    chart.NSeries[0].DataLabels.Position = DataLabelPositionType.OutsideEnd;
}

שלב 8: חבר הכל יחד

צור את התוכנית הראשית שמקשרת הכל יחד:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            // הגדר את נקודת הקצה של ה-API
            string baseUrl = "https://api.example.com";
            string endpoint = "/data/endpoint";
            string apiKey = "your-api-key"; // אם נדרש
            
            // התחבר ל-API וקבל נתונים
            Console.WriteLine("מתחבר ל-API...");
            var apiService = new ApiService(baseUrl);
            var jsonData = await apiService.GetApiDataAsync<string>(endpoint, apiKey);
            
            Console.WriteLine("הנתונים הושגו בהצלחה");
            
            // צור דו"ח Excel
            Console.WriteLine("יוצר דו"ח Excel...");
            var reportGenerator = new ExcelReportGenerator();
            
            // אפשרות 1: המרה ישירה מ-JSON ל-Excel
            string outputPath = "ApiReport_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".xlsx";
            reportGenerator.GenerateReport(jsonData, outputPath);
            
            // אפשרות 2: עיבוד JSON ויצירת דו"ח משופר
            // var processor = new DataProcessor();
            // var processedData = processor.FlattenJsonData(jsonData);
            // reportGenerator.GenerateReportFromObjects(processedData, outputPath);
            
            Console.WriteLine($"הדו"ח נשמר ב-{outputPath}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"שגיאה: {ex.Message}");
        }
    }
}

טיפול במבני תגובת API שונים

API-ים מסוג REST מחזירים נתונים במבנים שונים. הנה כיצד לטפל במבנים נפוצים:

1. מערך של אובייקטים

[
  { "id": 1, "name": "מוצר A", "price": 29.99 },
  { "id": 2, "name": "מוצר B", "price": 49.99 }
]

למבנה זה, השתמש ב:

JsonLayoutOptions options = new JsonLayoutOptions();
options.ArrayAsTable = true;
JsonUtility.ImportData(jsonData, sheet.Cells, 0, 0, options);

2. אובייקט מקונן עם מערך נתונים

{
  "status": "success",
  "data": [
    { "id": 1, "name": "מוצר A", "price": 29.99 },
    { "id": 2, "name": "מוצר B", "price": 49.99 }
  ]
}

השתמש במחלקת DataProcessor כדי לחלץ את מערך ה-“data”, או:

// ניתוח עם Newtonsoft.Json
JObject jsonObj = JObject.Parse(jsonData);
JArray dataArray = (JArray)jsonObj["data"];

// המרה למחרוזת וייבוא
string dataArrayJson = dataArray.ToString();
JsonUtility.ImportData(dataArrayJson, sheet.Cells, 0, 0, options);

3. מערכים ואובייקטים מקוננים

{
  "categories": [
    {
      "name": "אלקטרוניקה",
      "products": [
        { "id": 1, "name": "מחשב נייד", "price": 999.99 },
        { "id": 2, "name": "טלפון", "price": 699.99 }
      ]
    },
    {
      "name": "ספרים",
      "products": [
        { "id": 3, "name": "רומן", "price": 14.99 }
      ]
    }
  ]
}

למבנים מורכבים, צור חוברות עבודה מרובות:

// ניתוח ה-JSON
JObject root = JObject.Parse(jsonData);
JArray categories = (JArray)root["categories"];

// צור חוברת עבודה עבור כל קטגוריה
foreach (var category in categories)
{
    string categoryName = category["name"].ToString();
    Worksheet sheet = workbook.Worksheets.Add(categoryName);
    
    // קבל וייבא את מערך המוצרים
    JArray products = (JArray)category["products"];
    JsonUtility.ImportData(products.ToString(), sheet.Cells, 0, 0, options);
}

קידום לרמה הבאה: דוחות מתוזמנים

כדי לאוטומט את יצירת הדו"ח, הוסף יכולות תזמון:

// התקן חבילת מתזמן משימות
// dotnet add package TaskScheduler

using Microsoft.Win32.TaskScheduler;

public void ScheduleDailyReportGeneration(string appPath)
{
    using (TaskService ts = new TaskService())
    {
        // צור משימה חדשה
        TaskDefinition td = ts.NewTask();
        td.RegistrationInfo.Description = "יצירת דו"ח נתוני API יומי";
        
        // צור טריגר שיפעל מדי יום בשעה 7 בבוקר
        td.Triggers.Add(new DailyTrigger { StartBoundary = DateTime.Today.AddHours(7) });
        
        // צור פעולה שתפעיל את האפליקציה
        td.Actions.Add(new ExecAction(appPath));
        
        // רשם את המשימה בתיקייה הראשית
        ts.RootFolder.RegisterTaskDefinition("DailyApiReport", td);
    }
}

תכונות מתקדמות לשקול

  1. שליחת דוא"ל - שלח דוחות אוטומטית דרך דוא"ל
  2. אינטגרציה עם מספר API-ים - שילוב נתונים ממספר API-ים
  3. דוחות מבוססי תבניות - השתמש בתבניות Excel למיתוג עקבי
  4. יצירת לוחות מחוונים - יצירת לוחות מחוונים אינטראקטיביים ב-Excel
  5. מעקב ודיווח על שגיאות - רישום בעיות ודיווח על הצלחה/כישלון

באמצעות מדריך זה, יצרת אפליקציה חזקה ב-C# שמאוטמת את תהליך חילוץ נתוני ה-API והמרה שלהם לדוחות Excel מקצועיים—חוסכת זמן, מבטיחה דיוק ומספקת ערך עסקי.

 Ελληνικά