using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using Stimulsoft.Base.Drawing; using Stimulsoft.Report; using Stimulsoft.Report.Components; using Stimulsoft.Report.Components.Table; using Stimulsoft.Report.Dictionary; using Stimulsoft.Report.Events; using StiRestrictions = Stimulsoft.Report.Components.StiRestrictions; namespace StimulsoftTableTester { internal class DynamicTable { private StiReport tableReport = new StiReport(); private TableFormatter formatter = new TableFormatter(); private int textColumnCount; private int iconColumnCount; private List columnList; private DataSet reportDataSet; public DynamicTable(List colList, DataSet dataSet) { this.columnList = colList; this.reportDataSet = dataSet; } public StiReport GetTableReport(int textColCount, int iconColCount) { this.textColumnCount = textColCount; this.iconColumnCount = iconColCount; this.tableReport.NeedsCompiling = false; this.tableReport.ReportUnit = StiReportUnitType.Centimeters; this.tableReport.Pages.Clear(); var pages = new StiPagesCollection(this.tableReport); // copy styles var styleList = this.formatter.Vorlage.Styles; foreach (StiBaseStyle style in styleList) { this.tableReport.Styles.Add(style); } this.AddPages(pages, 1); StiPage page = pages[0]; var pageComponents = new StiComponentsCollection(); var colCount = textColCount + iconColCount; StiHeaderBand pageHeaderBand = AddHeaderBand(0, 0); pageHeaderBand.Page = page; pageHeaderBand.Parent = page; // add table column header StiColumnHeaderBand colHeaderBand = this.AddColumnHeader(0, 0); // assign page to header colHeaderBand.Page = page; colHeaderBand.Parent = page; var tableComponents = new StiComponentsCollection(); var headerComponents = new StiComponentsCollection(); // Add a new table StiTable table = this.AddTable(0, 0); table.ColumnCount = colCount; // assign page to table table.Page = page; table.Parent = page; // add the header texts and cells for one row for (int currentCol = 0; currentCol < colCount; currentCol++) { // firstly the header text double positionY = 0D; StiText headerText = this.AddHeaderText(currentCol, 0, positionY); // add text to header band headerText.Page = page; headerText.Parent = colHeaderBand; // add the text to the collection headerComponents.Add(headerText); // now the cell this.AddCell(currentCol, ref page, ref table, ref tableComponents, 0); } // only 1 row is defined table.RowCount = 1; table.HeaderRowsCount = 0; // Add the header texts to the header band's components colHeaderBand.Components.Clear(); colHeaderBand.Components.AddRange(headerComponents); // Add the cells to the table's components table.Components.Clear(); table.Components.AddRange(tableComponents); pageComponents.Add(pageHeaderBand); pageComponents.Add(colHeaderBand); pageComponents.Add(table); page.Components.AddRange(pageComponents); this.tableReport.Pages.AddRange(pages); return tableReport; } #region helpers private StiTableCellImage AddImageCell(int currentCol, int tableNumber) { double positionY = 0D; StiTableCellImage cell = new StiTableCellImage(); StiTableCell cellTemplate = this.formatter.GetTextCell(tableNumber); cell.ClientRectangle = this.GetCellRectangle(currentCol, positionY, cellTemplate.Height); cell.ID = currentCol; cell.Name = string.Format("IC_{0}", currentCol); // get the formatter for image cells StiTableCellImage imageTemplate = this.formatter.GetImageCell(tableNumber); cell.CanGrow = imageTemplate.CanGrow; cell.CanShrink = imageTemplate.CanShrink; cell.MultipleFactor = imageTemplate.MultipleFactor; cell.GrowToHeight = imageTemplate.GrowToHeight; cell.Stretch = imageTemplate.Stretch; cell.Restrictions = StiRestrictions.None | StiRestrictions.AllowMove | StiRestrictions.AllowSelect | StiRestrictions.AllowChange; cell.Border = cellTemplate.Border; cell.Brush = cellTemplate.Brush; cell.HorAlignment = imageTemplate.HorAlignment; cell.VertAlignment = imageTemplate.VertAlignment; cell.GetImageData += this.TableCell__GetImage; return cell; } private void AddCell( int currentCol, ref StiPage page, ref StiTable table, ref StiComponentsCollection tableComponents, int tableNumber) { // decide which type of cell is required var colDetails = this.columnList.FirstOrDefault(x => x.ColId == currentCol); switch (colDetails.ColType) { case 1: StiTableCellImage imageCell = this.AddImageCell(currentCol, tableNumber); // add cell to table imageCell.Page = page; imageCell.Parent = table; // add the cell to the collection tableComponents.Add(imageCell); break; default: // e.g. strings StiTableCell textCell = this.AddTextCell(currentCol, tableNumber); // add cell to table textCell.Page = page; textCell.Parent = table; // add the cell to the collection tableComponents.Add(textCell); break; } } private StiTableCell AddTextCell(int currentCol, int tableNumber) { double positionY = 0D; StiTableCell cell = new StiTableCell(); StiTableCell cellTemplate = this.formatter.GetTextCell(tableNumber); cell.Type = StiSystemTextType.DataColumn; cell.ClientRectangle = this.GetCellRectangle(currentCol, positionY, cellTemplate.Height); cell.ID = currentCol; cell.Name = string.Format("TC_{0}", currentCol); cell.CanGrow = cellTemplate.CanGrow; cell.CanShrink = cellTemplate.CanShrink; cell.GrowToHeight = cellTemplate.GrowToHeight; cell.WordWrap = cellTemplate.WordWrap; // for an advanced style, just copy it if (cellTemplate.Border.GetType() == typeof(StiAdvancedBorder)) { cell.Border = cellTemplate.Border; } else { // no shading cell.Border = new StiBorder( cellTemplate.Border.Side, cellTemplate.Border.Color, cellTemplate.Border.Size, StiPenStyle.Solid, false, 4, new StiSolidBrush(Color.FromArgb(255, 105, 105, 105))); } cell.Brush = cellTemplate.Brush; cell.Font = new Font(cellTemplate.Font.FontFamily, cellTemplate.Font.Size, cellTemplate.Font.Style); cell.TextBrush = cellTemplate.TextBrush; cell.TextOptions = new StiTextOptions( false, false, cellTemplate.WordWrap, 0F, System.Drawing.Text.HotkeyPrefix.None, StringTrimming.None); cell.VertAlignment = cellTemplate.VertAlignment; cell.GetValue += this.TableCell__GetValue; return cell; } private StiText AddHeaderText(int currentCol, int tableNumber, double positionY) { var text = new StiText(); StiText templateText = this.formatter.GetHeaderText(tableNumber); text.ClientRectangle = this.GetCellRectangle(currentCol, positionY, templateText.Height); text.Name = string.Format("HT_{0}", currentCol); text.ShrinkFontToFit = templateText.ShrinkFontToFit; text.CanGrow = templateText.CanGrow; text.GrowToHeight = templateText.GrowToHeight; text.Type = StiSystemTextType.Expression; text.Border = new StiBorder( templateText.Border.Side, templateText.Border.Color, templateText.Border.Size, StiPenStyle.Solid, false, 4, new StiSolidBrush(Color.FromArgb(255, 105, 105, 105))); text.Brush = templateText.Brush; text.Font = new Font(templateText.Font.FontFamily, templateText.Font.Size, templateText.Font.Style); text.Margins = templateText.Margins; text.TextBrush = templateText.TextBrush; text.TextOptions = new StiTextOptions( false, false, templateText.WordWrap, 0F, System.Drawing.Text.HotkeyPrefix.None, StringTrimming.None); // aligment text.VertAlignment = templateText.VertAlignment; text.HorAlignment = templateText.HorAlignment; // text event text.GetValue += this.HeaderText__GetValue; return text; } private RectangleD GetCellRectangle(int currentCol, double positionY, double height) { var tc = this.columnList.FirstOrDefault(x => x.ColId == currentCol); var posX = tc.CumulativeWidth - tc.Width; return new RectangleD(posX, positionY, tc.Width, height); } private StiTable AddTable(int curPage, int tableNumber) { StiTable table = new StiTable(); StiTable templateTable = this.formatter.GetTable(0); table.DockableTable = true; table.AutoWidth = StiTableAutoWidth.None; table.AutoWidthType = StiTableAutoWidthType.LastColumns; table.EvenStyle = this.formatter.TableEvenStyleName; table.OddStyle = this.formatter.TableOddStyleName; table.ClientRectangle = templateTable.ClientRectangle; table.DataSourceName = "Content"; table.Name = string.Format("Table{0}{1}", tableNumber + 1, curPage + 1); table.Sort = new string[0]; table.Border = new StiBorder( StiBorderSides.None, templateTable.Border.Color, 1, StiPenStyle.Solid, false, 1, new StiSolidBrush(Color.Black)); table.Brush = new StiSolidBrush(Color.Transparent); table.ColumnGaps = templateTable.ColumnGaps; return table; } private StiColumnHeaderBand AddColumnHeader(int tableNo, int pageNo) { StiColumnHeaderBand templateHeader = this.formatter.GetHeaderBand(tableNo); StiColumnHeaderBand header = new StiColumnHeaderBand { ClientRectangle = new RectangleD(templateHeader.Left, templateHeader.Top, templateHeader.Width, templateHeader.Height), Name = string.Format("Header{0}_{1}", tableNo, pageNo), Border = new StiBorder(StiBorderSides.None, Color.Black, 1, StiPenStyle.Solid, false, 4, new StiSolidBrush(Color.Black)), Brush = new StiSolidBrush(Color.Transparent), Dockable = true, CanGrow = templateHeader.CanGrow }; return header; } private void AddPages(StiPagesCollection pages, int pagesToAdd) { // get the template StiPage pageTemplate = this.formatter.FirstPage; int pageCount = pages.Count; for (int i = 0; i < pagesToAdd; i++) { int curPage = pageCount + i + 1; StiPage page = new StiPage { Orientation = pageTemplate.Orientation, PageHeight = pageTemplate.PageHeight, PageWidth = pageTemplate.PageWidth, Name = string.Format("Page{0}", curPage), Margins = pageTemplate.Margins, Border = new StiBorder( StiBorderSides.None, Color.Black, 2, StiPenStyle.Solid, false, 4, new StiSolidBrush(Color.Black)), Brush = new StiSolidBrush(Color.Transparent), Report = this.tableReport }; // add page to collection pages.Add(page); } } private StiHeaderBand AddHeaderBand(int currentPage, int currentTable) { StiPage pageTemplate = this.formatter.FirstPage; StiHeaderBand headerBandFormatter = this.GetSpecificItemByName(this.formatter.Vorlage, "HeaderBandTop"); if (headerBandFormatter == null) { headerBandFormatter = new StiHeaderBand() { ClientRectangle = new RectangleD(0, 2, pageTemplate.ClientRectangle.Width, 0.4) }; } double height = headerBandFormatter.ClientRectangle.Height; StiHeaderBand headerBand = new StiHeaderBand() { Name = string.Format("HeaderBand{0}_{1}", currentTable, currentPage), ClientRectangle = new RectangleD(0, 2, pageTemplate.ClientRectangle.Width, height), Border = new StiBorder(StiBorderSides.None, Color.Transparent, 1, StiPenStyle.Solid, false, 4, new StiSolidBrush(Color.Black)), Brush = new StiSolidBrush(Color.Transparent) }; return headerBand; } public T GetSpecificItemByName(StiReport report, string itemName) where T : class { StiComponentsCollection compList = report.GetComponents(); foreach (var item in compList) { if (item.GetType() == typeof(T)) { var component = (StiComponent)item; if (component.Name == itemName) { return item as T; } } } return null; } private Image AssignAndRetrieveIconVariable(string varName) { // is the variable already there? if (this.tableReport.Dictionary.Variables == null) this.tableReport.Dictionary.Variables = new StiVariablesCollection(); if (!this.tableReport.Dictionary.Variables.Contains(varName)) { // get the icon and save to the variable byte[] imageArray = this.formatter.GetSymbolIcon(varName); using (var ms = new MemoryStream(imageArray)) { this.tableReport.Dictionary.Variables.Add(new StiVariable(varName, Image.FromStream(ms))); hs[varName] = Image.FromStream(ms); } } //return this.tableReport.Dictionary.Variables == null ? null : this.tableReport.Dictionary.Variables[varName].ValueObject as Image; return this.tableReport.Dictionary.Variables == null ? null : hs[varName] as Image; } #endregion Hashtable hs = new Hashtable(); #region events private void TableCell__GetValue(object sender, StiGetValueEventArgs e) { string cellText = ((StiText) sender).Name; string[] cellTextArray = cellText.Split('_'); int currentCol = int.Parse(cellTextArray[1]); int currentRow = this.tableReport.Line - 1; DataTable contentTable = this.reportDataSet.Tables[0]; e.Value = contentTable.Rows[currentRow][currentCol] as string; } private void HeaderText__GetValue(object sender, StiGetValueEventArgs e) { string cellText = ((StiText)sender).Name; string[] cellTextArray = cellText.Split('_'); e.Value = string.Format("H{0}", cellTextArray[1]); } private void TableCell__GetImage(object sender, StiGetImageDataEventArgs e) { string cellText = ((StiTableCellImage) sender).Name; string[] cellTextArray = cellText.Split('_'); int currentCol = int.Parse(cellTextArray[1]); int currentRow = this.tableReport.Line - 1; DataTable contentTable = this.reportDataSet.Tables[0]; var iconPointer = contentTable.Rows[currentRow][currentCol] as string; e.Value = this.AssignAndRetrieveIconVariable(iconPointer); } #endregion } }