using System.Globalization; using System.Text; using System.Xml; using System.Xml.Serialization; using ClosedXML.Excel; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; namespace NejCommon.Controllers; public static class Responses { public static string ToAscii(string input) { if (string.IsNullOrEmpty(input)) return input; // Normalize to FormD (decomposition) string normalized = input.Normalize(NormalizationForm.FormD); var sb = new StringBuilder(); foreach (char c in normalized) { var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c); // Skip non-spacing marks (accents, umlauts, etc.) if (unicodeCategory != UnicodeCategory.NonSpacingMark) { sb.Append(c); } } // Normalize back to FormC and remove any remaining non-ASCII chars string cleaned = sb.ToString().Normalize(NormalizationForm.FormC); // Ensure only ASCII characters remain var ascii = new StringBuilder(); foreach (char c in cleaned) { ascii.Append(c <= 127 ? c : '?'); // replace non-ASCII with '?' or remove } return ascii.ToString(); } public static FileStreamHttpResult RespondFileStream(this ControllerBase controller, Stream stream, string contentType, string fileName) { stream.Seek(0, SeekOrigin.Begin); controller.Response.Headers.Add("Content-Disposition", "inline; filename=" + ToAscii(fileName.Normalize(NormalizationForm.FormD))); return TypedResults.File(stream, contentType, fileName); } public static FileStreamHttpResult RespondXlsx(this ControllerBase controller, XLWorkbook file, string fileName) { var stream = new MemoryStream(); file.SaveAs(stream); return RespondFileStream(controller, stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); } public static FileStreamHttpResult RespondXlsxTable(this ControllerBase controller, IEnumerable data, string name = "Data", string? sheetName = null) { if (sheetName is null) { //limit the name to 31 characters sheetName = name.Length > 31 ? name.Substring(0, 31) : name; } var notebook = new XLWorkbook(); var sheet = notebook.Worksheets.Add(sheetName); sheet.FirstCell().InsertTable(data); sheet.Columns().AdjustToContents(); return controller.RespondXlsx(notebook, name + ".xlsx"); } public static FileStreamHttpResult RespondXml(this ControllerBase controller, T obj, string fileName = "Data.xml") { var stream = Utils.Xml.Serialize(obj); return RespondFileStream(controller, stream, "text/xml", fileName); } }