Правки по пакету word

This commit is contained in:
kotcheshir73 2022-12-19 22:11:48 +04:00
parent faa59fbd6e
commit 72cb1f1e63
15 changed files with 264 additions and 134 deletions

View File

@ -1,10 +1,13 @@
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using ToolsOffice.Interfaces.Word.Models;
namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
public static class WordCellExtension
{
private static readonly int _coefToPoins = 567;
/// <summary>
/// Добавление ячейки в строку
/// </summary>
@ -37,6 +40,10 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
return;
}
var properties = new TableCellProperties();
if (model.Width.HasValue)
{
properties.AppendChild(new TableCellWidth { Width = new StringValue((model.Width.Value * _coefToPoins).ToString()), Type = TableWidthUnitValues.Dxa });
}
if (model.IsNewMerge)
{
properties.AppendChild(new VerticalMerge()

View File

@ -7,6 +7,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
public static class WordDocumentExtension
{
private static readonly int _coefToPoins = 567;
/// <summary>
/// Добавление общих настроек документа
/// </summary>
@ -24,11 +25,11 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
var pageSize = new PageSize();
if (model.PageSizeHeight != null)
{
pageSize.Height = new UInt32Value(Convert.ToUInt32(model.PageSizeHeight.Value));
pageSize.Height = new UInt32Value(Convert.ToUInt32(model.PageSizeHeight.Value * _coefToPoins));
}
if (model.PageSizeWidth != null)
{
pageSize.Width = new UInt32Value(Convert.ToUInt32(model.PageSizeWidth.Value));
pageSize.Width = new UInt32Value(Convert.ToUInt32(model.PageSizeWidth.Value * _coefToPoins));
}
if (model.WordPageOrientation.HasValue)
{
@ -39,19 +40,31 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
var pageMargin = new PageMargin();
if (model.PageMarginBottom.HasValue)
{
pageMargin.Bottom = Convert.ToInt32(model.PageMarginBottom.Value);
pageMargin.Bottom = Convert.ToInt32(model.PageMarginBottom.Value * _coefToPoins);
}
if (model.PageMarginLeft != null)
{
pageMargin.Left = new UInt32Value(Convert.ToUInt32(model.PageMarginLeft.Value));
pageMargin.Left = new UInt32Value(Convert.ToUInt32(model.PageMarginLeft.Value * _coefToPoins));
}
if (model.PageMarginRight != null)
{
pageMargin.Right = new UInt32Value(Convert.ToUInt32(model.PageMarginRight.Value));
pageMargin.Right = new UInt32Value(Convert.ToUInt32(model.PageMarginRight.Value * _coefToPoins));
}
if (model.PageMarginTop.HasValue)
{
pageMargin.Top = Convert.ToInt32(model.PageMarginTop.Value);
pageMargin.Top = Convert.ToInt32(model.PageMarginTop.Value * _coefToPoins);
}
if (model.PageMarginGutter.HasValue)
{
pageMargin.Gutter = new UInt32Value(Convert.ToUInt32(model.PageMarginGutter.Value * _coefToPoins));
}
if (model.PageHeader.HasValue)
{
pageMargin.Header = new UInt32Value(Convert.ToUInt32(model.PageHeader.Value * _coefToPoins));
}
if (model.PageFooter.HasValue)
{
pageMargin.Footer = new UInt32Value(Convert.ToUInt32(model.PageFooter.Value * _coefToPoins));
}
properties.AppendChild(pageMargin);

View File

@ -2,6 +2,7 @@
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using ToolsModule.ManagmentExtension;
using ToolsOffice.Interfaces;
using ToolsOffice.Interfaces.Word.Models;
namespace ToolsOffice.Implements.WordOpenXML.Extensions
@ -19,20 +20,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
return;
}
var paragraph = new Paragraph();
paragraph.AddParagraphProperties(model);
if (model.Text.IsNotEmpty())
{
paragraph.AddRun(model.Text);
}
else if (model.WordTexts != null)
{
foreach (var text in model.WordTexts)
{
paragraph.AddRun(text);
}
}
body.AppendChild(paragraph);
body.AppendChild(CreateParagraph(model));
}
/// <summary>
@ -46,20 +34,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
return;
}
var paragraph = new Paragraph();
paragraph.AddParagraphProperties(model);
if (model.Text.IsNotEmpty())
{
paragraph.AddRun(model.Text);
}
else if (model.WordTexts != null)
{
foreach (var text in model.WordTexts)
{
paragraph.AddRun(text);
}
}
cell.AppendChild(paragraph);
cell.AppendChild(CreateParagraph(model));
}
/// <summary>
@ -119,9 +94,20 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
properties.AppendChild(indentation);
var paragraphMarkRunProperties = new ParagraphMarkRunProperties();
if (model.FontName.HasValue)
{
var font = GetFontName(model.FontName.Value);
paragraphMarkRunProperties.AppendChild(new RunFonts
{
Ascii = new StringValue(font.Ascii),
HighAnsi = new StringValue(font.HighAnsi),
ComplexScript = new StringValue(font.ComplexScript)
});
}
if (model.FontSize.HasValue)
{
paragraphMarkRunProperties.AppendChild(new FontSize { Val = new StringValue(model.FontSize.Value.ToString()) });
paragraphMarkRunProperties.AppendChild(new FontSize { Val = new StringValue((model.FontSize.Value * 1.75).ToString()) });
paragraphMarkRunProperties.AppendChild(new FontSizeComplexScript { Val = new StringValue((model.FontSize.Value * 1.75).ToString()) });
}
if (model.IsBold)
{
@ -139,5 +125,76 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
paragraph.AppendChild(properties);
}
/// <summary>
/// Создание абзаца
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private static Paragraph CreateParagraph(ModelWordParagraph model)
{
var paragraph = new Paragraph();
paragraph.AddParagraphProperties(model);
if (model.Text.IsNotEmpty())
{
var text = new ModelWordText { Text = model.Text };
CheckRunProps(model, text);
paragraph.AddRun(text);
}
else if (model.WordTexts != null)
{
foreach (var text in model.WordTexts)
{
CheckRunProps(model, text);
paragraph.AddRun(text);
}
}
return paragraph;
}
/// <summary>
/// Получение шрифта из FontNames
/// </summary>
/// <param name="fn"></param>
/// <returns></returns>
private static (string Ascii, string HighAnsi, string ComplexScript) GetFontName(FontNames fn) => fn switch
{
FontNames.TimesNewRoman => ("Times New Roman", "Times New Roman", "Times New Roman"),
_ => default,
};
/// <summary>
/// Пеоедача параметров текста из параметров абзаца, если не заданы параметры текста
/// </summary>
/// <param name="paragraph"></param>
/// <param name="run"></param>
private static void CheckRunProps(ModelWordParagraph paragraph, ModelWordText run)
{
if (run == null)
{
return;
}
if (!run.FontSize.HasValue)
{
run.FontSize = paragraph.FontSize;
}
if (!run.FontName.HasValue)
{
run.FontName = paragraph.FontName;
}
if (!run.IsBold.HasValue)
{
run.IsBold = paragraph.IsBold;
}
if (!run.IsItalic.HasValue)
{
run.IsItalic = paragraph.IsItalic;
}
if (!run.IsUnderline.HasValue)
{
run.IsUnderline = paragraph.IsUnderline;
}
}
}
}

