Initial import
This commit is contained in:
380
XLimport.cs
Normal file
380
XLimport.cs
Normal file
@@ -0,0 +1,380 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace bdf
|
||||
{
|
||||
class CXLFile
|
||||
{
|
||||
//public static List<XLWorkbook> ServiceOrders = new List<XLWorkbook> { };
|
||||
|
||||
public static List<Spire.Xls.Workbook> S_ServiceOrders = new List<Spire.Xls.Workbook> { };
|
||||
|
||||
|
||||
public static void S_getXLS(string task, string dir)
|
||||
{
|
||||
//string folderPath = dir;
|
||||
string filePrefix1 = "ROGERS_";
|
||||
string filePrefix2 = task + "_SO";
|
||||
var excelFiles = getLatestVersionFiles(dir, filePrefix1, filePrefix2);
|
||||
|
||||
if ( (excelFiles.Length == 0) || (excelFiles == null) )
|
||||
{
|
||||
Console.WriteLine("No Excel files found with prefix: " + filePrefix1 + "*" + filePrefix2);
|
||||
//throw new System.ArgumentNullException("filePaths");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string path in excelFiles)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
continue;
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
throw new System.IO.FileNotFoundException(
|
||||
"Excel file not found.", path);
|
||||
|
||||
Logger.Log(1, "Scanning: {0}", Path.GetFileName(path));
|
||||
|
||||
// Create a new workbook and load the file
|
||||
Spire.Xls.Workbook wb = new Spire.Xls.Workbook();
|
||||
|
||||
//straight up load from file
|
||||
//wb.LoadFromFile(path); // FreeSpire autodetects .xls vs .xlsx
|
||||
|
||||
//more network savvy way that handles sharepoint's idiosyncrasies
|
||||
FileStream stream = null;
|
||||
|
||||
// OneDrive sync engine frequently locks files briefly:
|
||||
const int maxRetries = 12;
|
||||
const int retryDelayMs = 150;
|
||||
|
||||
for (int i = 0; i < maxRetries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
stream = new FileStream(
|
||||
path,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.ReadWrite | FileShare.Delete
|
||||
);
|
||||
break; // opened successfully
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
if (i == maxRetries - 1)
|
||||
throw;
|
||||
|
||||
System.Threading.Thread.Sleep(retryDelayMs);
|
||||
}
|
||||
}
|
||||
wb.LoadFromStream(stream);
|
||||
|
||||
Logger.Log(5, " -loaded SO={0}", wb.Worksheets[1][2, 1].Value.ToString() );
|
||||
|
||||
S_ServiceOrders.Add(wb);
|
||||
}
|
||||
Logger.Log("All SO Excel files processed successfully.");
|
||||
return; // S_ServiceOrders;
|
||||
}
|
||||
|
||||
|
||||
// This routine is wholly dependent on the filename structure being ROGERS*LDF*_SO*VER*number
|
||||
// in future should just open each workbook and read exact version from the first worksheet.
|
||||
public static string[] getLatestVersionFiles(string folder, string prefixA, string prefixB)
|
||||
{
|
||||
var files = Directory.GetFiles(folder);
|
||||
|
||||
// Build wildcard pattern:
|
||||
// file must contain prefixA ... anything ... prefixB
|
||||
Func<string, bool> matchesPrefix = name =>
|
||||
name.IndexOf(prefixA, StringComparison.OrdinalIgnoreCase) >= 0 &&
|
||||
name.IndexOf(prefixB, StringComparison.OrdinalIgnoreCase) >
|
||||
name.IndexOf(prefixA, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var filtered = files
|
||||
.Where(f => matchesPrefix(Path.GetFileName(f)))
|
||||
.ToList();
|
||||
|
||||
// Serial = 6 digits
|
||||
// After "VER" allow ANY non-digit characters, then the version number
|
||||
var regex = new Regex(
|
||||
@"(?<serial>\d{6}).*?VER\D*(?<ver>\d+)",
|
||||
RegexOptions.IgnoreCase
|
||||
);
|
||||
|
||||
Dictionary<string, (int version, string file)> best =
|
||||
new Dictionary<string, (int, string)>();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
string name = Path.GetFileName(file);
|
||||
var match = regex.Match(name);
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
Logger.Log(1, " Did not find SO and Version for file {0}", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
string serial = match.Groups["serial"].Value;
|
||||
|
||||
if (!int.TryParse(match.Groups["ver"].Value, out int ver))
|
||||
{
|
||||
Logger.Log(1, " Did not extract Version for file {0}", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Keep highest version per serial
|
||||
if (!best.ContainsKey(serial)) // || ver > best[serial].version)
|
||||
{
|
||||
best[serial] = (ver, file);
|
||||
Logger.Log(5, " Adding: {0} ver {1}", serial, ver);
|
||||
}
|
||||
else if (ver > best[serial].version)
|
||||
{
|
||||
Logger.Log(2, " Replacing: {0} ver {1} with ver {2}", serial, best[serial].version, ver);
|
||||
best[serial] = (ver, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log(4, " Ignoring: {0} v.{1}", serial, ver);
|
||||
}
|
||||
}
|
||||
|
||||
return best.Values.Select(v => v.file).ToArray();
|
||||
}
|
||||
|
||||
/*
|
||||
public static void getXLS(string task, string dir)
|
||||
{
|
||||
//string folderPath = @"C:\Data\ExcelFiles"; // Folder to scan
|
||||
string folderPath = dir;
|
||||
string filePrefix1 = "ROGERS_";
|
||||
string filePrefix2 = task + "_SO";
|
||||
|
||||
//List<XLWorkbook> ServiceOrders = new List<XLWorkbook> { };
|
||||
|
||||
try
|
||||
{
|
||||
// Required for ExcelDataReader in .NET 4
|
||||
System.Text.Encoding.RegisterProvider(
|
||||
System.Text.CodePagesEncodingProvider.Instance);
|
||||
|
||||
// Get all Excel files that match the prefix
|
||||
//var excelFiles = Directory.GetFiles(folderPath, filePrefix1 + "*" + filePrefix2 + "*.xls*", SearchOption.TopDirectoryOnly);
|
||||
|
||||
var excelFiles = getLatestVersionFiles(dir, filePrefix1, filePrefix2);
|
||||
|
||||
if (excelFiles.Length == 0)
|
||||
{
|
||||
Console.WriteLine("No Excel files found with prefix: " + filePrefix1 + "*" + filePrefix2);
|
||||
return;
|
||||
}
|
||||
|
||||
DataSet _dataSet = null;
|
||||
|
||||
foreach (var filePath in excelFiles)
|
||||
{
|
||||
Logger.Log(1, "Scanning: {0}", Path.GetFileName(filePath));
|
||||
// DataSet dataSet = ReadExcelFile(filePath);
|
||||
|
||||
// STEP 1: Read file into DataSet using ExcelDataReader
|
||||
try
|
||||
{
|
||||
_dataSet = ReadExcelFile(filePath);
|
||||
//_dataSet = LoadOneDriveDataSet(filePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
_dataSet = LoadOneDriveDataSet(filePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(0, "Error trying to access file {0}. ({1})", filePath, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// STEP 2: Convert DataSet into a ClosedXML workbook for manipulation
|
||||
var workbook = new XLWorkbook();
|
||||
//using (var workbook = new XLWorkbook())
|
||||
|
||||
{
|
||||
foreach (DataTable table in _dataSet.Tables)
|
||||
{
|
||||
var worksheet = workbook.Worksheets.Add(table.TableName);
|
||||
|
||||
// Insert headers
|
||||
for (int col = 0; col < table.Columns.Count; col++)
|
||||
{
|
||||
worksheet.Cell(1, col + 1).Value = table.Columns[col].ColumnName;
|
||||
worksheet.Cell(1, col + 1).Style.Font.Bold = true;
|
||||
}
|
||||
|
||||
// Insert rows
|
||||
for (int row = 0; row < table.Rows.Count; row++)
|
||||
{
|
||||
for (int col = 0; col < table.Columns.Count; col++)
|
||||
{
|
||||
//Logger.Log(5, "type is {0}", table.Rows[row][col].GetType().Name);
|
||||
|
||||
string valuetype = table.Rows[row][col].GetType().Name;
|
||||
|
||||
if (valuetype == "Int32")
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = (Int32)table.Rows[row][col];
|
||||
}
|
||||
else if (valuetype == "String")
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = (String)table.Rows[row][col];
|
||||
}
|
||||
else if (valuetype == "Decimal")
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = (Decimal)table.Rows[row][col];
|
||||
}
|
||||
else if (valuetype == "Double")
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = (Double)table.Rows[row][col];
|
||||
}
|
||||
else if (valuetype == "DBNull")
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
worksheet.Cell(row + 2, col + 1).Value = "fix me";
|
||||
}
|
||||
|
||||
//worksheet.Cell(row + 2, col + 1).Value = table.Rows[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
worksheet.Columns().AdjustToContents();
|
||||
//Logger.Log(0, "Sheet{0} Value={1}", workbook.Worksheets.Count, workbook.Worksheet(workbook.Worksheets.Count).Cell("C2").Value);
|
||||
}
|
||||
|
||||
// Example: Save modified workbook (optional)
|
||||
string outputFile = Path.Combine(folderPath, "" + Path.GetFileName(filePath) + "x");
|
||||
|
||||
//workbook.SaveAs(outputFile);
|
||||
Logger.Log(7, "Processed file: {0}", outputFile);
|
||||
//Logger.Log(0, "Book has {0} sheets", workbook.Worksheets.Count );
|
||||
|
||||
CXLFile.ServiceOrders.Add(workbook);
|
||||
//Logger.Log("test: " + workbook.Worksheet(1).Cell("C2").Value);
|
||||
}
|
||||
|
||||
//Logger.Log("Finished: " + Path.GetFileName(filePath));
|
||||
//Logger.Log(new string('-', 50));
|
||||
}
|
||||
|
||||
Logger.Log("All SO Excel files processed successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log(0, "SO processing error: {0}" + ex.Message);
|
||||
//Logger.Log("Press any key to exit...");
|
||||
//Console.ReadKey();
|
||||
}
|
||||
|
||||
//
|
||||
//return ServiceOrders;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an Excel file into a DataSet using ExcelDataReader.
|
||||
/// Each worksheet becomes a DataTable.
|
||||
/// </summary>
|
||||
static DataSet ReadExcelFile(string filePath)
|
||||
{
|
||||
// Required for ExcelDataReader to process XLS files
|
||||
System.Text.Encoding.RegisterProvider(
|
||||
System.Text.CodePagesEncodingProvider.Instance);
|
||||
|
||||
using (var stream = System.IO.File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
IExcelDataReader reader;
|
||||
|
||||
// Auto-detect format (XLS or XLSX)
|
||||
if (Path.GetExtension(filePath).Equals(".xls", StringComparison.OrdinalIgnoreCase))
|
||||
reader = ExcelReaderFactory.CreateBinaryReader(stream);
|
||||
else
|
||||
reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
|
||||
|
||||
// Convert to DataSet (with first row as header)
|
||||
var result = reader.AsDataSet(new ExcelDataSetConfiguration()
|
||||
{
|
||||
ConfigureDataTable = _ => new ExcelDataTableConfiguration()
|
||||
{
|
||||
UseHeaderRow = true
|
||||
}
|
||||
});
|
||||
|
||||
reader.Close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static DataSet LoadOneDriveDataSet(string path)
|
||||
{
|
||||
if (!System.IO.File.Exists(path))
|
||||
throw new FileNotFoundException("OneDrive file not found.", path);
|
||||
|
||||
// Required for ExcelDataReader to process XLS files
|
||||
System.Text.Encoding.RegisterProvider(
|
||||
System.Text.CodePagesEncodingProvider.Instance);
|
||||
|
||||
FileStream stream = null;
|
||||
|
||||
// OneDrive sync engine frequently locks files briefly:
|
||||
const int maxRetries = 12;
|
||||
const int retryDelayMs = 150;
|
||||
|
||||
for (int i = 0; i < maxRetries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
stream = new FileStream(
|
||||
path,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.ReadWrite | FileShare.Delete
|
||||
);
|
||||
break; // opened successfully
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
if (i == maxRetries - 1)
|
||||
throw;
|
||||
|
||||
System.Threading.Thread.Sleep(retryDelayMs);
|
||||
}
|
||||
}
|
||||
|
||||
// STEP 1: Read the workbook into a DataSet (ExcelDataReader)
|
||||
DataSet dataSet;
|
||||
|
||||
using (var reader = ExcelReaderFactory.CreateReader(stream))
|
||||
{
|
||||
dataSet = reader.AsDataSet(new ExcelDataSetConfiguration
|
||||
{
|
||||
ConfigureDataTable = _ => new ExcelDataTableConfiguration
|
||||
{
|
||||
UseHeaderRow = true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user