ASP.NET Core  

Generating Word, Excel, and PDF Documents Dynamically in ASP.NET Core

Introduction

In modern web applications, exporting data is a standard requirement. Whether it is reports, invoices, logs, or summaries, developers often need to generate Word (.docx), Excel (.xlsx), and PDF files from an ASP.NET Core API.

This article gives you a complete, practical, production-ready guide with:

  • ASP.NET Core service and controller code

  • Using OpenXML for Word & Excel

  • Using iText7 / QuestPDF for PDF

  • Download API

  • ER diagram

  • Architecture diagram

  • Sequence diagram

  • Flowchart

When Do We Need File Generation?

This technique is required in:

  • Invoice and report generation

  • Exporting search results

  • Audit summaries

  • Certificate generation

  • Payroll & attendance exports

  • Data backup in Excel

Technologies Used

  • ASP.NET Core 8 API

  • OpenXML SDK (for Word & Excel)

  • QuestPDF (for PDF)

  • Angular (for downloading files – optional)

ER Diagram (Simple Export Log)

+------------------+       +------------------------+
|  ExportLog       | 1   ∞ |  ExportLogDetail       |
+------------------+       +------------------------+
| LogId (PK)       |-------| DetailId (PK)          |
| FileName         |       | LogId (FK)             |
| FileType         |       | FieldName              |
| CreatedBy        |       | OldValue               |
| CreatedDate      |       | NewValue               |
+------------------+       +------------------------+

Architecture Diagram (Visio Style Text Format)

+---------------------+          +-------------------------+
| Angular App         | <------> | ASP.NET Core API        |
| (Download buttons)  |          | Controllers + Services  |
+---------------------+          +-------------------------+
                                          |
                                          v
                             +-----------------------------+
                             | Document Generation Layer   |
                             | - WordService (OpenXML)     |
                             | - ExcelService (OpenXML)    |
                             | - PdfService (QuestPDF)     |
                             +-----------------------------+
                                          |
                                          v
                             +-----------------------------+
                             | Database (ExportLog tables) |
                             +-----------------------------+

Sequence Diagram (Generate File)

User → Angular: Click "Export PDF"
Angular → API: GET /export/pdf
API → PdfService: Generate PDF
PdfService → API: PDF bytes
API → Angular: Return file
Angular → User: Download file

Flowchart (File Generation Flow)

[Start]
    |
    v
[User requests export]
    |
    v
[API reads data]
    |
    v
[Generate file (Word/Excel/PDF)?]
    |
    |--- Word → WordService
    |--- Excel → ExcelService
    |--- PDF → PdfService
    |
    v
[Store log in DB]
    |
    v
[Return file]
    |
    v
[End]

Part 1: Generate Word (.docx) Using OpenXML

Install package

dotnet add package DocumentFormat.OpenXml

WordService.cs

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

public class WordService
{
    public byte[] GenerateDocument(string title, string content)
    {
        using var ms = new MemoryStream();
        using (var doc = WordprocessingDocument.Create(ms,
            DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
        {
            var main = doc.AddMainDocumentPart();
            main.Document = new Document();
            var body = main.Document.AppendChild(new Body());

            body.AppendChild(new Paragraph(
                new Run(new Text(title))));

            body.AppendChild(new Paragraph(
                new Run(new Text(content))));
        }
        return ms.ToArray();
    }
}

Part 2: Generate Excel (.xlsx) Using OpenXML

ExcelService.cs

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

public class ExcelService
{
    public byte[] GenerateExcel(List<string> rows)
    {
        using var ms = new MemoryStream();
        using (var doc = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
        {
            var wbPart = doc.AddWorkbookPart();
            wbPart.Workbook = new Workbook();

            var wsPart = wbPart.AddNewPart<WorksheetPart>();
            var sheetData = new SheetData();
            wsPart.Worksheet = new Worksheet(sheetData);

            foreach (var rowVal in rows)
            {
                var row = new Row();
                row.Append(new Cell() { DataType = CellValues.String, CellValue = new CellValue(rowVal) });
                sheetData.Append(row);
            }

            var sheets = doc.WorkbookPart.Workbook.AppendChild(new Sheets());
            sheets.Append(new Sheet() { Id = doc.WorkbookPart.GetIdOfPart(wsPart), SheetId = 1, Name = "Sheet1" });
        }
        return ms.ToArray();
    }
}

Part 3: Generate PDF Using QuestPDF

Install package

dotnet add package QuestPDF

PdfService.cs

using QuestPDF.Fluent;
using QuestPDF.Infrastructure;

public class PdfService
{
    public byte[] GeneratePdf(string header, string text)
    {
        var doc = Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Margin(30);
                page.Header().Text(header).FontSize(20).Bold();
                page.Content().Text(text).FontSize(12);
            });
        });

        return doc.GeneratePdf();
    }
}

API Controller

ExportController.cs

[ApiController]
[Route("api/[controller]")]
public class ExportController : ControllerBase
{
    private readonly WordService _word;
    private readonly ExcelService _excel;
    private readonly PdfService _pdf;

    public ExportController(WordService word, ExcelService excel, PdfService pdf)
    {
        _word = word;
        _excel = excel;
        _pdf = pdf;
    }

    [HttpGet("word")]
    public IActionResult ExportWord()
    {
        var file = _word.GenerateDocument("Report", "This is sample Word content.");
        return File(file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "report.docx");
    }

    [HttpGet("excel")]
    public IActionResult ExportExcel()
    {
        var file = _excel.GenerateExcel(new List<string> { "Row 1", "Row 2" });
        return File(file, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "report.xlsx");
    }

    [HttpGet("pdf")]
    public IActionResult ExportPdf()
    {
        var file = _pdf.GeneratePdf("PDF Title", "This is PDF content.");
        return File(file, "application/pdf", "report.pdf");
    }
}

Angular Code to Download File

downloadFile(type: string) {
  this.http.get(`api/export/${type}`, { responseType: 'blob' })
    .subscribe(blob => {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `report.${type}`;
      a.click();
    });
}

Database Scripts (Export Log)

CREATE TABLE ExportLog (
    LogId INT IDENTITY(1,1) PRIMARY KEY,
    FileName VARCHAR(200),
    FileType VARCHAR(50),
    CreatedBy VARCHAR(150),
    CreatedDate DATETIME DEFAULT GETDATE()
);

Best Practices

  • Use background jobs for large exports

  • Add file caching if frequently downloaded

  • Use GUID filenames

  • Avoid generating files on disk; use memory stream

Conclusion

You have now seen a full, practical solution for generating Word, Excel, and PDF documents using ASP.NET Core.
With this approach, you can build:

  • Complex dynamic reports

  • Invoices

  • Certificates

  • Dashboard exports

  • Automated scheduled reports