├── .gitignore
├── Docs
├── Tutorial.docx
└── Tutorial.pdf
├── ExcelReportGenerator.Samples
├── App.config
├── ConnectionFactory.cs
├── Customizations
│ ├── CustomInstanceProvider.cs
│ ├── CustomReportGenerator.cs
│ ├── CustomSystemFunctions.cs
│ ├── CustomSystemVariableProvider.cs
│ └── CustomTemplateProcessor.cs
├── DataProvider.cs
├── ExcelReportGenerator.Samples.csproj
├── Extensions
│ └── DataReaderExtensions.cs
├── Ioc.cs
├── Program.cs
├── Reports
│ ├── CustomReportGeneratorSample.cs
│ ├── DataReaderConnect.cs
│ ├── DataSetConnect.cs
│ ├── DataTableConnect.cs
│ ├── DynamicPanelDataTableConnect.cs
│ ├── DynamicPanelEnumerableConnect.cs
│ ├── EnumerableConnect.cs
│ ├── EnumerableOfDictionaryConnect.cs
│ ├── GroupingWithPanelHierarchy.cs
│ ├── ReportBase.cs
│ └── Templates
│ │ ├── CustomReportGeneratorSample.xlsx
│ │ ├── DataReaderConnect.xlsx
│ │ ├── DataSetConnect.xlsx
│ │ ├── DataTableConnect.xlsx
│ │ ├── DynamicPanelDataTableConnect.xlsx
│ │ ├── DynamicPanelEnumerableConnect.xlsx
│ │ ├── EnumerableConnect.xlsx
│ │ ├── EnumerableOfDictionaryConnect.xlsx
│ │ └── GroupingWithPanelHierarchy.xlsx
├── RestoreDbTemplate.sql
├── SamplesForm.Designer.cs
├── SamplesForm.cs
└── SamplesForm.resx
├── ExcelReportGenerator.Tests
├── Configuration.cs
├── Converters
│ └── ExternalPropertiesConverters
│ │ ├── PanelTypeConverterTest.cs
│ │ ├── RenderPriorityConverterTest.cs
│ │ └── ShiftTypeConverterTest.cs
├── CustomAsserts
│ ├── ExcelAssert.cs
│ └── ExceptionAssert.cs
├── Enumerators
│ ├── DataReaderEnumeratorTest.cs
│ ├── DataSetEnumeratorTest.cs
│ ├── DataTableEnumeratorTest.cs
│ ├── EnumerableEnumeratorTest.cs
│ └── EnumeratorFactoryTest.cs
├── Excel
│ └── ExcelHelperTest.cs
├── ExcelReportGenerator.Tests.csproj
├── Extensions
│ ├── DataReaderExtensionsTest.cs
│ ├── ParameterInfoExtensionsTest.cs
│ ├── StringExtensionsTest.cs
│ ├── TemplateProcessorExtensionsTest.cs
│ ├── TypeExtensionsTest.cs
│ └── XLRangeBaseExtensionsTest.cs
├── GlobalSetup.cs
├── Helpers
│ ├── EnumHelperTest.cs
│ ├── ReflectionHelperTest.cs
│ ├── RegexHelperTest.cs
│ └── TypeHelperTest.cs
├── Rendering
│ ├── DataProvider.cs
│ ├── DefaultReportGeneratorTest.cs
│ ├── Panels
│ │ └── ExcelPanels
│ │ │ ├── ExcelDataItemPanelTest.cs
│ │ │ ├── ExcelDataSourceDynamicPanelTest.cs
│ │ │ ├── ExcelDataSourcePanelTest.cs
│ │ │ ├── ExcelNamedPanelTest.cs
│ │ │ ├── ExcelPanelFactoryTests.cs
│ │ │ ├── ExcelPanelTest.cs
│ │ │ ├── ExcelTotalsPanelTest.cs
│ │ │ ├── PanelRenderTests
│ │ │ ├── DataSourceDynamicPanelRenderTests
│ │ │ │ ├── DataSourceDynamicPanelDataReaderRenderTest.cs
│ │ │ │ ├── DataSourceDynamicPanelDataSetRenderTest.cs
│ │ │ │ ├── DataSourceDynamicPanelDataTableRenderTest.cs
│ │ │ │ ├── DataSourceDynamicPanelDictionaryRenderTest.cs
│ │ │ │ ├── DataSourceDynamicPanelEnumerableRenderTest.cs
│ │ │ │ ├── DataSourceDynamicPanelSingleItemRenderTest.cs
│ │ │ │ └── DataSourceDynamicPanel_InsideDataSourcePanel_Test.cs
│ │ │ ├── DataSourcePanelRenderTests
│ │ │ │ ├── DataSourcePanelDataReaderRenderTest.cs
│ │ │ │ ├── DataSourcePanelDataSetRenderTest.cs
│ │ │ │ ├── DataSourcePanelDataTableRenderTest.cs
│ │ │ │ ├── DataSourcePanelDictionaryRenderTest.cs
│ │ │ │ ├── DataSourcePanelEmptyIEnumerableRenderTest.cs
│ │ │ │ ├── DataSourcePanelIEnumerableRenderTest.cs
│ │ │ │ ├── DataSourcePanelNullItemRenderTest.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_MixedPanels_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_PageBreaks_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test.cs
│ │ │ │ ├── DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test.cs
│ │ │ │ └── DataSourcePanelSingleItemRenderTest.cs
│ │ │ ├── PanelRenderTest.cs
│ │ │ ├── TestReport.cs
│ │ │ └── TotalsPanelRenderTest.cs
│ │ │ └── PanelsExpandTest.cs
│ ├── Parsers
│ │ └── DefaultPanelPropertiesParserTest.cs
│ ├── Providers
│ │ ├── ColumnsProvider
│ │ │ ├── ColumnsProviderFactoryTest.cs
│ │ │ ├── DataReaderColumnsProviderTest.cs
│ │ │ ├── DataSetColumnsProviderTest.cs
│ │ │ ├── DataTableColumnsProviderTest.cs
│ │ │ ├── DictionaryColumnsProviderTest.cs
│ │ │ ├── EnumerableColumnsProviderTest.cs
│ │ │ ├── GenericEnumerableColumnsProviderTest.cs
│ │ │ ├── KeyValuePairColumnsProviderTest.cs
│ │ │ ├── ObjectColumnsProviderTest.cs
│ │ │ └── TypeColumnsProviderTest.cs
│ │ ├── DataItemValueProviders
│ │ │ ├── DataItemValueProviderFactoryTest.cs
│ │ │ ├── DataReaderValueProviderTest.cs
│ │ │ ├── DataRowValueProviderTest.cs
│ │ │ ├── DictionaryValueProviderTest.cs
│ │ │ ├── HierarchicalDataItemValueProviderTest.cs
│ │ │ └── ObjectPropertyValueProviderTest.cs
│ │ ├── DefaultInstanceProviderTest.cs
│ │ ├── DefaultMethodCallValueProviderTest.cs
│ │ ├── DefaultPropertyValueProviderTest.cs
│ │ ├── DefaultTypeProviderTest.cs
│ │ └── VariableProviders
│ │ │ └── DefaultVariableProviderTest.cs
│ ├── SystemFunctionsTest.cs
│ └── TemplateProcessors
│ │ └── DefaultTemplateProcessorTest.cs
├── TestData
│ ├── DataSourceDynamicPanelDataReaderRenderTest
│ │ ├── TestRenderDataReader.xlsx
│ │ ├── TestRenderDataReader_HorizontalPanel.xlsx
│ │ └── TestRenderEmptyDataReader.xlsx
│ ├── DataSourceDynamicPanelDataSetRenderTest
│ │ ├── TestDynamicPanelAfterRenderEvent.xlsx
│ │ ├── TestRenderDataSetWithEvents.xlsx
│ │ ├── TestRenderDataSetWithEvents_HorizontalPanel.xlsx
│ │ └── TestRenderEmptyDataSet.xlsx
│ ├── DataSourceDynamicPanelDataTableRenderTest
│ │ ├── TestRenderDataTable.xlsx
│ │ └── TestRenderEmptyDataTable.xlsx
│ ├── DataSourceDynamicPanelDictionaryRenderTest
│ │ ├── TestRenderDictionary.xlsx
│ │ └── TestRenderDictionaryEnumerable.xlsx
│ ├── DataSourceDynamicPanelEnumerableRenderTest
│ │ ├── TestRenderEmptyEnumerable.xlsx
│ │ └── TestRenderEnumerable.xlsx
│ ├── DataSourceDynamicPanelSingleItemRenderTest
│ │ └── TestRenderSingleItem.xlsx
│ ├── DataSourceDynamicPanel_InsideDataSourcePanel_Test
│ │ ├── TestRender_DynamicPanel_In_DataSourcePanel_Horizontal.xlsx
│ │ └── TestRender_DynamicPanel_In_DataSourcePanel_Vertical.xlsx
│ ├── DataSourcePanelDataReaderRenderTest
│ │ └── TestRenderDataReader.xlsx
│ ├── DataSourcePanelDataSetRenderTest
│ │ └── TestRenderDataSet.xlsx
│ ├── DataSourcePanelDataTableRenderTest
│ │ └── TestRenderDataTable.xlsx
│ ├── DataSourcePanelDictionaryRenderTest
│ │ ├── TestRenderDictionary.xlsx
│ │ └── TestRenderDictionaryEnumerable.xlsx
│ ├── DataSourcePanelEmptyIEnumerableRenderTest
│ │ ├── TestRenderEmptyIEnumerableHorizontalCellsShift.xlsx
│ │ ├── TestRenderEmptyIEnumerableHorizontalNoShift.xlsx
│ │ ├── TestRenderEmptyIEnumerableHorizontalRowsShift.xlsx
│ │ ├── TestRenderEmptyIEnumerableVerticalCellsShift.xlsx
│ │ ├── TestRenderEmptyIEnumerableVerticalNoShift.xlsx
│ │ └── TestRenderEmptyIEnumerableVerticalRowsShift.xlsx
│ ├── DataSourcePanelIEnumerableRenderTest
│ │ ├── TestPanelRenderEvents.xlsx
│ │ ├── TestRenderIEnumerableHorizontalCellsShift.xlsx
│ │ ├── TestRenderIEnumerableHorizontalNoShift.xlsx
│ │ ├── TestRenderIEnumerableHorizontalRowsShift.xlsx
│ │ ├── TestRenderIEnumerableOfInt.xlsx
│ │ ├── TestRenderIEnumerableOfString.xlsx
│ │ ├── TestRenderIEnumerableVerticalCellsShift.xlsx
│ │ ├── TestRenderIEnumerableVerticalNoShift.xlsx
│ │ └── TestRenderIEnumerableVerticalRowsShift.xlsx
│ ├── DataSourcePanelNullItemRenderTest
│ │ ├── TestRenderNullItemHorizontalCellsShift.xlsx
│ │ ├── TestRenderNullItemHorizontalNoShift.xlsx
│ │ ├── TestRenderNullItemHorizontalRowShift.xlsx
│ │ ├── TestRenderNullItemVerticalCellsShift.xlsx
│ │ ├── TestRenderNullItemVerticalNoShift.xlsx
│ │ └── TestRenderNullItemVerticalRowShift.xlsx
│ ├── DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test
│ │ └── Test_VerticalPanelsGrouping_ChildEqualsParent.xlsx
│ ├── DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test
│ │ ├── ParentCellsShiftChildCellsShift.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithRichText.xlsx
│ │ ├── ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentNoShiftChildRowShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentRowShiftChildRowShift.xlsx
│ │ └── ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx
│ ├── DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test
│ │ ├── ParentCellsShiftChildCellsShift.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx
│ │ ├── ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentNoShiftChildRowShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx
│ │ ├── ParentRowShiftChildRowShift.xlsx
│ │ └── ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx
│ ├── DataSourcePanelRender_WithGrouping_MixedPanels_Test
│ │ ├── TestHorizontalInVerticalPanelsGrouping.xlsx
│ │ ├── TestMultipleHorizontalPanelsGrouping.xlsx
│ │ ├── TestMultipleVerticalPanelsGrouping.xlsx
│ │ └── TestVerticalInHorizontalPanelsGrouping.xlsx
│ ├── DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent
│ │ ├── Test_TwoChildren_Horizontal.xlsx
│ │ └── Test_TwoChildren_Vertical.xlsx
│ ├── DataSourcePanelRender_WithGrouping_PageBreaks_Test
│ │ ├── Test_HorizontalPageBreaks.xlsx
│ │ └── Test_VerticalPageBreaks.xlsx
│ ├── DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test
│ │ ├── ParentCellsShiftChildCellsShift.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx
│ │ ├── ParentNoShiftChildCellsShift.xlsx
│ │ ├── ParentNoShiftChildRowShift_WithFictitiousRow.xlsx
│ │ ├── ParentRowShiftChildCellsShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift_WithFictitiousRow.xlsx
│ │ ├── ParentRowShiftChildRowShift.xlsx
│ │ └── ParentRowShiftChildRowShift_WithFictitiousRow.xlsx
│ ├── DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test
│ │ ├── ParentCellsShiftChildCellsShift.xlsx
│ │ ├── ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx
│ │ ├── ParentCellsShiftChildRowShift_WithFictitiousRow.xlsx
│ │ ├── ParentNoShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx
│ │ ├── ParentNoShiftChildRowShift.xlsx
│ │ ├── ParentRowShiftChildCellsShift.xlsx
│ │ └── ParentRowShiftChildRowShift.xlsx
│ ├── DataSourcePanelSingleItemRenderTest
│ │ ├── TestRenderSingleItemHorizontalCellsShift.xlsx
│ │ ├── TestRenderSingleItemHorizontalNoShift.xlsx
│ │ ├── TestRenderSingleItemHorizontalRowShift.xlsx
│ │ ├── TestRenderSingleItemVerticalCellsShift.xlsx
│ │ ├── TestRenderSingleItemVerticalNoShift.xlsx
│ │ └── TestRenderSingleItemVerticalRowShift.xlsx
│ ├── DefaultReportGeneratorTest
│ │ ├── TestRender.xlsx
│ │ ├── TestRenderPartialWorksheets.xlsx
│ │ ├── TestRenderWithCustomVariableAndFunctionProviders.xlsx
│ │ └── TestRenderWithEvents.xlsx
│ ├── ExcelDataSourcePanelTest
│ │ ├── TestGroupResultHorizontal.xlsx
│ │ ├── TestGroupResultHorizontal_WithoutGroupingBlankValues.xlsx
│ │ ├── TestGroupResultVertical.xlsx
│ │ ├── TestGroupResultVertical_WithoutGroupingBlankValues.xlsx
│ │ └── TestIfGroupByPropertyIsEmpty.xlsx
│ ├── PanelRenderTest
│ │ └── TestSimplePanelExpansion.xlsx
│ ├── SystemFunctionsTest
│ │ └── TestFormatOnRender.xlsx
│ └── TotalsPanelRenderTest
│ │ ├── TestPanelRender.xlsx
│ │ ├── TestPanelRenderWithParentContext.xlsx
│ │ ├── TestPanelWithNoData.xlsx
│ │ └── TestPanelWithNullData.xlsx
├── TestDb.mdf
├── TestDb_log.ldf
├── TestHelper.cs
└── appsettings.json
├── ExcelReportGenerator.sln
├── ExcelReportGenerator
├── AssemblyInfo.cs
├── Attributes
│ ├── ExcelColumnAttribute.cs
│ ├── ExternalPropertyAttribute.cs
│ ├── NoExcelColumnAttribute.cs
│ └── NullValueAttribute.cs
├── Constants.cs
├── Converters
│ ├── ExternalPropertiesConverters
│ │ ├── IExternalPropertyConverter.cs
│ │ ├── PanelTypeConverter.cs
│ │ ├── RenderPriorityConverter.cs
│ │ └── ShiftTypeConverter.cs
│ ├── IConverter.cs
│ └── IGenericConverter.cs
├── Enumerators
│ ├── DataReaderEnumerator.cs
│ ├── DataSetEnumerator.cs
│ ├── DataTableEnumerator.cs
│ ├── EnumerableEnumerator.cs
│ ├── EnumeratorFactory.cs
│ ├── ICustomenumerator.cs
│ └── IGenericCustomEnumerator.cs
├── Enums
│ ├── AggregateFunction.cs
│ ├── Direction.cs
│ ├── PanelType.cs
│ └── ShiftType.cs
├── Excel
│ ├── AddressShift.cs
│ ├── CellCoords.cs
│ ├── ExcelHelper.cs
│ └── RangeCoords.cs
├── ExcelReportGenerator.csproj
├── Exceptions
│ ├── ColumnNotFoundException.cs
│ ├── InvalidTemplateException.cs
│ ├── InvalidVariableException.cs
│ ├── MemberNotFoundException.cs
│ ├── MethodNotFoundException.cs
│ └── TypeNotFoundException.cs
├── Extensions
│ ├── CustomAttributeExtensions.cs
│ ├── DataReaderExtensions.cs
│ ├── ParameterInfoExtensions.cs
│ ├── StringExtensions.cs
│ ├── TemplateProcessorExtensions.cs
│ ├── TypeExtensions.cs
│ └── XLRangeBaseExtensions.cs
├── Helpers
│ ├── ArgumentHelper.cs
│ ├── EnumHelper.cs
│ ├── IReflectionHelper.cs
│ ├── ReflectionHelper.cs
│ ├── RegexHelper.cs
│ └── TypeHelper.cs
└── Rendering
│ ├── DefaultReportGenerator.cs
│ ├── EventArgs
│ ├── DataItemPanelBeforeRenderEventArgs.cs
│ ├── DataItemPanelEventArgs.cs
│ ├── DataSourceDynamicPanelBeforeRenderEventArgs.cs
│ ├── DataSourceDynamicPanelEventArgs.cs
│ ├── DataSourcePanelBeforeRenderEventArgs.cs
│ ├── DataSourcePanelEventArgs.cs
│ ├── PanelBeforeRenderEventArgs.cs
│ ├── PanelEventArgs.cs
│ ├── ReportRenderEventArgs.cs
│ └── WorksheetRenderEventArgs.cs
│ ├── ExcelDynamicColumn.cs
│ ├── HierarchicalDataItem.cs
│ ├── PanelParsingSettings.cs
│ ├── Panels
│ ├── ExcelPanels
│ │ ├── ExcelDataItemPanel.cs
│ │ ├── ExcelDataSourceDynamicPanel.cs
│ │ ├── ExcelDataSourcePanel.cs
│ │ ├── ExcelNamedPanel.cs
│ │ ├── ExcelPanel.cs
│ │ ├── ExcelPanelFactory.cs
│ │ ├── ExcelTotalsPanel.cs
│ │ ├── IExcelNamedPanel.cs
│ │ └── IExcelPanel.cs
│ ├── IDataItemPanel.cs
│ ├── INamedPanel.cs
│ └── IPanel.cs
│ ├── Parsers
│ ├── DefaultPanelPropertiesParser.cs
│ └── IPanelPropertiesParser.cs
│ ├── Providers
│ ├── ColumnsProviders
│ │ ├── ColumnsProviderFactory.cs
│ │ ├── DataReaderColumnsProvider.cs
│ │ ├── DataSetColumnsProvider.cs
│ │ ├── DataTableColumnsProvider.cs
│ │ ├── DictionaryColumnsProvider.cs
│ │ ├── EnumerableColumnsProvider.cs
│ │ ├── GenericEnumerableColumnsProvider.cs
│ │ ├── IColumnsProvider.cs
│ │ ├── IColumnsProviderFactory.cs
│ │ ├── IGenericColumnsProvider.cs
│ │ ├── KeyValuePairColumnsProvider.cs
│ │ ├── ObjectColumnsProvider.cs
│ │ └── TypeColumnsProvider.cs
│ ├── DataItemValueProviders
│ │ ├── DataItemValueProviderFactory.cs
│ │ ├── DataReaderValueProvider.cs
│ │ ├── DataRowValueProvider.cs
│ │ ├── DefaultDataItemValueProvider.cs
│ │ ├── DictionaryValueProvider.cs
│ │ ├── IDataItemValueProvider.cs
│ │ ├── IDataItemValueProviderFactory.cs
│ │ ├── IGenericDataItemValueProvider.cs
│ │ └── ObjectPropertyValueProvider.cs
│ ├── DefaultInstanceProvider.cs
│ ├── DefaultMethodCallValueProvider.cs
│ ├── DefaultPropertyValueProvider.cs
│ ├── DefaultTypeProvider.cs
│ ├── IInstanceProvider.cs
│ ├── IMethodCallValueProvider.cs
│ ├── IPropertyValueProvider.cs
│ ├── ITypeProvider.cs
│ └── VariableProviders
│ │ └── SystemVariableProvider.cs
│ ├── SystemFunctions.cs
│ ├── TemplateParts
│ ├── MemberTemplateParts.cs
│ └── MethodCallTemplateParts.cs
│ └── TemplateProcessors
│ ├── DefaultTemplateProcessor.cs
│ └── ITemplateProcessor.cs
├── LICENSE.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /packages
2 | /TestResults
3 | *.user
4 | bin
5 | obj
6 | *.suo
7 | /.vs
8 | /.idea
9 | /ExcelReportGenerator.Samples/Database
10 | ~$*
11 | /Dotfuscated
12 | /Dotfuscator/Map
13 | /NugetPackage/lib
14 | /NugetPackage/ExcelReportGenerator.Samples.zip
15 | /NugetPackage/Tutorial.pdf
16 |
--------------------------------------------------------------------------------
/Docs/Tutorial.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/Docs/Tutorial.docx
--------------------------------------------------------------------------------
/Docs/Tutorial.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/Docs/Tutorial.pdf
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/ConnectionFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 | using System.Data;
3 | using System.Data.SqlClient;
4 |
5 | namespace ExcelReportGenerator.Samples;
6 |
7 | public static class ConnectionFactory
8 | {
9 | public static IDbConnection Create()
10 | {
11 | var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["AdventureWorks"].ConnectionString);
12 | connection.Open();
13 | return connection;
14 | }
15 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Customizations/CustomInstanceProvider.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Rendering.Providers;
2 |
3 | namespace ExcelReportGenerator.Samples.Customizations;
4 |
5 | public class CustomInstanceProvider : DefaultInstanceProvider
6 | {
7 | private readonly object _defaultInstance;
8 |
9 | public CustomInstanceProvider(object defaultInstance = null) : base(defaultInstance)
10 | {
11 | _defaultInstance = defaultInstance;
12 | }
13 |
14 | public override object GetInstance(Type type)
15 | {
16 | return type == null ? _defaultInstance : Ioc.Container.GetInstance(type);
17 | }
18 |
19 | public override T GetInstance()
20 | {
21 | return (T)GetInstance(typeof(T));
22 | }
23 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Customizations/CustomReportGenerator.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Rendering;
2 | using ExcelReportGenerator.Rendering.Providers;
3 | using ExcelReportGenerator.Rendering.Providers.VariableProviders;
4 | using ExcelReportGenerator.Rendering.TemplateProcessors;
5 |
6 | namespace ExcelReportGenerator.Samples.Customizations;
7 |
8 | public class CustomReportGenerator : DefaultReportGenerator
9 | {
10 | private IInstanceProvider _instanceProvider;
11 | private PanelParsingSettings _panelParsingSettings;
12 | private ITemplateProcessor _templateProcessor;
13 |
14 | public CustomReportGenerator(object report) : base(report)
15 | {
16 | }
17 |
18 | public override Type SystemFunctionsType => typeof(CustomSystemFunctions);
19 |
20 | public override SystemVariableProvider SystemVariableProvider => new CustomSystemVariableProvider();
21 |
22 | public override IInstanceProvider InstanceProvider => _instanceProvider ??= new CustomInstanceProvider(Report);
23 |
24 | public override ITemplateProcessor TemplateProcessor => _templateProcessor ??=
25 | new CustomTemplateProcessor(PropertyValueProvider, SystemVariableProvider, MethodCallValueProvider,
26 | DataItemValueProvider);
27 |
28 | public override PanelParsingSettings PanelParsingSettings
29 | {
30 | get
31 | {
32 | return _panelParsingSettings ??= new PanelParsingSettings
33 | {
34 | PanelPrefixSeparator = "_",
35 | SimplePanelPrefix = "simple",
36 | DataSourcePanelPrefix = "data",
37 | DynamicDataSourcePanelPrefix = "dynamic",
38 | TotalsPanelPrefix = "total",
39 | PanelPropertiesSeparators = new[] {","},
40 | PanelPropertyNameValueSeparator = "="
41 | };
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Customizations/CustomSystemFunctions.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Rendering;
2 |
3 | namespace ExcelReportGenerator.Samples.Customizations;
4 |
5 | public class CustomSystemFunctions : SystemFunctions
6 | {
7 | public static string ConvertGender(string gender) => gender == "M" ? "Male" : "Female";
8 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Customizations/CustomSystemVariableProvider.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Rendering.Providers.VariableProviders;
2 |
3 | namespace ExcelReportGenerator.Samples.Customizations;
4 |
5 | public class CustomSystemVariableProvider : SystemVariableProvider
6 | {
7 | public string ReportTime => DateTime.Now.ToString("g");
8 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Customizations/CustomTemplateProcessor.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Rendering;
2 | using ExcelReportGenerator.Rendering.Providers;
3 | using ExcelReportGenerator.Rendering.Providers.DataItemValueProviders;
4 | using ExcelReportGenerator.Rendering.Providers.VariableProviders;
5 | using ExcelReportGenerator.Rendering.TemplateProcessors;
6 |
7 | namespace ExcelReportGenerator.Samples.Customizations;
8 |
9 | public class CustomTemplateProcessor : DefaultTemplateProcessor
10 | {
11 | public CustomTemplateProcessor(IPropertyValueProvider propertyValueProvider, SystemVariableProvider systemVariableProvider, IMethodCallValueProvider methodCallValueProvider = null, IGenericDataItemValueProvider dataItemValueProvider = null) : base(propertyValueProvider, systemVariableProvider, methodCallValueProvider, dataItemValueProvider)
12 | {
13 | }
14 |
15 | public override string LeftTemplateBorder => "<";
16 |
17 | public override string RightTemplateBorder => ">";
18 |
19 | public override string MemberLabelSeparator => "-";
20 |
21 | public override string PropertyMemberLabel => "prop";
22 |
23 | public override string MethodCallMemberLabel => "meth";
24 |
25 | public override string DataItemMemberLabel => "dataitem";
26 |
27 | public override string SystemVariableMemberLabel => "var";
28 |
29 | public override string SystemFunctionMemberLabel => "func";
30 |
31 | public override string DataItemSelfTemplate => "self";
32 |
33 | public override string HorizontalPageBreakLabel => "hbreak";
34 |
35 | public override string VerticalPageBreakLabel => "vbreak";
36 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/ExcelReportGenerator.Samples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows
6 | true
7 | latest
8 | enable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Always
23 |
24 |
25 | Always
26 |
27 |
28 | Always
29 |
30 |
31 | Always
32 |
33 |
34 | Always
35 |
36 |
37 | Always
38 |
39 |
40 | Always
41 |
42 |
43 | Always
44 |
45 |
46 | Always
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Extensions/DataReaderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 |
3 | namespace ExcelReportGenerator.Samples.Extensions;
4 |
5 | public static class DataReaderExtensions
6 | {
7 | public static T GetValueSafe(this IDataReader reader, int columnIndex)
8 | {
9 | return reader.IsDBNull(columnIndex) ? default : (T)reader.GetValue(columnIndex);
10 | }
11 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Ioc.cs:
--------------------------------------------------------------------------------
1 | using SimpleInjector;
2 |
3 | namespace ExcelReportGenerator.Samples;
4 |
5 | public static class Ioc
6 | {
7 | public static Container Container { get; set; }
8 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Program.cs:
--------------------------------------------------------------------------------
1 | using SimpleInjector;
2 |
3 | namespace ExcelReportGenerator.Samples;
4 |
5 | internal static class Program
6 | {
7 | ///
8 | /// The main entry point for the application.
9 | ///
10 | [STAThread]
11 | private static void Main()
12 | {
13 | Ioc.Container = new Container();
14 | Ioc.Container.Register(Lifestyle.Singleton);
15 | Ioc.Container.Options.ResolveUnregisteredConcreteTypes = true;
16 |
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new SamplesForm());
20 | }
21 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/CustomReportGeneratorSample.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class CustomReportGeneratorSample : ReportBase
4 | {
5 | public override string ReportName => "Custom report generator sample";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/DataReaderConnect.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class DataReaderConnect : ReportBase
4 | {
5 | public override string ReportName => "Connect to IDataReader";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/DataSetConnect.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class DataSetConnect : ReportBase
4 | {
5 | public override string ReportName => "Connect to DataSet";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/DataTableConnect.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class DataTableConnect : ReportBase
4 | {
5 | public override string ReportName => "Connect to DataTable";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/DynamicPanelDataTableConnect.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Enums;
2 | using ExcelReportGenerator.Rendering.EventArgs;
3 |
4 | namespace ExcelReportGenerator.Samples.Reports;
5 |
6 | public class DynamicPanelDataTableConnect : DynamicPanelEnumerableConnect
7 | {
8 | public override string ReportName => "Connect to DataTable via dynamic panel";
9 |
10 | public void BeforeHeadersRender(DataSourceDynamicPanelBeforeRenderEventArgs args)
11 | {
12 | args.Columns[6].AggregateFunction = AggregateFunction.Max;
13 | args.Columns[7].AggregateFunction = AggregateFunction.Min;
14 | args.Columns[8].DisplayFormat = "$#,0.00";
15 | }
16 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/DynamicPanelEnumerableConnect.cs:
--------------------------------------------------------------------------------
1 | using ClosedXML.Excel;
2 | using ExcelReportGenerator.Rendering.EventArgs;
3 |
4 | namespace ExcelReportGenerator.Samples.Reports;
5 |
6 | public class DynamicPanelEnumerableConnect : ReportBase
7 | {
8 | public override string ReportName => "Connect to IEnumerable via dynamic panel";
9 |
10 | public void AfterDataTemplatesRender(DataSourceDynamicPanelEventArgs args)
11 | {
12 | args.Range.FirstCell().Style.Fill.BackgroundColor = XLColor.FromTheme(XLThemeColor.Background2);
13 | args.Range.Range(1, 7, 1, 9).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right;
14 | }
15 |
16 | public void AfterTotalsRender(DataSourcePanelEventArgs args)
17 | {
18 | args.Range.Range(1, 7, 1, 9).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right;
19 | IXLRange mergedRange = args.Range.Range(1, 1, 1, 6).Merge();
20 | mergedRange.Value = "Totals";
21 | mergedRange.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left;
22 | }
23 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/EnumerableConnect.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class EnumerableConnect : ReportBase
4 | {
5 | public override string ReportName => "Connect to IEnumerable";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/EnumerableOfDictionaryConnect.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class EnumerableOfDictionaryConnect : ReportBase
4 | {
5 | public override string ReportName => "Connect to IEnumerable of Dictionary";
6 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/GroupingWithPanelHierarchy.cs:
--------------------------------------------------------------------------------
1 | namespace ExcelReportGenerator.Samples.Reports;
2 |
3 | public class GroupingWithPanelHierarchy : ReportBase
4 | {
5 | private readonly DataProvider _dataProvider = new DataProvider();
6 |
7 | private DataProvider.Result[] _allEmployeesCache;
8 |
9 | private readonly IDictionary _employeesByDepartmentCache = new Dictionary();
10 |
11 | public override string ReportName => "Grouping with Panel Hierarchy";
12 |
13 | public IEnumerable GetDepartments()
14 | {
15 | return GetAllEmployees().Select(e => e.DepartmentName).Distinct();
16 | }
17 |
18 | public IEnumerable GetDepartmentEmployees(string department)
19 | {
20 | if (_employeesByDepartmentCache.TryGetValue(department, out var result))
21 | {
22 | return result;
23 | }
24 |
25 | result = GetAllEmployees().Where(e => e.DepartmentName == department).ToArray();
26 | _employeesByDepartmentCache[department] = result;
27 | return result;
28 | }
29 |
30 | public IEnumerable GetAllEmployees()
31 | {
32 | return _allEmployeesCache ??= _dataProvider.GetEmployeesAsIEnumerable().ToArray();
33 | }
34 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/ReportBase.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Samples.Customizations;
2 |
3 | namespace ExcelReportGenerator.Samples.Reports;
4 |
5 | public abstract class ReportBase
6 | {
7 | public abstract string ReportName { get; }
8 |
9 | public string ConvertGender(string gender)
10 | {
11 | return CustomSystemFunctions.ConvertGender(gender);
12 | }
13 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/CustomReportGeneratorSample.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/CustomReportGeneratorSample.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/DataReaderConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/DataReaderConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/DataSetConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/DataSetConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/DataTableConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/DataTableConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/DynamicPanelDataTableConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/DynamicPanelDataTableConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/DynamicPanelEnumerableConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/DynamicPanelEnumerableConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/EnumerableConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/EnumerableConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/EnumerableOfDictionaryConnect.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/EnumerableOfDictionaryConnect.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/Reports/Templates/GroupingWithPanelHierarchy.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Samples/Reports/Templates/GroupingWithPanelHierarchy.xlsx
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/RestoreDbTemplate.sql:
--------------------------------------------------------------------------------
1 | -- Download database backup from https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2012.bak
2 |
3 | -- Restore backup on server (change , and templates)
4 | RESTORE DATABASE AdventureWorks
5 | FROM DISK = '\AdventureWorks2012.bak'
6 | WITH MOVE 'AdventureWorks2012' TO '\AdventureWorks2012.mdf',
7 | MOVE 'AdventureWorks2012_log' TO '\AdventureWorks2012_log.ldf';
8 |
9 | -- Then change the connection string in App.config if necessary
--------------------------------------------------------------------------------
/ExcelReportGenerator.Samples/SamplesForm.cs:
--------------------------------------------------------------------------------
1 | using ClosedXML.Excel;
2 | using ExcelReportGenerator.Rendering;
3 | using ExcelReportGenerator.Samples.Customizations;
4 | using ExcelReportGenerator.Samples.Reports;
5 | using System.Reflection;
6 |
7 | namespace ExcelReportGenerator.Samples;
8 |
9 | public partial class SamplesForm : Form
10 | {
11 | public SamplesForm()
12 | {
13 | InitializeComponent();
14 | }
15 |
16 | private void SamplesForm_Load(object sender, EventArgs e)
17 | {
18 | cmbReports.DataSource = typeof(ReportBase).Assembly.GetTypes()
19 | .Where(t => typeof(ReportBase).IsAssignableFrom(t) && !t.IsAbstract).ToArray();
20 | txtOutputFolder.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
21 | }
22 |
23 | private async void btnRun_Click(object sender, EventArgs e)
24 | {
25 | var reportType = GetSelectedReport();
26 | var reportGenerator = GetReportGenerator(reportType);
27 |
28 | ToggleControlEnabled(true);
29 |
30 | try
31 | {
32 | await Task.Factory.StartNew(() =>
33 | {
34 | var result = reportGenerator.Render(GetReportTemplateWorkbook(reportType));
35 | result.SaveAs(Path.Combine(txtOutputFolder.Text, $"{reportType.Name}_Result.xlsx"));
36 | });
37 | }
38 | catch (Exception ex)
39 | {
40 | MessageBox.Show($"An error occurred while running report: {ex.GetBaseException().Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
41 | }
42 |
43 | ToggleControlEnabled(false);
44 | }
45 |
46 | private void ToggleControlEnabled(bool reportRunning)
47 | {
48 | btnRun.Enabled = !reportRunning;
49 | progressBar.Visible = reportRunning;
50 | }
51 |
52 | private static ReportBase GetReportInstance(Type reportType)
53 | {
54 | return (ReportBase)Activator.CreateInstance(reportType);
55 | }
56 |
57 | private Type GetSelectedReport()
58 | {
59 | return (Type)cmbReports.SelectedItem;
60 | }
61 |
62 | private static XLWorkbook GetReportTemplateWorkbook(MemberInfo reportType)
63 | {
64 | return new XLWorkbook(Path.Combine("Reports", "Templates", $"{reportType.Name}.xlsx"));
65 | }
66 |
67 | private static DefaultReportGenerator GetReportGenerator(Type reportType)
68 | {
69 | var report = GetReportInstance(reportType);
70 | return reportType == typeof(CustomReportGeneratorSample) ? new CustomReportGenerator(report) : new DefaultReportGenerator(report);
71 | }
72 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Configuration.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Configuration;
2 |
3 | namespace ExcelReportGenerator.Tests;
4 |
5 | public static class Configuration
6 | {
7 | private static readonly IConfigurationRoot _configuration;
8 |
9 | static Configuration()
10 | {
11 | var builder = new ConfigurationBuilder()
12 | .SetBasePath(Directory.GetCurrentDirectory())
13 | .AddJsonFile("appsettings.json", true, true);
14 | _configuration = builder.Build();
15 | }
16 |
17 | public static string TestDbConnectionString
18 | {
19 | get
20 | {
21 | var projectPath = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent.Parent.Parent.FullName;
22 | return _configuration["ConnectionStrings:TestDb"].Replace("%DBPATH%", projectPath);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Converters/ExternalPropertiesConverters/PanelTypeConverterTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Converters.ExternalPropertiesConverters;
2 | using ExcelReportGenerator.Enums;
3 | using ExcelReportGenerator.Tests.CustomAsserts;
4 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
5 |
6 | namespace ExcelReportGenerator.Tests.Converters.ExternalPropertiesConverters;
7 |
8 | public class PanelTypeConverterTest
9 | {
10 | [Test]
11 | public void TestConvert()
12 | {
13 | var converter = new PanelTypeConverter();
14 | Assert.AreEqual(PanelType.Horizontal, converter.Convert("Horizontal"));
15 | Assert.AreEqual(PanelType.Horizontal, converter.Convert("horizontal"));
16 | Assert.AreEqual(PanelType.Vertical, converter.Convert("Vertical"));
17 | ExceptionAssert.Throws(() => converter.Convert("BadValue"),
18 | "Value \"BadValue\" is invalid for Type property");
19 | ExceptionAssert.Throws(() => converter.Convert(null),
20 | "Type property cannot be null or empty");
21 | ExceptionAssert.Throws(() => converter.Convert(string.Empty),
22 | "Type property cannot be null or empty");
23 | ExceptionAssert.Throws(() => converter.Convert(" "),
24 | "Type property cannot be null or empty");
25 | }
26 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Converters/ExternalPropertiesConverters/RenderPriorityConverterTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Converters.ExternalPropertiesConverters;
2 | using ExcelReportGenerator.Tests.CustomAsserts;
3 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
4 |
5 | namespace ExcelReportGenerator.Tests.Converters.ExternalPropertiesConverters;
6 |
7 | public class RenderPriorityConverterTest
8 | {
9 | [Test]
10 | public void TestConvert()
11 | {
12 | var converter = new RenderPriorityConverter();
13 | Assert.AreEqual(1, converter.Convert("1"));
14 | Assert.AreEqual(100, converter.Convert("100"));
15 | Assert.AreEqual(-10, converter.Convert("-10"));
16 | ExceptionAssert.Throws(() => converter.Convert("10.5"),
17 | "Cannot convert value \"10.5\" to int");
18 | ExceptionAssert.Throws(() => converter.Convert("BadValue"),
19 | "Cannot convert value \"BadValue\" to int");
20 | ExceptionAssert.Throws(() => converter.Convert(null),
21 | "RenderPriority property cannot be null or empty");
22 | ExceptionAssert.Throws(() => converter.Convert(string.Empty),
23 | "RenderPriority property cannot be null or empty");
24 | ExceptionAssert.Throws(() => converter.Convert(" "),
25 | "RenderPriority property cannot be null or empty");
26 | }
27 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Converters/ExternalPropertiesConverters/ShiftTypeConverterTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Converters.ExternalPropertiesConverters;
2 | using ExcelReportGenerator.Enums;
3 | using ExcelReportGenerator.Tests.CustomAsserts;
4 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
5 |
6 | namespace ExcelReportGenerator.Tests.Converters.ExternalPropertiesConverters;
7 |
8 | public class ShiftTypeConverterTest
9 | {
10 | [Test]
11 | public void TestConvert()
12 | {
13 | var converter = new ShiftTypeConverter();
14 | Assert.AreEqual(ShiftType.Cells, converter.Convert("Cells"));
15 | Assert.AreEqual(ShiftType.Cells, converter.Convert("cells"));
16 | Assert.AreEqual(ShiftType.Row, converter.Convert("Row"));
17 | Assert.AreEqual(ShiftType.NoShift, converter.Convert("NoShift"));
18 | ExceptionAssert.Throws(() => converter.Convert("BadValue"),
19 | "Value \"BadValue\" is invalid for ShiftType property");
20 | ExceptionAssert.Throws(() => converter.Convert(null),
21 | "ShiftType property cannot be null or empty");
22 | ExceptionAssert.Throws(() => converter.Convert(string.Empty),
23 | "ShiftType property cannot be null or empty");
24 | ExceptionAssert.Throws(() => converter.Convert(" "),
25 | "ShiftType property cannot be null or empty");
26 | }
27 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/CustomAsserts/ExceptionAssert.cs:
--------------------------------------------------------------------------------
1 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
2 |
3 | namespace ExcelReportGenerator.Tests.CustomAsserts;
4 |
5 | public class ExceptionAssert
6 | {
7 | public static void Throws(Action action, string expectedMessage = null) where T : Exception
8 | {
9 | try
10 | {
11 | action.Invoke();
12 | }
13 | catch (T e)
14 | {
15 | if (expectedMessage != null)
16 | {
17 | Assert.AreEqual(expectedMessage, e.Message, "Wrong exception message was returned");
18 | }
19 |
20 | return;
21 | }
22 | catch (Exception e)
23 | {
24 | Assert.IsInstanceOf(e, "Wrong type of exception was thrown");
25 | return;
26 | }
27 |
28 | Assert.Fail("No exception was thrown");
29 | }
30 |
31 | public static void ThrowsBaseException(Action action, string expectedMessage = null) where T : Exception
32 | {
33 | try
34 | {
35 | action.Invoke();
36 | }
37 | catch (Exception e)
38 | {
39 | var baseException = e.GetBaseException();
40 | Assert.IsInstanceOf(baseException, "Wrong type of exception was thrown");
41 | if (expectedMessage != null)
42 | {
43 | Assert.AreEqual(expectedMessage, baseException.Message, "Wrong exception message was returned");
44 | }
45 |
46 | return;
47 | }
48 |
49 | Assert.Fail("No exception was thrown");
50 | }
51 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Enumerators/DataTableEnumeratorTest.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using ExcelReportGenerator.Enumerators;
3 | using ExcelReportGenerator.Tests.CustomAsserts;
4 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
5 |
6 | namespace ExcelReportGenerator.Tests.Enumerators;
7 |
8 | public class DataTableEnumeratorTest
9 | {
10 | [Test]
11 | public void TestEnumerator()
12 | {
13 | ExceptionAssert.Throws(() => new DataTableEnumerator(null));
14 |
15 | var dataTable = new DataTable("Table1");
16 | dataTable.Columns.Add("Column", typeof(int));
17 |
18 | dataTable.Rows.Add(1);
19 | dataTable.Rows.Add(2);
20 | dataTable.Rows.Add(3);
21 |
22 | IList result = new List(dataTable.Rows.Count);
23 | var enumerator = new DataTableEnumerator(dataTable);
24 |
25 | Assert.AreEqual(3, enumerator.RowCount);
26 |
27 | Assert.IsNull(enumerator.Current);
28 | Assert.IsNull(enumerator.Current);
29 | while (enumerator.MoveNext())
30 | {
31 | result.Add((int) enumerator.Current.ItemArray[0]);
32 | }
33 |
34 | Assert.IsFalse(enumerator.MoveNext());
35 | Assert.IsFalse(enumerator.MoveNext());
36 |
37 | Assert.IsNull(enumerator.Current);
38 |
39 | Assert.AreEqual(3, result.Count);
40 | Assert.AreEqual(1, result[0]);
41 | Assert.AreEqual(2, result[1]);
42 | Assert.AreEqual(3, result[2]);
43 |
44 | Assert.AreEqual(3, enumerator.RowCount);
45 |
46 | enumerator.Dispose();
47 | enumerator.Reset();
48 | result.Clear();
49 |
50 | Assert.AreEqual(3, enumerator.RowCount);
51 |
52 | Assert.IsNull(enumerator.Current);
53 | Assert.IsNull(enumerator.Current);
54 | while (enumerator.MoveNext())
55 | {
56 | result.Add((int) enumerator.Current.ItemArray[0]);
57 | }
58 |
59 | Assert.IsFalse(enumerator.MoveNext());
60 | Assert.IsFalse(enumerator.MoveNext());
61 |
62 | Assert.IsNull(enumerator.Current);
63 |
64 | Assert.AreEqual(3, result.Count);
65 | Assert.AreEqual(1, result[0]);
66 | Assert.AreEqual(2, result[1]);
67 | Assert.AreEqual(3, result[2]);
68 |
69 | Assert.AreEqual(3, enumerator.RowCount);
70 | }
71 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Enumerators/EnumeratorFactoryTest.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Data;
3 | using ExcelReportGenerator.Enumerators;
4 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
5 |
6 | namespace ExcelReportGenerator.Tests.Enumerators;
7 |
8 | public class EnumeratorFactoryTest
9 | {
10 | [Test]
11 | public void TestCreate()
12 | {
13 | Assert.IsNull(EnumeratorFactory.Create(null));
14 |
15 | Assert.IsInstanceOf(EnumeratorFactory.Create(new List()));
16 | Assert.IsInstanceOf(EnumeratorFactory.Create(new int[0]));
17 | Assert.IsInstanceOf(EnumeratorFactory.Create(new Dictionary()));
18 | Assert.IsInstanceOf(EnumeratorFactory.Create(new HashSet()));
19 | Assert.IsInstanceOf(EnumeratorFactory.Create(new Hashtable()));
20 | Assert.IsInstanceOf(EnumeratorFactory.Create(new ArrayList()));
21 |
22 | var dataSet = new DataSet();
23 | dataSet.Tables.Add(new DataTable());
24 |
25 | Assert.IsInstanceOf(EnumeratorFactory.Create(dataSet));
26 | Assert.IsInstanceOf(EnumeratorFactory.Create(new DataTable()));
27 |
28 | var dataReader = Substitute.For();
29 | Assert.IsInstanceOf(EnumeratorFactory.Create(dataReader));
30 | }
31 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Extensions/DataReaderExtensionsTest.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using System.Data.SqlClient;
3 | using ExcelReportGenerator.Extensions;
4 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
5 |
6 | namespace ExcelReportGenerator.Tests.Extensions;
7 |
8 | public class DataReaderExtensionsTest
9 | {
10 | private readonly string _conStr = Configuration.TestDbConnectionString;
11 |
12 | [Test]
13 | public void TestSafeGetValue()
14 | {
15 | var reader = GetTestBoolData();
16 | reader.Read();
17 |
18 | Assert.IsNull(reader.SafeGetValue(reader.GetOrdinal("IsVip")));
19 | var id = reader.SafeGetValue(reader.GetOrdinal("Id"));
20 | Assert.IsNotNull(id);
21 | Assert.AreNotEqual(0, id);
22 |
23 | reader.Close();
24 |
25 | reader = GetTestIntData();
26 | reader.Read();
27 |
28 | Assert.IsNull(reader.SafeGetValue(reader.GetOrdinal("Type")));
29 | id = reader.SafeGetValue(reader.GetOrdinal("Id"));
30 | Assert.IsNotNull(id);
31 | Assert.AreNotEqual(0, id);
32 |
33 | reader.Close();
34 |
35 | reader = GetTestStringData();
36 | reader.Read();
37 |
38 | Assert.IsNull(reader.SafeGetValue(reader.GetOrdinal("Description")));
39 | id = reader.SafeGetValue(reader.GetOrdinal("Id"));
40 | Assert.IsNotNull(id);
41 | Assert.AreNotEqual(0, id);
42 |
43 | reader.Close();
44 | }
45 |
46 | private IDataReader GetTestBoolData()
47 | {
48 | IDbConnection connection = new SqlConnection(_conStr);
49 | var command = connection.CreateCommand();
50 | command.CommandText = "SELECT TOP 1 * FROM Customers WHERE IsVip IS NULL";
51 | connection.Open();
52 | return command.ExecuteReader(CommandBehavior.CloseConnection);
53 | }
54 |
55 | private IDataReader GetTestIntData()
56 | {
57 | IDbConnection connection = new SqlConnection(_conStr);
58 | var command = connection.CreateCommand();
59 | command.CommandText = "SELECT TOP 1 * FROM Customers WHERE Type IS NULL";
60 | connection.Open();
61 | return command.ExecuteReader(CommandBehavior.CloseConnection);
62 | }
63 |
64 | private IDataReader GetTestStringData()
65 | {
66 | IDbConnection connection = new SqlConnection(_conStr);
67 | var command = connection.CreateCommand();
68 | command.CommandText = "SELECT TOP 1 * FROM Customers WHERE Description IS NULL";
69 | connection.Open();
70 | return command.ExecuteReader(CommandBehavior.CloseConnection);
71 | }
72 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Extensions/ParameterInfoExtensionsTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Extensions;
2 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
3 |
4 | namespace ExcelReportGenerator.Tests.Extensions;
5 |
6 | public class ParameterInfoExtensionsTest
7 | {
8 | [Test]
9 | public void TestIsParams()
10 | {
11 | var method = typeof(TestClass).GetMethod("Meth1");
12 | var parameters = method.GetParameters();
13 | Assert.IsFalse(parameters[0].IsParams());
14 | Assert.IsFalse(parameters[1].IsParams());
15 | Assert.IsTrue(parameters[2].IsParams());
16 | }
17 |
18 | [Test]
19 | public void TestHasDefaultValue()
20 | {
21 | var method = typeof(TestClass).GetMethod("Meth2");
22 | var methodParams = method.GetParameters();
23 | Assert.IsFalse(methodParams[0].HasDefaultValue());
24 | Assert.IsTrue(methodParams[1].HasDefaultValue());
25 | Assert.IsTrue(methodParams[2].HasDefaultValue());
26 | Assert.IsTrue(methodParams[3].HasDefaultValue());
27 | }
28 |
29 | private class TestClass
30 | {
31 | public void Meth1(int arg1, string arg2, params string[] arg3)
32 | {
33 | }
34 |
35 | public void Meth2(int arg1, int arg2 = 0, DateTime? arg3 = null, object arg4 = null)
36 | {
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Extensions/StringExtensionsTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Extensions;
2 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
3 |
4 | namespace ExcelReportGenerator.Tests.Extensions;
5 |
6 | public class StringExtensionsTest
7 | {
8 | [Test]
9 | public void TestReplaceFirst()
10 | {
11 | var input = "Hello World";
12 | Assert.AreEqual("Helle World", input.ReplaceFirst("o", "e"));
13 | Assert.AreEqual("Hello World", input.ReplaceFirst("O", "e"));
14 | Assert.AreEqual("ppello World", input.ReplaceFirst("H", "pp"));
15 | Assert.AreEqual("HeLLlo World", input.ReplaceFirst("l", "LL"));
16 | Assert.IsNull(StringExtensions.ReplaceFirst(null, "a", "A"));
17 | }
18 |
19 | [Test]
20 | public void TestReverse()
21 | {
22 | Assert.AreEqual("!dlroW olleH", "Hello World!".Reverse());
23 | Assert.AreEqual(string.Empty, string.Empty.Reverse());
24 | Assert.IsNull(StringExtensions.Reverse(null));
25 | }
26 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/GlobalSetup.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 |
3 | namespace ExcelReportGenerator.Tests
4 | {
5 | [SetUpFixture]
6 | public class GlobalSetup
7 | {
8 | [OneTimeSetUp]
9 | public void SetUp()
10 | {
11 | var culture = new CultureInfo("ru-RU");
12 |
13 | CultureInfo.CurrentCulture = culture;
14 | CultureInfo.CurrentUICulture = culture;
15 |
16 | Thread.CurrentThread.CurrentCulture = culture;
17 | Thread.CurrentThread.CurrentUICulture = culture;
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Helpers/EnumHelperTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Helpers;
2 | using ExcelReportGenerator.Tests.CustomAsserts;
3 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
4 |
5 | namespace ExcelReportGenerator.Tests.Helpers;
6 |
7 | public class EnumHelperTest
8 | {
9 | [Test]
10 | public void TestParse()
11 | {
12 | Assert.AreEqual(TestEnum.One, EnumHelper.Parse("One"));
13 | ExceptionAssert.Throws(() => EnumHelper.Parse("one", false));
14 | Assert.AreEqual(TestEnum.One, EnumHelper.Parse("one"));
15 | Assert.AreEqual(TestEnum.Two, EnumHelper.Parse("Two"));
16 | Assert.AreEqual(TestEnum.Three, EnumHelper.Parse("Three"));
17 | ExceptionAssert.Throws(() => EnumHelper.Parse("Four"));
18 | ExceptionAssert.Throws(() => EnumHelper.Parse(null));
19 | ExceptionAssert.Throws(() => EnumHelper.Parse("One"));
20 | }
21 |
22 | private enum TestEnum
23 | {
24 | One,
25 | Two,
26 | Three
27 | }
28 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Helpers/RegexHelperTest.cs:
--------------------------------------------------------------------------------
1 | using ExcelReportGenerator.Helpers;
2 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
3 |
4 | namespace ExcelReportGenerator.Tests.Helpers;
5 |
6 | public class RegexHelperTest
7 | {
8 | [Test]
9 | public void TestSafeEscape()
10 | {
11 | Assert.IsNull(RegexHelper.SafeEscape(null));
12 | Assert.AreEqual(string.Empty, RegexHelper.SafeEscape(string.Empty));
13 | Assert.AreEqual("abc", RegexHelper.SafeEscape("abc"));
14 | Assert.AreEqual("\\ ", RegexHelper.SafeEscape(" "));
15 | Assert.AreEqual("\\[", RegexHelper.SafeEscape("["));
16 | Assert.AreEqual("]", RegexHelper.SafeEscape("]"));
17 | Assert.AreEqual("\\*\\*", RegexHelper.SafeEscape("**"));
18 | }
19 | }
--------------------------------------------------------------------------------
/ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/ExcelDataItemPanelTest.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using ClosedXML.Excel;
3 | using ExcelReportGenerator.Enums;
4 | using ExcelReportGenerator.Rendering;
5 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels;
6 | using ExcelReportGenerator.Rendering.TemplateProcessors;
7 | using Assert = NUnit.Framework.Legacy.ClassicAssert;
8 |
9 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels;
10 |
11 | public class ExcelDataItemPanelTest
12 | {
13 | [Test]
14 | public void TestCopy()
15 | {
16 | var wb = new XLWorkbook();
17 | var ws = wb.AddWorksheet("Test");
18 | var excelReport = Substitute.For