Этап 1. Формирование документов с отчетами

This commit is contained in:
prodigygirl 2023-05-18 18:22:45 +04:00
parent d431b48bf9
commit a0ce881f77
21 changed files with 1038 additions and 8 deletions

View File

@ -7,10 +7,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.20.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.2.3" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.2.3" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,123 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
namespace HospitalBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
/// <summary>
/// Создание отчета
/// </summary>
/// <param name="info"></param>
public MemoryStream CreateReport(ExcelInfo info)
{
CreateExcel(info);
// название таблицы
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "E1"
});
// названия столбцов
char columnName = 'A';
foreach (var header in info.Headers)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = columnName.ToString(),
RowIndex = 2,
Text = header,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
columnName++;
}
uint rowIndex = 3;
foreach (var element in info.PatientsMedicines)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = element.MedicineName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
int patientNum = 1;
foreach (var patient in element.Patients)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = patientNum.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = patient.Item1,
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = patient.Item2,
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "D",
RowIndex = rowIndex,
Text = patient.Item3 != null ? patient.Item3 : "",
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "E",
RowIndex = rowIndex,
Text = patient.Item4.ToString(),
StyleInfo = ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
patientNum++;
}
rowIndex++;
}
return SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info);
/// <summary>
/// Добавляем новую ячейку в лист
/// </summary>
/// <param name="cellParameters"></param>
protected abstract void InsertCellInWorksheet(ExcelCellParameters excelParams);
/// <summary>
/// Объединение ячеек
/// </summary>
/// <param name="mergeParameters"></param>
protected abstract void MergeCells(ExcelMergeParameters excelParams);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract MemoryStream SaveExcel(ExcelInfo info);
}
}

View File

@ -0,0 +1,68 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
namespace HospitalBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public MemoryStream CreateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"с { info.DateFrom.ToShortDateString() } по { info.DateTo.ToShortDateString() }", Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "3cm", "3cm", "3cm", "3cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Дата поступления", "Лекарство", "Количество", "Название процедуры" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var element in info.Prescriptions)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { element.DateCreate.ToShortDateString(), element.MedicineName, element.Number.ToString(), element.ProcedureName.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
return SavePdf(info);
}
/// <summary>
/// Создание pdf-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfo info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract MemoryStream SavePdf(PdfInfo info);
}
}

View File

@ -0,0 +1,68 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
namespace HospitalBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public MemoryStream CreateDoc(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var element in info.PatientsMedicines)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (element.MedicineName, new WordTextProperties { Size = "24", Bold = true }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
foreach (var patient in element.Patients)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {
(patient.Item1, new WordTextProperties { Size = "24"}),
(" " + patient.Item2, new WordTextProperties { Size = "24", }),
(" " + patient.Item3, new WordTextProperties { Size = "24", }), (", " + patient.Item4, new WordTextProperties { Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
}
return SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfo info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract MemoryStream SaveWord(WordInfo info);
}
}

View File

@ -0,0 +1,9 @@
namespace HospitalBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,9 @@
namespace HospitalBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Right
}
}

View File

@ -0,0 +1,8 @@
namespace HospitalBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,13 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class ExcelCellParameters
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using HospitalContracts.ViewModels;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<string> Headers { get; set; } = new();
public List<ReportPatientsMedicinesViewModel> PatientsMedicines{ get; set; } = new();
}
}

View File

@ -0,0 +1,9 @@
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,14 @@
using HospitalContracts.ViewModels;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportPrescriptionProcedureViewModel> Prescriptions { get; set; } = new();
}
}

View File

