Add nullable support to CellAddress;

Add example block
This commit is contained in:
ngfrolov 2022-06-24 11:41:46 +05:00
parent 0c488f3b6b
commit 69780e8aaf
7 changed files with 178 additions and 68 deletions

View File

@ -0,0 +1,98 @@
using AsbCloudApp.Data.DailyReportModel;
using ClosedXML.Excel;
using System.Linq;
namespace AsbCloudInfrastructure.Services.DailyReport
{
internal class BlockHeader : BlockAbstract
{
private readonly DailyReportHeadDto blockDto;
public CellAddress AddressTitle { get; }
public CellAddress AddressCustomer { get; }
public CellAddress AddressDriller { get; }
public CellAddress AddressPeriod { get; }
public CellAddress AddressExampleData1 { get; }
public CellAddress[] AddressesExampleDataArray { get; }
/// <summary>
/// Значение нижняя правая ячейка блока
/// </summary>
public override CellAddress AddressBlockBegin { get; }
/// <summary>
/// Значение нижняя правая ячейка блока
/// </summary>
public override CellAddress AddressBlockEnd { get; }
public BlockHeader(CellAddress addressBlockBegin, DailyReportHeadDto blockDto)
{
AddressBlockBegin = addressBlockBegin.Copy();
this.blockDto = blockDto;
AddressTitle = addressBlockBegin + (0, 0);
AddressCustomer = addressBlockBegin + (1,0);
AddressDriller = addressBlockBegin + (2, 0);
AddressPeriod = addressBlockBegin + (3, 0);
AddressExampleData1 = addressBlockBegin + (5, 0);
AddressesExampleDataArray = new CellAddress[5];
for (int i = 0; i < 5; i++)
AddressesExampleDataArray[i] = addressBlockBegin + (6 + i, 0);
AddressBlockEnd = AddressesExampleDataArray.Last();
}
public override void Draw(IXLWorksheet sheet)
{
// значение в одну ячейку
sheet.Cell(AddressTitle)
._SetValue($"Суточная сводка бурения скважины: {blockDto.WellName}, куст: {blockDto.ClusterName}")
.Style.SetH1();
// значение в несколько ячеек с объединением
sheet._Range(AddressCustomer, AddressCustomer + (0,7))
._SetValue($"Заказчик: {blockDto.Customer}");
sheet.Cell(AddressDriller)
._SetValue($"Подрядчик: {blockDto.Contractor}");
sheet._Range(AddressExampleData1, AddressExampleData1 + (0, 4))
._SetValue(blockDto.BottomholeDepth); // для примера с будущей формулой
}
}
internal class BlockWithFormula : BlockAbstract
{
private readonly BlockHeader blockHeader;
public override CellAddress AddressBlockBegin { get; }
public override CellAddress AddressBlockEnd { get; }
public CellAddress AddressFomulaExample { get; set; }
public BlockWithFormula(CellAddress addressBlockBegin, BlockHeader blockHeader)
{
AddressFomulaExample = addressBlockBegin + (0, 0);
AddressBlockBegin = addressBlockBegin.Copy();
AddressBlockEnd = addressBlockBegin + (1, 0);
this.blockHeader = blockHeader;
}
public override void Draw(IXLWorksheet sheet)
{
var formula = string.Format("{0}/5", blockHeader.AddressExampleData1.ToString());
sheet.Cell(AddressFomulaExample)
.SetFormulaA1(formula);
}
}
internal abstract class BlockAbstract
{
public abstract CellAddress AddressBlockBegin { get; }
public abstract CellAddress AddressBlockEnd { get; }
public abstract void Draw(IXLWorksheet sheet);
}
}

View File