View File

@ -7,6 +7,8 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
public static class WordRowExtension
{
private static readonly int _coefToPoins = 567;
/// <summary>
/// Добавление строки в таблицу
/// </summary>
@ -41,7 +43,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
if (model.Height.HasValue)
{
var properties = new TableRowProperties();
properties.AppendChild(new TableRowHeight() { Val = new UInt32Value(Convert.ToUInt32(model.Height.Value)) });
properties.AppendChild(new TableRowHeight() { Val = new UInt32Value(Convert.ToUInt32((model.Height * _coefToPoins).Value)) });
row.AppendChild(properties);
}
}

View File

@ -1,6 +1,6 @@
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using ToolsModule.ManagmentExtension;
using ToolsOffice.Interfaces;
using ToolsOffice.Interfaces.Word.Models;
namespace ToolsOffice.Implements.WordOpenXML.Extensions
@ -30,25 +30,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
}
else
{
docRun.AppendChild(new Text { Text = model.Text, Space = SpaceProcessingModeValues.Preserve });
}
paragraph.AppendChild(docRun);
}
/// <summary>
/// Добавление текста в абзац
/// </summary>
/// <param name="paragraph"></param>
/// <param name="text"></param>
public static void AddRun(this Paragraph paragraph, string text)
{
if (text.IsEmpty())
{
return;
}
var docRun = new Run();
{
docRun.AppendChild(new Text { Text = text, Space = SpaceProcessingModeValues.Preserve });
docRun.AppendChild(new Text { Text = model.Text });
}
paragraph.AppendChild(docRun);
}
@ -65,27 +47,49 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
return;
}
if (model.FontSize.HasValue || model.IsBold || model.IsItalic || model.IsUnderline)
if (model.FontSize.HasValue || model.IsBold.HasValue || model.IsItalic.HasValue || model.IsUnderline.HasValue)
{
var properties = new RunProperties();
if (model.FontName.HasValue)
{
var font = GetFontName(model.FontName.Value);
properties.AppendChild(new RunFonts
{
Ascii = new StringValue(font.Ascii),
HighAnsi = new StringValue(font.HighAnsi),
ComplexScript = new StringValue(font.ComplexScript)
});
}
if (model.FontSize.HasValue)
{
properties.AppendChild(new FontSize { Val = new StringValue(model.FontSize.Value.ToString()) });
properties.AppendChild(new FontSize { Val = new StringValue((model.FontSize.Value * 2).ToString()) });
properties.AppendChild(new FontSizeComplexScript { Val = new StringValue((model.FontSize.Value * 2).ToString()) });
}
if (model.IsBold)
if (model.IsBold.HasValue && model.IsBold.Value)
{
properties.AppendChild(new Bold());
}
if (model.IsItalic)
if (model.IsItalic.HasValue && model.IsItalic.Value)
{
properties.AppendChild(new Italic());
}
if (model.IsUnderline)
if (model.IsUnderline.HasValue && model.IsUnderline.Value)
{
properties.AppendChild(new Underline());
}
run.AppendChild(properties);
}
}
/// <summary>
/// Получение шрифта из FontNames
/// </summary>
/// <param name="fn"></param>
/// <returns></returns>
private static (string Ascii, string HighAnsi, string ComplexScript) GetFontName(FontNames fn) => fn switch
{
FontNames.TimesNewRoman => ("Times New Roman", "Times New Roman", "Times New Roman"),
_ => default,
};
}
}