@ -0,0 +1,11 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class PdfParagraph
{
public string Text { get; set; } = string.Empty;
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class PdfRowParameters
{
public List<string> Texts { get; set; } = new();
public string Style { get; set; } = string.Empty;
public PdfParagraphAlignmentType ParagraphAlignment { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using HospitalContracts.ViewModels;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class WordInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportPatientsMedicinesViewModel> PatientsMedicines { get; set; } = new();
}
}

View File

@ -0,0 +1,8 @@
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class WordParagraph
{
public List<(string, WordTextProperties)> Texts { get; set; } = new();
public WordTextProperties? TextProperties { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
namespace HospitalBusinessLogic.OfficePackage.HelperModels
{
public class WordTextProperties
{
public string Size { get; set; } = string.Empty;
public bool Bold { get; set; }
public WordJustificationType JustificationType { get; set; }
}
}

View File

@ -0,0 +1,359 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Office2010.Excel;
using DocumentFormat.OpenXml.Office2013.Excel;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
namespace HospitalBusinessLogic.OfficePackage.Implements
{
public class SaveToExcel : AbstractSaveToExcel
{
private SpreadsheetDocument? _spreadsheetDocument;
private SharedStringTablePart? _shareStringPart;
private Worksheet? _worksheet;
private MemoryStream? stream;
/// <summary>
/// Настройка стилей для файла
/// </summary>
/// <param name="workbookpart"></param>
private static void CreateStyles(WorkbookPart workbookpart)
{
var sp = workbookpart.AddNewPart<WorkbookStylesPart>();
sp.Stylesheet = new Stylesheet();
var fonts = new Fonts() { Count = 2U, KnownFonts = true };
var fontUsual = new Font();
fontUsual.Append(new FontSize() { Val = 12D });
fontUsual.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontUsual.Append(new FontName() { Val = "Times New Roman" });
fontUsual.Append(new FontFamilyNumbering() { Val = 2 });
fontUsual.Append(new FontScheme() { Val = FontSchemeValues.Minor });
var fontTitle = new Font();
fontTitle.Append(new Bold());
fontTitle.Append(new FontSize() { Val = 14D });
fontTitle.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Theme = 1U });
fontTitle.Append(new FontName() { Val = "Times New Roman" });
fontTitle.Append(new FontFamilyNumbering() { Val = 2 });
fontTitle.Append(new FontScheme() { Val = FontSchemeValues.Minor });
fonts.Append(fontUsual);
fonts.Append(fontTitle);
var fills = new Fills() { Count = 2U };
var fill1 = new Fill();
fill1.Append(new PatternFill() { PatternType = PatternValues.None });
var fill2 = new Fill();
fill2.Append(new PatternFill()
{
PatternType = PatternValues.Gray125
});
fills.Append(fill1);
fills.Append(fill2);
var borders = new Borders() { Count = 2U };
var borderNoBorder = new Border();
borderNoBorder.Append(new LeftBorder());
borderNoBorder.Append(new RightBorder());
borderNoBorder.Append(new TopBorder());
borderNoBorder.Append(new BottomBorder());
borderNoBorder.Append(new DiagonalBorder());
var borderThin = new Border();
var leftBorder = new LeftBorder() { Style = BorderStyleValues.Thin };
leftBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var rightBorder = new RightBorder()
{
Style = BorderStyleValues.Thin
};
rightBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var topBorder = new TopBorder() { Style = BorderStyleValues.Thin };
topBorder.Append(new DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
var bottomBorder = new BottomBorder()
{
Style =
BorderStyleValues.Thin
};
bottomBorder.Append(new
DocumentFormat.OpenXml.Office2010.Excel.Color()
{ Indexed = 64U });
borderThin.Append(leftBorder);
borderThin.Append(rightBorder);
borderThin.Append(topBorder);
borderThin.Append(bottomBorder);
borderThin.Append(new DiagonalBorder());
borders.Append(borderNoBorder);
borders.Append(borderThin);
var cellStyleFormats = new CellStyleFormats() { Count = 1U };
var cellFormatStyle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 0U,
FillId = 0U,
BorderId = 0U
};
cellStyleFormats.Append(cellFormatStyle);
var cellFormats = new CellFormats() { Count = 3U };
var cellFormatFont = new CellFormat()
{
NumberFormatId = 0U,
FontId =
0U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
ApplyFont = true
};
var cellFormatFontAndBorder = new CellFormat()
{
NumberFormatId = 0U,
FontId = 0U,
FillId = 0U,
BorderId = 1U,
FormatId = 0U,
ApplyFont = true,
ApplyBorder = true
};
var cellFormatTitle = new CellFormat()
{
NumberFormatId = 0U,
FontId
= 1U,
FillId = 0U,
BorderId = 0U,
FormatId = 0U,
Alignment = new Alignment()
{
Vertical = VerticalAlignmentValues.Center,
WrapText = true,
Horizontal =
HorizontalAlignmentValues.Center
},
ApplyFont = true
};
cellFormats.Append(cellFormatFont);
cellFormats.Append(cellFormatFontAndBorder);
cellFormats.Append(cellFormatTitle);
var cellStyles = new CellStyles() { Count = 1U };
cellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0U,
BuiltinId = 0U
});
var differentialFormats = new
DocumentFormat.OpenXml.Office2013.Excel.DifferentialFormats()
{ Count = 0U };
var tableStyles = new TableStyles()
{
Count = 0U,
DefaultTableStyle =
"TableStyleMedium2",
DefaultPivotStyle = "PivotStyleLight16"
};
var stylesheetExtensionList = new StylesheetExtensionList();
var stylesheetExtension1 = new StylesheetExtension()
{
Uri =
"{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"
};
stylesheetExtension1.AddNamespaceDeclaration("x14",
"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
stylesheetExtension1.Append(new SlicerStyles()
{
DefaultSlicerStyle =
"SlicerStyleLight1"
});
var stylesheetExtension2 = new StylesheetExtension()
{
Uri =
"{9260A510-F301-46a8-8635-F512D64BE5F5}"
};
stylesheetExtension2.AddNamespaceDeclaration("x15",
"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
stylesheetExtension2.Append(new TimelineStyles()
{
DefaultTimelineStyle = "TimeSlicerStyleLight1"
});
stylesheetExtensionList.Append(stylesheetExtension1);
stylesheetExtensionList.Append(stylesheetExtension2);
sp.Stylesheet.Append(fonts);
sp.Stylesheet.Append(fills);
sp.Stylesheet.Append(borders);
sp.Stylesheet.Append(cellStyleFormats);
sp.Stylesheet.Append(cellFormats);
sp.Stylesheet.Append(cellStyles);
sp.Stylesheet.Append(differentialFormats);
sp.Stylesheet.Append(tableStyles);
sp.Stylesheet.Append(stylesheetExtensionList);
}
/// <summary>
/// Получение номера стиля из типа
/// </summary>
/// <param name="styleInfo"></param>
/// <returns></returns>
private static uint GetStyleValue(ExcelStyleInfoType styleInfo)
{
return styleInfo switch
{
ExcelStyleInfoType.Title => 2U,
ExcelStyleInfoType.TextWithBroder => 1U,
ExcelStyleInfoType.Text => 0U,
_ => 0U,
};
}
protected override void CreateExcel(ExcelInfo info)
{
stream = new MemoryStream();
_spreadsheetDocument = SpreadsheetDocument.Create(stream,
SpreadsheetDocumentType.Workbook);
// Создаем книгу (в ней хранятся листы)
var workbookpart = _spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
CreateStyles(workbookpart);
// Получаем/создаем хранилище текстов для книги
_shareStringPart =
_spreadsheetDocument.WorkbookPart!.GetPartsOfType<SharedStringTablePart>().Any()
?
_spreadsheetDocument.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First()
:
_spreadsheetDocument.WorkbookPart.AddNewPart<SharedStringTablePart>();
// Создаем SharedStringTable, если его нет
if (_shareStringPart.SharedStringTable == null)
{
_shareStringPart.SharedStringTable = new SharedStringTable();
}
// Создаем лист в книгу
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Добавляем лист в книгу
var sheets =
_spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
var sheet = new Sheet()
{
Id =
_spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Лист"
};
sheets.Append(sheet);
_worksheet = worksheetPart.Worksheet;
}
protected override void InsertCellInWorksheet(ExcelCellParameters excelParams)
{
if (_worksheet == null || _shareStringPart == null)
{
return;
}
var sheetData = _worksheet.GetFirstChild<SheetData>();
if (sheetData == null)
{
return;
}
// Ищем строку, либо добавляем ее
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex! ==
excelParams.RowIndex).Any())
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex! ==
excelParams.RowIndex).First();
}
else
{
row = new Row() { RowIndex = excelParams.RowIndex };
sheetData.Append(row);
}
// Ищем нужную ячейку
Cell cell;
if (row.Elements<Cell>().Where(c => c.CellReference!.Value ==
excelParams.CellReference).Any())
{
cell = row.Elements<Cell>().Where(c => c.CellReference!.Value ==
excelParams.CellReference).First();
}
else
{
// Все ячейки должны быть последовательно друг за другом расположены
// нужно определить, после какой вставлять
Cell? refCell = null;
foreach (Cell rowCell in row.Elements<Cell>())
{
if (string.Compare(rowCell.CellReference!.Value,
excelParams.CellReference, true) > 0)
{
refCell = rowCell;
break;
}
}
var newCell = new Cell()
{
CellReference =
excelParams.CellReference
};
row.InsertBefore(newCell, refCell);
cell = newCell;
}
// вставляем новый текст
_shareStringPart.SharedStringTable.AppendChild(new
SharedStringItem(new Text(excelParams.Text)));
_shareStringPart.SharedStringTable.Save();
cell.CellValue = new
CellValue((_shareStringPart.SharedStringTable.Elements<SharedStringItem>().Count(
) - 1).ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
cell.StyleIndex = GetStyleValue(excelParams.StyleInfo);
}
protected override void MergeCells(ExcelMergeParameters excelParams)
{
if (_worksheet == null)
{
return;
}
MergeCells mergeCells;
if (_worksheet.Elements<MergeCells>().Any())
{
mergeCells = _worksheet.Elements<MergeCells>().First();
}
else
{
mergeCells = new MergeCells();
if (_worksheet.Elements<CustomSheetView>().Any())
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<CustomSheetView>().First());
}
else
{
_worksheet.InsertAfter(mergeCells,
_worksheet.Elements<SheetData>().First());
}
}
var mergeCell = new MergeCell()
{
Reference = new StringValue(excelParams.Merge)
};
mergeCells.Append(mergeCell);
}
protected override MemoryStream SaveExcel(ExcelInfo info)
{
if (_spreadsheetDocument == null)
{
throw new InvalidOperationException("Document is not created");
}
_spreadsheetDocument.WorkbookPart!.Workbook.Save();
_spreadsheetDocument.Dispose();
if (stream == null)
throw new InvalidOperationException("Stream is empty");
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
}
}