@ -5,6 +5,7 @@ using System.Text;
namespace AsbCloudInfrastructure.Services.DailyReport
{
#nullable enable
internal class CellAddress: IXLAddress
{
const int excelLettersCount = 'Z' - 'A' + 1;
@ -22,56 +23,26 @@ namespace AsbCloudInfrastructure.Services.DailyReport
public string UniqueId => ToString(XLReferenceStyle.A1, true);
public IXLWorksheet Worksheet { get; set; }
public IXLWorksheet? Worksheet { get; set; }
public CellAddress(int row, int colunm)
public CellAddress(IXLWorksheet? worksheet, int row, int colunm)
{
Worksheet = worksheet;
RowNumber = row;
ColumnNumber = colunm;
}
public static CellAddress operator + (CellAddress a, CellAddress b)
=> new CellAddress(a.RowNumber + b.RowNumber, a.ColumnNumber + b.ColumnNumber);
=> new CellAddress(a.Worksheet, a.RowNumber + b.RowNumber, a.ColumnNumber + b.ColumnNumber);
public static CellAddress operator +(CellAddress a, (int row, int column) b)
=> new CellAddress(a.RowNumber + b.row, a.ColumnNumber + b.column);
=> new CellAddress(a.Worksheet, a.RowNumber + b.row, a.ColumnNumber + b.column);
public static CellAddress operator - (CellAddress a, CellAddress b)
=> new CellAddress(a.RowNumber - b.RowNumber, a.ColumnNumber - b.ColumnNumber);
=> new CellAddress(a.Worksheet, a.RowNumber - b.RowNumber, a.ColumnNumber - b.ColumnNumber);
public static bool operator == (CellAddress a, CellAddress b)
=> a.RowNumber == b.RowNumber && a.ColumnNumber == b.ColumnNumber;
public static bool operator !=(CellAddress a, CellAddress b)
=> !(a == b);
public static bool TryParse(string cellAddress, out CellAddress parsedAddress)
{
if (cellAddress.Length < 2)
{
parsedAddress = default;
return false;
}
int row = 0;
int col = 0;
for (int i = 0; i < cellAddress.Length; i++)
switch (cellAddress[i])
{
case >= '0' and <= '9':
row = row * 10 + cellAddress[i] - '0';
break;
case >= 'A' and <= 'Z':
col = col * excelLettersCount + cellAddress[i] - 'A';
break;
case >= 'a' and <= 'z':
col = col * excelLettersCount + cellAddress[i] - 'a';
break;
default:
parsedAddress = default;
return false;
}
parsedAddress = new CellAddress(row, col);
return true;
}
private string CalcColumnLetter()
{
string letter = "";
@ -87,7 +58,14 @@ namespace AsbCloudInfrastructure.Services.DailyReport
}
public CellAddress Copy()
=> new CellAddress(this.RowNumber, this.ColumnNumber);
=> new CellAddress(Worksheet, RowNumber, ColumnNumber)
{
FixedColumn = this.FixedColumn,
FixedRow = this.FixedRow,
};
public override string ToString()
=> ToString(XLReferenceStyle.A1);
public string ToString(XLReferenceStyle referenceStyle)
=> ToString(referenceStyle, false);
@ -192,4 +170,5 @@ namespace AsbCloudInfrastructure.Services.DailyReport
return false;
}
}
#nullable disable
}

View File