View File

@ -9,6 +9,8 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
public static class WordTableExtension
{
private static readonly int _coefToPoins = 567;
/// <summary>
/// Добавление таблицы в тело документа
/// </summary>
@ -47,8 +49,8 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
for(int rowIndex = 0; rowIndex < headerRowsCount; ++rowIndex)
{
var header = new ModelWordTableRow();
if (model.RowsHeight.ContainsKey(rowIndex))
var header = new ModelWordTableRow { Cells = new Queue<ModelWordTableCell>() };
if (model.RowsHeight?.ContainsKey(rowIndex) ?? false)
{
header.Height = model.RowsHeight[rowIndex];
}
@ -60,8 +62,8 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
}
for (int i = 0; i < model.Data.Count; ++i)
{
var row = new ModelWordTableRow();
if (model.RowsHeight.ContainsKey(i + headerRowsCount))
var row = new ModelWordTableRow { Cells = new Queue<ModelWordTableCell>() };
if (model.RowsHeight?.ContainsKey(i + headerRowsCount) ?? false)
{
row.Height = model.RowsHeight[i + headerRowsCount];
}
@ -87,38 +89,23 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
var properties = new TableProperties();
var tableLook = new TableLook();
if (model.LookFirstRow)
properties.AppendChild(new TableLook
{
tableLook.FirstRow = new OnOffValue(model.LookFirstRow);
}
if (model.LookFirstColumn)
{
tableLook.FirstColumn = new OnOffValue(model.LookFirstColumn);
}
if (model.LookLastRow)
{
tableLook.LastRow = new OnOffValue(model.LookLastRow);
}
if (model.LookLastColumn)
{
tableLook.LastColumn = new OnOffValue(model.LookLastColumn);
}
if (model.LookNoHorizontalBand)
{
tableLook.NoHorizontalBand = new OnOffValue(model.LookNoHorizontalBand);
}
if (model.LookNoVerticalBand)
{
tableLook.NoVerticalBand = new OnOffValue(model.LookNoVerticalBand);
}
properties.AppendChild(tableLook);
FirstRow = new OnOffValue(model.LookFirstRow),
FirstColumn = new OnOffValue(model.LookFirstColumn),
LastRow = new OnOffValue(model.LookLastRow),
LastColumn = new OnOffValue(model.LookLastColumn),
NoHorizontalBand = new OnOffValue(model.LookNoHorizontalBand),
NoVerticalBand = new OnOffValue(model.LookNoVerticalBand)
});
var tableBorders = new TableBorders();
tableBorders.AddBorder(model, new TopBorder());
tableBorders.AddBorder(model, new BottomBorder());
tableBorders.AddBorder(model, new LeftBorder());
tableBorders.AddBorder(model, new RightBorder());
tableBorders.AddBorder(model, new InsideHorizontalBorder());
tableBorders.AddBorder(model, new InsideVerticalBorder());
properties.AppendChild(tableBorders);
@ -139,7 +126,7 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
var tableGrid = new TableGrid();
foreach (var grid in model.ColumnWidths)
{
tableGrid.AppendChild(new GridColumn() { Width = new StringValue(grid.ToString()) });
tableGrid.AppendChild(new GridColumn() { Width = new StringValue((grid.Value * _coefToPoins).ToString()) });
}
table.AppendChild(tableGrid);
}
@ -160,6 +147,10 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
{
borderType.Val = (BorderValues)Enum.Parse(typeof(BorderValues), model.BorderType.Value.ToString());
}
if (model.BorderWidth.HasValue)
{
borderType.Size = new UInt32Value(Convert.ToUInt32(model.BorderWidth.Value));
}
tableBorders.AppendChild(borderType);
}
@ -172,7 +163,10 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
/// <returns></returns>
private static ModelWordTableCell CreateHeaderCell(ModelWordTable model, int rowIndex, int columnIndex)
{
var cell = new ModelWordTableCell();
var cell = new ModelWordTableCell
{
Width = model.ColumnWidths.ContainsKey(columnIndex) ? model.ColumnWidths[columnIndex] : null
};
var elem = model.Headers.FirstOrDefault(x => x.ColumnIndex == columnIndex && x.RowIndex == rowIndex);
if (elem != default)
{
@ -187,6 +181,9 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
};
paragraph.WordTexts.Enqueue(new ModelWordText
{
FontSize = 14,
FontName = Interfaces.FontNames.TimesNewRoman,
IsBold = true,
Text = elem.Header
});
cell.Texts.Enqueue(paragraph);
@ -220,11 +217,11 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
private static ModelWordTableCell CreateCell(ModelWordTable model, int rowIndex, int columnIndex)
{
var cell = new ModelWordTableCell();
var union = model.CellUnion.FirstOrDefault(x => x.StartColumnIndex >= columnIndex && x.StartRowIndex >= rowIndex &&
var union = model.CellUnion?.FirstOrDefault(x => x.StartColumnIndex >= columnIndex && x.StartRowIndex >= rowIndex &&
x.FinishColumnIndex <= columnIndex && x.FinishRowIndex <= rowIndex);
if (union != default)
if (union != null && union.Value != default)
{
if (union.StartColumnIndex == columnIndex)
if (union.Value.StartColumnIndex == columnIndex)
{
cell.IsNewMerge = true;
}
@ -245,6 +242,8 @@ namespace ToolsOffice.Implements.WordOpenXML.Extensions
};
paragraph.WordTexts.Enqueue(new ModelWordText
{
FontSize = 14,
FontName = Interfaces.FontNames.TimesNewRoman,
Text = model.Data[rowIndex][columnIndex]
});
cell.Texts.Enqueue(paragraph);

View File

@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ToolsOffice.Interfaces
namespace ToolsOffice.Interfaces
{
/// <summary>
/// Возможные шрифты
/// </summary>
public enum FontNames
{
TimesNewRoman = 0
}
}
}

View File

@ -20,12 +20,41 @@
/// </summary>
public double? PageSizeWidth { get; set; }
/// <summary>
/// Отступ от нижнего края
/// </summary>
public double? PageMarginBottom { get; set; }
/// <summary>
/// Отступ от верхнего края
/// </summary>
public double? PageMarginTop { get; set; }
/// <summary>
/// Отступ от левого края
/// </summary>
public double? PageMarginLeft { get; set; }
/// <summary>
/// Отступ от правого края
/// </summary>
public double? PageMarginRight { get; set; }
/// <summary>
/// Расстояние между полосами страницы
/// Если свойство MirrorMargins настроено на True, свойство Gutter добавляет дополнительное пространство на внутренние поля.
/// В противном случае дополнительное пространство добавляется в левую поля.
/// </summary>
public double? PageMarginGutter { get; set; }
/// <summary>
/// Расстояние до верхнего колонтитула
/// </summary>
public double? PageHeader { get; set; }
/// <summary>
/// Расстояние до нижнего колонтитула
/// </summary>
public double? PageFooter { get; set; }
}
}

