HumanReadableReports 1.0.0
dotnet add package HumanReadableReports --version 1.0.0
NuGet\Install-Package HumanReadableReports -Version 1.0.0
<PackageReference Include="HumanReadableReports" Version="1.0.0" />
<PackageVersion Include="HumanReadableReports" Version="1.0.0" />
<PackageReference Include="HumanReadableReports" />
paket add HumanReadableReports --version 1.0.0
#r "nuget: HumanReadableReports, 1.0.0"
#:package HumanReadableReports@1.0.0
#addin nuget:?package=HumanReadableReports&version=1.0.0
#tool nuget:?package=HumanReadableReports&version=1.0.0
๐ HumanReadableReports
A clean, production-ready report engine for .NET Framework 4.5.2+ that converts SQL result data into business-friendly Excel, HTML, and CSV reports with minimal code.
๐ฏ What Problem Does This Solve?
Enterprise developers often need to:
- Convert SQL query results into formatted reports
- Present data in a business-friendly way (not just raw tables)
- Support multiple output formats (Excel, HTML, PDF, CSV)
- Add grouping, subtotals, and grand totals
- Format currencies correctly for different regions
- Make reports understandable by non-technical stakeholders
Traditional approach: Write complex rendering code, handle formatting logic, manage EPPlus manually, repeat for each report.
With HumanReadableReports: Define your report in 5 lines of readable code. The library handles all the complexity.
โจ Key Features
- ๐จ Fluent API - Readable, chainable code that looks like plain English
- ๐ Multiple Formats - Excel (.xlsx), HTML, and CSV output
- ๐ Smart Grouping - Group by day, month, year, or any value
- ๐ฐ Currency Formatting - Custom formatting for IDR, USD, EUR, GBP, and more
- ๐งฎ Automatic Calculations - Subtotals and grand totals calculated automatically
- ๐ "Explain Like I'm Five" - Generate human-readable report summaries
- ๐๏ธ Clean Architecture - Separation of concerns: Definition โ Processing โ Rendering
- โ Production-Ready - Enterprise code quality, fully commented, unit-testable
๐ Quick Start
Installation
Install-Package HumanReadableReports
Basic Example
using HumanReadableReports.Definition;
using HumanReadableReports.Models;
// Get your data
DataTable data = GetSalesDataFromDatabase();
// Define and generate report
var report = Report
.From(data)
.WithTitle("Monthly Sales Report")
.Column("TransactionDate", "Date").AsDate("dd MMM yyyy")
.Column("Product")
.Column("Amount").AsCurrency("IDR")
.GroupBy("TransactionDate", GroupingType.Month)
.Total("Amount");
// Generate Excel file
byte[] excelFile = report.ToExcel();
File.WriteAllBytes("SalesReport.xlsx", excelFile);
That's it! You now have a professional Excel report with:
- Formatted headers
- Grouped data by month
- Subtotals for each month
- Grand total at the bottom
- Professional styling (borders, alternating rows, frozen headers)
๐ Detailed Usage
1. Data Sources
The library supports two data sources:
DataTable (Most Common)
DataTable data = GetDataFromStoredProcedure();
var report = Report.From(data);
List<Dictionary<string, object>>
var data = new List<Dictionary<string, object>>
{
new Dictionary<string, object>
{
{ "Date", new DateTime(2024, 10, 15) },
{ "Customer", "PT Maju Jaya" },
{ "Amount", 25000000m }
}
};
var report = Report.From(data);
2. Column Definitions
// Basic column
.Column("ColumnName")
// Column with display name
.Column("ColumnName", "Display Name")
// Date column with format
.Column("OrderDate").AsDate("dd MMM yyyy")
// Currency column
.Column("Amount").AsCurrency("IDR") // Rp 1.000.000,00
.Column("Price").AsCurrency("USD") // $1,000.00
.Column("Total").AsCurrency("EUR") // โฌ1,000.00
// Number column
.Column("Quantity").AsNumber() // 1,234.56
// Percentage column
.Column("Growth").AsPercentage() // 12.34%
3. Grouping
// Group by month
.GroupBy("TransactionDate", GroupingType.Month)
// Group by year
.GroupBy("TransactionDate", GroupingType.Year)
// Group by day
.GroupBy("TransactionDate", GroupingType.Day)
// Group by any value (e.g., Category, Department)
.GroupBy("Category", GroupingType.Value)
// No grouping (default)
// Just don't call GroupBy()
4. Totals
// Add totals for specific columns
.Total("Amount")
.Total("Quantity")
.Total("Revenue")
The library will automatically:
- Calculate subtotals for each group
- Calculate grand totals
- Format totals using the column's format (currency, number, etc.)
5. Output Formats
// Excel (XLSX)
byte[] excelFile = report.ToExcel();
// HTML (standalone HTML file)
byte[] htmlFile = report.ToHtml();
// CSV
byte[] csvFile = report.ToCsv();
6. Explain Like I'm Five
string explanation = report.ExplainLikeImFive();
Console.WriteLine(explanation);
Output:
๐ Report Summary
This report shows 156 records organized into 12 groups.
๐ฐ Total Amount: Rp 1.250.000.000,00
๐ Highest group: December 2024 with Rp 150.000.000,00
๐ Trend: Growing by 15.3% from start to end.
โ
All calculations have been verified and formatted for easy reading.
๐ข Real-World Examples
MVC Controller Integration
using System.Web.Mvc;
using HumanReadableReports.Definition;
public class ReportController : Controller
{
public ActionResult DownloadSalesReport(string format = "excel")
{
// Get data from database
var data = GetSalesData();
// Build report
var report = Report
.From(data)
.WithTitle("Sales Report")
.Column("Date").AsDate("dd MMM yyyy")
.Column("Product")
.Column("Amount").AsCurrency("IDR")
.GroupBy("Date", GroupingType.Month)
.Total("Amount");
// Render based on requested format
byte[] fileContent;
string contentType;
string fileName;
switch (format.ToLower())
{
case "html":
fileContent = report.ToHtml();
contentType = "text/html";
fileName = "SalesReport.html";
break;
case "csv":
fileContent = report.ToCsv();
contentType = "text/csv";
fileName = "SalesReport.csv";
break;
default:
fileContent = report.ToExcel();
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
fileName = "SalesReport.xlsx";
break;
}
return File(fileContent, contentType, fileName);
}
}
Working with Stored Procedures
public byte[] GenerateFinancialReport(DateTime startDate, DateTime endDate)
{
DataTable data;
using (var conn = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand("sp_GetFinancialData", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@StartDate", startDate);
cmd.Parameters.AddWithValue("@EndDate", endDate);
var adapter = new SqlDataAdapter(cmd);
data = new DataTable();
adapter.Fill(data);
}
}
var report = Report
.From(data)
.WithTitle($"Financial Report {startDate:MMM yyyy} - {endDate:MMM yyyy}")
.Column("TransactionDate", "Date").AsDate("dd MMM yyyy")
.Column("Description")
.Column("Debit").AsCurrency("IDR")
.Column("Credit").AsCurrency("IDR")
.Column("Balance").AsCurrency("IDR")
.GroupBy("TransactionDate", GroupingType.Month)
.Total("Debit")
.Total("Credit");
return report.ToExcel();
}
๐๏ธ Architecture
The library follows clean architecture principles:
HumanReadableReports/
โโโ Core/ # Interfaces
โ โโโ IReportDefinition
โ โโโ IReportProcessor
โ โโโ IReportRenderer
โโโ Definition/ # Fluent API
โ โโโ Report.cs
โ โโโ ReportDefinition.cs
โโโ Processing/ # Business Logic
โ โโโ ReportProcessor.cs
โ โโโ GroupingEngine.cs
โโโ Rendering/ # Output Generation
โ โโโ ExcelRenderer.cs
โ โโโ HtmlRenderer.cs
โ โโโ CsvRenderer.cs
โโโ Models/ # Data Models
โ โโโ ProcessedReport.cs
โ โโโ ReportGroup.cs
โ โโโ ColumnDefinition.cs
โโโ Explanation/ # Human Explanations
โโโ ReportExplainer.cs
Design Principles
- Fluent API - Readable, chainable interface
- Separation of Concerns - Definition โ Processing โ Rendering
- Single Responsibility - Each class has one job
- Open/Closed Principle - Easy to extend with new renderers
- Dependency Inversion - Depends on abstractions, not implementations
๐งช Testing
The library is designed to be easily testable:
[TestClass]
public class ReportProcessorTests
{
[TestMethod]
public void Should_Calculate_Subtotals_Correctly()
{
// Arrange
var data = CreateTestData();
var definition = CreateTestDefinition(data);
var processor = new ReportProcessor();
// Act
var result = processor.Process(definition);
// Assert
Assert.AreEqual(2, result.Groups.Count);
Assert.AreEqual(150000m, result.Groups[0].Subtotals["Amount"]);
Assert.AreEqual(250000m, result.Groups[1].Subtotals["Amount"]);
}
}
๐ฆ Dependencies
- EPPlus 4.5.3.3 - Excel generation (LGPL license, free for .NET Framework)
- .NET Framework 4.5.2+ - Target framework
That's it! Minimal dependencies keep the package small and maintainable.
๐ง Advanced Scenarios
Custom Currency Formatting
The library includes built-in formatters for IDR, USD, EUR, and GBP. To add more:
// Fork the library and modify ColumnDefinition.FormatCurrency()
case "JPY":
return string.Format("ยฅ{0:N0}", amount); // Japanese Yen (no decimals)
Custom Renderers
Want to add PDF output? Implement IReportRenderer:
public class PdfRenderer : IReportRenderer
{
public byte[] Render(ProcessedReport report)
{
// Use iTextSharp or similar
// Process report.Groups, report.Columns, etc.
return pdfBytes;
}
public string GetContentType() => "application/pdf";
public string GetFileExtension() => ".pdf";
}
๐ค Contributing
We welcome contributions! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Follow existing code style (C# 7.3, .NET Framework 4.5.2)
- Add unit tests for new features
- Update documentation
- Submit a pull request
๐ License
This project is licensed under the MIT License - see the LICENSE.txt file for details.
๐ FAQ
Q: Does this work with .NET Core?
A: Not currently. This library targets .NET Framework 4.5.2+. A .NET Standard version is planned for the future.
Q: Can I use this with Entity Framework?
A: Yes! Convert your query results to DataTable or List<Dictionary>:
var data = context.Orders.ToList().ConvertToDataTable();
var report = Report.From(data);
Q: What about very large datasets?
A: The library loads all data into memory for processing. For datasets with 100k+ rows, consider:
- Applying filters at the database level
- Processing in batches
- Using server-side pagination
Q: Can I customize Excel styling?
A: The library uses professional defaults. For custom styling, you can modify ExcelRenderer.cs in your fork.
Q: Is this thread-safe?
A: Yes. Each report generation creates new instances, so you can safely generate multiple reports concurrently.
๐ Support
- Documentation: https://github.com/yourcompany/HumanReadableReports
- Issues: GitHub Issues
- Email: support@yourcompany.com
๐ Show Your Support
If this library helps you, please:
- โญ Star the repository
- ๐ข Share with your team
- ๐ Report bugs
- ๐ก Suggest features
Built with โค๏ธ for enterprise .NET developers who value clean, readable code.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
-
.NETFramework 4.5.2
- EPPlus (>= 4.5.3.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 68 | 1/2/2026 |
Initial release (v1.0.0):
- Core report definition API
- Excel, HTML, and CSV renderers
- Grouping by date (Day, Month, Year) or value
- Currency and number formatting
- Subtotals and grand totals
- Report explanation feature