├── .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(); 19 | var templateProcessor = Substitute.For(); 20 | 21 | var range = ws.Range(1, 1, 1, 4); 22 | 23 | var parentDataItem = new HierarchicalDataItem {Value = 1}; 24 | var dataItem = new HierarchicalDataItem {Value = "One", Parent = parentDataItem}; 25 | 26 | var panel = new ExcelDataItemPanel(range, excelReport, templateProcessor) 27 | { 28 | RenderPriority = 10, 29 | Type = PanelType.Horizontal, 30 | ShiftType = ShiftType.NoShift, 31 | BeforeRenderMethodName = "BeforeRenderMethod", 32 | AfterRenderMethodName = "AfterRenderMethod", 33 | DataItem = dataItem 34 | }; 35 | 36 | var copiedPanel = (ExcelDataItemPanel) panel.Copy(ws.Cell(5, 5)); 37 | 38 | Assert.AreSame(excelReport, 39 | copiedPanel.GetType().GetField("_report", BindingFlags.Instance | BindingFlags.NonPublic) 40 | .GetValue(copiedPanel)); 41 | Assert.AreSame(templateProcessor, 42 | copiedPanel.GetType().GetField("_templateProcessor", BindingFlags.Instance | BindingFlags.NonPublic) 43 | .GetValue(copiedPanel)); 44 | Assert.AreEqual(ws.Cell(5, 5), copiedPanel.Range.FirstCell()); 45 | Assert.AreEqual(ws.Cell(5, 8), copiedPanel.Range.LastCell()); 46 | Assert.AreEqual(10, copiedPanel.RenderPriority); 47 | Assert.AreEqual(PanelType.Horizontal, copiedPanel.Type); 48 | Assert.AreEqual(ShiftType.NoShift, copiedPanel.ShiftType); 49 | Assert.AreEqual("BeforeRenderMethod", copiedPanel.BeforeRenderMethodName); 50 | Assert.AreEqual("AfterRenderMethod", copiedPanel.AfterRenderMethodName); 51 | Assert.AreSame(dataItem, copiedPanel.DataItem); 52 | Assert.AreSame(parentDataItem, copiedPanel.DataItem.Parent); 53 | Assert.IsNull(copiedPanel.Parent); 54 | 55 | //wb.SaveAs("test.xlsx"); 56 | } 57 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/PanelRenderTests/DataSourceDynamicPanelRenderTests/DataSourceDynamicPanelEnumerableRenderTest.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels.PanelRenderTests.DataSourceDynamicPanelRenderTests; 7 | 8 | public class DataSourceDynamicPanelEnumerableRenderTest 9 | { 10 | [Test] 11 | public void TestRenderEnumerable() 12 | { 13 | var report = new TestReport(); 14 | var ws = report.Workbook.AddWorksheet("Test"); 15 | var range1 = ws.Range(2, 2, 4, 2); 16 | range1.AddToNamed("TestRange", XLScope.Worksheet); 17 | 18 | ws.Cell(2, 2).Value = "{Headers}"; 19 | ws.Cell(3, 2).Value = "{Data}"; 20 | ws.Cell(4, 2).Value = "{Totals}"; 21 | 22 | var panel = new ExcelDataSourceDynamicPanel("m:DataProvider:GetIEnumerable()", ws.DefinedName("TestRange"), 23 | report, report.TemplateProcessor); 24 | panel.Render(); 25 | 26 | Assert.AreEqual(ws.Range(2, 2, 6, 5), panel.ResultRange); 27 | 28 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook( 29 | nameof(DataSourceDynamicPanelEnumerableRenderTest), 30 | nameof(TestRenderEnumerable)), ws.Workbook); 31 | 32 | //report.Workbook.SaveAs("test.xlsx"); 33 | } 34 | 35 | [Test] 36 | public void TestRenderEmptyEnumerable() 37 | { 38 | var report = new TestReport(); 39 | var ws = report.Workbook.AddWorksheet("Test"); 40 | var range1 = ws.Range(2, 2, 4, 2); 41 | range1.AddToNamed("TestRange", XLScope.Worksheet); 42 | 43 | ws.Cell(2, 2).Value = "{Headers}"; 44 | ws.Cell(3, 2).Value = "{Data}"; 45 | ws.Cell(4, 2).Value = "{Totals}"; 46 | 47 | var panel = new ExcelDataSourceDynamicPanel("m:DataProvider:GetEmptyIEnumerable()", ws.DefinedName("TestRange"), 48 | report, report.TemplateProcessor); 49 | panel.Render(); 50 | 51 | Assert.AreEqual(ws.Range(2, 2, 3, 5), panel.ResultRange); 52 | 53 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook( 54 | nameof(DataSourceDynamicPanelEnumerableRenderTest), 55 | nameof(TestRenderEmptyEnumerable)), ws.Workbook); 56 | 57 | //report.Workbook.SaveAs("test.xlsx"); 58 | } 59 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/PanelRenderTests/DataSourceDynamicPanelRenderTests/DataSourceDynamicPanelSingleItemRenderTest.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels.PanelRenderTests.DataSourceDynamicPanelRenderTests; 7 | 8 | public class DataSourceDynamicPanelSingleItemRenderTest 9 | { 10 | [Test] 11 | public void TestRenderSingleItem() 12 | { 13 | var report = new TestReport(); 14 | var ws = report.Workbook.AddWorksheet("Test"); 15 | var range1 = ws.Range(2, 2, 4, 2); 16 | range1.AddToNamed("TestRange", XLScope.Worksheet); 17 | 18 | ws.Cell(2, 2).Value = "{Headers}"; 19 | ws.Cell(3, 2).Value = "{Data}"; 20 | ws.Cell(4, 2).Value = "{Totals}"; 21 | 22 | var panel = new ExcelDataSourceDynamicPanel("m:DataProvider:GetSingleItem()", ws.DefinedName("TestRange"), 23 | report, report.TemplateProcessor); 24 | panel.Render(); 25 | 26 | Assert.AreEqual(ws.Range(2, 2, 4, 5), panel.ResultRange); 27 | 28 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook( 29 | nameof(DataSourceDynamicPanelSingleItemRenderTest), 30 | nameof(TestRenderSingleItem)), ws.Workbook); 31 | 32 | // report.Workbook.SaveAs("test.xlsx"); 33 | } 34 | 35 | [Test] 36 | public void TestRenderNullItem() 37 | { 38 | var report = new TestReport(); 39 | var ws = report.Workbook.AddWorksheet("Test"); 40 | var range1 = ws.Range(2, 2, 4, 2); 41 | range1.AddToNamed("TestRange", XLScope.Worksheet); 42 | 43 | ws.Cell(2, 2).Value = "{Headers}"; 44 | ws.Cell(3, 2).Value = "{Data}"; 45 | ws.Cell(4, 2).Value = "{Totals}"; 46 | 47 | var panel = new ExcelDataSourceDynamicPanel("m:DataProvider:GetNullItem()", ws.DefinedName("TestRange"), report, 48 | report.TemplateProcessor); 49 | panel.Render(); 50 | 51 | Assert.IsNull(panel.ResultRange); 52 | 53 | Assert.AreEqual(0, ws.CellsUsed(XLCellsUsedOptions.Contents).Count()); 54 | } 55 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/PanelRenderTests/DataSourcePanelRenderTests/DataSourcePanelDataSetRenderTest.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels.PanelRenderTests.DataSourcePanelRenderTests; 7 | 8 | public class DataSourcePanelDataSetRenderTest 9 | { 10 | [Test] 11 | public void TestRenderDataSet() 12 | { 13 | var report = new TestReport(); 14 | var ws = report.Workbook.AddWorksheet("Test"); 15 | var range = ws.Range(2, 2, 2, 6); 16 | range.AddToNamed("TestRange", XLScope.Worksheet); 17 | 18 | ws.Cell(2, 2).Value = "{di:Id}"; 19 | ws.Cell(2, 3).Value = "{di:Name}"; 20 | ws.Cell(2, 4).Value = "{di:IsVip}"; 21 | ws.Cell(2, 5).Value = "{di:Description}"; 22 | ws.Cell(2, 6).Value = "{di:Type}"; 23 | 24 | var panel = new ExcelDataSourcePanel("m:DataProvider:GetAllCustomersDataSet()", ws.DefinedName("TestRange"), 25 | report, report.TemplateProcessor); 26 | panel.Render(); 27 | 28 | Assert.AreEqual(ws.Range(2, 2, 4, 6), panel.ResultRange); 29 | 30 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook(nameof(DataSourcePanelDataSetRenderTest), 31 | nameof(TestRenderDataSet)), ws.Workbook); 32 | 33 | //report.Workbook.SaveAs("test.xlsx"); 34 | } 35 | 36 | [Test] 37 | public void TestRenderEmptyDataSet() 38 | { 39 | var report = new TestReport(); 40 | var ws = report.Workbook.AddWorksheet("Test"); 41 | var range = ws.Range(2, 2, 2, 6); 42 | range.AddToNamed("TestRange", XLScope.Worksheet); 43 | 44 | ws.Cell(2, 2).Value = "{di:Id}"; 45 | ws.Cell(2, 3).Value = "{di:Name}"; 46 | ws.Cell(2, 4).Value = "{di:IsVip}"; 47 | ws.Cell(2, 5).Value = "{di:Description}"; 48 | ws.Cell(2, 6).Value = "{di:Type}"; 49 | 50 | var panel = new ExcelDataSourcePanel("m:DataProvider:GetEmptyDataSet()", ws.DefinedName("TestRange"), report, 51 | report.TemplateProcessor); 52 | panel.Render(); 53 | 54 | Assert.IsNull(panel.ResultRange); 55 | 56 | Assert.AreEqual(0, ws.CellsUsed(XLCellsUsedOptions.Contents).Count()); 57 | 58 | Assert.AreEqual(0, ws.DefinedNames.Count()); 59 | Assert.AreEqual(0, ws.Workbook.DefinedNames.Count()); 60 | 61 | Assert.AreEqual(1, ws.Workbook.Worksheets.Count); 62 | 63 | //report.Workbook.SaveAs("test.xlsx"); 64 | } 65 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/PanelRenderTests/DataSourcePanelRenderTests/DataSourcePanelDataTableRenderTest.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels.PanelRenderTests.DataSourcePanelRenderTests; 7 | 8 | public class DataSourcePanelDataTableRenderTest 9 | { 10 | [Test] 11 | public void TestRenderDataTable() 12 | { 13 | var report = new TestReport(); 14 | var ws = report.Workbook.AddWorksheet("Test"); 15 | var range = ws.Range(2, 2, 2, 6); 16 | range.AddToNamed("TestRange", XLScope.Worksheet); 17 | 18 | ws.Cell(2, 2).Value = "{di:Id}"; 19 | ws.Cell(2, 3).Value = "{di:Name}"; 20 | ws.Cell(2, 4).Value = "{di:IsVip}"; 21 | ws.Cell(2, 5).Value = "{di:Description}"; 22 | ws.Cell(2, 6).Value = "{di:Type}"; 23 | 24 | var panel = new ExcelDataSourcePanel("m:DataProvider:GetAllCustomersDataTable()", ws.DefinedName("TestRange"), 25 | report, report.TemplateProcessor); 26 | panel.Render(); 27 | 28 | Assert.AreEqual(ws.Range(2, 2, 4, 6), panel.ResultRange); 29 | 30 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook(nameof(DataSourcePanelDataTableRenderTest), 31 | nameof(TestRenderDataTable)), ws.Workbook); 32 | 33 | //report.Workbook.SaveAs("test.xlsx"); 34 | } 35 | 36 | [Test] 37 | public void TestRenderEmptyDataTable() 38 | { 39 | var report = new TestReport(); 40 | var ws = report.Workbook.AddWorksheet("Test"); 41 | var range = ws.Range(2, 2, 2, 6); 42 | range.AddToNamed("TestRange", XLScope.Worksheet); 43 | 44 | ws.Cell(2, 2).Value = "{di:Id}"; 45 | ws.Cell(2, 3).Value = "{di:Name}"; 46 | ws.Cell(2, 4).Value = "{di:IsVip}"; 47 | ws.Cell(2, 5).Value = "{di:Description}"; 48 | ws.Cell(2, 6).Value = "{di:Type}"; 49 | 50 | var panel = new ExcelDataSourcePanel("m:DataProvider:GetEmptyDataTable()", ws.DefinedName("TestRange"), report, 51 | report.TemplateProcessor); 52 | panel.Render(); 53 | 54 | Assert.IsNull(panel.ResultRange); 55 | 56 | Assert.AreEqual(0, ws.CellsUsed(XLCellsUsedOptions.Contents).Count()); 57 | 58 | Assert.AreEqual(0, ws.DefinedNames.Count()); 59 | Assert.AreEqual(0, ws.Workbook.DefinedNames.Count()); 60 | 61 | Assert.AreEqual(1, ws.Workbook.Worksheets.Count); 62 | 63 | //report.Workbook.SaveAs("test.xlsx"); 64 | } 65 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Panels/ExcelPanels/PanelRenderTests/DataSourcePanelRenderTests/DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Rendering.Panels.ExcelPanels; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Panels.ExcelPanels.PanelRenderTests.DataSourcePanelRenderTests; 7 | 8 | public class DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test 9 | { 10 | [Test] 11 | public void Test_VerticalPanelsGrouping_ChildEqualsParent() 12 | { 13 | var report = new TestReport(); 14 | var ws = report.Workbook.AddWorksheet("Test"); 15 | var parentRange = ws.Range(2, 2, 2, 4); 16 | parentRange.AddToNamed("ParentRange", XLScope.Worksheet); 17 | 18 | var child = ws.Range(2, 2, 2, 4); 19 | child.AddToNamed("ChildRange", XLScope.Worksheet); 20 | 21 | ws.Cell(2, 2).Value = "{di:Field1}"; 22 | ws.Cell(2, 3).Value = "{di:Field2}"; 23 | ws.Cell(2, 4).Value = "{di:parent:Sum}"; 24 | 25 | var parentPanel = new ExcelDataSourcePanel("m:DataProvider:GetIEnumerable()", ws.DefinedName("ParentRange"), 26 | report, report.TemplateProcessor); 27 | var childPanel = new ExcelDataSourcePanel("m:DataProvider:GetChildIEnumerable(di:Name)", 28 | ws.DefinedName("ChildRange"), report, report.TemplateProcessor) 29 | { 30 | Parent = parentPanel 31 | }; 32 | parentPanel.Children = new[] {childPanel}; 33 | parentPanel.Render(); 34 | 35 | Assert.AreEqual(ws.Range(2, 2, 6, 4), parentPanel.ResultRange); 36 | 37 | ExcelAssert.AreWorkbooksContentEqual(TestHelper.GetExpectedWorkbook( 38 | nameof(DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test), 39 | "Test_VerticalPanelsGrouping_ChildEqualsParent"), ws.Workbook); 40 | 41 | //report.Workbook.SaveAs("test.xlsx"); 42 | } 43 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Parsers/DefaultPanelPropertiesParserTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering; 2 | using ExcelReportGenerator.Rendering.Parsers; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Parsers; 6 | 7 | public class DefaultPanelPropertiesParserTest 8 | { 9 | [Test] 10 | public void TestParse() 11 | { 12 | var input = 13 | $"Prop1=Val1;Prop2 = Val2 {Environment.NewLine} Prop6 \t\t \t Prop4=Val4; Prop5>(); 14 | 15 | var dataTable1 = new DataTable("Table1"); 16 | var dataTable2 = new DataTable("Table2"); 17 | var dataSet = new DataSet 18 | { 19 | Tables = {dataTable1, dataTable2} 20 | }; 21 | 22 | IColumnsProvider columnsProvider = new DataSetColumnsProvider(dataTableColumnsProvider); 23 | columnsProvider.GetColumnsList(dataSet); 24 | dataTableColumnsProvider.Received(1).GetColumnsList(dataTable1); 25 | 26 | dataTableColumnsProvider.ClearReceivedCalls(); 27 | 28 | columnsProvider = new DataSetColumnsProvider(dataTableColumnsProvider, "Table2"); 29 | columnsProvider.GetColumnsList(dataSet); 30 | dataTableColumnsProvider.Received(1).GetColumnsList(dataTable2); 31 | 32 | dataTableColumnsProvider.ClearReceivedCalls(); 33 | 34 | columnsProvider = new DataSetColumnsProvider(dataTableColumnsProvider, "BadTable"); 35 | Assert.AreEqual(0, columnsProvider.GetColumnsList(dataSet).Count); 36 | dataTableColumnsProvider.DidNotReceiveWithAnyArgs().GetColumnsList(Arg.Any()); 37 | } 38 | 39 | [Test] 40 | public void TestGetColumnsListIfDataSetIsNullOrEmpty() 41 | { 42 | IColumnsProvider columnsProvider = new DataSetColumnsProvider(new DataTableColumnsProvider()); 43 | Assert.AreEqual(0, columnsProvider.GetColumnsList(null).Count); 44 | Assert.AreEqual(0, columnsProvider.GetColumnsList(new DataSet()).Count); 45 | } 46 | 47 | [Test] 48 | public void TestGetColumnsListIfDataTableColumnsProviderIsNull() 49 | { 50 | ExceptionAssert.Throws(() => new DataSetColumnsProvider(null)); 51 | } 52 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/ColumnsProvider/EnumerableColumnsProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Providers.ColumnsProvider; 7 | 8 | public class EnumerableColumnsProviderTest 9 | { 10 | [Test] 11 | public void TestGetColumnsList() 12 | { 13 | var typeColumnsProvider = Substitute.For>(); 14 | IColumnsProvider columnsProvider = new EnumerableColumnsProvider(typeColumnsProvider); 15 | 16 | columnsProvider.GetColumnsList(columnsProvider.GetColumnsList(new ArrayList 17 | {new TypeColumnsProviderTest.TestType(), "str"})); 18 | typeColumnsProvider.Received(1).GetColumnsList(typeof(TypeColumnsProviderTest.TestType)); 19 | 20 | typeColumnsProvider.ClearReceivedCalls(); 21 | 22 | columnsProvider.GetColumnsList(columnsProvider.GetColumnsList(new ArrayList 23 | {"str", new TypeColumnsProviderTest.TestType()})); 24 | typeColumnsProvider.Received(1).GetColumnsList(typeof(string)); 25 | } 26 | 27 | [Test] 28 | public void TestGetColumnsListIfEnumerableIsNullOrEmpty() 29 | { 30 | IColumnsProvider columnsProvider = new EnumerableColumnsProvider(new TypeColumnsProvider()); 31 | Assert.AreEqual(0, columnsProvider.GetColumnsList(null).Count); 32 | Assert.AreEqual(0, columnsProvider.GetColumnsList(new ArrayList()).Count); 33 | } 34 | 35 | [Test] 36 | public void TestGetColumnsListIfTypeColumnsProviderIsNull() 37 | { 38 | ExceptionAssert.Throws(() => new EnumerableColumnsProvider(null)); 39 | } 40 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/ColumnsProvider/GenericEnumerableColumnsProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | using ExcelReportGenerator.Tests.CustomAsserts; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Providers.ColumnsProvider; 6 | 7 | public class GenericEnumerableColumnsProviderTest 8 | { 9 | [Test] 10 | public void TestGetColumnsList() 11 | { 12 | var typeColumnsProvider = Substitute.For>(); 13 | 14 | IColumnsProvider columnsProvider = new GenericEnumerableColumnsProvider(typeColumnsProvider); 15 | columnsProvider.GetColumnsList(new List()); 16 | 17 | typeColumnsProvider.Received(1).GetColumnsList(typeof(TypeColumnsProviderTest.TestType)); 18 | 19 | typeColumnsProvider.ClearReceivedCalls(); 20 | 21 | columnsProvider.GetColumnsList(new string[0]); 22 | typeColumnsProvider.Received(1).GetColumnsList(typeof(string)); 23 | } 24 | 25 | [Test] 26 | public void TestGetColumnsListIfEnumerableIsNull() 27 | { 28 | IColumnsProvider columnsProvider = new GenericEnumerableColumnsProvider(new TypeColumnsProvider()); 29 | Assert.AreEqual(0, columnsProvider.GetColumnsList(null).Count); 30 | } 31 | 32 | [Test] 33 | public void TestGetColumnsListIfTypeColumnsProviderIsNull() 34 | { 35 | ExceptionAssert.Throws(() => new GenericEnumerableColumnsProvider(null)); 36 | } 37 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/ColumnsProvider/KeyValuePairColumnsProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Providers.ColumnsProvider; 7 | 8 | public class KeyValuePairColumnsProviderTest 9 | { 10 | [Test] 11 | public void TestGetColumnsList() 12 | { 13 | IColumnsProvider columnsProvider = new KeyValuePairColumnsProvider(); 14 | var columns = columnsProvider.GetColumnsList(new KeyValuePair()); 15 | 16 | Assert.AreEqual(2, columns.Count); 17 | 18 | Assert.AreEqual("Key", columns[0].Name); 19 | Assert.AreEqual("Key", columns[0].Caption); 20 | Assert.AreEqual(typeof(int), columns[0].DataType); 21 | Assert.IsNull(columns[0].Width); 22 | 23 | Assert.AreEqual("Value", columns[1].Name); 24 | Assert.AreEqual("Value", columns[1].Caption); 25 | Assert.AreEqual(typeof(string), columns[1].DataType); 26 | Assert.IsNull(columns[1].Width); 27 | 28 | columns = columnsProvider.GetColumnsList(new[] {new KeyValuePair()}); 29 | 30 | Assert.AreEqual(2, columns.Count); 31 | 32 | Assert.AreEqual("Key", columns[0].Name); 33 | Assert.AreEqual("Key", columns[0].Caption); 34 | Assert.AreEqual(typeof(Guid?), columns[0].DataType); 35 | Assert.IsNull(columns[0].Width); 36 | 37 | Assert.AreEqual("Value", columns[1].Name); 38 | Assert.AreEqual("Value", columns[1].Caption); 39 | Assert.AreEqual(typeof(decimal), columns[1].DataType); 40 | Assert.IsNull(columns[1].Width); 41 | 42 | columns = columnsProvider.GetColumnsList(null); 43 | 44 | Assert.AreEqual(2, columns.Count); 45 | 46 | Assert.AreEqual("Key", columns[0].Name); 47 | Assert.AreEqual("Key", columns[0].Caption); 48 | Assert.IsNull(columns[0].DataType); 49 | Assert.IsNull(columns[0].Width); 50 | 51 | Assert.AreEqual("Value", columns[1].Name); 52 | Assert.AreEqual("Value", columns[1].Caption); 53 | Assert.IsNull(columns[1].DataType); 54 | Assert.IsNull(columns[1].Width); 55 | 56 | ExceptionAssert.Throws(() => columnsProvider.GetColumnsList(new DataSet()), 57 | "Type of data must be KeyValuePair or IEnumerable>"); 58 | } 59 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/ColumnsProvider/ObjectColumnsProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | using ExcelReportGenerator.Tests.CustomAsserts; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Providers.ColumnsProvider; 6 | 7 | public class ObjectColumnsProviderTest 8 | { 9 | [Test] 10 | public void TestGetColumnsList() 11 | { 12 | var typeColumnsProvider = Substitute.For>(); 13 | 14 | IColumnsProvider columnsProvider = new ObjectColumnsProvider(typeColumnsProvider); 15 | var testObject = new TypeColumnsProviderTest.TestType(); 16 | columnsProvider.GetColumnsList(testObject); 17 | typeColumnsProvider.Received(1).GetColumnsList(testObject.GetType()); 18 | 19 | typeColumnsProvider.ClearReceivedCalls(); 20 | 21 | var str = "str"; 22 | columnsProvider.GetColumnsList(str); 23 | typeColumnsProvider.Received(1).GetColumnsList(str.GetType()); 24 | } 25 | 26 | [Test] 27 | public void TestGetColumnsListIfObjectIsNull() 28 | { 29 | IColumnsProvider columnsProvider = new ObjectColumnsProvider(new TypeColumnsProvider()); 30 | Assert.AreEqual(0, columnsProvider.GetColumnsList(null).Count); 31 | } 32 | 33 | [Test] 34 | public void TestGetColumnsListIfTypeColumnsProviderIsNull() 35 | { 36 | ExceptionAssert.Throws(() => new ObjectColumnsProvider(null)); 37 | } 38 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/DataItemValueProviders/DataItemValueProviderFactoryTest.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Providers.DataItemValueProviders; 6 | 7 | public class DataItemValueProviderFactoryTest 8 | { 9 | [Test] 10 | public void TestCreate() 11 | { 12 | var factory = new DataItemValueProviderFactory(); 13 | Assert.IsInstanceOf(factory.Create(null)); 14 | Assert.IsInstanceOf>(factory.Create(new Dictionary())); 15 | Assert.IsInstanceOf>(factory.Create(new Dictionary())); 16 | Assert.IsInstanceOf>(factory.Create(new Dictionary())); 17 | 18 | var dataTable = new DataTable(); 19 | dataTable.Columns.Add("Column", typeof(int)); 20 | dataTable.Rows.Add(1); 21 | Assert.IsInstanceOf(factory.Create(dataTable.Rows[0])); 22 | 23 | Assert.IsInstanceOf(factory.Create(Substitute.For())); 24 | 25 | Assert.IsInstanceOf(factory.Create(new int())); 26 | Assert.IsInstanceOf(factory.Create(new object())); 27 | Assert.IsInstanceOf(factory.Create(new Dictionary())); 28 | } 29 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/DataItemValueProviders/DataRowValueProviderTest.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Exceptions; 3 | using ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 4 | using ExcelReportGenerator.Tests.CustomAsserts; 5 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 6 | 7 | namespace ExcelReportGenerator.Tests.Rendering.Providers.DataItemValueProviders; 8 | 9 | public class DataRowValueProviderTest 10 | { 11 | [Test] 12 | public void TestGetValue() 13 | { 14 | IGenericDataItemValueProvider provider = new DataRowValueProvider(); 15 | 16 | var dataTable = new DataTable(); 17 | dataTable.Columns.Add("Column1", typeof(int)); 18 | dataTable.Columns.Add("Column2", typeof(string)); 19 | 20 | dataTable.Rows.Add(1, "One"); 21 | dataTable.Rows.Add(2, "Two"); 22 | dataTable.Rows.Add(3, "Three"); 23 | 24 | Assert.AreEqual(dataTable.Rows[0].ItemArray[0], provider.GetValue("Column1", dataTable.Rows[0])); 25 | Assert.AreEqual(dataTable.Rows[0].ItemArray[0], provider.GetValue(" Column1 ", dataTable.Rows[0])); 26 | Assert.AreEqual(dataTable.Rows[0].ItemArray[0], provider.GetValue(" column1 ", dataTable.Rows[0])); 27 | Assert.AreEqual(dataTable.Rows[0].ItemArray[1], provider.GetValue("Column2", dataTable.Rows[0])); 28 | Assert.AreEqual(dataTable.Rows[1].ItemArray[0], provider.GetValue("Column1", dataTable.Rows[1])); 29 | Assert.AreEqual(dataTable.Rows[1].ItemArray[1], provider.GetValue("Column2", dataTable.Rows[1])); 30 | Assert.AreEqual(dataTable.Rows[2].ItemArray[0], provider.GetValue("Column1", dataTable.Rows[2])); 31 | Assert.AreEqual(dataTable.Rows[2].ItemArray[1], provider.GetValue("Column2", dataTable.Rows[2])); 32 | 33 | ExceptionAssert.Throws(() => provider.GetValue("BadColumn", dataTable.Rows[0]), 34 | "DataRow does not contain column \"BadColumn\""); 35 | ExceptionAssert.Throws(() => provider.GetValue(null, dataTable.Rows[0])); 36 | ExceptionAssert.Throws(() => provider.GetValue(string.Empty, dataTable.Rows[0])); 37 | ExceptionAssert.Throws(() => provider.GetValue(" ", dataTable.Rows[0])); 38 | ExceptionAssert.Throws(() => provider.GetValue("Column1", null)); 39 | } 40 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/DataItemValueProviders/DictionaryValueProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 2 | using ExcelReportGenerator.Tests.CustomAsserts; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Providers.DataItemValueProviders; 6 | 7 | public class DictionaryValueProviderTest 8 | { 9 | [Test] 10 | public void TestGetValue() 11 | { 12 | var dict = new Dictionary 13 | { 14 | ["StrParam"] = "value1", 15 | ["IntParam"] = 5, 16 | ["BoolParam"] = true, 17 | ["GuidParam"] = Guid.NewGuid() 18 | }; 19 | 20 | var provider = new DictionaryValueProvider(); 21 | 22 | Assert.AreEqual(dict["StrParam"], provider.GetValue("StrParam", dict)); 23 | Assert.AreEqual(dict["IntParam"], provider.GetValue("IntParam", dict)); 24 | Assert.AreEqual(dict["BoolParam"], provider.GetValue("BoolParam", dict)); 25 | Assert.AreEqual(dict["GuidParam"], provider.GetValue("GuidParam", dict)); 26 | 27 | ExceptionAssert.Throws(() => provider.GetValue(null, dict)); 28 | ExceptionAssert.Throws(() => provider.GetValue(" StrParam ", dict), 29 | "Key \" StrParam \" was not found in dictionary"); 30 | ExceptionAssert.Throws(() => provider.GetValue("strParam", dict), 31 | "Key \"strParam\" was not found in dictionary"); 32 | ExceptionAssert.Throws(() => provider.GetValue("BadParam", dict), 33 | "Key \"BadParam\" was not found in dictionary"); 34 | } 35 | 36 | [Test] 37 | public void TestGetValueIfDictionaryHasDecimalValues() 38 | { 39 | var dict = new Dictionary 40 | { 41 | ["Key1"] = 27.67m, 42 | ["Key2"] = 64m 43 | }; 44 | 45 | var provider = new DictionaryValueProvider(); 46 | 47 | Assert.AreEqual(dict["Key1"], provider.GetValue("Key1", dict)); 48 | Assert.AreEqual(dict["Key2"], provider.GetValue("Key2", dict)); 49 | } 50 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/DataItemValueProviders/ObjectPropertyValueProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Providers.DataItemValueProviders; 7 | 8 | public class ObjectPropertyValueProviderTest 9 | { 10 | [Test] 11 | public void TestGetValue() 12 | { 13 | var reflectionHelper = Substitute.For(); 14 | IDataItemValueProvider dataItemValueProvider = new ObjectPropertyValueProvider(reflectionHelper); 15 | var date = DateTime.Now; 16 | 17 | dataItemValueProvider.GetValue("StrProp", date); 18 | reflectionHelper.Received(1).GetValueOfPropertiesChain("StrProp", date); 19 | 20 | dataItemValueProvider.GetValue(" StrProp ", date); 21 | reflectionHelper.Received(2).GetValueOfPropertiesChain("StrProp", date); 22 | 23 | dataItemValueProvider.GetValue("ObjProp.StrProp", date); 24 | reflectionHelper.Received(1).GetValueOfPropertiesChain("ObjProp.StrProp", date); 25 | 26 | dataItemValueProvider.GetValue("ObjProp.ObjProp.GuidProp", date); 27 | reflectionHelper.Received(1).GetValueOfPropertiesChain("ObjProp.ObjProp.GuidProp", date); 28 | 29 | ExceptionAssert.Throws(() => dataItemValueProvider.GetValue(null, date)); 30 | ExceptionAssert.Throws(() => dataItemValueProvider.GetValue(string.Empty, date)); 31 | ExceptionAssert.Throws(() => dataItemValueProvider.GetValue(" ", date)); 32 | } 33 | 34 | [Test] 35 | public void TestGetValueFromKeyValuePair() 36 | { 37 | IDataItemValueProvider dataItemValueProvider = new ObjectPropertyValueProvider(); 38 | var dataItem = new KeyValuePair("key", "val"); 39 | Assert.AreEqual(dataItem.Key, dataItemValueProvider.GetValue("Key", dataItem)); 40 | Assert.AreEqual(dataItem.Value, dataItemValueProvider.GetValue(" Value ", dataItem)); 41 | } 42 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/DefaultInstanceProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering.Providers; 2 | using ExcelReportGenerator.Tests.CustomAsserts; 3 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 4 | 5 | namespace ExcelReportGenerator.Tests.Rendering.Providers; 6 | 7 | public class DefaultInstanceProviderTest 8 | { 9 | [Test] 10 | public void TestGetInstance() 11 | { 12 | IInstanceProvider instanceProvider = new DefaultInstanceProvider(); 13 | ExceptionAssert.Throws(() => instanceProvider.GetInstance(null), 14 | "Type is not specified but defaultInstance is null"); 15 | 16 | var instance1 = (TestType_3) instanceProvider.GetInstance(typeof(TestType_3)); 17 | var instance2 = (TestType_3) instanceProvider.GetInstance(typeof(TestType_3)); 18 | var instance3 = instanceProvider.GetInstance(); 19 | Assert.AreSame(instance1, instance2); 20 | Assert.AreSame(instance1, instance3); 21 | Assert.AreSame(instance2, instance3); 22 | 23 | Assert.IsInstanceOf(instanceProvider.GetInstance(typeof(TestType_5))); 24 | Assert.IsInstanceOf(instanceProvider.GetInstance(typeof(DateTime))); 25 | 26 | ExceptionAssert.Throws(() => instanceProvider.GetInstance(typeof(FileInfo))); 27 | ExceptionAssert.Throws(() => instanceProvider.GetInstance(typeof(Math))); 28 | 29 | var testInstance = new TestType_3(); 30 | instanceProvider = new DefaultInstanceProvider(testInstance); 31 | 32 | instance3 = (TestType_3) instanceProvider.GetInstance(null); 33 | instance1 = (TestType_3) instanceProvider.GetInstance(typeof(TestType_3)); 34 | instance2 = instanceProvider.GetInstance(); 35 | Assert.AreSame(instance1, instance2); 36 | Assert.AreSame(instance1, instance3); 37 | Assert.AreSame(instance2, instance3); 38 | } 39 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/Rendering/Providers/VariableProviders/DefaultVariableProviderTest.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Exceptions; 2 | using ExcelReportGenerator.Rendering.Providers.VariableProviders; 3 | using ExcelReportGenerator.Tests.CustomAsserts; 4 | using Assert = NUnit.Framework.Legacy.ClassicAssert; 5 | 6 | namespace ExcelReportGenerator.Tests.Rendering.Providers.VariableProviders; 7 | 8 | public class DefaultVariableProviderTest 9 | { 10 | [Test] 11 | public void TestGetVariable() 12 | { 13 | SystemVariableProvider variableProvider = new CustomVariableProvider 14 | { 15 | RenderDate = new DateTime(2018, 1, 1), 16 | CustomProp = 999, 17 | SheetName = "Sheet", 18 | SheetNumber = 3 19 | }; 20 | 21 | Assert.AreEqual(new DateTime(2018, 1, 1), variableProvider.GetVariable("RenderDate")); 22 | Assert.AreEqual(999, variableProvider.GetVariable("CustomProp")); 23 | Assert.AreEqual("Sheet", variableProvider.GetVariable("SheetName")); 24 | Assert.AreEqual(3, variableProvider.GetVariable("SheetNumber")); 25 | ExceptionAssert.Throws(() => variableProvider.GetVariable("BadVariable"), 26 | $"Cannot find variable with name \"BadVariable\" in class {typeof(CustomVariableProvider).Name} and all its parents. Variable must be public instance property."); 27 | 28 | ExceptionAssert.Throws(() => variableProvider.GetVariable(null)); 29 | ExceptionAssert.Throws(() => variableProvider.GetVariable(string.Empty)); 30 | ExceptionAssert.Throws(() => variableProvider.GetVariable(" ")); 31 | } 32 | 33 | private class CustomVariableProvider : SystemVariableProvider 34 | { 35 | public new string SheetName { get; set; } 36 | 37 | public int CustomProp { get; set; } 38 | } 39 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderDataReader.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderDataReader.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderDataReader_HorizontalPanel.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderDataReader_HorizontalPanel.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderEmptyDataReader.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataReaderRenderTest/TestRenderEmptyDataReader.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestDynamicPanelAfterRenderEvent.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestDynamicPanelAfterRenderEvent.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderDataSetWithEvents.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderDataSetWithEvents.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderDataSetWithEvents_HorizontalPanel.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderDataSetWithEvents_HorizontalPanel.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderEmptyDataSet.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataSetRenderTest/TestRenderEmptyDataSet.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataTableRenderTest/TestRenderDataTable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataTableRenderTest/TestRenderDataTable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataTableRenderTest/TestRenderEmptyDataTable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDataTableRenderTest/TestRenderEmptyDataTable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDictionaryRenderTest/TestRenderDictionary.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDictionaryRenderTest/TestRenderDictionary.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDictionaryRenderTest/TestRenderDictionaryEnumerable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelDictionaryRenderTest/TestRenderDictionaryEnumerable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelEnumerableRenderTest/TestRenderEmptyEnumerable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelEnumerableRenderTest/TestRenderEmptyEnumerable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelEnumerableRenderTest/TestRenderEnumerable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelEnumerableRenderTest/TestRenderEnumerable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelSingleItemRenderTest/TestRenderSingleItem.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanelSingleItemRenderTest/TestRenderSingleItem.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanel_InsideDataSourcePanel_Test/TestRender_DynamicPanel_In_DataSourcePanel_Horizontal.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanel_InsideDataSourcePanel_Test/TestRender_DynamicPanel_In_DataSourcePanel_Horizontal.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanel_InsideDataSourcePanel_Test/TestRender_DynamicPanel_In_DataSourcePanel_Vertical.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourceDynamicPanel_InsideDataSourcePanel_Test/TestRender_DynamicPanel_In_DataSourcePanel_Vertical.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelDataReaderRenderTest/TestRenderDataReader.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelDataReaderRenderTest/TestRenderDataReader.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelDataSetRenderTest/TestRenderDataSet.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelDataSetRenderTest/TestRenderDataSet.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelDataTableRenderTest/TestRenderDataTable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelDataTableRenderTest/TestRenderDataTable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelDictionaryRenderTest/TestRenderDictionary.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelDictionaryRenderTest/TestRenderDictionary.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelDictionaryRenderTest/TestRenderDictionaryEnumerable.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelDictionaryRenderTest/TestRenderDictionaryEnumerable.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalRowsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableHorizontalRowsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalRowsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelEmptyIEnumerableRenderTest/TestRenderEmptyIEnumerableVerticalRowsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestPanelRenderEvents.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestPanelRenderEvents.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalRowsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableHorizontalRowsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableOfInt.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableOfInt.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableOfString.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableOfString.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalRowsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelIEnumerableRenderTest/TestRenderIEnumerableVerticalRowsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemHorizontalRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelNullItemRenderTest/TestRenderNullItemVerticalRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test/Test_VerticalPanelsGrouping_ChildEqualsParent.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_ChildEqualsParent_Test/Test_VerticalPanelsGrouping_ChildEqualsParent.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithRichText.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentCellsShiftChildCellsShift_WithRichText.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentNoShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentNoShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildLeft_Test/ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentCellsShiftChildCellsShift_WithFictitiousColumnWhichDeleteAfterRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentNoShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentNoShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentNoShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildCellsShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_HorizontalPanels_ChildRight_Test/ParentRowShiftChildRowShift_WithFictitiousColumn.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestHorizontalInVerticalPanelsGrouping.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestHorizontalInVerticalPanelsGrouping.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestMultipleHorizontalPanelsGrouping.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestMultipleHorizontalPanelsGrouping.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestMultipleVerticalPanelsGrouping.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestMultipleVerticalPanelsGrouping.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestVerticalInHorizontalPanelsGrouping.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MixedPanels_Test/TestVerticalInHorizontalPanelsGrouping.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent/Test_TwoChildren_Horizontal.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent/Test_TwoChildren_Horizontal.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent/Test_TwoChildren_Vertical.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_MultipleChildrenInOneParent/Test_TwoChildren_Vertical.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_PageBreaks_Test/Test_HorizontalPageBreaks.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_PageBreaks_Test/Test_HorizontalPageBreaks.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_PageBreaks_Test/Test_VerticalPageBreaks.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_PageBreaks_Test/Test_VerticalPageBreaks.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentCellsShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentNoShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentNoShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentNoShiftChildRowShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentNoShiftChildRowShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildCellsShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildCellsShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildRowShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildBottom_Test/ParentRowShiftChildRowShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildCellsShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildRowShift_WithFictitiousRow.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentCellsShiftChildRowShift_WithFictitiousRow.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentNoShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentNoShiftChildCellsShift_WithFictitiousRowWhichDeleteAfterRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentNoShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentNoShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentRowShiftChildCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentRowShiftChildCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentRowShiftChildRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelRender_WithGrouping_VerticalPanels_ChildTop_Test/ParentRowShiftChildRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemHorizontalRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalCellsShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalCellsShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalNoShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalNoShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalRowShift.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DataSourcePanelSingleItemRenderTest/TestRenderSingleItemVerticalRowShift.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderPartialWorksheets.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderPartialWorksheets.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderWithCustomVariableAndFunctionProviders.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderWithCustomVariableAndFunctionProviders.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderWithEvents.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/DefaultReportGeneratorTest/TestRenderWithEvents.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultHorizontal.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultHorizontal.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultHorizontal_WithoutGroupingBlankValues.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultHorizontal_WithoutGroupingBlankValues.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultVertical.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultVertical.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultVertical_WithoutGroupingBlankValues.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestGroupResultVertical_WithoutGroupingBlankValues.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestIfGroupByPropertyIsEmpty.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/ExcelDataSourcePanelTest/TestIfGroupByPropertyIsEmpty.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/PanelRenderTest/TestSimplePanelExpansion.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/PanelRenderTest/TestSimplePanelExpansion.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/SystemFunctionsTest/TestFormatOnRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/SystemFunctionsTest/TestFormatOnRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelRender.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelRender.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelRenderWithParentContext.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelRenderWithParentContext.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelWithNoData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelWithNoData.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelWithNullData.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestData/TotalsPanelRenderTest/TestPanelWithNullData.xlsx -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestDb.mdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestDb.mdf -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestDb_log.ldf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/traf72/excel-report-generator/4a3c0646dfbfebbb117d06997f1ba7d57eba8752/ExcelReportGenerator.Tests/TestDb_log.ldf -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/TestHelper.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Tests; 4 | 5 | public static class TestHelper 6 | { 7 | public static XLWorkbook GetExpectedWorkbook(string testClassName, string testMethod) 8 | { 9 | return new XLWorkbook(Path.Combine("TestData", testClassName, $"{testMethod}.xlsx")); 10 | } 11 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.Tests/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "TestDb": "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=%DBPATH%\\TestDb.mdf;Integrated Security=True;Connect Timeout=30" 4 | } 5 | } -------------------------------------------------------------------------------- /ExcelReportGenerator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2037 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelReportGenerator", "ExcelReportGenerator\ExcelReportGenerator.csproj", "{1C802C04-06DE-433D-B79E-1179F1D931C0}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelReportGenerator.Tests", "ExcelReportGenerator.Tests\ExcelReportGenerator.Tests.csproj", "{49759C4A-2CB5-4672-BD36-C4138B7DA076}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelReportGenerator.Samples", "ExcelReportGenerator.Samples\ExcelReportGenerator.Samples.csproj", "{803B2AA5-96FC-4B3F-A6B2-4E22DEF83A77}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {1C802C04-06DE-433D-B79E-1179F1D931C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {1C802C04-06DE-433D-B79E-1179F1D931C0}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {1C802C04-06DE-433D-B79E-1179F1D931C0}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {1C802C04-06DE-433D-B79E-1179F1D931C0}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {49759C4A-2CB5-4672-BD36-C4138B7DA076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {49759C4A-2CB5-4672-BD36-C4138B7DA076}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {49759C4A-2CB5-4672-BD36-C4138B7DA076}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {49759C4A-2CB5-4672-BD36-C4138B7DA076}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {803B2AA5-96FC-4B3F-A6B2-4E22DEF83A77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {803B2AA5-96FC-4B3F-A6B2-4E22DEF83A77}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {803B2AA5-96FC-4B3F-A6B2-4E22DEF83A77}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {803B2AA5-96FC-4B3F-A6B2-4E22DEF83A77}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {3E4E5340-53DF-4704-8631-31C68BC24D92} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /ExcelReportGenerator/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("ExcelReportGenerator.Tests")] 4 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] -------------------------------------------------------------------------------- /ExcelReportGenerator/Attributes/ExcelColumnAttribute.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Enums; 2 | 3 | namespace ExcelReportGenerator.Attributes; 4 | 5 | /// 6 | /// An attribute that allows you to configure excel column output more flexibly 7 | /// 8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 9 | public class ExcelColumnAttribute : Attribute 10 | { 11 | public ExcelColumnAttribute() 12 | { 13 | AggregateFunction = AggregateFunction.NoAggregation; 14 | } 15 | 16 | /// 17 | /// Column caption which will be displayed in excel sheet 18 | /// 19 | public string Caption { get; set; } 20 | 21 | /// 22 | /// Column width if panel is vertical or row height if panel is horizontal 23 | /// 24 | public double Width { get; set; } 25 | 26 | /// 27 | /// Aggregate function applied to this column 28 | /// 29 | public AggregateFunction AggregateFunction { get; set; } 30 | 31 | /// 32 | /// Do not apply an aggregate function even it is specified 33 | /// 34 | public bool NoAggregate { get; set; } 35 | 36 | /// 37 | /// Display format for number and date columns 38 | /// 39 | public string DisplayFormat { get; set; } 40 | 41 | /// 42 | /// Do not apply display format even it is specified 43 | /// 44 | public bool IgnoreDisplayFormat { get; set; } 45 | 46 | /// 47 | /// Adjust to content column width if panel is vertical or row height if panel is horizontal 48 | /// 49 | public bool AdjustToContent { get; set; } 50 | 51 | /// 52 | /// Order in which the column appears in Excel 53 | /// 54 | public int Order { get; set; } 55 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Attributes/ExternalPropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Attributes; 2 | 3 | /// 4 | /// Marks panel property which can be populated from excel 5 | /// 6 | [AttributeUsage(AttributeTargets.Property)] 7 | internal class ExternalPropertyAttribute : Attribute 8 | { 9 | public Type Converter { get; set; } 10 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Attributes/NoExcelColumnAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Attributes; 2 | 3 | /// 4 | /// An attribute that allows you to mark property as no excel column 5 | /// 6 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 7 | public class NoExcelColumnAttribute : Attribute 8 | { 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Attributes/NullValueAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Attributes; 2 | 3 | /// 4 | /// An attribute that allows you to replace null-values to more readable 5 | /// 6 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 7 | public class NullValueAttribute : Attribute 8 | { 9 | public NullValueAttribute(object value) 10 | { 11 | Value = value; 12 | } 13 | 14 | /// 15 | /// The value that will be write to Excel if original value is null 16 | /// 17 | public object Value { get; } 18 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator; 2 | 3 | internal static class Constants 4 | { 5 | public const string InvalidTemplateMessage = "Template \"{0}\" is invalid"; 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/ExternalPropertiesConverters/IExternalPropertyConverter.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Converters.ExternalPropertiesConverters; 2 | 3 | internal interface IExternalPropertyConverter : IGenericConverter 4 | { 5 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/ExternalPropertiesConverters/PanelTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Enums; 2 | using ExcelReportGenerator.Helpers; 3 | 4 | namespace ExcelReportGenerator.Converters.ExternalPropertiesConverters; 5 | 6 | internal class PanelTypeConverter : IExternalPropertyConverter 7 | { 8 | public PanelType Convert(string panelType) 9 | { 10 | if (string.IsNullOrWhiteSpace(panelType)) 11 | { 12 | throw new ArgumentException("Type property cannot be null or empty"); 13 | } 14 | 15 | try 16 | { 17 | return EnumHelper.Parse(panelType.Trim()); 18 | } 19 | catch (ArgumentException e) 20 | { 21 | throw new ArgumentException($"Value \"{panelType}\" is invalid for Type property", e); 22 | } 23 | } 24 | 25 | object IConverter.Convert(object input) 26 | { 27 | return Convert((string)input); 28 | } 29 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/ExternalPropertiesConverters/RenderPriorityConverter.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Converters.ExternalPropertiesConverters; 2 | 3 | internal class RenderPriorityConverter : IExternalPropertyConverter 4 | { 5 | public int Convert(string input) 6 | { 7 | if (string.IsNullOrWhiteSpace(input)) 8 | { 9 | throw new ArgumentException("RenderPriority property cannot be null or empty"); 10 | } 11 | 12 | if (int.TryParse(input, out int renderPriority)) 13 | { 14 | return renderPriority; 15 | } 16 | 17 | throw new ArgumentException($"Cannot convert value \"{input}\" to int"); 18 | } 19 | 20 | object IConverter.Convert(object input) 21 | { 22 | return Convert((string)input); 23 | } 24 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/ExternalPropertiesConverters/ShiftTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Enums; 2 | using ExcelReportGenerator.Helpers; 3 | 4 | namespace ExcelReportGenerator.Converters.ExternalPropertiesConverters; 5 | 6 | internal class ShiftTypeConverter : IExternalPropertyConverter 7 | { 8 | public ShiftType Convert(string shiftType) 9 | { 10 | if (string.IsNullOrWhiteSpace(shiftType)) 11 | { 12 | throw new ArgumentException("ShiftType property cannot be null or empty"); 13 | } 14 | 15 | try 16 | { 17 | return EnumHelper.Parse(shiftType.Trim()); 18 | } 19 | catch (ArgumentException e) 20 | { 21 | throw new ArgumentException($"Value \"{shiftType}\" is invalid for ShiftType property", e); 22 | } 23 | } 24 | 25 | object IConverter.Convert(object input) 26 | { 27 | return Convert((string)input); 28 | } 29 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/IConverter.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Converters; 2 | 3 | internal interface IConverter 4 | { 5 | object Convert(object input); 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Converters/IGenericConverter.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Converters; 2 | 3 | internal interface IGenericConverter : IConverter 4 | { 5 | TOut Convert(TIn input); 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/DataReaderEnumerator.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Collections; 3 | using System.Data; 4 | 5 | namespace ExcelReportGenerator.Enumerators; 6 | 7 | internal class DataReaderEnumerator : IGenericCustomEnumerator 8 | { 9 | private readonly IGenericCustomEnumerator _dataTableEnumerator; 10 | 11 | public DataReaderEnumerator(IDataReader dataReader) 12 | { 13 | if (dataReader == null) 14 | { 15 | throw new ArgumentNullException(nameof(dataReader), ArgumentHelper.NullParamMessage); 16 | } 17 | 18 | var dataTable = new DataTable(); 19 | dataTable.Load(dataReader); 20 | dataReader.Dispose(); 21 | _dataTableEnumerator = new DataTableEnumerator(dataTable); 22 | } 23 | 24 | public DataRow Current => _dataTableEnumerator.Current; 25 | 26 | object IEnumerator.Current => Current; 27 | 28 | public bool MoveNext() => _dataTableEnumerator.MoveNext(); 29 | 30 | public void Reset() => _dataTableEnumerator.Reset(); 31 | 32 | public int RowCount => _dataTableEnumerator.RowCount; 33 | 34 | public void Dispose() => _dataTableEnumerator.Dispose(); 35 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/DataSetEnumerator.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Collections; 3 | using System.Data; 4 | 5 | namespace ExcelReportGenerator.Enumerators; 6 | 7 | internal class DataSetEnumerator : IGenericCustomEnumerator 8 | { 9 | private readonly IGenericCustomEnumerator _dataTableEnumerator; 10 | 11 | public DataSetEnumerator(DataSet dataSet, string tableName = null) 12 | { 13 | if (dataSet == null) 14 | { 15 | throw new ArgumentNullException(nameof(dataSet), ArgumentHelper.NullParamMessage); 16 | } 17 | if (dataSet.Tables.Count == 0) 18 | { 19 | throw new InvalidOperationException("DataSet does not contain any table"); 20 | } 21 | 22 | DataTable dataTable; 23 | if (!string.IsNullOrWhiteSpace(tableName)) 24 | { 25 | dataTable = dataSet.Tables[tableName]; 26 | if (dataTable == null) 27 | { 28 | throw new InvalidOperationException($"DataSet does not contain table with name \"{tableName}\""); 29 | } 30 | } 31 | else 32 | { 33 | dataTable = dataSet.Tables[0]; 34 | } 35 | 36 | _dataTableEnumerator = new DataTableEnumerator(dataTable); 37 | } 38 | 39 | public DataRow Current => _dataTableEnumerator.Current; 40 | 41 | object IEnumerator.Current => Current; 42 | 43 | public bool MoveNext() => _dataTableEnumerator.MoveNext(); 44 | 45 | public void Reset() => _dataTableEnumerator.Reset(); 46 | 47 | public int RowCount => _dataTableEnumerator.RowCount; 48 | 49 | public void Dispose() => _dataTableEnumerator.Dispose(); 50 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/DataTableEnumerator.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Collections; 3 | using System.Data; 4 | 5 | namespace ExcelReportGenerator.Enumerators; 6 | 7 | internal class DataTableEnumerator : IGenericCustomEnumerator 8 | { 9 | private readonly DataTable _dataTable; 10 | 11 | private IEnumerator _dataTableEnumerator; 12 | 13 | public DataTableEnumerator(DataTable dataTable) 14 | { 15 | _dataTable = dataTable ?? throw new ArgumentNullException(nameof(dataTable), ArgumentHelper.NullParamMessage); 16 | _dataTableEnumerator = _dataTable.AsEnumerable().GetEnumerator(); 17 | } 18 | 19 | public DataRow Current => _dataTableEnumerator.Current; 20 | 21 | object IEnumerator.Current => Current; 22 | 23 | public bool MoveNext() => _dataTableEnumerator.MoveNext(); 24 | 25 | public void Reset() => _dataTableEnumerator = _dataTable.AsEnumerable().GetEnumerator(); 26 | 27 | public int RowCount => _dataTable.Rows.Count; 28 | 29 | public void Dispose() => _dataTableEnumerator.Dispose(); 30 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/EnumerableEnumerator.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Collections; 3 | 4 | namespace ExcelReportGenerator.Enumerators; 5 | 6 | internal class EnumerableEnumerator : ICustomEnumerator 7 | { 8 | private readonly IEnumerable _enumerable; 9 | private IEnumerator _enumerator; 10 | 11 | private int? _rowCount; 12 | 13 | public EnumerableEnumerator(IEnumerable enumerable) 14 | { 15 | _enumerable = enumerable ?? throw new ArgumentNullException(nameof(enumerable), ArgumentHelper.NullParamMessage); 16 | _enumerator = enumerable.GetEnumerator(); 17 | } 18 | 19 | public bool MoveNext() => _enumerator.MoveNext(); 20 | 21 | public void Reset() 22 | { 23 | try 24 | { 25 | _enumerator.Reset(); 26 | } 27 | catch (Exception e) when (e is NotSupportedException || e is NotImplementedException) 28 | { 29 | _enumerator = _enumerable.GetEnumerator(); 30 | } 31 | } 32 | 33 | public object Current => _enumerator.Current; 34 | 35 | public int RowCount 36 | { 37 | get 38 | { 39 | if (!_rowCount.HasValue) 40 | { 41 | if (_enumerable is ICollection collection) 42 | { 43 | _rowCount = collection.Count; 44 | } 45 | else 46 | { 47 | Type enumerableType = _enumerable.GetType(); 48 | Type genericCollectionInterface = TypeHelper.TryGetGenericCollectionInterface(enumerableType); 49 | if (genericCollectionInterface != null) 50 | { 51 | _rowCount = (int)enumerableType.GetProperty(nameof(ICollection.Count)).GetValue(_enumerable, null); 52 | } 53 | else 54 | { 55 | int itemsCount = 0; 56 | foreach (object _ in _enumerable) 57 | { 58 | itemsCount++; 59 | } 60 | _rowCount = itemsCount; 61 | } 62 | } 63 | } 64 | 65 | return _rowCount.Value; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/EnumeratorFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Data; 3 | 4 | namespace ExcelReportGenerator.Enumerators; 5 | 6 | internal static class EnumeratorFactory 7 | { 8 | public static ICustomEnumerator Create(object instance) 9 | { 10 | return instance switch 11 | { 12 | null => null, 13 | IDataReader dr => new DataReaderEnumerator(dr), 14 | DataTable dt => new DataTableEnumerator(dt), 15 | DataSet ds => new DataSetEnumerator(ds), 16 | IEnumerable e => new EnumerableEnumerator(e), 17 | _ => new EnumerableEnumerator(new[] {instance}) 18 | }; 19 | } 20 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/ICustomenumerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | 3 | namespace ExcelReportGenerator.Enumerators; 4 | 5 | internal interface ICustomEnumerator : IEnumerator 6 | { 7 | int RowCount { get; } 8 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enumerators/IGenericCustomEnumerator.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Enumerators; 2 | 3 | internal interface IGenericCustomEnumerator : ICustomEnumerator, IEnumerator 4 | { 5 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enums/AggregateFunction.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Enums; 2 | 3 | /// 4 | /// Built-in aggregate functions 5 | /// 6 | public enum AggregateFunction 7 | { 8 | Sum, 9 | Count, 10 | Avg, 11 | Max, 12 | Min, 13 | Custom, 14 | NoAggregation, 15 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enums/Direction.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Enums; 2 | 3 | internal enum Direction 4 | { 5 | Bottom, 6 | Right, 7 | Top, 8 | Left, 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enums/PanelType.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Enums; 2 | 3 | internal enum PanelType 4 | { 5 | Vertical, 6 | Horizontal, 7 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Enums/ShiftType.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Enums; 2 | 3 | internal enum ShiftType 4 | { 5 | Cells, 6 | Row, 7 | NoShift, 8 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Excel/AddressShift.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Excel; 2 | 3 | internal struct AddressShift 4 | { 5 | public AddressShift(int rowCount, int colCount) 6 | { 7 | RowCount = rowCount; 8 | ColCount = colCount; 9 | } 10 | 11 | public int RowCount { get; } 12 | 13 | public int ColCount { get; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Excel/CellCoords.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Excel; 2 | 3 | internal struct CellCoords 4 | { 5 | public CellCoords(int rowNum, int colNum) 6 | { 7 | RowNum = rowNum; 8 | ColNum = colNum; 9 | } 10 | 11 | public int RowNum { get; } 12 | 13 | public int ColNum { get; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Excel/RangeCoords.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Excel; 2 | 3 | internal struct RangeCoords 4 | { 5 | public RangeCoords(CellCoords firstCell, CellCoords lastCell) 6 | { 7 | FirstCell = firstCell; 8 | LastCell = lastCell; 9 | } 10 | 11 | public CellCoords FirstCell { get; } 12 | 13 | public CellCoords LastCell { get; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/ExcelReportGenerator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | latest 6 | enable 7 | Traf 8 | 9 | The library ExcelReportGenerator allows you to render data to Microsoft Excel by marking Excel sheets using panels and templates. It makes it easy to connect to various data sources like IDataReader, DataSet, DataTable, IEnumerable<T> and others and to render data from them to Excel. You can also apply aggregation, various types of grouping, formatting and so on to the data. More detailed documentation you can find inside the project repository. 10 | Copyright © Traf 2025 11 | 2.3.0 12 | 2.3.0 13 | excel report reports reporting xlsx closedxml spreadsheet workbook worksheet generator export openxml export-excel export-to-excel export-xlsx export-to-xlsx 14 | true 15 | 2.3.0 16 | https://github.com/traf72/excel-report-generator/releases/tag/2.3.0 17 | https://github.com/traf72/excel-report-generator 18 | 2.3.0 19 | MIT 20 | git 21 | https://github.com/traf72/excel-report-generator 22 | README.md 23 | 24 | 25 | 26 | 27 | bin\ExcelReportGenerator.xml 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | NETCORE;NETSTANDARD;NETSTANDARD2_0 39 | 40 | 41 | -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/ColumnNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class ColumnNotFoundException : Exception 4 | { 5 | public ColumnNotFoundException(string message) : base(message) 6 | { 7 | } 8 | 9 | public ColumnNotFoundException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/InvalidTemplateException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class InvalidTemplateException : Exception 4 | { 5 | public InvalidTemplateException(string message) : base(message) 6 | { 7 | } 8 | 9 | public InvalidTemplateException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/InvalidVariableException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class InvalidVariableException : Exception 4 | { 5 | public InvalidVariableException(string message) : base(message) 6 | { 7 | } 8 | 9 | public InvalidVariableException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/MemberNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class MemberNotFoundException : Exception 4 | { 5 | public MemberNotFoundException(string message) : base(message) 6 | { 7 | } 8 | 9 | public MemberNotFoundException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/MethodNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class MethodNotFoundException : Exception 4 | { 5 | public MethodNotFoundException(string message) : base(message) 6 | { 7 | } 8 | 9 | public MethodNotFoundException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Exceptions/TypeNotFoundException.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Exceptions; 2 | 3 | public class TypeNotFoundException : Exception 4 | { 5 | public TypeNotFoundException(string message) : base(message) 6 | { 7 | } 8 | 9 | public TypeNotFoundException(string message, Exception innerException) : base(message, innerException) 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Extensions/DataReaderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace ExcelReportGenerator.Extensions; 4 | 5 | internal static class DataReaderExtensions 6 | { 7 | public static object SafeGetValue(this IDataReader reader, int columnIndex) 8 | { 9 | return !reader.IsDBNull(columnIndex) ? reader.GetValue(columnIndex) : null; 10 | } 11 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Extensions/ParameterInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace ExcelReportGenerator.Extensions; 4 | 5 | internal static class ParameterInfoExtensions 6 | { 7 | public static bool IsParams(this ParameterInfo parameter) 8 | { 9 | return parameter.IsDefined(typeof(ParamArrayAttribute), false); 10 | } 11 | 12 | // Support .NET 4.0 13 | public static bool HasDefaultValue(this ParameterInfo parameter) 14 | { 15 | return parameter.DefaultValue != DBNull.Value; 16 | } 17 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Extensions; 2 | 3 | internal static class StringExtensions 4 | { 5 | public static string ReplaceFirst(this string input, string oldValue, string newValue) 6 | { 7 | if (input == null) 8 | { 9 | return null; 10 | } 11 | 12 | int pos = input.IndexOf(oldValue, StringComparison.CurrentCulture); 13 | if (pos < 0) 14 | { 15 | return input; 16 | } 17 | return input.Substring(0, pos) + newValue + input.Substring(pos + oldValue.Length); 18 | } 19 | 20 | public static string Reverse(this string input) 21 | { 22 | if (input == null) 23 | { 24 | return null; 25 | } 26 | 27 | int inputLength = input.Length; 28 | char[] inputChars = input.ToCharArray(); 29 | char[] result = new char[inputLength]; 30 | for (int i = 0; i < result.Length; i++) 31 | { 32 | result[i] = inputChars[inputLength - (i + 1)]; 33 | } 34 | return string.Join(string.Empty, result); 35 | } 36 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Extensions/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Extensions; 2 | 3 | internal static class TypeExtensions 4 | { 5 | private static readonly Type[] _numericTypes = { 6 | typeof(byte), typeof(ushort), typeof(uint), typeof(ulong), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal), 7 | typeof(byte?), typeof(ushort?), typeof(uint?), typeof(ulong?), typeof(sbyte?), typeof(short?), typeof(int?), typeof(long?), typeof(float?), typeof(double?), typeof(decimal?) 8 | }; 9 | 10 | private static readonly Type[] _extendedPrimitiveTypes; 11 | 12 | static TypeExtensions() 13 | { 14 | _extendedPrimitiveTypes = _numericTypes.Concat(new[] 15 | { 16 | typeof(char), typeof(bool), typeof(string), typeof(Guid), typeof(DateTime), 17 | typeof(char?), typeof(bool?), typeof(Guid?), typeof(DateTime?) 18 | }).ToArray(); 19 | } 20 | 21 | public static bool IsNumeric(this Type type) 22 | { 23 | return _numericTypes.Contains(type); 24 | } 25 | 26 | public static bool IsExtendedPrimitive(this Type type) 27 | { 28 | return _extendedPrimitiveTypes.Contains(type); 29 | } 30 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Extensions/XLRangeBaseExtensions.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Extensions; 4 | 5 | internal static class XLRangeBaseExtensions 6 | { 7 | public static IXLCells CellsUsedWithoutFormulas(this IXLRangeBase range) 8 | { 9 | return range.CellsUsed(c => !c.HasFormula); 10 | } 11 | 12 | public static IXLCells CellsUsedWithoutFormulas(this IXLRangeBase range, Func predicate) 13 | { 14 | return range.CellsUsed(c => predicate(c) && !c.HasFormula); 15 | } 16 | 17 | public static IXLCells CellsUsedWithoutFormulas(this IXLRangeBase range, XLCellsUsedOptions options) 18 | { 19 | return range.CellsUsed(options, c => !c.HasFormula); 20 | } 21 | 22 | public static IXLCells CellsUsedWithoutFormulas(this IXLRangeBase range, XLCellsUsedOptions options, Func predicate) 23 | { 24 | return range.CellsUsed(options, c => predicate(c) && !c.HasFormula); 25 | } 26 | 27 | public static IXLCells CellsWithoutFormulas(this IXLRangeBase range) 28 | { 29 | return range.Cells(c => !c.HasFormula); 30 | } 31 | 32 | public static IXLCells CellsWithoutFormulas(this IXLRangeBase range, Func predicate) 33 | { 34 | return range.Cells(c => predicate(c) && !c.HasFormula); 35 | } 36 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Helpers/ArgumentHelper.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Helpers; 2 | 3 | internal static class ArgumentHelper 4 | { 5 | public const string NullParamMessage = "Parameter cannot be null"; 6 | 7 | public const string EmptyStringParamMessage = "Parameter cannot be null or empty"; 8 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Helpers/EnumHelper.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Helpers; 2 | 3 | internal static class EnumHelper 4 | { 5 | public static TEnum Parse(string value, bool ignoreCase = true) where TEnum : struct, IConvertible 6 | { 7 | return (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); 8 | } 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Helpers/IReflectionHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace ExcelReportGenerator.Helpers; 4 | 5 | internal interface IReflectionHelper 6 | { 7 | object GetValueOfPropertiesChain(string propertiesChain, object instance, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public); 8 | 9 | PropertyInfo GetProperty(Type type, string propertyName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public); 10 | 11 | PropertyInfo TryGetProperty(Type type, string propertyName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public); 12 | 13 | FieldInfo GetField(Type type, string fieldName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public); 14 | 15 | FieldInfo TryGetField(Type type, string fieldName, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public); 16 | 17 | object GetNullValueAttributeValue(MemberInfo member); 18 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Helpers/RegexHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace ExcelReportGenerator.Helpers; 4 | 5 | internal static class RegexHelper 6 | { 7 | public static string SafeEscape(string value) 8 | { 9 | return value == null ? null : Regex.Escape(value); 10 | } 11 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataItemPanelBeforeRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data item panel before render event 5 | /// 6 | public class DataItemPanelBeforeRenderEventArgs : PanelBeforeRenderEventArgs 7 | { 8 | /// 9 | /// Hierarchical data item 10 | /// 11 | public HierarchicalDataItem DataItem { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataItemPanelEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data item panel event 5 | /// 6 | public class DataItemPanelEventArgs : PanelEventArgs 7 | { 8 | /// 9 | /// Hierarchical data item 10 | /// 11 | public HierarchicalDataItem DataItem { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataSourceDynamicPanelBeforeRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data source dynamic panel before render event 5 | /// 6 | public class DataSourceDynamicPanelBeforeRenderEventArgs : DataSourcePanelBeforeRenderEventArgs 7 | { 8 | /// 9 | /// Data source dynamic panel columns 10 | /// 11 | public IList Columns { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataSourceDynamicPanelEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data source dynamic panel event 5 | /// 6 | public class DataSourceDynamicPanelEventArgs : DataSourcePanelEventArgs 7 | { 8 | /// 9 | /// Data source dynamic panel columns 10 | /// 11 | public IList Columns { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataSourcePanelBeforeRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data source panel before render event 5 | /// 6 | public class DataSourcePanelBeforeRenderEventArgs : PanelBeforeRenderEventArgs 7 | { 8 | /// 9 | /// Data source panel data 10 | /// 11 | public object Data { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/DataSourcePanelEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of data source panel event 5 | /// 6 | public class DataSourcePanelEventArgs : PanelEventArgs 7 | { 8 | /// 9 | /// Data source panel data 10 | /// 11 | public object Data { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/PanelBeforeRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.EventArgs; 2 | 3 | /// 4 | /// Represent arguments of panel before render event 5 | /// 6 | public class PanelBeforeRenderEventArgs : PanelEventArgs 7 | { 8 | /// 9 | /// Is rendering canceled 10 | /// 11 | public bool IsCanceled { get; set; } 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/PanelEventArgs.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Rendering.EventArgs; 4 | 5 | /// 6 | /// Represent arguments of panel event 7 | /// 8 | public class PanelEventArgs : System.EventArgs 9 | { 10 | /// 11 | /// Excel range 12 | /// 13 | public IXLRange Range { get; set; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/ReportRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Rendering.EventArgs; 4 | 5 | /// 6 | /// Represent arguments of report render event 7 | /// 8 | public class ReportRenderEventArgs : System.EventArgs 9 | { 10 | /// 11 | /// Excel workbook 12 | /// 13 | public XLWorkbook Workbook { get; set; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/EventArgs/WorksheetRenderEventArgs.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Rendering.EventArgs; 4 | 5 | /// 6 | /// Represent arguments of worksheet render event 7 | /// 8 | public class WorksheetRenderEventArgs : System.EventArgs 9 | { 10 | /// 11 | /// Excel worksheet 12 | /// 13 | public IXLWorksheet Worksheet { get; set; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/ExcelDynamicColumn.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Enums; 2 | 3 | namespace ExcelReportGenerator.Rendering; 4 | 5 | /// 6 | /// Describes excel dynamic column 7 | /// 8 | public class ExcelDynamicColumn 9 | { 10 | private string _caption; 11 | 12 | public ExcelDynamicColumn(string name, Type dataType = null, string caption = null) 13 | { 14 | Name = name; 15 | DataType = dataType; 16 | Caption = caption; 17 | AggregateFunction = AggregateFunction.NoAggregation; 18 | if (dataType == typeof(decimal) || dataType == typeof(decimal?)) 19 | { 20 | AggregateFunction = AggregateFunction.Sum; 21 | DisplayFormat = "#,0.00"; 22 | } 23 | } 24 | 25 | /// 26 | /// Column name from data source 27 | /// 28 | public string Name { get; } 29 | 30 | /// 31 | /// Column caption which will be displayed in excel sheet 32 | /// 33 | public string Caption 34 | { 35 | get => string.IsNullOrWhiteSpace(_caption) ? Name : _caption; 36 | private set => _caption = value; 37 | } 38 | 39 | /// 40 | /// Column width if panel is vertical or row height if panel is horizontal 41 | /// 42 | public double? Width { get; set; } 43 | 44 | /// 45 | /// Column data type 46 | /// 47 | public Type DataType { get; } 48 | 49 | /// 50 | /// Aggregate function applied to this column 51 | /// 52 | public AggregateFunction AggregateFunction { get; set; } 53 | 54 | /// 55 | /// Display format for number and date columns 56 | /// 57 | public string DisplayFormat { get; set; } 58 | 59 | /// 60 | /// Adjust to content column width if panel is vertical or row height if panel is horizontal 61 | /// 62 | public bool AdjustToContent { get; set; } 63 | 64 | // Order in which the column appears in Excel (for internal use) 65 | internal int Order { get; set; } 66 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/HierarchicalDataItem.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering; 2 | 3 | /// 4 | /// Type that represent hierarchical data item 5 | /// 6 | public class HierarchicalDataItem 7 | { 8 | public object Value { get; set; } 9 | 10 | public HierarchicalDataItem Parent { get; set; } 11 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/PanelParsingSettings.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering; 2 | 3 | /// 4 | /// Allow to configure panel parsing settings 5 | /// 6 | public class PanelParsingSettings 7 | { 8 | /// 9 | /// Separator between panel type prefix and panel name 10 | /// Cannot be null, empty string or whitespace 11 | /// 12 | /// For "s_panel" panel name the separator is "_" 13 | public string PanelPrefixSeparator { get; set; } 14 | 15 | /// 16 | /// Prefix for simple panel 17 | /// Cannot be null, empty string or whitespace 18 | /// 19 | /// For "s_header" panel name the prefix is "s" 20 | public string SimplePanelPrefix { get; set; } 21 | 22 | /// 23 | /// Prefix for data source panel 24 | /// Cannot be null, empty string or whitespace 25 | /// 26 | /// For "d_data" panel name the prefix is "d" 27 | public string DataSourcePanelPrefix { get; set; } 28 | 29 | /// 30 | /// Prefix for dynamic panel 31 | /// Cannot be null, empty string or whitespace 32 | /// 33 | /// For "dyn_data" panel name the prefix is "dyn" 34 | public string DynamicDataSourcePanelPrefix { get; set; } 35 | 36 | /// 37 | /// Prefix for totals panel 38 | /// Cannot be null, empty string or whitespace 39 | /// 40 | /// For "t_data" panel name the prefix is "t" 41 | public string TotalsPanelPrefix { get; set; } 42 | 43 | /// 44 | /// Separator between different panel properties. Allow to specify multiple separators 45 | /// Cannot be null or empty array 46 | /// 47 | public string[] PanelPropertiesSeparators { get; set; } 48 | 49 | /// 50 | /// Separator between panel property name and value 51 | /// Cannot be null, empty string or whitespace 52 | /// 53 | public string PanelPropertyNameValueSeparator { get; set; } 54 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/ExcelPanels/ExcelDataItemPanel.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Excel; 3 | using ExcelReportGenerator.Rendering.EventArgs; 4 | using ExcelReportGenerator.Rendering.TemplateProcessors; 5 | 6 | namespace ExcelReportGenerator.Rendering.Panels.ExcelPanels; 7 | 8 | internal class ExcelDataItemPanel : ExcelPanel, IDataItemPanel 9 | { 10 | public ExcelDataItemPanel(IXLRange range, object report, ITemplateProcessor templateProcessor) 11 | : base(range, report, templateProcessor) 12 | { 13 | } 14 | 15 | public HierarchicalDataItem DataItem { get; set; } 16 | 17 | protected override HierarchicalDataItem GetDataContext() 18 | { 19 | return DataItem; 20 | } 21 | 22 | protected override PanelBeforeRenderEventArgs GetBeforePanelRenderEventArgs() 23 | { 24 | return new DataItemPanelBeforeRenderEventArgs { Range = Range, DataItem = DataItem }; 25 | } 26 | 27 | protected override PanelEventArgs GetAfterPanelRenderEventArgs() 28 | { 29 | return new DataItemPanelEventArgs { Range = ResultRange, DataItem = DataItem }; 30 | } 31 | 32 | protected override IExcelPanel CopyPanel(IXLCell cell) 33 | { 34 | IXLRange newRange = ExcelHelper.CopyRange(Range, cell); 35 | var panel = new ExcelDataItemPanel(newRange, _report, _templateProcessor); 36 | FillCopyProperties(panel); 37 | return panel; 38 | } 39 | 40 | protected override void FillCopyProperties(IExcelPanel panel) 41 | { 42 | var dataItemPanel = panel as ExcelDataItemPanel; 43 | dataItemPanel.DataItem = DataItem; 44 | base.FillCopyProperties(panel); 45 | } 46 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/ExcelPanels/IExcelNamedPanel.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | 3 | namespace ExcelReportGenerator.Rendering.Panels.ExcelPanels; 4 | 5 | internal interface IExcelNamedPanel : INamedPanel, IExcelPanel 6 | { 7 | IExcelNamedPanel Copy(IXLCell cell, string name, bool recursive = true); 8 | 9 | void RemoveName(bool recursive = false); 10 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/ExcelPanels/IExcelPanel.cs: -------------------------------------------------------------------------------- 1 | using ClosedXML.Excel; 2 | using ExcelReportGenerator.Enums; 3 | 4 | namespace ExcelReportGenerator.Rendering.Panels.ExcelPanels; 5 | 6 | internal interface IExcelPanel : IPanel 7 | { 8 | IExcelPanel Parent { get; set; } 9 | 10 | IList Children { get; set; } 11 | 12 | IXLRange Range { get; } 13 | 14 | IXLRange ResultRange { get; } 15 | 16 | ShiftType ShiftType { get; set; } 17 | 18 | PanelType Type { get; set; } 19 | 20 | int RenderPriority { get; set; } 21 | 22 | void Render(); 23 | 24 | IExcelPanel Copy(IXLCell cell, bool recursive = true); 25 | 26 | void Move(IXLCell cell); 27 | 28 | internal void RecalculateRangeRelativeParentRecursive(); 29 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/IDataItemPanel.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Panels; 2 | 3 | internal interface IDataItemPanel : IPanel 4 | { 5 | HierarchicalDataItem DataItem { get; set; } 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/INamedPanel.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Panels; 2 | 3 | internal interface INamedPanel : IPanel 4 | { 5 | string Name { get; } 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Panels/IPanel.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Panels; 2 | 3 | internal interface IPanel 4 | { 5 | void Delete(); 6 | 7 | string BeforeRenderMethodName { get; set; } 8 | 9 | string AfterRenderMethodName { get; set; } 10 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Parsers/DefaultPanelPropertiesParser.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Parsers; 2 | 3 | internal class DefaultPanelPropertiesParser : IPanelPropertiesParser 4 | { 5 | private readonly PanelParsingSettings _panelParsingSettings; 6 | 7 | public DefaultPanelPropertiesParser(PanelParsingSettings panelParsingSettings) 8 | { 9 | _panelParsingSettings = panelParsingSettings; 10 | } 11 | 12 | public IDictionary Parse(string input) 13 | { 14 | IDictionary result = new Dictionary(); 15 | if (string.IsNullOrWhiteSpace(input)) 16 | { 17 | return result; 18 | } 19 | 20 | string[] props = input.Split(_panelParsingSettings.PanelPropertiesSeparators, StringSplitOptions.RemoveEmptyEntries); 21 | foreach (string prop in props) 22 | { 23 | int propNameSeparatorIndex = prop.IndexOf(_panelParsingSettings.PanelPropertyNameValueSeparator, StringComparison.Ordinal); 24 | if (propNameSeparatorIndex == -1) 25 | { 26 | continue; 27 | } 28 | 29 | string name = prop.Substring(0, propNameSeparatorIndex).Trim(); 30 | string value = prop.Substring(propNameSeparatorIndex + _panelParsingSettings.PanelPropertyNameValueSeparator.Length).Trim(); 31 | result[name] = value; 32 | } 33 | 34 | return result; 35 | } 36 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Parsers/IPanelPropertiesParser.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Parsers; 2 | 3 | internal interface IPanelPropertiesParser 4 | { 5 | IDictionary Parse(string input); 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/ColumnsProviderFactory.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Collections; 3 | using System.Data; 4 | 5 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 6 | 7 | internal class ColumnsProviderFactory : IColumnsProviderFactory 8 | { 9 | public virtual IColumnsProvider Create(object data) 10 | { 11 | switch (data) 12 | { 13 | case null: 14 | return null; 15 | 16 | case IDataReader _: 17 | return new DataReaderColumnsProvider(); 18 | 19 | case DataTable _: 20 | return new DataTableColumnsProvider(); 21 | 22 | case DataSet _: 23 | return new DataSetColumnsProvider(new DataTableColumnsProvider()); 24 | } 25 | 26 | Type dataType = data.GetType(); 27 | if (TypeHelper.IsKeyValuePair(dataType)) 28 | { 29 | return new KeyValuePairColumnsProvider(); 30 | } 31 | 32 | Type genericEnumerable = TypeHelper.TryGetGenericEnumerableInterface(dataType); 33 | if (genericEnumerable != null) 34 | { 35 | Type genericType = genericEnumerable.GetGenericArguments()[0]; 36 | if (TypeHelper.IsKeyValuePair(genericType)) 37 | { 38 | return new KeyValuePairColumnsProvider(); 39 | } 40 | if (TypeHelper.IsDictionaryStringObject(genericType)) 41 | { 42 | // If data type is dictionary and type of key is String and type of value is not Object 43 | Type dictionaryValueProviderRawType = typeof(DictionaryColumnsProvider<>); 44 | Type dictionary = TypeHelper.TryGetGenericDictionaryInterface(genericType); 45 | Type dictionaryValueProviderGenericType = dictionaryValueProviderRawType.MakeGenericType(dictionary.GetGenericArguments()[1]); 46 | return (IColumnsProvider)Activator.CreateInstance(dictionaryValueProviderGenericType); 47 | } 48 | return new GenericEnumerableColumnsProvider(new TypeColumnsProvider()); 49 | } 50 | 51 | if (data is IEnumerable) 52 | { 53 | return new EnumerableColumnsProvider(new TypeColumnsProvider()); 54 | } 55 | 56 | return new ObjectColumnsProvider(new TypeColumnsProvider()); 57 | } 58 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/DataReaderColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 4 | 5 | /// 6 | /// Provides columns info from IDataReader 7 | /// 8 | internal class DataReaderColumnsProvider : IGenericColumnsProvider 9 | { 10 | public IList GetColumnsList(IDataReader reader) 11 | { 12 | DataTable schemaTable = reader?.GetSchemaTable(); 13 | if (schemaTable == null) 14 | { 15 | return new List(); 16 | } 17 | 18 | return schemaTable.Rows 19 | .Cast() 20 | .Select(r => new ExcelDynamicColumn((string)r["ColumnName"], (Type)r["DataType"])) 21 | .ToList(); 22 | } 23 | 24 | IList IColumnsProvider.GetColumnsList(object reader) 25 | { 26 | return GetColumnsList((IDataReader)reader); 27 | } 28 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/DataSetColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Helpers; 3 | 4 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 5 | 6 | /// 7 | /// Provides columns info from DataSet 8 | /// 9 | internal class DataSetColumnsProvider : IGenericColumnsProvider 10 | { 11 | private readonly IGenericColumnsProvider _dataTableColumnsProvider; 12 | private readonly string _tableName; 13 | 14 | public DataSetColumnsProvider(IGenericColumnsProvider dataTableColumnsProvider, string tableName = null) 15 | { 16 | _dataTableColumnsProvider = dataTableColumnsProvider ?? throw new ArgumentNullException(nameof(dataTableColumnsProvider), ArgumentHelper.NullParamMessage); 17 | _tableName = tableName; 18 | } 19 | 20 | public IList GetColumnsList(DataSet dataSet) 21 | { 22 | if (dataSet == null || dataSet.Tables.Count == 0) 23 | { 24 | return new List(); 25 | } 26 | 27 | if (string.IsNullOrWhiteSpace(_tableName)) 28 | { 29 | return _dataTableColumnsProvider.GetColumnsList(dataSet.Tables[0]); 30 | } 31 | 32 | DataTable table = dataSet.Tables[_tableName]; 33 | return table == null ? new List() : _dataTableColumnsProvider.GetColumnsList(table); 34 | } 35 | 36 | IList IColumnsProvider.GetColumnsList(object dataSet) 37 | { 38 | return GetColumnsList((DataSet)dataSet); 39 | } 40 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/DataTableColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 4 | 5 | /// 6 | /// Provides columns info from DataTable 7 | /// 8 | internal class DataTableColumnsProvider : IGenericColumnsProvider 9 | { 10 | public IList GetColumnsList(DataTable dataTable) 11 | { 12 | if (dataTable == null) 13 | { 14 | return new List(); 15 | } 16 | 17 | return dataTable.Columns 18 | .Cast() 19 | .Select(column => new ExcelDynamicColumn(column.ColumnName, column.DataType, column.Caption)) 20 | .ToList(); 21 | } 22 | 23 | IList IColumnsProvider.GetColumnsList(object dataTable) 24 | { 25 | return GetColumnsList((DataTable)dataTable); 26 | } 27 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/DictionaryColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | 3 | /// 4 | /// Provides columns info from collection of IDictionary 5 | /// 6 | internal class DictionaryColumnsProvider : IGenericColumnsProvider>> 7 | { 8 | public IList GetColumnsList(IEnumerable> data) 9 | { 10 | IDictionary firstElement = data?.FirstOrDefault(); 11 | if (firstElement == null) 12 | { 13 | return new List(); 14 | } 15 | 16 | IList result = new List(); 17 | foreach (KeyValuePair pair in firstElement) 18 | { 19 | result.Add(new ExcelDynamicColumn(pair.Key, pair.Value?.GetType())); 20 | } 21 | 22 | return result; 23 | } 24 | 25 | IList IColumnsProvider.GetColumnsList(object data) 26 | { 27 | return GetColumnsList((IEnumerable>)data); 28 | } 29 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/EnumerableColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using ExcelReportGenerator.Helpers; 3 | 4 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 5 | 6 | /// 7 | /// Provides columns info from not generic enumerable 8 | /// 9 | internal class EnumerableColumnsProvider : IGenericColumnsProvider 10 | { 11 | private readonly IGenericColumnsProvider _typeColumnsProvider; 12 | 13 | public EnumerableColumnsProvider(IGenericColumnsProvider typeColumnsProvider) 14 | { 15 | _typeColumnsProvider = typeColumnsProvider ?? throw new ArgumentNullException(nameof(typeColumnsProvider), ArgumentHelper.NullParamMessage); 16 | } 17 | 18 | public IList GetColumnsList(IEnumerable data) 19 | { 20 | object firstElement = data?.Cast().FirstOrDefault(); 21 | if (firstElement == null) 22 | { 23 | return new List(); 24 | } 25 | 26 | return _typeColumnsProvider.GetColumnsList(firstElement.GetType()); 27 | } 28 | 29 | IList IColumnsProvider.GetColumnsList(object data) 30 | { 31 | return GetColumnsList((IEnumerable)data); 32 | } 33 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/GenericEnumerableColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 4 | 5 | /// 6 | /// Provides columns info from generic enumerable 7 | /// 8 | internal class GenericEnumerableColumnsProvider : IGenericColumnsProvider> 9 | { 10 | private readonly IGenericColumnsProvider _typeColumnsProvider; 11 | 12 | public GenericEnumerableColumnsProvider(IGenericColumnsProvider typeColumnsProvider) 13 | { 14 | _typeColumnsProvider = typeColumnsProvider ?? throw new ArgumentNullException(nameof(typeColumnsProvider), ArgumentHelper.NullParamMessage); 15 | } 16 | 17 | public IList GetColumnsList(IEnumerable data) 18 | { 19 | if (data == null) 20 | { 21 | return new List(); 22 | } 23 | 24 | Type genericEnumerable = TypeHelper.TryGetGenericEnumerableInterface(data.GetType()); 25 | return _typeColumnsProvider.GetColumnsList(genericEnumerable.GetGenericArguments()[0]); 26 | } 27 | 28 | IList IColumnsProvider.GetColumnsList(object data) 29 | { 30 | return GetColumnsList((IEnumerable)data); 31 | } 32 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/IColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | 3 | internal interface IColumnsProvider 4 | { 5 | /// 6 | /// Provides columns info based on data 7 | /// 8 | IList GetColumnsList(object data); 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/IColumnsProviderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | 3 | internal interface IColumnsProviderFactory 4 | { 5 | /// 6 | /// Create appropriate column provider based on data 7 | /// 8 | IColumnsProvider Create(object data); 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/IGenericColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 2 | 3 | internal interface IGenericColumnsProvider : IColumnsProvider 4 | { 5 | IList GetColumnsList(T data); 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/KeyValuePairColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 4 | 5 | /// 6 | /// Provides columns info from KeyValuePair 7 | /// 8 | internal class KeyValuePairColumnsProvider : IColumnsProvider 9 | { 10 | public IList GetColumnsList(object data) 11 | { 12 | Type[] genericArgs; 13 | 14 | if (data == null) 15 | { 16 | genericArgs = new Type[2]; 17 | } 18 | else 19 | { 20 | Type dataType = data.GetType(); 21 | if (TypeHelper.IsKeyValuePair(dataType)) 22 | { 23 | genericArgs = dataType.GetGenericArguments(); 24 | } 25 | else 26 | { 27 | Type genericEnumerable = TypeHelper.TryGetGenericEnumerableInterface(dataType); 28 | if (genericEnumerable != null) 29 | { 30 | genericArgs = genericEnumerable.GetGenericArguments()[0].GetGenericArguments(); 31 | } 32 | else 33 | { 34 | throw new InvalidOperationException("Type of data must be KeyValuePair or IEnumerable>"); 35 | } 36 | } 37 | } 38 | 39 | return new List 40 | { 41 | new("Key", genericArgs[0]), 42 | new("Value", genericArgs[1]), 43 | }; 44 | } 45 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ColumnsProviders/ObjectColumnsProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.ColumnsProviders; 4 | 5 | /// 6 | /// Provides columns info from any object 7 | /// 8 | internal class ObjectColumnsProvider : IColumnsProvider 9 | { 10 | private readonly IGenericColumnsProvider _typeColumnsProvider; 11 | 12 | public ObjectColumnsProvider(IGenericColumnsProvider typeColumnsProvider) 13 | { 14 | _typeColumnsProvider = typeColumnsProvider ?? throw new ArgumentNullException(nameof(typeColumnsProvider), ArgumentHelper.NullParamMessage); 15 | } 16 | 17 | public IList GetColumnsList(object dataItem) 18 | { 19 | return dataItem == null 20 | ? new List() 21 | : _typeColumnsProvider.GetColumnsList(dataItem.GetType()); 22 | } 23 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/DataItemValueProviderFactory.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | using System.Data; 3 | 4 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 5 | 6 | internal class DataItemValueProviderFactory : IDataItemValueProviderFactory 7 | { 8 | public virtual IDataItemValueProvider Create(object data) 9 | { 10 | switch (data) 11 | { 12 | case null: 13 | return new ObjectPropertyValueProvider(); 14 | 15 | case DataRow _: 16 | return new DataRowValueProvider(); 17 | 18 | case IDataReader _: 19 | return new DataReaderValueProvider(); 20 | 21 | case IDictionary _: 22 | return new DictionaryValueProvider(); 23 | } 24 | 25 | Type dataType = data.GetType(); 26 | if (TypeHelper.IsDictionaryStringObject(dataType)) 27 | { 28 | // If data type is dictionary and type of key is String and type of value is not Object 29 | Type dictionaryValueProviderRawType = typeof(DictionaryValueProvider<>); 30 | Type dictionary = TypeHelper.TryGetGenericDictionaryInterface(dataType); 31 | Type dictionaryValueProviderGenericType = dictionaryValueProviderRawType.MakeGenericType(dictionary.GetGenericArguments()[1]); 32 | return (IDataItemValueProvider)Activator.CreateInstance(dictionaryValueProviderGenericType); 33 | } 34 | 35 | return new ObjectPropertyValueProvider(); 36 | } 37 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/DataReaderValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Exceptions; 3 | using ExcelReportGenerator.Extensions; 4 | using ExcelReportGenerator.Helpers; 5 | 6 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 7 | 8 | /// 9 | /// Provides values from data reader 10 | /// 11 | internal class DataReaderValueProvider : IGenericDataItemValueProvider 12 | { 13 | private string _columnName; 14 | private IDataReader _dataReader; 15 | 16 | /// 17 | /// Returns value from specified column of data reader 18 | /// 19 | public virtual object GetValue(string columnName, IDataReader dataReader) 20 | { 21 | if (string.IsNullOrWhiteSpace(columnName)) 22 | { 23 | throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(columnName)); 24 | } 25 | if (dataReader == null) 26 | { 27 | throw new ArgumentNullException(nameof(dataReader), ArgumentHelper.NullParamMessage); 28 | } 29 | if (dataReader.IsClosed) 30 | { 31 | throw new InvalidOperationException("DataReader is closed"); 32 | } 33 | 34 | _columnName = columnName.Trim(); 35 | _dataReader = dataReader; 36 | 37 | return dataReader.SafeGetValue(GetColumnIndex()); 38 | } 39 | 40 | private int GetColumnIndex() 41 | { 42 | int colIndex = -1; 43 | try 44 | { 45 | colIndex = _dataReader.GetOrdinal(_columnName); 46 | } 47 | catch (IndexOutOfRangeException e) 48 | { 49 | ThrowColumnNotFoundException(e); 50 | } 51 | 52 | if (colIndex == -1) 53 | { 54 | ThrowColumnNotFoundException(); 55 | } 56 | return colIndex; 57 | } 58 | 59 | private void ThrowColumnNotFoundException(Exception innerException = null) 60 | { 61 | throw new ColumnNotFoundException($"DataReader does not contain column \"{_columnName}\"", innerException); 62 | } 63 | 64 | object IDataItemValueProvider.GetValue(string columnName, object dataReader) 65 | { 66 | return GetValue(columnName, (IDataReader)dataReader); 67 | } 68 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/DataRowValueProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using ExcelReportGenerator.Exceptions; 3 | using ExcelReportGenerator.Helpers; 4 | 5 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 6 | 7 | /// 8 | /// Provides values from data row 9 | /// 10 | internal class DataRowValueProvider : IGenericDataItemValueProvider 11 | { 12 | private string _columnName; 13 | private DataRow _dataRow; 14 | 15 | /// 16 | /// Returns value from specified column of data row 17 | /// 18 | public virtual object GetValue(string columnName, DataRow dataRow) 19 | { 20 | if (string.IsNullOrWhiteSpace(columnName)) 21 | { 22 | throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(columnName)); 23 | } 24 | 25 | _dataRow = dataRow ?? throw new ArgumentNullException(nameof(dataRow), ArgumentHelper.NullParamMessage); 26 | _columnName = columnName.Trim(); 27 | return dataRow.ItemArray[GetColumnIndex()]; 28 | } 29 | 30 | private int GetColumnIndex() 31 | { 32 | DataColumn column = _dataRow.Table.Columns[_columnName]; 33 | if (column == null) 34 | { 35 | throw new ColumnNotFoundException($"DataRow does not contain column \"{_columnName}\""); 36 | } 37 | return column.Ordinal; 38 | } 39 | 40 | object IDataItemValueProvider.GetValue(string columnName, object dataRow) 41 | { 42 | return GetValue(columnName, (DataRow)dataRow); 43 | } 44 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/DictionaryValueProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 4 | 5 | /// 6 | /// Provides values from dictionary 7 | /// 8 | internal class DictionaryValueProvider : IGenericDataItemValueProvider> 9 | { 10 | public object GetValue(string key, IDictionary dataItem) 11 | { 12 | if (string.IsNullOrWhiteSpace(key)) 13 | { 14 | throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(key)); 15 | } 16 | 17 | if (dataItem.TryGetValue(key, out TValue value)) 18 | { 19 | return value; 20 | } 21 | throw new KeyNotFoundException($"Key \"{key}\" was not found in dictionary"); 22 | } 23 | 24 | public object GetValue(string key, object dataItem) 25 | { 26 | return GetValue(key, (IDictionary)dataItem); 27 | } 28 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/IDataItemValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 2 | 3 | /// 4 | /// Provides values for data item templates 5 | /// 6 | public interface IDataItemValueProvider 7 | { 8 | /// 9 | /// Get value from based on 10 | /// 11 | object GetValue(string template, object dataItem); 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/IDataItemValueProviderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 2 | 3 | internal interface IDataItemValueProviderFactory 4 | { 5 | IDataItemValueProvider Create(object data); 6 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/IGenericDataItemValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 2 | 3 | /// See 4 | /// Type of data item 5 | public interface IGenericDataItemValueProvider : IDataItemValueProvider 6 | { 7 | /// See 8 | object GetValue(string template, T dataItem); 9 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DataItemValueProviders/ObjectPropertyValueProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Helpers; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers.DataItemValueProviders; 4 | 5 | /// 6 | /// Provides properties values from object instance 7 | /// 8 | internal class ObjectPropertyValueProvider : IDataItemValueProvider 9 | { 10 | private readonly IReflectionHelper _reflectionHelper; 11 | 12 | public ObjectPropertyValueProvider() : this(new ReflectionHelper()) 13 | { 14 | } 15 | 16 | internal ObjectPropertyValueProvider(IReflectionHelper reflectionHelper) 17 | { 18 | _reflectionHelper = reflectionHelper; 19 | } 20 | 21 | /// 22 | /// Returns property value from data item object 23 | /// 24 | public virtual object GetValue(string propTemplate, object dataItem) 25 | { 26 | if (string.IsNullOrWhiteSpace(propTemplate)) 27 | { 28 | throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(propTemplate)); 29 | } 30 | 31 | return _reflectionHelper.GetValueOfPropertiesChain(propTemplate.Trim(), dataItem); 32 | } 33 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/DefaultInstanceProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers; 2 | 3 | /// 4 | /// Default implementation of 5 | /// 6 | public class DefaultInstanceProvider : IInstanceProvider 7 | { 8 | private readonly IDictionary _instanceCache = new Dictionary(); 9 | 10 | /// Instance which will be returned if the type is not specified explicitly 11 | public DefaultInstanceProvider(object defaultInstance = null) 12 | { 13 | DefaultInstance = defaultInstance; 14 | if (DefaultInstance != null) 15 | { 16 | _instanceCache[DefaultInstance.GetType()] = DefaultInstance; 17 | } 18 | } 19 | 20 | /// 21 | /// Return instance if the type is not specified explicitly 22 | /// 23 | protected object DefaultInstance { get; } 24 | 25 | /// 26 | /// 27 | /// Provides instance of specified as singleton. Type must have a default constructor. 28 | /// 29 | /// 30 | public virtual object GetInstance(Type type) 31 | { 32 | if (type == null) 33 | { 34 | return DefaultInstance ?? throw new InvalidOperationException("Type is not specified but defaultInstance is null"); 35 | } 36 | 37 | if (_instanceCache.TryGetValue(type, out object instance)) 38 | { 39 | return instance; 40 | } 41 | 42 | instance = Activator.CreateInstance(type); 43 | _instanceCache[type] = instance; 44 | return instance; 45 | } 46 | 47 | /// 48 | /// 49 | /// Provides instance of type as singleton. Type must have a default constructor. 50 | /// 51 | /// 52 | public virtual T GetInstance() 53 | { 54 | return (T)GetInstance(typeof(T)); 55 | } 56 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/IInstanceProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers; 2 | 3 | /// 4 | /// Provides instances for templates 5 | /// 6 | public interface IInstanceProvider 7 | { 8 | /// 9 | /// Provides instance of specified 10 | /// 11 | object GetInstance(Type type); 12 | 13 | /// 14 | /// Provides instance of specified 15 | /// 16 | T GetInstance(); 17 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/IMethodCallValueProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Rendering.TemplateProcessors; 2 | 3 | namespace ExcelReportGenerator.Rendering.Providers; 4 | 5 | /// 6 | /// Provides results for methods invocation templates 7 | /// 8 | public interface IMethodCallValueProvider 9 | { 10 | /// 11 | /// Call method by template 12 | /// 13 | /// Template processor that will be used for parameters specified as templates 14 | /// Data item that will be used for parameters specified as data item templates 15 | /// Method call result 16 | object CallMethod(string methodCallTemplate, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem); 17 | 18 | /// 19 | /// Call method by template 20 | /// 21 | /// Concrete type where method will be searched 22 | /// Template processor that will be used for parameters specified as templates 23 | /// Data item that will be used for parameters specified as data item templates 24 | /// Method call result 25 | object CallMethod(string methodCallTemplate, Type concreteType, ITemplateProcessor templateProcessor, HierarchicalDataItem dataItem); 26 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/IPropertyValueProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers; 2 | 3 | /// 4 | /// Provides values for properties templates 5 | /// 6 | public interface IPropertyValueProvider 7 | { 8 | /// 9 | /// Provides property value based on 10 | /// 11 | object GetValue(string propertyTemplate); 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/ITypeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.Providers; 2 | 3 | /// 4 | /// Provides types for templates 5 | /// 6 | public interface ITypeProvider 7 | { 8 | /// 9 | /// Provides type based on 10 | /// 11 | Type GetType(string typeTemplate); 12 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/Providers/VariableProviders/SystemVariableProvider.cs: -------------------------------------------------------------------------------- 1 | using ExcelReportGenerator.Exceptions; 2 | using ExcelReportGenerator.Helpers; 3 | using System.Reflection; 4 | 5 | namespace ExcelReportGenerator.Rendering.Providers.VariableProviders; 6 | 7 | /// 8 | /// Provides values for system variable templates 9 | /// 10 | public class SystemVariableProvider 11 | { 12 | private readonly IReflectionHelper _reflectionHelper; 13 | 14 | public SystemVariableProvider() : this(new ReflectionHelper()) 15 | { 16 | } 17 | 18 | internal SystemVariableProvider(IReflectionHelper reflectionHelper) 19 | { 20 | _reflectionHelper = reflectionHelper; 21 | } 22 | 23 | /// 24 | /// Report render date 25 | /// 26 | public DateTime RenderDate { get; set; } 27 | 28 | /// 29 | /// Name of worksheet that is currently render 30 | /// 31 | public string SheetName { get; set; } 32 | 33 | /// 34 | /// Number of worksheet that is currently render 35 | /// 36 | public int SheetNumber { get; set; } 37 | 38 | /// 39 | /// Get variable value by its 40 | /// 41 | /// Thrown when is null, empty string or whitespace 42 | /// 43 | public virtual object GetVariable(string name) 44 | { 45 | if (string.IsNullOrWhiteSpace(name)) 46 | { 47 | throw new ArgumentException(ArgumentHelper.EmptyStringParamMessage, nameof(name)); 48 | } 49 | 50 | PropertyInfo prop = _reflectionHelper.TryGetProperty(GetType(), name); 51 | if (prop == null) 52 | { 53 | throw new InvalidVariableException($"Cannot find variable with name \"{name}\" in class {GetType().Name} and all its parents. Variable must be public instance property."); 54 | } 55 | 56 | return prop.GetValue(this, null); 57 | } 58 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/TemplateParts/MemberTemplateParts.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.TemplateParts; 2 | 3 | /// 4 | /// Represent parts from which member template consist of 5 | /// 6 | public class MemberTemplateParts 7 | { 8 | public MemberTemplateParts(string typeName, string memberName) 9 | { 10 | TypeName = typeName; 11 | MemberName = memberName; 12 | } 13 | 14 | public string TypeName { get; } 15 | 16 | public string MemberName { get; } 17 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/TemplateParts/MethodCallTemplateParts.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.TemplateParts; 2 | 3 | /// 4 | /// Represent parts from which method template consist of 5 | /// 6 | public class MethodCallTemplateParts : MemberTemplateParts 7 | { 8 | public MethodCallTemplateParts(string typeName, string memberName, string methodParams) : base(typeName, memberName) 9 | { 10 | MethodParams = methodParams; 11 | } 12 | 13 | public string MethodParams { get; } 14 | } -------------------------------------------------------------------------------- /ExcelReportGenerator/Rendering/TemplateProcessors/ITemplateProcessor.cs: -------------------------------------------------------------------------------- 1 | namespace ExcelReportGenerator.Rendering.TemplateProcessors; 2 | 3 | /// 4 | /// Handles report templates 5 | /// 6 | public interface ITemplateProcessor 7 | { 8 | /// 9 | /// Left template border 10 | /// Cannot be null, empty or whitespace 11 | /// 12 | string LeftTemplateBorder { get; } 13 | 14 | /// 15 | /// Right template border 16 | /// Cannot be null, empty or whitespace 17 | /// 18 | string RightTemplateBorder { get; } 19 | 20 | /// 21 | /// Separator between member label (Property, MethodCall, DataItem) and member template 22 | /// Cannot be null or empty 23 | /// 24 | string MemberLabelSeparator { get; } 25 | 26 | /// 27 | /// Property label 28 | /// Cannot be null, empty or whitespace 29 | /// 30 | string PropertyMemberLabel { get; } 31 | 32 | /// 33 | /// Method call label 34 | /// Cannot be null, empty or whitespace 35 | /// 36 | string MethodCallMemberLabel { get; } 37 | 38 | /// 39 | /// Data item label 40 | /// Cannot be null, empty or whitespace 41 | /// 42 | string DataItemMemberLabel { get; } 43 | 44 | /// 45 | /// System variable label 46 | /// Cannot be null, empty or whitespace 47 | /// 48 | string SystemVariableMemberLabel { get; } 49 | 50 | /// 51 | /// System function label 52 | /// Cannot be null, empty or whitespace 53 | /// 54 | string SystemFunctionMemberLabel { get; } 55 | 56 | /// 57 | /// Horizontal page break label 58 | /// Cannot be null, empty or whitespace 59 | /// 60 | string HorizontalPageBreakLabel { get; } 61 | 62 | /// 63 | /// Vertical page break label 64 | /// Cannot be null, empty or whitespace 65 | /// 66 | string VerticalPageBreakLabel { get; } 67 | 68 | /// 69 | /// This template used if you want to return the data item itself 70 | /// Cannot be null, empty or whitespace 71 | /// 72 | string DataItemSelfTemplate { get; } 73 | 74 | /// 75 | /// Get value based on 76 | /// 77 | /// Data item that will be used if template is the data item template 78 | object GetValue(string template, HierarchicalDataItem dataItem = null); 79 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Traf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ExcelReportGenerator 2 | 3 | This library allows you to render data to Microsoft Excel by marking Excel sheets using panels and templates. It makes it easy to connect to various data sources like IDataReader, DataSet, DataTable, IEnumerable and others and to render data from them to Excel. You can also apply aggregation, various types of grouping, formatting and so on to the data. You can include the library to your project via [NuGet package](https://www.nuget.org/packages/ExcelReportGenerator). 4 | 5 | ## How to use? 6 | First of all you have to create a report template in Microsoft Excel. You need to mark up an excel sheet (or multiple sheets) using panels and templates which will be handled by the library. You can add any other formatting you want. All styles will be preserved after rendering. Your template can look like this: 7 | 8 | **Template** 9 | 10 | ![template](https://user-images.githubusercontent.com/45209977/48908282-e29a8b80-ee7a-11e8-9b54-6997ba617474.png) 11 | 12 | Next you need to create a report class that will supply data for this template 13 | 14 | **Code** 15 | 16 | ```c# 17 | public class ReportSample 18 | { 19 | private readonly DataProvider _dataProvider = new DataProvider(); 20 | 21 | public string ReportName => "Grouping with Panel Hierarchy"; 22 | 23 | public IEnumerable GetDepartments() 24 | { 25 | return GetAllEmployees().Select(e => e.DepartmentName).Distinct(); 26 | } 27 | 28 | public IEnumerable GetDepartmentEmployees(string department) 29 | { 30 | return GetAllEmployees().Where(e => e.DepartmentName == department).ToArray(); 31 | } 32 | 33 | public IEnumerable GetAllEmployees() 34 | { 35 | return _dataProvider.GetEmployeesAsIEnumerable().ToArray(); 36 | } 37 | 38 | public string ConvertGender(string gender) 39 | { 40 | return gender == "M" ? "Male" : "Female"; 41 | } 42 | } 43 | ``` 44 | 45 | **Result** 46 | 47 | ![result](https://user-images.githubusercontent.com/45209977/48908531-94d25300-ee7b-11e8-8022-5c6cfdfca4e3.png) 48 | 49 | The detailed documentation is inside the [Docs](https://github.com/traf72/excel-report-generator/tree/master/Docs) folder. For more information see also [ExcelReportGenerator.Samples](https://github.com/traf72/excel-report-generator/tree/master/ExcelReportGenerator.Samples). 50 | --------------------------------------------------------------------------------