HumanReadableReports 1.0.0

dotnet add package HumanReadableReports --version 1.0.0
                    
NuGet\Install-Package HumanReadableReports -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HumanReadableReports" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HumanReadableReports" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="HumanReadableReports" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add HumanReadableReports --version 1.0.0
                    
#r "nuget: HumanReadableReports, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package HumanReadableReports@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=HumanReadableReports&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=HumanReadableReports&version=1.0.0
                    
Install as a Cake Tool

๐Ÿ“Š 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.

NuGet .NET Framework License


๐ŸŽฏ 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

  1. Fluent API - Readable, chainable interface
  2. Separation of Concerns - Definition โ†’ Processing โ†’ Rendering
  3. Single Responsibility - Each class has one job
  4. Open/Closed Principle - Easy to extend with new renderers
  5. 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:

  1. Fork the repository
  2. Create a feature branch
  3. Follow existing code style (C# 7.3, .NET Framework 4.5.2)
  4. Add unit tests for new features
  5. Update documentation
  6. 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


๐ŸŒŸ 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.5.2

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