@ -16,13 +16,26 @@ namespace AsbCloudInfrastructure.Services.DailyReport
public Stream MakeReportFromBlocks(DailyReportHeadDto blockHead, DailyReportBhaDto blockBha, DailyReportDimensionlessDto blockDimensionless, DailyReportSaubDto blockSaub, DailyReportSignDto blockSign)
{
using var workbook = new XLWorkbook();
FillSheet6blocks(workbook, blockHead, blockBha, blockDimensionless, blockSaub, blockSign);
FillExampleBlocks(workbook, blockHead);
//FillSheet6blocks(workbook, blockHead, blockBha, blockDimensionless, blockSaub, blockSign);
MemoryStream memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
private void FillExampleBlocks(XLWorkbook workbook, DailyReportHeadDto blockHeadDto)
{
var sheet = workbook.Worksheets.Add(blockHeadDto.ReportDate.ToString("dd.MM.yyyy"));
var addressStart = new CellAddress(sheet, 1, 1);
var blockHeader = new BlockHeader(addressStart, blockHeadDto);
addressStart = blockHeader.AddressBlockEnd + (1, 0);
var blockWithFormula = new BlockWithFormula(addressStart, blockHeader);
blockHeader.Draw(sheet);
blockWithFormula.Draw(sheet);
}
private String converteCellCoordinate(int row, bool isCaps, int column)
{
var c = (Char)((isCaps ? 65 : 97) + (column - 1));

View File

@ -1,11 +0,0 @@
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport
{
internal abstract class SheetBlockAbstract
{
public abstract CellAddress Draw(IXLWorksheet sheet, CellAddress startPoint);
}
}

View File

@ -5,25 +5,26 @@ namespace AsbCloudInfrastructure.Services.DailyReport
{
internal static class XLExtentions
{
public static IXLRange SetValue(this IXLRange range, object value)
public static IXLRange _SetValue(this IXLRange range, object value)
{
range.Merge();
range.FirstCell().SetValue(value);
return range;
var mergedRange = range.Merge();
mergedRange.FirstCell()._SetValue(value);
mergedRange.Style.SetAllBorders();
return mergedRange;
}
public static IXLCell SetValue(this IXLCell cell, object value)
public static IXLCell _SetValue(this IXLCell cell, object value)
{
switch (value)
{
case DateTime dateTime:
cell.SetValue(dateTime);
cell._SetValue(dateTime);
break;
case IFormattable formattable:
cell.SetValue(formattable);
cell._SetValue(formattable);
break;
case string valueString:
cell.SetValue(valueString);
cell._SetValue(valueString);
break;
default:
cell.Value = value;
@ -33,7 +34,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport
return cell;
}
public static IXLCell SetValue(this IXLCell cell, string value, bool adaptRowHeight = false)
public static IXLCell _SetValue(this IXLCell cell, string value, bool adaptRowHeight = false)
{
cell.Value = value;
cell.Style
@ -57,7 +58,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport
return cell;
}
public static IXLCell SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
public static IXLCell _SetValue(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
{
cell.Value = value;
cell.Style
@ -72,7 +73,7 @@ namespace AsbCloudInfrastructure.Services.DailyReport
return cell;
}
public static IXLCell SetValue(this IXLCell cell, IFormattable value, string format = "0.00")
public static IXLCell _SetValue(this IXLCell cell, IFormattable value, string format = "0.00")
{
cell.Value = value;
cell.Style
@ -97,5 +98,29 @@ namespace AsbCloudInfrastructure.Services.DailyReport
style.Border.OutsideBorder = borderStyle;
return style;
}
public static IXLStyle SetBaseFont(this IXLStyle style)
{
style.Font.FontName = "Calibri";
style.Font.FontSize = 10;
return style;
}
public static IXLStyle SetH1(this IXLStyle style)
{
style.Font.FontName = "Calibri";
style.Font.FontSize = 14;
return style;
}
/// <summary>
/// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress.
/// </summary>
/// <param name="sheet"></param>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <returns></returns>
public static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end)
=> sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber);
}
}

View File

@ -1,5 +1,6 @@
using AsbCloudApp.Data.DailyReportModel;
using AsbCloudInfrastructure.EfCache;
using AsbCloudInfrastructure.Services.DailyReport;
using ClosedXML.Excel;
using System;
using System.IO;
@ -27,6 +28,19 @@ namespace ConsoleApp1
WellDepthIntervalStartDate= 26.5,
BottomholeDepth= 66.6
};
//------------- example -----------------
var service = new DailyReportMakerExcel();
var stream = service.MakeReportFromBlocks(block, null, null, null, null);
var filename = "____.xlsx";
if (File.Exists(filename))
File.Delete(filename);
using var fileStream = File.OpenWrite(filename);
stream.CopyTo(fileStream);
return;
//------------- end of example -----------------
var block2 = new DailyReportBhaDto()
{
BHADescription="sadasdasdasdasdasdjlaskjdaksjdlasdlalskdklj"

View File

@ -1,8 +0,0 @@
{
"profiles": {
"WSL": {
"commandName": "WSL2",
"distributionName": ""
}
}
}