mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-12 21:57:19 -04:00
CsvHelper was only used to write headers and flat DTO rows in the csv
exports. The new internal writer reproduces its output byte-for-byte:
the delimiter is the culture's list separator, records end with CRLF,
fields containing the delimiter, quotes, newlines, or leading/trailing
spaces are quoted per RFC 4180, and values are formatted with the
culture. The [Name]/[Ignore] attributes it replaced are now two tiny
local attributes.
Verified byte-identical output against CsvHelper 33.1.0 for both
exporters in en-US, de-DE (';' delimiter), and invariant cultures, and
for a seeded 30-book demo library export before/after.
Co-authored-by: rmcrackan <rmcrackan@gmail.com>
80 lines
2.5 KiB
C#
80 lines
2.5 KiB
C#
using ClosedXML.Excel;
|
|
using DataLayer;
|
|
using Newtonsoft.Json;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace ApplicationServices;
|
|
|
|
public static class LibraryExporter
|
|
{
|
|
public static void ToCsv(string saveFilePath, IEnumerable<LibraryBook>? libraryBooks = null)
|
|
{
|
|
libraryBooks ??= DbContexts.GetLibrary_Flat_NoTracking();
|
|
var dtos = libraryBooks.ToDtos();
|
|
if (dtos.Count == 0)
|
|
return;
|
|
|
|
using var csv = new CsvWriter(new System.IO.StreamWriter(saveFilePath), CultureInfo.CurrentCulture);
|
|
csv.WriteHeader(typeof(ExportDto));
|
|
csv.NextRecord();
|
|
csv.WriteRecords(dtos);
|
|
}
|
|
|
|
public static void ToJson(string saveFilePath, IEnumerable<LibraryBook>? libraryBooks = null)
|
|
{
|
|
libraryBooks ??= DbContexts.GetLibrary_Flat_NoTracking();
|
|
var dtos = libraryBooks.ToDtos();
|
|
var serializer = new JsonSerializer();
|
|
using var writer = new JsonTextWriter(new System.IO.StreamWriter(saveFilePath)) { Formatting = Formatting.Indented };
|
|
serializer.Serialize(writer, dtos);
|
|
}
|
|
|
|
public static void ToXlsx(string saveFilePath, IEnumerable<LibraryBook>? libraryBooks = null)
|
|
{
|
|
libraryBooks ??= DbContexts.GetLibrary_Flat_NoTracking();
|
|
var dtos = libraryBooks.ToDtos();
|
|
|
|
using var workbook = new XLWorkbook();
|
|
var sheet = workbook.AddWorksheet("Library");
|
|
var columns = typeof(ExportDto).GetProperties().Where(p => p.GetCustomAttribute<NameAttribute>() is not null).ToArray();
|
|
|
|
// headers
|
|
var currentRow = sheet.FirstRow();
|
|
var currentCell = currentRow.FirstCell();
|
|
foreach (var column in columns)
|
|
{
|
|
currentCell.Value = GetColumnName(column);
|
|
currentCell.Style.Font.Bold = true;
|
|
currentCell = currentCell.CellRight();
|
|
}
|
|
|
|
var dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " HH:mm:ss";
|
|
|
|
// Add data rows
|
|
foreach (var dto in dtos)
|
|
{
|
|
currentRow = currentRow.RowBelow();
|
|
currentCell = currentRow.FirstCell();
|
|
|
|
foreach (var column in columns)
|
|
{
|
|
var value = column.GetValue(dto);
|
|
currentCell.Value = XLCellValue.FromObject(value);
|
|
currentCell.Style.DateFormat.Format = currentCell.DataType is XLDataType.DateTime ? dateFormat : string.Empty;
|
|
currentCell = currentCell.CellRight();
|
|
}
|
|
}
|
|
|
|
workbook.SaveAs(saveFilePath);
|
|
}
|
|
|
|
private static List<ExportDto> ToDtos(this IEnumerable<LibraryBook> library)
|
|
=> library.Select(a => new ExportDto(a)).ToList();
|
|
|
|
private static string GetColumnName(PropertyInfo property)
|
|
=> property.GetCustomAttribute<NameAttribute>()?.Names?.FirstOrDefault() ?? property.Name;
|
|
}
|