View File

@ -0,0 +1,103 @@
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
using MigraDoc.Rendering;
namespace HospitalBusinessLogic.OfficePackage.Implements
{
public class SaveToPdf : AbstractSaveToPdf
{
private Document? _document;
private Section? _section;
private Table? _table;
private MemoryStream _stream;
private static ParagraphAlignment GetParagraphAlignment(PdfParagraphAlignmentType type)
{
return type switch
{
PdfParagraphAlignmentType.Center => ParagraphAlignment.Center,
PdfParagraphAlignmentType.Left => ParagraphAlignment.Left,
PdfParagraphAlignmentType.Right => ParagraphAlignment.Right,
_ => ParagraphAlignment.Justify,
};
}
/// <summary>
/// Создание стилей для документа
/// </summary>
/// <param name="document"></param>
private static void DefineStyles(Document document)
{
var style = document.Styles["Normal"];
style.Font.Name = "Times New Roman";
style.Font.Size = 14;
style = document.Styles.AddStyle("NormalTitle", "Normal");
style.Font.Bold = true;
}
protected override void CreatePdf(PdfInfo info)
{
_stream = new MemoryStream();
_document = new Document();
DefineStyles(_document);
_section = _document.AddSection();
}
protected override void CreateParagraph(PdfParagraph pdfParagraph)
{
if (_section == null)
{
return;
}
var paragraph = _section.AddParagraph(pdfParagraph.Text);
paragraph.Format.SpaceAfter = "1cm";
paragraph.Format.Alignment =
GetParagraphAlignment(pdfParagraph.ParagraphAlignment);
paragraph.Style = pdfParagraph.Style;
}
protected override void CreateTable(List<string> columns)
{
if (_document == null)
{
return;
}
_table = _document.LastSection.AddTable();
foreach (var elem in columns)
{
_table.AddColumn(elem);
}
}
protected override void CreateRow(PdfRowParameters rowParameters)
{
if (_table == null)
{
return;
}
var row = _table.AddRow();
for (int i = 0; i < rowParameters.Texts.Count; ++i)
{
row.Cells[i].AddParagraph(rowParameters.Texts[i]);
if (!string.IsNullOrEmpty(rowParameters.Style))
{
row.Cells[i].Style = rowParameters.Style;
}
Unit borderWidth = 0.5;
row.Cells[i].Borders.Left.Width = borderWidth;
row.Cells[i].Borders.Right.Width = borderWidth;
row.Cells[i].Borders.Top.Width = borderWidth;
row.Cells[i].Borders.Bottom.Width = borderWidth;
row.Cells[i].Format.Alignment =
GetParagraphAlignment(rowParameters.ParagraphAlignment);
row.Cells[i].VerticalAlignment = VerticalAlignment.Center;
}
}
protected override MemoryStream SavePdf(PdfInfo info)
{
var renderer = new PdfDocumentRenderer(true)
{
Document = _document
};
renderer.RenderDocument();
renderer.PdfDocument.Save(_stream);
return _stream;
}
}
}