View File

@ -25,7 +25,7 @@ namespace ToolsOffice.Interfaces.Word.Models
/// <summary>
/// Название шрифта
/// </summary>
public FontNames FontName { get; set; }
public FontNames? FontName { get; set; }
/// <summary>
/// Жирный

View File

@ -10,12 +10,12 @@ namespace ToolsOffice.Interfaces.Word.Models
/// <summary>
/// Информация по ширине колонок (номер колонки, ширина колонки), отсчет с 0
/// </summary>
public Dictionary<int, int> ColumnWidths { get; set; }
public Dictionary<int, double> ColumnWidths { get; set; }
/// <summary>
/// Информация по высоте строк (номер строки, высота строки), отсчет с 0
/// </summary>
public Dictionary<int, int > RowsHeight { get; set; }
public Dictionary<int, double> RowsHeight { get; set; }
/// <summary>
/// Информация по объединению ячеек
@ -33,40 +33,45 @@ namespace ToolsOffice.Interfaces.Word.Models
public List<string[]> Data { get; set; }
/// <summary>
/// Иной вывод первой строки
/// Указывает, что следует применить условное форматирование первой строки
/// </summary>
public bool LookFirstRow { get; set; }
public bool LookFirstRow { get; set; } = false;
/// <summary>
/// Иной вывод первого столбца
/// Указывает, что следует применить условное форматирование к первому столбцу
/// </summary>
public bool LookFirstColumn { get; set; }
public bool LookFirstColumn { get; set; } = false;
/// <summary>
/// Иной вывод последней строки
/// Указывает, что следует применять условное форматирование последней строки
/// </summary>
public bool LookLastRow { get; set; }
public bool LookLastRow { get; set; } = false;
/// <summary>
/// Иной вывод последнего столбца
/// Указывает, что следует применять условное форматирование последнего столбца
/// </summary>
public bool LookLastColumn { get; set; }
public bool LookLastColumn { get; set; } = false;
/// <summary>
///
/// Указывает, что условное форматирование горизонтальной полосы не должно применяться
/// </summary>
public bool LookNoHorizontalBand { get; set; }
public bool LookNoHorizontalBand { get; set; } = false;
/// <summary>
///
/// Указывает, что условное форматирование вертикальной полосы не должно применяться
/// </summary>
public bool LookNoVerticalBand { get; set; }
public bool LookNoVerticalBand { get; set; } = false;
/// <summary>
/// Тип рамки таблицы
/// </summary>
public TypeWordTableBorder? BorderType { get; set; }
/// <summary>
/// Толщина рамки таблицы
/// </summary>
public int? BorderWidth { get; set; }
/// <summary>
/// Список строк для таблицы
/// </summary>

