Files
EbayListingTool/EbayListingTool/Services/BulkImportService.cs
Peter Foster 9fad0f2ac0 Initial commit: EbayListingTool WPF application
C# WPF desktop app for creating eBay UK listings with AI-powered
photo analysis. Features: multi-photo vision analysis via OpenRouter
(Claude), local listing save/export, saved listings browser,
single item listing form, bulk import from CSV/Excel, and eBay
OAuth authentication.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:33:27 +01:00

101 lines
3.3 KiB
C#

using System.Globalization;
using ClosedXML.Excel;
using CsvHelper;
using CsvHelper.Configuration;
using EbayListingTool.Models;
namespace EbayListingTool.Services;
public class BulkImportService
{
public List<BulkImportRow> ImportFile(string filePath)
{
var ext = Path.GetExtension(filePath).ToLower();
return ext switch
{
".csv" => ImportCsv(filePath),
".xlsx" or ".xls" => ImportExcel(filePath),
_ => throw new NotSupportedException($"File type '{ext}' is not supported. Use .csv or .xlsx")
};
}
private List<BulkImportRow> ImportCsv(string filePath)
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
MissingFieldFound = null,
HeaderValidated = null
};
using var reader = new StreamReader(filePath);
using var csv = new CsvReader(reader, config);
var rows = new List<BulkImportRow>();
csv.Read();
csv.ReadHeader();
while (csv.Read())
{
rows.Add(new BulkImportRow
{
Title = csv.TryGetField("Title", out string? t) ? t ?? "" : "",
Description = csv.TryGetField("Description", out string? d) ? d ?? "" : "",
Price = csv.TryGetField("Price", out string? p) ? p ?? "" : "",
Condition = csv.TryGetField("Condition", out string? c) ? c ?? "Used" : "Used",
CategoryKeyword = csv.TryGetField("CategoryKeyword", out string? k) ? k ?? "" : "",
Quantity = csv.TryGetField("Quantity", out string? q) ? q ?? "1" : "1",
PhotoPaths = csv.TryGetField("PhotoPaths", out string? ph) ? ph ?? "" : ""
});
}
return rows;
}
private List<BulkImportRow> ImportExcel(string filePath)
{
var rows = new List<BulkImportRow>();
using var workbook = new XLWorkbook(filePath);
var ws = workbook.Worksheets.First();
// Find header row (row 1)
var headers = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
var headerRow = ws.Row(1);
foreach (var cell in headerRow.CellsUsed())
headers[cell.GetString()] = cell.Address.ColumnNumber;
string GetValue(IXLRow row, string colName)
{
if (!headers.TryGetValue(colName, out var col)) return "";
return row.Cell(col).GetString().Trim();
}
int lastRow = ws.LastRowUsed()?.RowNumber() ?? 1;
for (int i = 2; i <= lastRow; i++)
{
var row = ws.Row(i);
if (row.IsEmpty()) continue;
rows.Add(new BulkImportRow
{
Title = GetValue(row, "Title"),
Description = GetValue(row, "Description"),
Price = GetValue(row, "Price"),
Condition = GetValue(row, "Condition").OrDefault("Used"),
CategoryKeyword = GetValue(row, "CategoryKeyword"),
Quantity = GetValue(row, "Quantity").OrDefault("1"),
PhotoPaths = GetValue(row, "PhotoPaths")
});
}
return rows;
}
}
internal static class StringExtensions
{
public static string OrDefault(this string value, string defaultValue)
=> string.IsNullOrWhiteSpace(value) ? defaultValue : value;
}