2026-06-08 14:31:31 +07:00
|
|
|
|
namespace QWERTYkez.ExcelProcessor;
|
2026-06-05 15:58:03 +07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Внутренняя реализация <see cref="ISheet"/>.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal sealed class ExcelSheet : ISheet
|
|
|
|
|
|
{
|
|
|
|
|
|
internal readonly ExcelWriter Book;
|
|
|
|
|
|
internal readonly Sheet SheetElement;
|
|
|
|
|
|
internal readonly Worksheet Worksheet;
|
|
|
|
|
|
internal readonly uint SheetId;
|
|
|
|
|
|
|
|
|
|
|
|
internal ExcelSheet(ExcelWriter book, Sheet sheetElement, uint sheetId)
|
|
|
|
|
|
{
|
|
|
|
|
|
Book = book;
|
|
|
|
|
|
SheetElement = sheetElement;
|
|
|
|
|
|
SheetId = sheetId;
|
|
|
|
|
|
|
|
|
|
|
|
string partId = SheetElement.Id?.Value ?? string.Empty;
|
|
|
|
|
|
if (string.IsNullOrEmpty(partId))
|
|
|
|
|
|
throw new InvalidOperationException("Sheet has no relationship ID");
|
|
|
|
|
|
if (Book._doc.WorkbookPart?.GetPartById(partId) is not WorksheetPart part)
|
|
|
|
|
|
throw new InvalidOperationException("WorksheetPart not found");
|
|
|
|
|
|
if (part.Worksheet is not Worksheet worksheet)
|
|
|
|
|
|
throw new InvalidOperationException("WorksheetPart not found");
|
|
|
|
|
|
Worksheet = worksheet;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int Index => (int)SheetId;
|
|
|
|
|
|
public string Name => SheetElement.Name?.Value ?? string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
public bool TrySetName(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(name)) return false;
|
|
|
|
|
|
Book.ThrowIfDisposed();
|
|
|
|
|
|
SheetElement.Name = name;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public IRow Row(uint row) => new ExcelRow(Book, this, row);
|
|
|
|
|
|
public ISheet Row(uint row, Action<IRow> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
edit(Row(row));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public IColumn Col(uint col) => new ExcelColumn(Book, this, col);
|
|
|
|
|
|
public ISheet Col(uint col, Action<IColumn> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
edit(Col(col));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public IColumn Col(string col) => Col(CellAddressHelper.ColumnLetterToIndex(col));
|
|
|
|
|
|
public ISheet Col(string col, Action<IColumn> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
edit(Col(col));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ICell Cell(uint row, uint col) => new ExcelCell(Book, this, row, col);
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, Action<ICell> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
edit(Cell(row, col));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, string value)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, bool value)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, string formula, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(formula, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, DateTime value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, decimal value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, double value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, float value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, int value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, uint col, long value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ICell Cell(uint row, string col) => Cell(row, CellAddressHelper.ColumnLetterToIndex(col));
|
|
|
|
|
|
public ISheet Cell(uint row, string col, Action<ICell> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
edit(Cell(row, col));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, string value)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, bool value)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, string formula, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(formula, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, DateTime value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, decimal value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, double value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, float value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, int value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ISheet Cell(uint row, string col, long value, NumberFormatPattern? format = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Cell(row, col).Set(value, format); return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ClearContents()
|
|
|
|
|
|
{
|
|
|
|
|
|
var sheetData = GetSheetData();
|
|
|
|
|
|
foreach (var row in sheetData.Elements<Row>().ToList())
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var cell in row.Elements<Cell>().ToList())
|
|
|
|
|
|
cell.Remove();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ClearFormats()
|
|
|
|
|
|
{
|
|
|
|
|
|
var sheetData = GetSheetData();
|
|
|
|
|
|
foreach (var row in sheetData.Elements<Row>())
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var cell in row.Elements<Cell>())
|
|
|
|
|
|
cell.StyleIndex = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
|
{
|
|
|
|
|
|
ClearContents();
|
|
|
|
|
|
ClearFormats();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Remove() => Book.TryRemoveSheet(this);
|
|
|
|
|
|
|
|
|
|
|
|
// Вспомогательные методы
|
|
|
|
|
|
|
|
|
|
|
|
internal SheetData GetSheetData()
|
|
|
|
|
|
{
|
|
|
|
|
|
var worksheet = Worksheet;
|
|
|
|
|
|
var sheetData = worksheet.GetFirstChild<SheetData>();
|
|
|
|
|
|
if (sheetData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
sheetData = new SheetData();
|
|
|
|
|
|
worksheet.Append(sheetData);
|
|
|
|
|
|
}
|
|
|
|
|
|
return sheetData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Range Operations
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public IRange RangeByIndexes(uint startRow, uint startCol, uint endRow, uint endCol)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new ExcelRange(Book, this, startRow, startCol, endRow, endCol);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public IRange RangeByIndexes(uint startRow, string startCol, uint endRow, string endCol)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint startColIdx = CellAddressHelper.ColumnLetterToIndex(startCol);
|
|
|
|
|
|
uint endColIdx = CellAddressHelper.ColumnLetterToIndex(endCol);
|
|
|
|
|
|
return new ExcelRange(Book, this, startRow, startColIdx, endRow, endColIdx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public ISheet RangeByIndexes(uint startRow, uint startCol, uint endRow, uint endCol, Action<IRange> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
var range = RangeByIndexes(startRow, startCol, endRow, endCol);
|
|
|
|
|
|
edit(range);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public ISheet RangeByIndexes(uint startRow, string startCol, uint endRow, string endCol, Action<IRange> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
var range = RangeByIndexes(startRow, startCol, endRow, endCol);
|
|
|
|
|
|
edit(range);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public IRange RangeByLength(uint startRow, uint startCol, uint rows, uint cols)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (rows == 0 || cols == 0)
|
|
|
|
|
|
throw new ArgumentException("Rows and columns must be greater than 0");
|
|
|
|
|
|
uint endRow = startRow + rows - 1;
|
|
|
|
|
|
uint endCol = startCol + cols - 1;
|
|
|
|
|
|
return new ExcelRange(Book, this, startRow, startCol, endRow, endCol);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public IRange RangeByLength(uint startRow, string startCol, uint rows, uint cols)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint startColIdx = CellAddressHelper.ColumnLetterToIndex(startCol);
|
|
|
|
|
|
return RangeByLength(startRow, startColIdx, rows, cols);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public ISheet RangeByLength(uint startRow, uint startCol, uint rows, uint cols, Action<IRange> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
var range = RangeByLength(startRow, startCol, rows, cols);
|
|
|
|
|
|
edit(range);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public ISheet RangeByLength(uint startRow, string startCol, uint rows, uint cols, Action<IRange> edit)
|
|
|
|
|
|
{
|
|
|
|
|
|
var range = RangeByLength(startRow, startCol, rows, cols);
|
|
|
|
|
|
edit(range);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
}
|