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:
Technologies Used
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: