হ্যালো হাসিব! তুমি কেমন আছো? এখন আমরা একটি খুবই ইন্টারেস্ট্রিং এবং ক্লায়েন্টদের সবচেয়ে পছন্দের ফিচার নিয়ে কথা বলবো—Excel File Export।
“Chatrabash” প্রজেক্টে যখন তুমি কোনো হোস্টেল বা স্টুডেন্টদের ডাটাবেস ক্লায়েন্টকে দেখাতে চাইবে, তখন CSV-এর চেয়ে Excel ফাইল অনেক বেশি প্রফেশনাল দেখায়। এই কাজের জন্য লেকচারার EPPlus নামের একটি দারুণ এবং শক্তিশালী প্যাকেজ ব্যবহার করেছেন।
চলো পুরো লেকচারটির একটি কুইক সামারি এবং বিস্তারিত আলোচনা শুরু করি।
📝 Lecture Summary at a Glance
- The Goal: ডাটাবেস থেকে Persons-এর লিস্ট নিয়ে একটি প্রপার
.xlsxএক্সেল ফাইল তৈরি করা। - The Tool (
EPPlus): এটি .NET-এ এক্সেল ফাইল জেনারেট এবং ম্যানিপুলেট করার জন্য সবচেয়ে জনপ্রিয় প্যাকেজ। তবে এর লেটেস্ট ভার্সনগুলো কমার্শিয়াল, তাই সেটিংসেNonCommercialলাইসেন্স সেট করতে হয়। - Excel Architecture: একটি Excel ফাইলে
ExcelPackage(Workbook) থাকে, তার ভেতরExcelWorksheet(Sheet) থাকে এবং শিটের ভেতর রো (Row) ও কলাম (Column) অনুযায়ীCellsথাকে (যেমন: A1, B2)। - Cell Formatting: EPPlus ব্যবহার করে শুধু ডাটাই লেখা যায় না, বরং ফন্ট বোল্ড করা, ব্যাকগ্রাউন্ড কালার দেওয়া এবং কলামের উইডথ অটো-অ্যাডজাস্ট (
AutoFitColumns) করা যায়। - The Bug Fix:
ExcelPackageতৈরি করার সময় অবশ্যই কনস্ট্রাক্টরেMemoryStreamপাস করতে হবে, না হলে ফাইল করাপ্ট হয়ে ডাউনলোড হবে!
🧠 Comprehensive Breakdown & Deep Dive
১. Setting up EPPlus (License Configuration) [Importance: 9/10]
- The “Why”: EPPlus ভার্সন ৫ এর পর থেকে ফ্রি এবং পেইড দুই ধরনের লাইসেন্স মডেলে চলে গেছে। তুমি যদি প্র্যাকটিসের জন্য বা নন-কমার্শিয়াল প্রজেক্টে এটি ব্যবহার করো, তবে অ্যাপ্লিকেশনকে বলে দিতে হবে যে তুমি ফ্রি লাইসেন্স ব্যবহার করছো, না হলে রানটাইম এক্সেপশন আসবে।
💻 Code Implementation (appsettings.json):
{
"EPPlus": {
"ExcelPackage": {
"LicenseContext": "NonCommercial"
}
}
}
২. Service Layer-এ Excel File Generation [Importance: 10/10]
- The “Why”: আগের CSV লেকচারের মতোই আমরা একটি
MemoryStreamরিটার্ন করবো যা Controller ইউজারের ব্রাউজারে পুশ করবে। - Addressing Cells: এক্সেলে কলামগুলো
A, B, Cএবং রো-গুলো1, 2, 3দিয়ে রিপ্রেজেন্ট হয়। কিন্তু কোড লেখার সুবিধার জন্য EPPlus-এCells[row, column](যেমনCells[2, 1]) ব্যবহার করা অনেক সহজ।
💻 Code Implementation (Modern .NET 10 / C# 12 Approach):
using OfficeOpenXml;
using OfficeOpenXml.Style; // স্টাইলিংয়ের জন্য
using System.Drawing; // কালারের জন্য
public async Task<MemoryStream> GetPersonsExcel()
{
var memoryStream = new MemoryStream();
// ১. ExcelPackage তৈরি করা (অবশ্যই MemoryStream পাস করতে হবে)
using (var excelPackage = new ExcelPackage(memoryStream))
{
// ২. নতুন একটি শিট তৈরি করা
var worksheet = excelPackage.Workbook.Worksheets.Add("PersonsSheet");
// ৩. Header Row লেখা (Row 1)
worksheet.Cells["A1"].Value = "Person Name";
worksheet.Cells["B1"].Value = "Email";
worksheet.Cells["C1"].Value = "Date of Birth";
worksheet.Cells["D1"].Value = "Country";
// ৪. Header Styling করা (A1 থেকে D1 পর্যন্ত)
using (ExcelRange headerCells = worksheet.Cells["A1:D1"])
{
headerCells.Style.Fill.PatternType = ExcelFillStyle.Solid;
headerCells.Style.Fill.BackgroundColor.SetColor(Color.LightGray); // ব্যাকগ্রাউন্ড কালার
headerCells.Style.Font.Bold = true; // ফন্ট বোল্ড
}
// ৫. ডাটাবেস থেকে ডাটা আনা
var persons = await _db.Persons.Include(p => p.Country).ToListAsync();
int row = 2; // ডাটা লেখা শুরু হবে ২ নম্বর রো থেকে
// ৬. লুপ চালিয়ে প্রতিটি ডাটা নির্দিষ্ট সেলে লেখা
foreach (var person in persons)
{
worksheet.Cells[row, 1].Value = person.PersonName;
worksheet.Cells[row, 2].Value = person.Email;
// DateOfBirth ফরম্যাটিং
worksheet.Cells[row, 3].Value = person.DateOfBirth?.ToString("yyyy-MM-dd") ?? "N/A";
worksheet.Cells[row, 4].Value = person.Country?.CountryName;
row++; // পরের রো-তে যাওয়া
}
// ৭. কলামগুলো অটো-অ্যাডজাস্ট করা (খুবই ইম্পরট্যান্ট প্রফেশনাল লুকের জন্য)
worksheet.Cells[$"A1:D{row - 1}"].AutoFitColumns();
// ৮. ডাটা MemoryStream-এ সেভ করা
await excelPackage.SaveAsync();
}
// ৯. Stream এর পজিশন শুরুতে আনা
memoryStream.Position = 0;
return memoryStream;
}
৩. Controller থেকে Excel ডাউনলোড করানো [Importance: 9/10]
- The “Why”: Excel ফাইলের জন্য নির্দিষ্ট একটি MIME টাইপ আছে, যা ব্রাউজারকে বলে দেয় যে এটি একটি
.xlsxফাইল।
💻 Code Implementation (PersonsController.cs):
[HttpGet]
[Route("[action]")]
public async Task<IActionResult> PersonsExcel()
{
// Service থেকে MemoryStream নিয়ে আসা
var memoryStream = await _personsService.GetPersonsExcel();
// Excel ফাইলের অফিশিয়াল MIME Type
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
// File() মেথডের মাধ্যমে ডাউনলোড রেসপন্স পাঠানো
return File(memoryStream, contentType, "PersonsData.xlsx");
}
🚀 Modern Architecture Notes & Best Practices
১. The LoadFromCollection Magic (The Ultimate Time Saver):
হাসিব, লেকচারার যে ম্যানুয়াল লুপ এবং Cells[row, col] পদ্ধতি দেখিয়েছেন, তা বেশ সময়সাপেক্ষ এবং কলাম বাড়লে কোড অনেক বড় হয়ে যায়। EPPlus-এ একটি জাদুকরী মেথড আছে যার নাম LoadFromCollection। এটি ব্যবহার করলে তোমার কোনো foreach লুপ লাগবে না, সে নিজে থেকেই লিস্ট রিড করে এক্সেল বানিয়ে দেবে!
💻 Pro Tip Implementation:
// ডাটা ফেচ করার পর জাস্ট এক লাইন লিখবে!
var personResponses = persons.Select(p => p.ToPersonResponse()).ToList();
// এটি A2 থেকে শুরু করে সব ডাটা লিখে দেবে, PrintHeaders = true দিলে অটোমেটিক হেডারও বানিয়ে দেবে!
worksheet.Cells["A1"].LoadFromCollection(personResponses, PrintHeaders: true);
worksheet.Cells.AutoFitColumns();
২. Memory Limitations for Huge Datasets:
তুমি যদি ১ লক্ষ ইউজারের ডাটা এক্সেলে এক্সপোর্ট করতে চাও, তবে EPPlus প্রচুর র্যাম খাবে (কারণ সে পুরো এক্সেল ফাইলটা মেমোরিতে রেন্ডার করে)। তখন তোমার সার্ভার ক্র্যাশ (Out of Memory) করতে পারে। যদি হিউজ ডাটা এক্সপোর্ট করার দরকার হয়, তবে EPPlus-এর বদলে ClosedXML বা FastExcel প্যাকেজ ব্যবহার করাটা বেশি সেফ।
পরবর্তী লেকচারে ডাটা ইমপোর্ট করা (অর্থাৎ এক্সেল আপলোড করে ডাটাবেসে সেভ করা) নিয়ে আলোচনা হতে পারে। তুমি রেডি হলে সেই ট্রান্সক্রিপ্টটি দিতে পারো!