many debugs
All checks were successful
Publish NuGet packages / publish (push) Successful in 28s

This commit is contained in:
melekhin
2026-06-19 15:06:40 +07:00
parent 08b39b7bfe
commit e373d4108a
24 changed files with 1569 additions and 632 deletions

View File

@@ -16,7 +16,161 @@ internal sealed class ExcelColumn : IColumn
_colIndex = colIndex;
}
public uint Index => _colIndex;
private CellStyle? GetColumnStyle(Column columnElement)
{
if (columnElement.Style?.Value is not uint styleIndex)
return null;
return _writer.GetCellStyle(styleIndex);
}
private void ApplyStyleToColumn(CellStyle style)
{
var columnElement = GetOrCreateColumnElement();
int styleIndex = _writer.GetOrCreateStyleId(style);
columnElement.Style = (uint)styleIndex;
// Принудительно устанавливаем customStyle через атрибут
if (!columnElement.ExtendedAttributes.Any(attr => attr.LocalName == "customStyle" && attr.Value == "1"))
columnElement.SetAttribute(new OpenXmlAttribute("customStyle", "", "1"));
}
internal static Column? GetColumnElementInternal(ExcelSheet sheet, uint colIndex)
{
var cols = sheet.Worksheet.GetFirstChild<Columns>();
if (cols == null) return null;
foreach (Column col in cols.Elements<Column>())
{
if (col.Min?.Value is { } min && col.Max?.Value is { } max && min <= colIndex && max >= colIndex)
return col;
}
return null;
}
/// <inheritdoc />
public IColumn Set(NumberFormatPattern format)
{
if (format == null) return this;
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(format, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
/// <inheritdoc />
public IColumn Set(CellAlign align)
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(align, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
/// <inheritdoc />
public IColumn Set(CellBorder border)
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(border, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
/// <inheritdoc />
public IColumn Set(CellFill fill)
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(fill, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
/// <inheritdoc />
public IColumn Set(CellFont font)
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(font, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
/// <inheritdoc />
public IColumn Set(CellStyle style)
{
if (style == null) return this;
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var columnElement = GetOrCreateColumnElement();
var currentStyle = GetColumnStyle(columnElement) ?? new CellStyle();
if (currentStyle.TryMerge(style, out var newStyle))
{
ApplyStyleToColumn(newStyle);
ApplyStyleToColumnCells(newStyle);
}
return this;
}
}
private void ApplyStyleToColumnCells(CellStyle style)
{
var sheetData = _sheet.GetSheetData();
foreach (var rowElement in sheetData.Elements<Row>())
{
var cellElement = FindCellInRow(rowElement, _colIndex);
if (cellElement != null)
{
var cell = new ExcelCell(_writer, _sheet, rowElement.RowIndex!.Value, _colIndex);
cell.Set(style);
}
}
}
public uint Index => _colIndex;
public string IndexLetter => NumberToColumnLetter(_colIndex);
@@ -64,23 +218,7 @@ internal sealed class ExcelColumn : IColumn
}
}
// Вспомогательные внутренние методы (перенести существующую логику)
private static Column? GetColumnElementInternal(ExcelSheet sheet, uint colIndex)
{
var cols = sheet.Worksheet.GetFirstChild<Columns>();
if (cols == null) return null;
foreach (Column col in cols.Elements<Column>())
{
if (col?.Min?.Value is { } min
&& col?.Max?.Value is { } max
&& min <= colIndex
&& max >= colIndex)
return col;
}
return null;
}
private static Column GetOrCreateColumnElementInternal(ExcelSheet sheet, uint colIndex)
static Column GetOrCreateColumnElementInternal(ExcelSheet sheet, uint colIndex)
{
var existing = GetColumnElementInternal(sheet, colIndex);
if (existing != null) return existing;
@@ -127,62 +265,46 @@ internal sealed class ExcelColumn : IColumn
}
public ColumnWidth Width
{
get
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
get
{
var column = GetColumnElement();
if (column is Column col && col.Width?.Value is { } val && col.CustomWidth?.Value == true)
return ColumnWidth.FromCharacters(val);
return ColumnWidth.FromCharacters(8.43); // стандартная ширина
}
}
set
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var col = GetOrCreateColumnElement();
double widthInChars;
if (value.IsCharacterUnit)
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
// Если ширина задана в символах, используем напрямую
widthInChars = value.CharacterValue;
}
else
{
double targetCm = value.GetTargetCentimeters();
widthInChars = _writer.TryGetCalibrateCoeff(targetCm, out var closestCw)
? closestCw : targetCm * (ColumnWidth.DefaultPointsPerChar / 28.3464566929);
}
col.Width = widthInChars;
col.CustomWidth = true;
}
}
}
public IColumn SetNumberFormat(NumberFormatPattern format)
{
if (format == null) return this;
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
int fmtId = GetOrCreateNumberFormatId(format);
// Применяем ко всем ячейкам столбца
var sheetData = _sheet.GetSheetData();
foreach (var row in sheetData.Elements<Row>())
{
var cell = FindCellInRow(row, _colIndex);
cell?.StyleIndex = (uint)fmtId;
var column = GetColumnElement();
if (column is Column col && col.Width?.Value is { } val && col.CustomWidth?.Value == true)
return ColumnWidth.FromCharacters(val);
return ColumnWidth.FromCharacters(8.43); // стандартная ширина
}
}
set
{
_writer.ThrowIfDisposed();
lock (_writer._syncLock)
{
var col = GetOrCreateColumnElement();
double widthInChars;
if (value.IsCharacterUnit)
{
// Если ширина задана в символах, используем напрямую
widthInChars = value.CharacterValue;
}
else
{
double targetCm = value.GetTargetCentimeters();
widthInChars = _writer.TryGetCalibrateCoeff(targetCm, out var closestCw)
? closestCw : targetCm * (ColumnWidth.DefaultPointsPerChar / 28.3464566929);
}
col.Width = widthInChars;
col.CustomWidth = true;
}
}
return this;
}
public ICell Cell(uint row)
{
return new ExcelCell(_writer, _sheet, row, _colIndex);
@@ -207,7 +329,7 @@ internal sealed class ExcelColumn : IColumn
public IColumn Cell(uint row, string value, NumberFormatPattern? format = null)
{
Cell(row).Set(value, format); return this;
Cell(row).SetFormula(value, format); return this;
}
public IColumn Cell(uint row, DateTime value, NumberFormatPattern? format = null)
@@ -305,7 +427,7 @@ internal sealed class ExcelColumn : IColumn
// Вспомогательные методы
private Column? GetColumnElement()
Column? GetColumnElement()
{
var cols = _sheet.Worksheet.GetFirstChild<Columns>();
if (cols == null) return null;
@@ -320,7 +442,7 @@ internal sealed class ExcelColumn : IColumn
return null;
}
private Column GetOrCreateColumnElement()
Column GetOrCreateColumnElement()
{
var existing = GetColumnElement();
if (existing != null) return existing;
@@ -344,13 +466,13 @@ internal sealed class ExcelColumn : IColumn
return newCol;
}
private void DeleteColumnElement()
void DeleteColumnElement()
{
var col = GetColumnElement();
col?.Remove();
}
private void CopyColumnData(uint sourceCol, uint targetCol)
void CopyColumnData(uint sourceCol, uint targetCol)
{
if (sourceCol == targetCol) return;
var sheetData = _sheet.GetSheetData();
@@ -389,7 +511,7 @@ internal sealed class ExcelColumn : IColumn
}
}
private void ClearColumnData(uint col)
void ClearColumnData(uint col)
{
var sheetData = _sheet.GetSheetData();
foreach (var row in sheetData.Elements<Row>().ToList())
@@ -399,7 +521,7 @@ internal sealed class ExcelColumn : IColumn
}
}
private Cell? FindCellInRow(Row row, uint colIndex)
Cell? FindCellInRow(Row row, uint colIndex)
{
foreach (var cell in row.Elements<Cell>())
{
@@ -410,7 +532,7 @@ internal sealed class ExcelColumn : IColumn
return null;
}
private void InsertCellInRow(Row row, Cell cell, uint colIndex)
void InsertCellInRow(Row row, Cell cell, uint colIndex)
{
string newRef = NumberToColumnLetter(colIndex) + (row.RowIndex?.Value ?? 1).ToString();
cell.CellReference = newRef;
@@ -430,7 +552,7 @@ internal sealed class ExcelColumn : IColumn
row.Append(cell);
}
private Column? GetColumnElementForIndex(uint col)
Column? GetColumnElementForIndex(uint col)
{
var cols = _sheet.Worksheet.GetFirstChild<Columns>();
if (cols == null) return null;
@@ -445,7 +567,7 @@ internal sealed class ExcelColumn : IColumn
return null;
}
private Column GetOrCreateColumnElementForIndex(uint col)
Column GetOrCreateColumnElementForIndex(uint col)
{
var existing = GetColumnElementForIndex(col);
if (existing != null) return existing;
@@ -468,12 +590,12 @@ internal sealed class ExcelColumn : IColumn
return newCol;
}
private int GetOrCreateNumberFormatId(NumberFormatPattern format)
int GetOrCreateNumberFormatId(NumberFormatPattern format)
{
return _writer.GetOrCreateCellFormatId(numberFormat: format);
}
private static bool TryParseCellReference(string reference, out uint row, out uint col)
static bool TryParseCellReference(string reference, out uint row, out uint col)
{
row = 0; col = 0;
if (string.IsNullOrEmpty(reference)) return false;
@@ -487,7 +609,7 @@ internal sealed class ExcelColumn : IColumn
return true;
}
private static string NumberToColumnLetter(uint col)
static string NumberToColumnLetter(uint col)
{
if (col == 0) throw new ArgumentException("Column number must be > 0");
string result = "";