View File

@ -7,6 +7,11 @@ namespace ToolsOffice.Interfaces.Word.Models
/// </summary>
public class ModelWordTableCell
{
/// <summary>
/// Ширина ячейки
/// </summary>
public double? Width { get; set; }
/// <summary>
/// Новое объединение ячеек
/// </summary>

View File

@ -10,7 +10,7 @@ namespace ToolsOffice.Interfaces.Word.Models
/// <summary>
/// Высота строки
/// </summary>
public int? Height { get; set; }
public double? Height { get; set; }
/// <summary>
/// Список ячеек строки

View File

@ -25,19 +25,24 @@
/// </summary>
public int? FontSize { get; set; }
/// <summary>
/// Название шрифта
/// </summary>
public FontNames? FontName { get; set; }
/// <summary>
/// Жирный
/// </summary>
public bool IsBold { get; set; } = false;
public bool? IsBold { get; set; }
/// <summary>
/// Курсив
/// </summary>
public bool IsItalic { get; set; } = false;
public bool? IsItalic { get; set; }
/// <summary>
/// Подчеркивание
/// </summary>
public bool IsUnderline { get; set; } = false;
public bool? IsUnderline { get; set; }
}
}

View File

@ -6,9 +6,9 @@ namespace ToolsOffice.Interfaces.Word
public class PageSizes
{
private static readonly
Dictionary<string, (double Height, double Width, double MarginBottom, double MarginTop, double MarginLeft, double MarginRigth)> _sizes = new()
Dictionary<string, (double Height, double Width, double MarginBottom, double MarginTop, double MarginLeft, double MarginRigth, double MarginGutter, double Header, double Footer)> _sizes = new()
{
{ "А4", (27.94, 21.59, 2, 2, 3, 1.5) }
{ "А4", (29.7, 21, 1.5, 3, 2, 2, 0, 1.5, 1.5) }
};
public static List<string> Sizes => _sizes.Keys.ToList();
@ -40,5 +40,11 @@ namespace ToolsOffice.Interfaces.Word
public double? PageMarginLeft => _hasKey ? _sizes[_key].MarginLeft : null;
public double? PageMarginRight => _hasKey ? _sizes[_key].MarginRigth : null;
public double? PageMarginGutter => _hasKey ? _sizes[_key].MarginGutter : null;
public double? PageHeader => _hasKey ? _sizes[_key].Header : null;
public double? PageFooter => _hasKey ? _sizes[_key].Footer : null;
}
}

View File

@ -1,15 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="2.19.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ToolsModule\ToolsModule.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ToolsModule\ToolsModule.csproj" />
</ItemGroup>
</Project>