View File

@ -0,0 +1,132 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using HospitalBusinessLogic.OfficePackage.HelperEnums;
using HospitalBusinessLogic.OfficePackage.HelperModels;
namespace HospitalBusinessLogic.OfficePackage.Implements
{
public class SaveToWord : AbstractSaveToWord
{
private WordprocessingDocument? _wordDocument;
private Body? _docBody;
private MemoryStream? stream;
/// <summary>
/// Получение типа выравнивания
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static JustificationValues GetJustificationValues(WordJustificationType type)
{
return type switch
{
WordJustificationType.Both => JustificationValues.Both,
WordJustificationType.Center => JustificationValues.Center,
_ => JustificationValues.Left,
};
}
/// <summary>
/// Настройки страницы
/// </summary>
/// <returns></returns>
private static SectionProperties CreateSectionProperties()
{
var properties = new SectionProperties();
var pageSize = new PageSize
{
Orient = PageOrientationValues.Portrait
};
properties.AppendChild(pageSize);
return properties;
}
/// <summary>
/// Задание форматирования для абзаца
/// </summary>
/// <param name="paragraphProperties"></param>
/// <returns></returns>
private static ParagraphProperties?
CreateParagraphProperties(WordTextProperties? paragraphProperties)
{
if (paragraphProperties == null)
{
return null;
}
var properties = new ParagraphProperties();
properties.AppendChild(new Justification()
{
Val =
GetJustificationValues(paragraphProperties.JustificationType)
});
properties.AppendChild(new SpacingBetweenLines
{
LineRule = LineSpacingRuleValues.Auto
});
properties.AppendChild(new Indentation());
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (!string.IsNullOrEmpty(paragraphProperties.Size))
{
paragraphMarkRunProperties.AppendChild(new FontSize
{
Val =
paragraphProperties.Size
});
}
properties.AppendChild(paragraphMarkRunProperties);
return properties;
}
protected override void CreateWord(WordInfo info)
{
stream = new MemoryStream();
_wordDocument = WordprocessingDocument.Create(stream,
WordprocessingDocumentType.Document);
MainDocumentPart mainPart = _wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
_docBody = mainPart.Document.AppendChild(new Body());
}
protected override void CreateParagraph(WordParagraph paragraph)
{
if (_docBody == null || paragraph == null)
{
return;
}
var docParagraph = new Paragraph();
docParagraph.AppendChild(CreateParagraphProperties(paragraph.TextProperties));
foreach (var run in paragraph.Texts)
{
var docRun = new Run();
var properties = new RunProperties();
properties.AppendChild(new FontSize { Val = run.Item2.Size });
if (run.Item2.Bold)
{
properties.AppendChild(new Bold());
}
docRun.AppendChild(properties);
docRun.AppendChild(new Text
{
Text = run.Item1,
Space =
SpaceProcessingModeValues.Preserve
});
docParagraph.AppendChild(docRun);
}
_docBody.AppendChild(docParagraph);
}
protected override MemoryStream SaveWord(WordInfo info)
{
if (_docBody == null || _wordDocument == null)
{
throw new InvalidOperationException("Document is not created");
}
_docBody.AppendChild(CreateSectionProperties());
_wordDocument.MainDocumentPart!.Document.Save();
_wordDocument.Dispose();
if (stream == null)
throw new InvalidOperationException("Stream is empty");
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
}
}

View File

@ -1,4 +1,7 @@
using HospitalContracts.BindingModels; using HospitalBusinessLogic.OfficePackage;
using HospitalBusinessLogic.OfficePackage.HelperModels;
using HospitalBusinessLogic.OfficePackage.Implements;
using HospitalContracts.BindingModels;
using HospitalContracts.BusinessLogicContracts; using HospitalContracts.BusinessLogicContracts;
using HospitalContracts.SearchModels; using HospitalContracts.SearchModels;
using HospitalContracts.StorageContracts; using HospitalContracts.StorageContracts;
@ -16,8 +19,14 @@ namespace HospitalBusinessLogic
private readonly IProcedureStorage _procedureStorage; private readonly IProcedureStorage _procedureStorage;
private readonly IRecipeStorage _recipeStorage; private readonly IRecipeStorage _recipeStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(IMedicineStorage medicineStorage, IPatientStorage patientStorage, public ReportLogic(IMedicineStorage medicineStorage, IPatientStorage patientStorage,
IPrescriptionStorage prescriptionStorage, ITreatmentStorage treatmentStorage, IProcedureStorage procedureStorage, IRecipeStorage recipeStorage) IPrescriptionStorage prescriptionStorage, ITreatmentStorage treatmentStorage,
IProcedureStorage procedureStorage, IRecipeStorage recipeStorage,
AbstractSaveToExcel abstractSaveToExcel, AbstractSaveToWord abstractSaveToWord, AbstractSaveToPdf abstractSaveToPdf)
{ {
_medicineStorage = medicineStorage; _medicineStorage = medicineStorage;
_patientStorage = patientStorage; _patientStorage = patientStorage;
@ -25,6 +34,10 @@ namespace HospitalBusinessLogic
_treatmentStorage = treatmentStorage; _treatmentStorage = treatmentStorage;
_procedureStorage = procedureStorage; _procedureStorage = procedureStorage;
_recipeStorage = recipeStorage; _recipeStorage = recipeStorage;
_saveToExcel = abstractSaveToExcel;
_saveToWord = abstractSaveToWord;
_saveToPdf = abstractSaveToPdf;
} }
public List<ReportPatientsMedicinesViewModel> GetMedicinePatients(ReportBindingModel model) public List<ReportPatientsMedicinesViewModel> GetMedicinePatients(ReportBindingModel model)
@ -89,14 +102,43 @@ namespace HospitalBusinessLogic
return list; return list;
} }
public void SavePatientsToExcelFile(ReportBindingModel model) public MemoryStream SavePatientsToExcelFile(ReportBindingModel model)
{ {
throw new NotImplementedException(); return _saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список пациентов",
PatientsMedicines = GetMedicinePatients(model),
Headers = {"№","Фамилия", "Имя", "Отчество", "Дата рождения"}
});
} }
public void SavePatientsToWordFile(ReportBindingModel model) public MemoryStream SavePatientsToWordFile(ReportBindingModel model)
{ {
throw new NotImplementedException(); return _saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список пациентов",
PatientsMedicines = GetMedicinePatients(model)
});
}
public MemoryStream SavePrescriptionsToPdfFile(ReportBindingModel model)
{
return _saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список поступлений и процедур",
Prescriptions = GetPrescriptionProcedures(model),
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value
});
}
public void SendMailWithReportAttachments(ReportBindingModel model)
{
var stream = SavePrescriptionsToPdfFile(model);
} }
} }
} }

View File

@ -20,11 +20,16 @@ namespace HospitalContracts.BusinessLogicContracts
/// Сохранение пациентов с указанием лекарств в файл-Word /// Сохранение пациентов с указанием лекарств в файл-Word
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
void SavePatientsToWordFile(ReportBindingModel model); MemoryStream SavePatientsToWordFile(ReportBindingModel model);
/// <summary> /// <summary>
/// Сохранение пациентов с указанием лекарств в файл-Excel /// Сохранение пациентов с указанием лекарств в файл-Excel
/// </summary> /// </summary>
/// <param name="model"></param> /// <param name="model"></param>
void SavePatientsToExcelFile(ReportBindingModel model); MemoryStream SavePatientsToExcelFile(ReportBindingModel model);
/// <summary>
/// Сохранение пациентов с указанием лекарств в файл-Pdf
/// </summary>
/// <param name="model"></param>
MemoryStream SavePrescriptionsToPdfFile(ReportBindingModel model);
} }
} }