Created
April 17, 2024 20:14
-
-
Save madmonkey/c5ed95360ea4c4887e779ef405608032 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class FileContentResultGenerator | |
{ | |
public static byte[] ToCsv(this DataSet ds) | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < ds.Tables[0].Columns.Count; i++) | |
{ | |
sb.Append(ds.Tables[0].Columns[i]); | |
if (i < ds.Tables[0].Columns.Count - 1) | |
{ | |
sb.Append(","); | |
} | |
} | |
sb.AppendLine(); | |
foreach (DataRow dr in ds.Tables[0].Rows) | |
{ | |
for (var i = 0; i < ds.Tables[0].Columns.Count; i++) | |
{ | |
/* for debugging - turns out I wasn't crazy */ | |
//Console.WriteLine($@"{ds.Tables[0].Columns[i]} :: {dr[i]}"); | |
if (!Convert.IsDBNull(dr[i])) | |
{ | |
var value = dr[i].ToString().ToCsvCell(); | |
sb.Append(value); | |
} | |
if (i < ds.Tables[0].Columns.Count - 1) | |
{ | |
sb.Append(","); | |
} | |
} | |
sb.AppendLine(); | |
} | |
return Encoding.UTF8.GetBytes(sb.ToString()); | |
} | |
public static byte[] ToTsv(this DataSet ds) | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < ds.Tables[0].Columns.Count; i++) | |
{ | |
sb.Append(ds.Tables[0].Columns[i]); | |
if (i < ds.Tables[0].Columns.Count - 1) | |
{ | |
sb.Append("\t"); | |
} | |
} | |
sb.AppendLine(); | |
foreach (DataRow dr in ds.Tables[0].Rows) | |
{ | |
for (var i = 0; i < ds.Tables[0].Columns.Count; i++) | |
{ | |
if (!Convert.IsDBNull(dr[i])) | |
{ | |
var value = dr[i].ToString().Contains("\t") | |
? $"{dr[i].ToString().Replace("\t", " ")}" | |
: dr[i]; | |
sb.Append(value); | |
} | |
if (i < ds.Tables[0].Columns.Count - 1) | |
{ | |
sb.Append("\t"); | |
} | |
} | |
sb.AppendLine(); | |
} | |
return Encoding.UTF8.GetBytes(sb.ToString()); | |
} | |
public static byte[] ToPdf(this DataSet ds, string identifier = "Report") | |
{ | |
var dataTable = ds.Tables[0]; | |
var pdfDoc = new Document(PageSize.A4, 25, 25, 25, 50); | |
if (dataTable.Columns.Count > 4) //<-- change to landscape if big enough | |
{ | |
pdfDoc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 50); | |
} | |
var mStream = new MemoryStream(); | |
int pageModOnData = 100; | |
var writer = PdfWriter.GetInstance(pdfDoc, mStream); | |
var cols = dataTable.Columns.Count; | |
var rows = dataTable.Rows.Count; | |
var pageEventHandler = new TwoColumnHeaderFooter(); | |
writer.PageEvent = pageEventHandler; | |
pdfDoc.Open(); | |
var para = new Paragraph($"{identifier} as of: " + DateTime.UtcNow.ToString("MM/dd/yyyy"), | |
new Font(Font.HELVETICA, 12, Font.BOLD)) | |
{ | |
Alignment = Element.ALIGN_CENTER | |
}; | |
pdfDoc.Add(para); | |
var pdfTable = new Table(cols, rows) | |
{ | |
BorderWidth = 1, | |
Width = 100, | |
Padding = 1, | |
Spacing = 1 | |
}; | |
//creating table headers | |
for (int i = 0; i < cols; i++) | |
{ | |
Cell cellCols = new Cell(); | |
Font colFont = FontFactory.GetFont(FontFactory.HELVETICA, 8, Font.BOLD); | |
Chunk chunkCols = new Chunk(dataTable.Columns[i].ColumnName, colFont); | |
cellCols.Add(chunkCols); | |
cellCols.Width = 250; | |
pdfTable.AddCell(cellCols); | |
} | |
Int64 rowCount = 0; | |
for (int k = 0; k < rows; k++) | |
{ | |
if (rowCount % pageModOnData == 0 && rowCount != 0) | |
{ | |
rowCount = 0; | |
pdfDoc.Add(pdfTable); | |
pdfTable.DeleteAllRows(); | |
} | |
for (int j = 0; j < cols; j++) | |
{ | |
Cell cellRows = new Cell(); | |
Font rowFont = FontFactory.GetFont(FontFactory.HELVETICA, 8); | |
Chunk chunkRows = new Chunk(dataTable.Rows[k][j].ToString(), rowFont); | |
cellRows.Add(chunkRows); | |
pdfTable.AddCell(cellRows); | |
} | |
rowCount++; | |
} | |
pdfDoc.Add(pdfTable); | |
pdfDoc.Close(); | |
return mStream.ToArray(); | |
} | |
public static byte[] ToXlsx(this DataSet ds) | |
{ | |
var excelApp = OfficeOpenXML.GetInstance(); | |
return excelApp.GetExcelStream(ds)?.ToArray() ?? Array.Empty<byte>(); | |
} | |
public static byte[] GetRequestedBytes(this DataSet ds, enumDownloadType downloadType, string identifier = "") | |
{ | |
switch (downloadType) | |
{ | |
case enumDownloadType.CSV: | |
return ds.ToCsv(); | |
case enumDownloadType.PDF: | |
return ds.ToPdf(identifier); | |
case enumDownloadType.XLS: | |
case enumDownloadType.XLSX: | |
return ds.ToXlsx(); | |
case enumDownloadType.TSV: | |
return ds.ToTsv(); | |
default: | |
throw new ArgumentOutOfRangeException(nameof(downloadType), downloadType, null); | |
} | |
} | |
public static FileContentResult Generate(byte[] data, | |
string filePrefix = "", | |
enumDownloadType downloadType = enumDownloadType.XLSX) | |
{ | |
switch (downloadType) | |
{ | |
case enumDownloadType.CSV: | |
return new FileContentResult(data, "text/csv") | |
{ | |
FileDownloadName = $@"{filePrefix}-{DateTime.Now.ToUniversalIso8601()}.csv", | |
}; | |
case enumDownloadType.PDF: | |
return new FileContentResult(data, "application/pdf") | |
{ | |
FileDownloadName = $@"{filePrefix}-{DateTime.Now.ToUniversalIso8601()}.pdf", | |
}; | |
case enumDownloadType.XLS: | |
case enumDownloadType.XLSX: | |
return new FileContentResult(data, | |
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | |
{ | |
FileDownloadName = | |
$@"{filePrefix}-{DateTime.Now.ToUniversalIso8601()}{(downloadType == enumDownloadType.XLSX | |
? ".xlsx" | |
: ".xls")}", | |
}; | |
case enumDownloadType.TSV: | |
return new FileContentResult(data, "text/tab-separated-values") | |
{ | |
FileDownloadName = $@"{filePrefix}-{DateTime.Now.ToUniversalIso8601()}.tsv", | |
}; | |
default: | |
throw new ArgumentOutOfRangeException(nameof(downloadType), downloadType, null); | |
} | |
} | |
public static bool IsValidExcelFile(this HttpPostedFileBase file) | |
{ | |
/* technically all of these file formats can be understood by the reader */ | |
if (file != null) | |
{ | |
switch (file.ContentType) | |
{ | |
/* xlsx */ | |
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": | |
/* xls */ | |
case "application/vnd.ms-excel": | |
/* xlst */ | |
case "application/vnd.openxmlformats-officedocument.spreadsheetml.template": | |
/* xlsm */ | |
case "application/vnd.ms-excel.sheet.macroEnabled.12": | |
/* xltm */ | |
case "application/vnd.ms-excel.template.macroEnabled.12": | |
/* xlsb */ | |
case "application/vnd.ms-excel.sheet.binary.macroEnabled.12": | |
return file.ContentLength > 0; | |
} | |
} | |
return false; | |
} | |
private static string ToCsvCell(this string column) | |
{ | |
/* Additional handling required for 'importing' csv into something like excel format*/ | |
var mustQuote = (column.Contains(",") || column.Contains("\"") || column.Contains("\r") || | |
column.Contains("\n")); | |
if (mustQuote) | |
{ | |
var sb = new StringBuilder(); | |
sb.Append("\""); | |
foreach (char nextChar in column) | |
{ | |
sb.Append(nextChar); | |
if (nextChar == '"') | |
sb.Append("\""); | |
} | |
sb.Append("\""); | |
return sb.ToString(); | |
} | |
return column; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment