using System; using System.Collections.Generic; using ceTe.DynamicPDF.Merger; using ceTe.DynamicPDF.PageElements; using ceTe.DynamicPDF; using System.Data; using System.Collections; using System.Linq; using Consulenza.ReportCommon; using Consulenza.ReportWriter.Business.CHART_PDF; using Consulenza.ReportWriter.Business.OBJ_PDF; using System.Configuration; using Consulenza.ReportWriter.Business.Entity; using RisorseEmbeddedRM; using Consulenza.DataServices; using ceTe.DynamicPDF.Text; using Consulenza.ReportWriter.Business.Headers; namespace Consulenza.ReportWriter.Business { /// /// Implementa i metodi di assegnazione degli elementi ObjectPDF alla pagina. /// public class RendererPDF { # region Fields private int numberPageOnChapter = 0; // Numero della pagina aggiunta al singolo capitolo. Si resetta a 0 ad ogni cambio capitolo. (Evita di doppiare il titolo del capitolo aggiunto da WriteChapterTitle e dall'invocazione del capitolo stesso) private readonly Document _document; private readonly List _elements = new List(); private List _entities = new List(); private EntityBase _currentchapter; // puntatore al chapter correntetra quelli aggiunti alla collezione _entities. private ImportedPage _page; private readonly PdfDocument _generictemplate; private readonly PdfDocument _covertemplate; // Margini private readonly float _yendpage; // limite prefissato e non variabile, corrisponde alla linea di chiusura pagina. private readonly float _ylowerlimitoriginal; // non variabile in funzione della presenza delle note di piè di pagina. la differenza tra _ylowerlimitoriginal - _ylowerlimit indica lo spazio dell apagina in cui vengono scritte le note di fondo pagina. /// /// Y corrente su cui verrà disegnato ObjectPDF /// private float _ywritable; public float YWritable { get { return _ywritable; } set { _ywritable = value; } } /// /// Permette di accedere alle impostazioni di "ambiente" specifiche del Report corrente (chiavi di invocazione etc...). /// private readonly ReportEnvironment _reportEnvironment; private float _spacenotefooterpagePerpage; /// /// Indica se il prossimo elemento che sarà stampatoo sulla pagina, verrà stampato in una nuova pagina. /// private bool _printinginnewpage = true; /// /// Limite sinitro della pagina (è già considerato lo spazio necessario per le avvertenze.) /// Di default 37 /// public float XLeftLimit { get; set; } /// /// Limite destro della pagina. /// Di default 560 /// public float XRightLimit { get; set; } /// /// Limite massimo superiore della pagina (corrisponde alla linea rossa superiore) /// Di default 130 /// public float YUpperLimit { get; set; } /// /// Limite massimo superiore della pagina (corrisponde alla linea rossa inferiore) /// Di default 750 /// public float YLowerLimit { get; set; } private List _repeaterElements; #endregion /// /// Costruttore. /// Imposta la il Template, la Page e passa una rappresentazione del DataModel all'implementazione estesa della classe corrente /// al fine di supportare l'invocazione dei metodi di rendering delle classi specifiche del Layout esteso di ciascuna pagina (vedere FrameClassMapperManager invocato dall'estensione RendererExtender.cs). /// /// public RendererPDF(ReportEnvironment environment) { _reportEnvironment = environment; _document = new Document(); Document.AddLicense(ConfigurationManager.AppSettings["Licenza"]); #region Template // Imposto il documento per la copertina del report var fileCoverTemplate = RisorseEmbedded.GetResourceByName(_reportEnvironment.ResourceNameCover); _covertemplate = new PdfDocument(fileCoverTemplate); // Imposto il documento per le pagine generiche del report. var fileGenericTemplate = RisorseEmbedded.GetResourceByName(_reportEnvironment.ResourceNameTemplate); _generictemplate = new PdfDocument(fileGenericTemplate); #endregion #region Margini del documento switch (environment.ReportType) { case ReportType.Base_Proposta: // Template A4 Verticale XLeftLimit = 37; XRightLimit = 560; YUpperLimit = 105; YLowerLimit = 745; _yendpage = 766F; _ylowerlimitoriginal = 745F; break; case ReportType.Immobiliare_Diagnosi: case ReportType.Immobiliare_DiagnosiNucleo: case ReportType.Immobiliare_MappaturaPreliminare: case ReportType.Immobiliare_Finalita: // Template A4 Orizzontale XLeftLimit = 50; XRightLimit = 805; YUpperLimit = 35; _yendpage = 510; _ylowerlimitoriginal = 485; YLowerLimit = 485; break; case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: case ReportType.Unica_Proposta: case ReportType.Unica_Nucleo: // Template A4 Verticale XLeftLimit = 37; XRightLimit = 560; YUpperLimit = 122; YLowerLimit = 745; _yendpage = 740F; _ylowerlimitoriginal = 740F; break; case ReportType.Immobiliare_Monitoraggio: // Template A4 Orizzontale XLeftLimit = 14; XRightLimit = 805; YUpperLimit = 17; _yendpage = 474; _ylowerlimitoriginal = 480; YLowerLimit = 490; break; case ReportType.Immobiliare_MonitoraggioNuclei: // Template A4 Orizzontale XLeftLimit = 14; XRightLimit = 805; YUpperLimit = 17; _yendpage = 474; _ylowerlimitoriginal = 480; YLowerLimit = 490; break; default: throw new Exception("ReportType da definire: [Consulenza.ReportWriter.Business.RendererPDF()]"); } #endregion #region Compression Level _document.CompressionLevel = 9; #endregion #region Security // Create a standard security object //var security = new StandardSecurity { AllowCopy = false, AllowEdit = false }; //FC 26/01/2017 //richiesta Casoli Abilitazione Copia e Modifica documenti var security = new StandardSecurity { AllowCopy = true, AllowEdit = true }; // Add the security object to the document _document.Security = security; #endregion #region Pdf Version _document.PdfVersion = PdfVersion.v1_7; _document.PdfXVersion = PdfXVersion.PDF_X_3_2003; #endregion #region ICCProfile var iccProfile = new IccProfile(RisorseEmbedded.GetResourceByName("RisorseEmbeddedRM.PDFTemplates.sRGB.icc")); const string configurationPath1 = "CGATS TR 001-1995 (SWOP)"; const string configurationPath2 = "CGATS TR 001"; const string configurationPath3 = "http://www.color.org"; const string configurationPath4 = "U.S. Web Coated (SWOP) v2"; var outputIntent = new OutputIntent(configurationPath1, configurationPath2, configurationPath3, configurationPath4, iccProfile); _document.OutputIntents.Add(outputIntent); _document.Trapped = Trapped.False; #endregion if (_ywritable == 0) _ywritable = YUpperLimit; } /// /// Ritorna la rappresentazione in array di byte[] del report. /// /// public byte[] Render(List entities) { _entities = entities; WriteElements(); if (_reportEnvironment.ReportType == ReportType.Immobiliare_Monitoraggio || _reportEnvironment.ReportType == ReportType.Immobiliare_MonitoraggioNuclei) { ReplaceHeadersIndexes(); ReplaceIndexPagePageNumbers(); } return _document.Draw(); } private void ReplaceIndexPagePageNumbers() { if (_document != null && _document.Pages != null) { foreach (Page page in _document.Pages) { foreach (var element in page.Elements) { if (element is FormattedTextArea) { FormattedTextArea el = element as FormattedTextArea; foreach (var tuple in MonitoraggioImmobiliarePageHeaderManager.IndexPagesPageNumbersToReplace) { if (el != null && (el.Text != null && el.Text.Contains(tuple.Item2))) { el.Text = el.Text.Replace(tuple.Item2, (headers.IndexOf(headers.Where(x => x.Item1.BelongToIndex == tuple.Item1).First()) + 3).ToString()); } } } } } } MonitoraggioImmobiliarePageHeaderManager.IndexPagesPageNumbersToReplace.Clear(); } private void ReplaceHeadersIndexes() { if (_document != null & _document.Pages != null && headers.Count() > 0) { foreach (var header in headers) { var sectionId = header.Item1; var sameSectionHeaders = headers.Where(x => x.Item1 == sectionId).ToList(); if (sameSectionHeaders.Count() == 1) { var guid = sameSectionHeaders.FirstOrDefault().Item1.TextReplaceGuid; var newHeaderText = sameSectionHeaders.FirstOrDefault().Item2.Text.Replace( guid, string.Empty); for (int i = 0; i < _document.Pages.Count; i++) { for (int j = 0; j < _document.Pages[i].Elements.Count; j++) { FormattedTextArea el = _document.Pages[i].Elements[j] as FormattedTextArea; if (el != null && (el.Text != null & el.Text.Contains(guid))) { el.Text = newHeaderText; } } } } else if (sameSectionHeaders.Count() > 1) { int maxPages = sameSectionHeaders.Count(); int indexPage = 1; for (int i = 0; i < maxPages; i++) { var guid = sameSectionHeaders[i].Item1.TextReplaceGuid; for (int a = 0; a < _document.Pages.Count; a++) { for (int j = 0; j < _document.Pages[a].Elements.Count; j++) { FormattedTextArea el = _document.Pages[a].Elements[j] as FormattedTextArea; if (el != null && (el.Text != null && el.Text.Contains(guid))) { var newHeaderText = sameSectionHeaders[i].Item2.Text.Replace(guid, string.Format(" ({0}/{1})", indexPage, maxPages)); el.Text = newHeaderText; indexPage++; break; } } } } } } } } #region WriteElements /// /// Disegna sulla pagina tutti gli elementi aggiunti al documento. /// Riduce lo spazio scrivibile della pagina se ci sono note a piedipagina da stampare /// private void WriteElements() { foreach (var entity in _entities) { // puntatore al chapter corrente. if (entity.EntityType == EntityTypePdf.Chapter) { _currentchapter = entity; numberPageOnChapter = 0; } // elementi Repeater var elementRepeater = entity.Elements.FirstOrDefault(o => o.ObjectType == ObjectTypePdf.REPEATER); if (elementRepeater != null) _repeaterElements = ((RepeaterPDF)elementRepeater).Elements; // Disegno tutti gli elementi (Elements) foreach (var element in entity.Elements) { _elements.Add(element); #region switch ObjectType elemento switch (element.ObjectType) { case ObjectTypePdf.FORMATTEDTEXTAREA: WriteElement((FormattedTextAreaPDF)element); break; case ObjectTypePdf.LINE: WriteElement((LinePDF)element); break; case ObjectTypePdf.IMAGE: WriteElement((ImagePDF)element); break; case ObjectTypePdf.TABLE: WriteElement((TablePDF)element); break; case ObjectTypePdf.SPACE: WriteElement((SpacePDF)element); break; case ObjectTypePdf.RECTANGLE: WriteElement((RectanglePDF)element); break; case ObjectTypePdf.UNORDEREDLIST: WriteElement((UnorderedListPDF)element); break; case ObjectTypePdf.PAGE: var page = (PagePDF)element; switch (page.Type) { case PagePDF.PagePDFType.Generic: AddPage(); numberPageOnChapter++; break; case PagePDF.PagePDFType.Cover: AddPage(PagePDF.PagePDFType.Cover); break; } break; case ObjectTypePdf.CIRCLE: WriteElement((CirclePDF)element); break; case ObjectTypePdf.RESETTER_Y: WriteElement((ResetterYPDF)element); break; case ObjectTypePdf.ACTIONPDF: WriteElement((ActionPDF)element); break; case ObjectTypePdf.COMPOSITE: WriteElement((CompositePDF)element); break; case ObjectTypePdf.CHART: var chart = element as ChartPDF; switch (chart.ChartType) { case ChartTypePdf.PIE: chart = element as PiePDF; break; case ChartTypePdf.STACKED: chart = element as StackedPDF; break; case ChartTypePdf.COMBINATION: chart = element as CombinationPDF; break; default: throw new Exception("Grafico non esistente"); } WriteElement(chart); break; case ObjectTypePdf.CIRCLEREAL: WriteElement((CircleRealPDF)element); break; case ObjectTypePdf.CUSTOMCHART: WriteElement((CustomChartPDF)element); break; } #endregion } _repeaterElements = null; } } #endregion #region WriteElement private void WriteElement(ObjectPDF element) { //var genericElement = Activator.CreateInstance(element.GetType()); switch (element.ObjectType) { case ObjectTypePdf.FORMATTEDTEXTAREA: case ObjectTypePdf.TABLENOTE: WriteElement((FormattedTextAreaPDF)element); break; case ObjectTypePdf.IMAGE: WriteElement((ImagePDF)element); break; case ObjectTypePdf.SPACE: WriteElement((SpacePDF)element); break; case ObjectTypePdf.LINE: WriteElement((LinePDF)element); break; case ObjectTypePdf.RECTANGLE: WriteElement((RectanglePDF)element); break; case ObjectTypePdf.CIRCLE: WriteElement((CirclePDF)element); break; case ObjectTypePdf.CIRCLEREAL: WriteElement((CircleRealPDF)element); break; case ObjectTypePdf.UNORDEREDLIST: WriteElement((UnorderedListPDF)element); break; case ObjectTypePdf.CHART: WriteElement((ChartPDF)element); break; case ObjectTypePdf.TABLE: WriteElement((TablePDF)element); break; case ObjectTypePdf.RESETTER_Y: WriteElement((ResetterYPDF)element); break; case ObjectTypePdf.ACTIONPDF: WriteElement((ActionPDF)element); break; case ObjectTypePdf.COMPOSITE: WriteElement((CompositePDF)element); break; case ObjectTypePdf.CUSTOMCHART: WriteElement((CustomChartPDF)element); break; } } /// /// Scrive l'elemento NotePDF nella pagina /// /// private void WriteElement(TableNotePDF element) { if (element.Image == null) { var elementConverted = element as FormattedTextAreaPDF; if (element.TypeMarker != TableNotePDF.TableNoteTypemarker.Numeri) elementConverted.Text = element.AsterisksNumber > 0 ? "(" + element.ToAsteriskString() + ") " + element.Text : element.Text; else elementConverted.Text = element.AsterisksNumber > 0 ? "(" + element.ToNumberAsteriskString() + ") " + element.Text : element.Text; WriteElement(elementConverted); } else { var elements = new List(); // testo della nota var elementText = element as FormattedTextAreaPDF; elementText.Text = element.Text; elementText.X += 20; // immagine della nota var elementImage = element.Image; elementImage.AutoIncrementYWritable = false; elements.Add(elementImage); elements.Add(elementText); // disegno gli oggetti aggiunti foreach (var item in elements) WriteElement(item); } } /// /// Scrive l'elemento RectanglePDF nella pagina /// /// private void WriteElement(RectanglePDF element) { var color = new RgbColor((byte)element.Color.Red, (byte)element.Color.Green, (byte)element.Color.Blue); element.BaseElement = new Rectangle(element.X, element.Y, element.Width, element.Height, color, color); //element.BaseElement.X += element.DeltaX; // Imposto Y if (element.Y == 0) element.BaseElement.Y = _ywritable + element.DeltaY; // CornerRadius if (element.CornerRadius > 0) element.BaseElement.CornerRadius = element.CornerRadius; // Angle if (element.Angle != 0) element.BaseElement.Angle = element.Angle; // Disegno BaseElement if (_ywritable + element.Height <= YLowerLimit) _page.Elements.Add(element.ToElement()); else { // aggiungere una pagina AddPage(); element.BaseElement.Y = _ywritable + element.DeltaY; _page.Elements.Add(element.ToElement()); } // Imposto Border if (element.BorderWidth > 0) { var colorBorder = new RgbColor((byte)element.BorderColor.Red, (byte)element.BorderColor.Green, (byte)element.BorderColor.Blue); element.BaseElement.BorderWidth = element.BorderWidth; element.BaseElement.BorderColor = colorBorder; element.BaseElement.BorderStyle = LineStyle.Solid; } // Incremento _ywritable if (element.AutoIncrementYWritable) _ywritable += element.Height; } /// /// Scrive l'elemento CirclePDF nella pagina /// /// private void WriteElement(CirclePDF element) { WriteElement((RectanglePDF)element); } private void WriteElement(CircleRealPDF element) { var color = new RgbColor((byte)element.Color.Red, (byte)element.Color.Green, (byte)element.Color.Blue); element.BaseElement = new Circle(element.X, element.Y, element.Radius, color) { FillColor = color }; element.BaseElement.X += element.DeltaX; // Imposto Y if (element.Y == 0) element.BaseElement.Y = _ywritable + element.DeltaY; // Disegno BaseElement if (_ywritable + element.Radius * 2 <= YLowerLimit) _page.Elements.Add(element.ToElement()); else { // aggiungere una pagina AddPage(); element.BaseElement.Y = _ywritable + element.DeltaY; _page.Elements.Add(element.ToElement()); } // Incremento _ywritable if (element.AutoIncrementYWritable) _ywritable += element.Radius * 2; } /// /// Scrive l'elemento FormattedTextAreaPDF nella pagina /// /// private void WriteElement(FormattedTextAreaPDF element) { // Style var color = new RgbColor((byte)element.FontColor.Red, (byte)element.FontColor.Green, (byte)element.FontColor.Blue); var styleFormattedTextArea = new FormattedTextAreaStyle(_reportEnvironment.FontFamily, element.FontSize, false) { Bold = element.FontBold }; element.BaseElement = new FormattedTextArea(element.Text, element.X, element.Y, element.Width, element.Height, styleFormattedTextArea) { Style = styleFormattedTextArea }; element.BaseElement.Style.Font.Color = color; element.BaseElement.Style.Paragraph.Align = element.TextHorizontalAlign; element.BaseElement.VAlign = element.TextVerticalAlign; // Imposto Height if (element.Width > 0 && !string.IsNullOrEmpty(element.Text)) { element.SetHeight(element.FixedHeight > 0 ? element.FixedHeight : element.BaseElement.GetRequiredHeight()); } //else // element.Height = element.FixedHeight; element.BaseElement.Height = element.Height; // Imposto Y element.BaseElement.Y = element.Y == 0 ? _ywritable + element.DeltaY : element.Y + element.DeltaY; // Imposto X element.BaseElement.X += element.DeltaX; // Imposto testo in verticale. if (element.TextVerticalDirection) { element.BaseElement.Angle = -90; } #region BackGround if (element.BackGroundColor != null) { var rectangleBackColor = new RectanglePDF(element.BackGroundHeight, element.Width, element.BackGroundColor) { X = element.X }; rectangleBackColor.Y = element.BaseElement.Y - (rectangleBackColor.Height / 2) + (element.FontSize / 2); if (element.BaseElement.VAlign == VAlign.Top) element.BaseElement.Y = _ywritable - (rectangleBackColor.Height / 2) + (element.FontSize / 2); rectangleBackColor.AutoIncrementYWritable = false; WriteElement(rectangleBackColor); // Margine sinistro dell'etichetta (BackGroundMarginLeft) element.BaseElement.X += element.BackGroundMarginLeft; } #endregion // Disegno BaseElement if (_ywritable + element.Height <= YLowerLimit || element.AbsolutePosition) { if (element.ID == "debug") _page.Elements.Add(new Line(element.BaseElement.X, element.BaseElement.Y, element.BaseElement.X + element.Width, element.BaseElement.Y, RgbColor.Red)); _page.Elements.Add(element.ToElement()); if (element.ID == "debug") _page.Elements.Add(new Line(element.BaseElement.X, element.BaseElement.Y + element.Height, element.BaseElement.X + element.Width, element.BaseElement.Y + element.Height, RgbColor.Yellow)); } else { // aggiungere una pagina AddPage(); element.BaseElement.Y = _ywritable + element.DeltaY; _page.Elements.Add(element.ToElement()); } if (element.AutoIncrementYWritable && element.BackGroundColor == null) _ywritable += element.Height; if (element.AutoIncrementYWritable && element.BackGroundColor != null) _ywritable += element.BackGroundHeight - (element.BackGroundHeight / 2) + (element.FontSize / 2); } /// /// Scrive l'elemento LinePDF nella pagina /// /// private void WriteElement(LinePDF element) { var color = new RgbColor((byte)element.Color.Red, (byte)element.Color.Green, (byte)element.Color.Blue); element.BaseElement = new Line(element.X1, element.Y1, element.X2, element.Y2, element.Width, color, element.BorderStyle); if (element.Y1 == 0) { element.BaseElement.Y1 = _ywritable; element.BaseElement.Y2 = _ywritable; } element.BaseElement.Y1 += element.DeltaY; element.BaseElement.Y2 += element.DeltaY; element.BaseElement.Y2 += element.DeltaY2ForVerticalLine; // Disegno il BaseElement _page.Elements.Add(element.ToElement()); if (element.DeltaY2ForVerticalLine == 0 && element.AutoIncrementYWritable) _ywritable += element.Width; } /// /// Scrive l'elemento ImagePDF nella pagina /// /// private void WriteElement(ImagePDF element) { var imageFound = true; try { // Imposto il sorgente dell'immagine element.BaseElement = string.IsNullOrEmpty(element.Path) ? new Image(element.File, element.X + element.DeltaX, element.Y, element.Scale) : new Image(element.Path, element.X + element.DeltaX, element.Y, element.Scale); } catch (Exception ex) { imageFound = false; } if (imageFound) { // Imposto Y element.BaseElement.Y = element.Y == 0 ? _ywritable : element.Y; element.BaseElement.Y += element.DeltaY; // Imposto dimensioni e allineamento element.BaseElement.Align = element.Align; if (element.Height > 0) element.BaseElement.Height = element.Height; if (element.Width > 0) element.BaseElement.Width = element.Width; // Disegno il BaseElement. _page.Elements.Add(element.ToElement()); if (element.AutoIncrementYWritable) _ywritable += element.BaseElement.Height; } } /// /// Scrive l'elemento TabellaPDF nella pagina /// La tabella è disegnata come un insieme di LabelPDF separate da LinePDF /// /// private void WriteElement(TablePDF element) { _ywritable += element.YOffset; var originalYWritable = _ywritable; if (element.Y == 0) element.Y = _ywritable; var dataSourceInput = element.DataSource; var rowsHeightList = new List(); int columnIndex = 0; int rowIndex = 0; int rowIndexPerPage = 0; // è l'indice della riga che si azzera al saltopagina. var columnsWidthOriginal = new List(); // è la larghezza originale delle colonne non modificata se impostata la Cell.ColSpan columnsWidthOriginal.AddRange(element.Columns.Select(o => o.Width)); // Imposto HeaderFontSize di tutte le colonne per cui non è stato impostato (=0) uguale a HeaderFontSize della relativa tabella. // Questo perché HeaderFontSize della tabella è variabile in funzione dello Style. element.Columns.FindAll(o => o.HeaderFontSize == 0).ToList().ForEach(c => c.HeaderFontSize = element.HeaderFontSize); #region Controllo dimensione della larghezza della tabella if (element.X + element.Width > XRightLimit) throw new Exception("La tabella è troppo grande in larghezza"); #endregion // TABLE TITLE //if (element.TableTitle != null) //{ // FormattedTextAreaPDF title = new FormattedTextAreaPDF(element.TableTitle, element.X + element.TableTitleDeltaX, element.Width) { FontBold = element.TableTitleFontBold, FontSize = element.TableTitleFontSize, FontColor = element.TableTitleFontColor, AutoIncrementYWritable = true }; // WriteElement(title); // WriteElement(new SpacePDF(5)); //} #region Recupero colonne del datatable da stampare e imposto il Datasource // Recupera le colonne in base alla proprietà Colonne della tabella. // Vengono escluse le colonne che non hanno la proprietà Nome impostata. var arrList = new ArrayList(); foreach (ColumnPDF c in element.Columns) { switch (c.TipoColonna) { case ColumnType.Testo: case ColumnType.Decimale: case ColumnType.Intero: case ColumnType.Percentuale: if (!string.IsNullOrEmpty(c.Name)) arrList.Add(c.Name); break; case ColumnType.Immagine: case ColumnType.Objectpdf: if (!string.IsNullOrEmpty(c.Id)) arrList.Add(c.Id); break; } // Imposto la colonna a visible=false se la larghezza è pari a 0 c.Visibile = c.Width != 0; } var strArray = (string[])arrList.ToArray(typeof(string)); #region Settaggio DataSource int numeroRigheInvisibili = 0; int numeroRigheTotali; if (element.DataSource == null) { #region Impostazione del datasource se non passato in input var dtDataSource = new DataTable("DataSource"); // Creo le colonne del dtDataSource foreach (var colonnaDataSource in element.Columns) { dtDataSource.Columns.Add(colonnaDataSource.Id); } for (int nRiga = 0; nRiga < element.RowsCount; nRiga++) { var drToAdd = dtDataSource.NewRow(); for (int nColonna = 0; nColonna < element.Columns.Count; nColonna++) { if (!string.IsNullOrEmpty(element.Cells[nColonna, nRiga].Value)) drToAdd[nColonna] = element.Cells[nColonna, nRiga].Value; else { try { var formattedtextareaToPrint = (FormattedTextAreaPDF)element.Cells[nColonna, nRiga].ValueObject; if (formattedtextareaToPrint != null) drToAdd[nColonna] = formattedtextareaToPrint.Text; } catch (Exception) { drToAdd[nColonna] = string.Empty; } } } if (element.Row[nRiga].Visible) dtDataSource.Rows.Add(drToAdd); } element.DataSource = dtDataSource; numeroRigheTotali = element.DataSource.Rows.Count; #endregion } else { #region Impostazione del datasource se passato in input #region Aggiunta manuale dei dati relativi alle colonne di tipo RISORSEEMBEDDED // Controllo se sono state aggiunte colonne di tipo IMMAGINE o OBJECTPDF. // Le colonne IMMAGINE con un "Name" impostato vengono escluse dall'aggiunta manuale. [In questo modo nella colonna verrà rendirizzata l'immagine definita del datasource, ad esempio "riseva.png, liquidita.png, etc"] var columnsEmbeddedOrObject = element.Columns.FindAll(col => col.TipoColonna == ColumnType.Objectpdf || (col.TipoColonna == ColumnType.Immagine && col.Name == string.Empty)); if (columnsEmbeddedOrObject.Count > 0) { foreach (ColumnPDF column in columnsEmbeddedOrObject) element.DataSource.Columns.Add(column.Id); } #endregion // imposto il datasource element.DataSource = element.DataSource.DefaultView.ToTable(false, strArray); if (columnsEmbeddedOrObject.Count > 0) { for (int nRiga = 0; nRiga < element.RowsCount; nRiga++) { for (int nColonna = 0; nColonna < element.Columns.Count; nColonna++) { if (!string.IsNullOrEmpty(element.Cells[nColonna, nRiga].Value)) element.DataSource.Rows[nRiga][nColonna] = element.Cells[nColonna, nRiga].Value; } } } numeroRigheTotali = element.DataSource.Rows.Count; // elimino le righe rese invisibili. for (int nRiga = element.RowsCount - 1; nRiga >= 0; nRiga--) { if (element.Row[nRiga].Visible == false) { element.DataSource.Rows[nRiga].Delete(); element.DataSource.AcceptChanges(); numeroRigheInvisibili++; } } #endregion } #region Merge da Cell.Value // Tutto ciò che è impostato a livello di Cell deve essere riportato nel DataSource for (int col = 0; col < element.DataSource.Columns.Count; col++) { for (int row = 0; row < element.DataSource.Rows.Count; row++) { if (!string.IsNullOrEmpty(element.Cells[col, row].Value)) { element.DataSource.Rows[row][col] = element.Cells[col, row].Value; } } } #endregion #endregion #endregion #region Righe alternate con sfondo bianco a sfondo grigio if (element.AlternateRow) { for (int i = 0; i < element.Row.Length; i++) { if (i % 2 != 0) element.Row[i].BackgroundGray = true; } } #endregion #region Recupero le note, associate alla tabella, da inserire sotto il footer della tabella e nel footer della pagina #region Note footer della pagina var notesFooterPage = element.Notes.FindAll(o => o.Position == TableNotePDF.TableNotePositionType.PièDiPagina); if (notesFooterPage.Count > 0) YLowerLimit -= _spacenotefooterpagePerpage + (notesFooterPage.Count * notesFooterPage[0].FontSize) * 2; else YLowerLimit -= _spacenotefooterpagePerpage; #endregion #region Note footer della tabella var notesFooterTable = element.Notes.FindAll(o => o.Position == TableNotePDF.TableNotePositionType.PièDiTabella); float variabileAltezzaTabellaPerPresenzaNote = element.AdditionalSpaceBelow; foreach (var note in notesFooterTable) { variabileAltezzaTabellaPerPresenzaNote += GetTextHeigth(note.Text, XRightLimit - XLeftLimit, note.FontSize); if (note.Image != null) variabileAltezzaTabellaPerPresenzaNote += 10; // ulteriore 10 se la nota contiene immagine } #endregion var arrayAsterischiNote_Intestazione = new string[1, element.DataSource.Columns.Count]; // array di righe e colonne dell'intestazione della tabella dove sono contenuti gli asterischi var arrayAsterischiNote_Corpo = new string[element.DataSource.Rows.Count, element.DataSource.Columns.Count]; // array di righe e colonne del dettaglio della tabella dove sono contenuti gli asterischi var arrayAsterischiNote_PieDiPagina = new string[1, element.FooterColumns.Count]; // array di righe e colonne del footer della tabella dove sono contenuti gli asterischi foreach (TableNotePDF note in element.Notes) { if (note.TypeMarker == TableNotePDF.TableNoteTypemarker.Asterisco) { if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.CorpoTabella) { #region Asterischi del dettaglio della tabella var rowNoteFooterTable = dataSourceInput.Select(note.Condition); //element.DataSource.Select(note.Condition); if (rowNoteFooterTable.Length.Equals(0)) { notesFooterTable.Remove(note); //Rimuovo le note che non trovano corrispondenza. continue; } if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); foreach (var row in rowNoteFooterTable) { int indiceColonna = 0; int indiceRiga; foreach (ColumnPDF column in element.Columns) { switch (note.MappingType) { case TableNotePDF.TableNoteMappingType.Fisso: indiceRiga = dataSourceInput.Rows.IndexOf(row); if (note.MappingFields.Contains(column.Id.ToLower())) { if (string.IsNullOrEmpty(arrayAsterischiNote_Corpo[indiceRiga, indiceColonna])) arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] = TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); else arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] += " " + TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); } break; case TableNotePDF.TableNoteMappingType.Dinamico: bool astericoPresente = false; indiceRiga = new DataView(dataSourceInput).ToTable(false, new[] { note.MappingKey }) .AsEnumerable() .Select(riga => riga.Field(note.MappingKey)) .ToList() .FindIndex(o => o == Convert.ToInt32(row[note.MappingKey])); //Recupero la ConditionFields che ha il nome che inizia con column.Id var campo = note.ConditionFields.FirstOrDefault(o => o.ToLower().StartsWith(column.Id.ToLower())); if (campo != null) astericoPresente = Convert.ToInt32(dataSourceInput.Rows[indiceRiga][campo]) == note.ConditionValue; if (astericoPresente) { if (string.IsNullOrEmpty(arrayAsterischiNote_Corpo[indiceRiga, indiceColonna])) arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] = TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); else arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] += " " + TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); } break; } indiceColonna++; } } } #endregion } else if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.IntestazioneTabella) { #region Asterischi dell'intestazione della tabella if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); int indiceColonna = 0; foreach (ColumnPDF column in element.Columns) { if (note.MappingFields.Contains(column.Id.ToLower())) arrayAsterischiNote_Intestazione[0, indiceColonna] = TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); indiceColonna++; } } #endregion } else if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.PieDiTabella) { #region Asterischi del footer della tabella if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); int indiceColonna = 0; foreach (ColumnPDF column in element.FooterColumns) { if (note.MappingFields.Contains(column.Id.ToLower())) arrayAsterischiNote_PieDiPagina[0, indiceColonna] = TableNotePDF.ToAsteriskString(GetAsterisksNumber(note)); indiceColonna++; } } #endregion } } else { if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.CorpoTabella) { #region Asterischi del dettaglio della tabella var rowNoteFooterTable = dataSourceInput.Select(note.Condition); //element.DataSource.Select(note.Condition); if (rowNoteFooterTable.Length.Equals(0)) { notesFooterTable.Remove(note); //Rimuovo le note che non trovano corrispondenza. continue; } if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); foreach (var row in rowNoteFooterTable) { int indiceColonna = 0; int indiceRiga; foreach (ColumnPDF column in element.Columns) { switch (note.MappingType) { case TableNotePDF.TableNoteMappingType.Fisso: indiceRiga = dataSourceInput.Rows.IndexOf(row); if (note.MappingFields.Contains(column.Id.ToLower())) { if (string.IsNullOrEmpty(arrayAsterischiNote_Corpo[indiceRiga, indiceColonna])) arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] = TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); else arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] += " " + TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); } break; case TableNotePDF.TableNoteMappingType.Dinamico: bool astericoPresente = false; indiceRiga = new DataView(dataSourceInput).ToTable(false, new[] { note.MappingKey }) .AsEnumerable() .Select(riga => riga.Field(note.MappingKey)) .ToList() .FindIndex(o => o == Convert.ToInt32(row[note.MappingKey])); //Recupero la ConditionFields che ha il nome che inizia con column.Id var campo = note.ConditionFields.FirstOrDefault(o => o.ToLower().StartsWith(column.Id.ToLower())); if (campo != null) astericoPresente = Convert.ToInt32(dataSourceInput.Rows[indiceRiga][campo]) == note.ConditionValue; if (astericoPresente) { if (string.IsNullOrEmpty(arrayAsterischiNote_Corpo[indiceRiga, indiceColonna])) arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] = TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); else arrayAsterischiNote_Corpo[indiceRiga, indiceColonna] += " " + TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); } break; } indiceColonna++; } } } #endregion } else if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.IntestazioneTabella) { #region Asterischi dell'intestazione della tabella if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); int indiceColonna = 0; foreach (ColumnPDF column in element.Columns) { if (note.MappingFields.Contains(column.Id.ToLower())) arrayAsterischiNote_Intestazione[0, indiceColonna] = TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); indiceColonna++; } } #endregion } else if (note.AsterisksPosition == TableNotePDF.TableNoteAsteriskPositionType.PieDiTabella) { #region Asterischi del footer della tabella if (note.MappingFields != null) { // ToLower di tutti gli elementi memorizzati in ListIdColumnsAssociatedNote. for (int i = 0; i < note.MappingFields.Length; i++) note.MappingFields[i] = note.MappingFields[i].ToLower(); int indiceColonna = 0; foreach (ColumnPDF column in element.FooterColumns) { if (note.MappingFields.Contains(column.Id.ToLower())) arrayAsterischiNote_PieDiPagina[0, indiceColonna] = TableNotePDF.ToNumberAsteriskString(GetAsterisksNumber(note)); indiceColonna++; } } #endregion } } } #endregion #region Recupero le altezze di ogni riga e popolo la rowsHeightList float rowHeight; // altezza calcolata della riga corrente; foreach (DataRow dr in element.DataSource.Rows) { rowHeight = element.RowHeight; // altezza calcolata della riga corrente; columnIndex = 0; foreach (DataColumn dc in element.DataSource.Columns) { var testoCella = string.Format("{0}{1}", dr[dc], arrayAsterischiNote_Corpo[rowIndex, columnIndex] ?? string.Empty); var fontBold = false; if (element.DataSource.Columns.Contains("FontBold")) fontBold = Convert.ToBoolean(dr["FontBold"]); float tempRowHeight = GetTextHeigth(testoCella, element.Columns[columnIndex].Width - element.Columns[columnIndex].PaddingLeft, element.Columns[columnIndex].FontSize, fontBold, element.Columns[columnIndex].TipoColonna); // altezza calcolata della riga corrente; rowHeight = tempRowHeight > rowHeight ? tempRowHeight : rowHeight; if (element.MinimumRowHeight > 0) rowHeight = rowHeight < element.MinimumRowHeight ? element.MinimumRowHeight : rowHeight; columnIndex++; } if (element.SpecifiedRowHeights.Count > rowIndex) { rowHeight = element.SpecifiedRowHeights[rowIndex]; } //Aggiungo alla lista rowsHeightList.Add(rowHeight); rowIndex++; } rowIndex = 0; columnIndex = 0; #endregion float y = element.Y; float yTextToPrint = y + variabileAltezzaTabellaPerPresenzaNote; float xTextToPrint; bool autoincrementY = true; bool printedTitleRow = false; // il title row di una tabella deve essere stampato una sola volta, anche se la tabella effettuta un salto pagina _printinginnewpage = true; #region Stampo l'Header della tabella se sono state rese invisibili tutte le righe del datasource if (numeroRigheInvisibili == numeroRigheTotali) // in questo caso devo stampare comunque l'header della tabella. { TablePDF_DrawHeader(element, arrayAsterischiNote_Intestazione); y = _ywritable; y += element.HeaderHeight + element.HeaderMargin; } #endregion foreach (DataRow dr in element.DataSource.Rows) // Scorro tutte le righe del DataSource { float x = element.X; if (element.Y > YLowerLimit) _ywritable = YUpperLimit; // --- Patryk: RowsIndexesThatCantEndPage // Ernesto Usare questo per Salto Pagina if (element.RowsIndexesThatCantEndPage.Count() > 0 && element.RowsIndexesThatCantEndPage.Contains(rowIndex) && yTextToPrint > element.RowsIndexesThatCantEndPageYLimit && element.RowsIndexesThatCantEndPageYLimit != 0) //if (element.RowsIndexesThatCantEndPage.Count() > 0 && // element.RowsIndexesThatCantEndPage.Contains(rowIndex) && // _ywritable > element.RowsIndexesThatCantEndPageYLimit && // element.RowsIndexesThatCantEndPageYLimit != 0) { WriteElement(new LinePDF(element.X, y, element.X + element.Width, y, 0.5F, new ColorPDF(153, 148, 133))); // lineaOrizzontale WriteNoteFooterPage(notesFooterPage); TablePDF_ContinuedOnNextPage(); } // --------------------------------------- #region Recupero altezza massima della riga corrente e quella successiva (necessario per il salto pagina) rowHeight = rowsHeightList[rowIndex]; float nextRowHeight = rowIndex == rowsHeightList.Count - 1 ? 0 : rowsHeightList[rowIndex + 1]; // altezza temporanea della riga successiva; #endregion #region Salto pagina su ultime 2 righe della tabella // Se sto per stampare le ultime 2 righe, e la tabella contiene un footer, controllo che // il footer sia contenuto comunque nella pagina corrente, altrimenti ne aggiungo 1 e // gli elementi restanti (2 righe + footer) vengono stampati nella nuova pagina. // Considero anche la possibilità che la tabella abbia note aggiuntive sotto al footer float variabilePerPresenzaTitleRow = 0; float variabilePerPresenzaFooterDatasource = 0; if (rowIndex == element.DataSource.Rows.Count - 2 && element.Footer && element.PageBreak) { //variabileAltezzaTabellaPerPresenzaNota = 10 * notesFooterTable.Count; variabilePerPresenzaTitleRow = element.TitleRow ? element.TitleRowHeight + element.TitleRowSpace : 0; variabilePerPresenzaFooterDatasource = element.FooterDatasource != null ? element.FooterHeight * element.FooterDatasource.Rows.Count : element.FooterHeight; if (y + (rowHeight + nextRowHeight) + variabilePerPresenzaFooterDatasource + variabileAltezzaTabellaPerPresenzaNote + variabilePerPresenzaTitleRow + 10 > YLowerLimit) //+ 10: ulteriore margine di sicurezza per evitare sforamenti { if (element.ShowBorderLastLineInPageBreak) WriteElement(new LinePDF(element.X, y, element.X + element.Width, y, 0.5F, new ColorPDF(153, 148, 133))); // lineaOrizzontale _ywritable = YLowerLimit; // Controllo qui se la tabella ha solamente 2 righe. // In tal caso non disegno ne le note nel footer ne il salto pagina ma vado direttamente a pagina nuova. if (!element.DataSource.Rows.Count.Equals(2)) { WriteNoteFooterPage(notesFooterPage); TablePDF_ContinuedOnNextPage(); } y = _ywritable; element.Y = y; rowIndexPerPage = -1; } } #endregion #region Disegno il TitleRow ( Titolo sopra l'Header della tabella ) if (element.TitleRow && _printinginnewpage && printedTitleRow == false) { if (_reportEnvironment.ReportType == ReportType.Base_Proposta) { printedTitleRow = TablePDF_DrawTitleRow(element); y = _ywritable; } else { printedTitleRow = TablePDF_DrawTitleRow(element, true); y = _ywritable;// +element.TitleRowHeight; } } #endregion #region Disegno dell'Header della tabella if (element.Header && _printinginnewpage) { TablePDF_DrawHeader(element, arrayAsterischiNote_Intestazione); y = _ywritable; y += element.HeaderHeight + element.HeaderMargin; } #endregion #region Disegno il BorderContent if (element.ShowBorderContent) { if (rowIndex == 0) // Disegno il bordo sulla prima riga { if (element.ShowBorderFooter) { //bordoSuperiore WriteElement(new LinePDF(element.X - 1, ((element.X - 1) + element.Width + 1)) { AutoIncrementYWritable = false, DeltaY = -1 }); //bordoSuperioreSinistro WriteElement(new LinePDF(element.X - 1, element.X - 1) { AutoIncrementYWritable = false, DeltaY2ForVerticalLine = 10 }); //bordoSuperioreDestro WriteElement(new LinePDF((element.X - 1) + (element.Width + 1) + 1, (element.X - 1) + (element.Width + 1) + 1) { AutoIncrementYWritable = false, DeltaY2ForVerticalLine = 10 }); } } else if (rowIndex == element.DataSource.Rows.Count - 1) // Disegno il bordo sull'ultima riga { //bordoInferiore WriteElement(new LinePDF(element.X - 1, y + rowHeight, ((element.X - 1) + element.Width + 1), y + rowHeight) { AutoIncrementYWritable = false, DeltaY = -1 }); //bordoInferioreSinistro WriteElement(new LinePDF(element.X - 1, y + rowHeight, element.X - 1, y + rowHeight) { AutoIncrementYWritable = false, DeltaY2ForVerticalLine = -10 }); //bordoInferioreDestro WriteElement(new LinePDF((element.X - 1) + (element.Width + 1) + 1, y + rowHeight, (element.X - 1) + (element.Width + 1) + 1, y + rowHeight) { AutoIncrementYWritable = false, DeltaY2ForVerticalLine = -10 }); } } #endregion // -start foreach (DataColumn dc in element.DataSource.Columns) // Scorro tutte le colonne del DataSource { // Il testo della cella è recuperato dalla relativa colonna del DataSource var testoCella = string.Format("{0}{1}", dr[dc], arrayAsterischiNote_Corpo[rowIndex, columnIndex] ?? string.Empty); // Recupero il testo della cella dalla collezione Cells se specificato un value. if (!string.IsNullOrEmpty(element.Cells[columnIndex, rowIndex].Value)) testoCella = element.Cells[columnIndex, rowIndex].Value; #region Gestione del ColSpan della cella e ridefinizione della larghezza della colonna. if (element.Cells[columnIndex, rowIndex].ColSpan > 0) { int countcolumnspan = element.Cells[columnIndex, rowIndex].ColSpan;//quante colonne compongono il colspan inclusa la cella che ha la proprietà if ((columnIndex + countcolumnspan) > element.Columns.Count) throw new Exception("TablePDF: ColSpan non può essere maggiore del numero di colonne"); for (int f = 1; f < countcolumnspan; f++) { //aumento la larghezza della colonna corrente (columnIndex) con la somma delle altre colonne interessate da colspan element.Columns[columnIndex].Width += element.Columns[columnIndex + f].Width; // Azzero tutte le restanti interessate dal colspan element.Columns[columnIndex + f].Width = 0; element.Columns[columnIndex + f].Visibile = false; } } #endregion #region Allineamento orizzontale // Allineamento preso a livello di colonna var textHorizontalAlign = GetTextAlign(element.Columns[columnIndex].HorizontalAlignment); // Allineamento preso a livello di cella if (element.Cells[columnIndex, rowIndex].HorizontalAlignment != HorizontalAlignmentType.Nonimpostato) textHorizontalAlign = GetTextAlign(element.Cells[columnIndex, rowIndex].HorizontalAlignment); #endregion #region Allineamento verticale e recupero della Y su cui scrivere la riga switch (element.Columns[columnIndex].VerticalAlignment) { case VerticalAlignmentType.Alto: yTextToPrint = y + element.Columns[columnIndex].DeltaYContent; break; case VerticalAlignmentType.Basso: yTextToPrint = y + rowHeight - element.Columns[columnIndex].FontSize; break; case VerticalAlignmentType.Centrato: var fontBold = false; if (element.DataSource.Columns.Contains("FontBold")) fontBold = Convert.ToBoolean(dr["FontBold"]); float textHeight = GetTextHeigth( testoCella, element.Columns[columnIndex].Width - element.Columns[columnIndex].PaddingLeft, element.Columns[columnIndex].FontSize, fontBold, element.Columns[columnIndex].TipoColonna); float delta = textHeight == 0 ? 0 : rowHeight - textHeight; yTextToPrint = y + (delta / 2) + element.Columns[columnIndex].DeltaYContent; // + incrementWidthSeparationLines; break; } #endregion var colorRectangleBackground = ColorPDF.Bianco; // Bianco di default #region BackgroundGray della riga if (element.Row[rowIndex].BackgroundColor != null) colorRectangleBackground = element.Row[rowIndex].BackgroundColor; if (element.Row[rowIndex].BackgroundGray) colorRectangleBackground = ColorPDF.Standard_Grigio_SfondoColonnaTabella; // Disegno lo sfondo grigio se impostata la proprietà BackgroundGray dell'oggetto Row. if (element.Row[rowIndex].BackgroundGray || element.Row[rowIndex].BackgroundColor != null) WriteElement(new RectanglePDF(x, y, rowHeight + element.RowsPadding, element.Columns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }); // x+1 per evitare che il riquadro grigio copra il testo #endregion //start2 #region BackgroundGray e BackgroundColor della colonna // Aggiungo un rettangolo di sfondo (BackgroundGray o BackgroundColor) della COLONNA. if (element.Columns[columnIndex].BackgroundGray || element.Columns[columnIndex].BackgroundColor != null) { colorRectangleBackground = element.Columns[columnIndex].BackgroundColor; if (element.Columns[columnIndex].BackgroundGray) colorRectangleBackground = ColorPDF.Standard_Grigio_SfondoColonnaTabella; RectanglePDF rectangleBackground = null; if (element.WhiteSpacesHorizontalSeparator) { rectangleBackground = new RectanglePDF(x, y, rowHeight - 3, element.Columns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; } else { rectangleBackground = new RectanglePDF(x, y, rowHeight, element.Columns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; } // Se è impostato un BackgroundColor sulla colonna, rectangleBackground avrà Height pari a Height + RowsPadding, // in modo da riempire completamente la colonna senza lasciare spazi bianchi. if (element.Columns[columnIndex].BackgroundColor != null) { rectangleBackground.Height += element.RowsPadding + 1; } rectangleBackground.Height += element.RowsHeightOffset; if (!element.RowsIndexesThatIgnoreColumnBackgroundColor.Contains(rowIndex)) { WriteElement(rectangleBackground); } } #endregion #region BackgroundGray e BackgroundColor della cella // Aggiungo un rettangolo di sfondo (BackgroundColor) della CELLA. if (element.Cells[columnIndex, rowIndex].BackgroundColor != null) { colorRectangleBackground = element.Cells[columnIndex, rowIndex].BackgroundColor; RectanglePDF rectangleBackground = null; if (element.WhiteSpacesHorizontalSeparator) { // Quando è impostato un BackgroundColor sulla riga, rectangleBackground avrà Height pari a Height + RowsPadding, // in modo da riempire completamente la riga senza lasciare spazi bianchi. rectangleBackground = new RectanglePDF(x, y, rowHeight + element.RowsPadding - 1, element.Columns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; var rectangleWhiteSpace = new RectanglePDF(x, y + rectangleBackground.Height, 1, element.Columns[columnIndex].Width, new ColorPDF(255, 255, 255)) { AutoIncrementYWritable = true }; WriteElement(rectangleBackground); WriteElement(rectangleWhiteSpace); } else { rectangleBackground = new RectanglePDF(x, y, rowHeight + element.RowsPadding + element.RowsHeightOffset + (element.RowsHeightOffset != 0 ? +1 : 0), element.Columns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; WriteElement(rectangleBackground); } } #endregion //end2 #region Disegno cella // Disegno la cella. La cella è una FormattedTextAreaPDF if (element.Columns[columnIndex].Visibile) { if ((element.Columns[columnIndex].TipoColonna == ColumnType.Testo || element.Columns[columnIndex].TipoColonna == ColumnType.Decimale || element.Columns[columnIndex].TipoColonna == ColumnType.Intero || element.Columns[columnIndex].TipoColonna == ColumnType.Percentuale) && !(dr[dc].ToString().ToLower().Contains("flags") && dr[dc].ToString().ToLower().Contains(".png"))) { #region TIPO DI COLONNA TESTO o DECIMALE o INTERO o PERCENTUALE // FormattedTextAreaPDF testo della singola cella. var textToPrint = new FormattedTextAreaPDF(); var fontColor = ColorPDF.Nero; switch (element.Style) { case Style.ConsulenzaBase: case Style.ConsulenzaUnica: fontColor = ColorPDF.Nero; break; case Style.Immobiliare: fontColor = ColorPDF.Immobiliare_Grigio_TestoStandard; // Grigio break; default: break; } bool fontBold = false; var fontSize = 0F; bool forcestylerow_fontbold = false; bool forcestylerow_fontcolor = false; bool forcestylecolumn_fontbold = false; bool forcestylecolumn_fontcolor = false; #region Attributi FontSize, FontBold, FontColor della RIGA if (element.Row != null) { if (element.Row[rowIndex].FontBold.HasValue) // grassetto dell'intera riga (se specificato) fontBold = element.Row[rowIndex].FontBold.Value; if (element.Row[rowIndex].FontColor != null) // colore dell'intera riga (se specificato) fontColor = element.Row[rowIndex].FontColor; forcestylerow_fontbold = element.Row[rowIndex].ForceStyleFontBold; forcestylerow_fontcolor = element.Row[rowIndex].ForceStyleFontColor; } #endregion #region Attributi FontSize, FontBold, FontColor della COLONNA forcestylecolumn_fontbold = element.Columns[columnIndex].ForceStyleFontBold; forcestylecolumn_fontcolor = element.Columns[columnIndex].ForceStyleFontColor; if (!forcestylerow_fontcolor || forcestylecolumn_fontcolor) { if (element.Columns[columnIndex].FontColor != null) fontColor = element.Columns[columnIndex].FontColor; } if (!forcestylerow_fontbold || forcestylecolumn_fontbold) { if (element.Columns[columnIndex].FontBold.HasValue) fontBold = element.Columns[columnIndex].FontBold.Value; } #endregion #region Attributi FontSize, FontBold, FontColor della CELLA fontSize = element.Columns[columnIndex].FontSize; // eredito quello della colonna. if (!forcestylerow_fontcolor) { if (element.Cells[columnIndex, rowIndex].FontColor != null) fontColor = element.Cells[columnIndex, rowIndex].FontColor; } if (!forcestylerow_fontbold) { if (element.Cells[columnIndex, rowIndex].FontBold.HasValue) fontBold = element.Cells[columnIndex, rowIndex].FontBold.Value; } #endregion // Testo della singola cella. var stringTextToPrint = string.Empty; switch (element.Columns[columnIndex].TipoColonna) { case ColumnType.Testo: stringTextToPrint = testoCella; if (element.Cells[columnIndex, rowIndex].ReplaceIfZero != string.Empty) if (testoCella.Equals("0,00")) stringTextToPrint = testoCella.Replace("0,00", element.Cells[columnIndex, rowIndex].ReplaceIfZero); break; case ColumnType.Decimale: stringTextToPrint = element.Cells[columnIndex, rowIndex].ReplaceIfZero != string.Empty ? Convert.ToDecimal(testoCella).Equals(0) ? element.Cells[columnIndex, rowIndex].ReplaceIfZero : Helper.FormatCurrency(testoCella) : Helper.FormatCurrency(testoCella); break; case ColumnType.Intero: stringTextToPrint = element.Cells[columnIndex, rowIndex].ReplaceIfZero != string.Empty ? Convert.ToDecimal(testoCella).Equals(0) ? element.Cells[columnIndex, rowIndex].ReplaceIfZero : Helper.FormatInteger(testoCella) : Helper.FormatInteger(testoCella); break; case ColumnType.Percentuale: stringTextToPrint = Helper.FormatPercentage(testoCella, 2); break; } // Incremento della X a livello di Colonna. // Se è impostato un allineamento a livello di Cella, l'incremento viene fatto solo se tale allineamento è Nonimpostato oppure Sinistra. if (element.Cells[columnIndex, rowIndex].HorizontalAlignment == HorizontalAlignmentType.Nonimpostato || element.Cells[columnIndex, rowIndex].HorizontalAlignment == HorizontalAlignmentType.Sinistra) xTextToPrint = TablePDF_GetXTextContent(x + element.Columns[columnIndex].PaddingLeft, columnIndex, element); else xTextToPrint = x + element.Columns[columnIndex].PaddingLeft; xTextToPrint += element.Cells[columnIndex, rowIndex].XContentOffset; textToPrint = new FormattedTextAreaPDF(stringTextToPrint, xTextToPrint, element.Columns[columnIndex].Width - element.Columns[columnIndex].PaddingLeft - element.Columns[columnIndex].PaddingRight, textHorizontalAlign) { Y = yTextToPrint + element.Cells[columnIndex, rowIndex].YContentOffset, FontSize = fontSize, FontColor = fontColor, FontBold = fontBold, AutoIncrementYWritable = autoincrementY }; //Scrivo il testo. WriteElement(textToPrint); #endregion } else if (element.Columns[columnIndex].TipoColonna == ColumnType.Immagine || (dr[dc].ToString().ToLower().Contains("flags") && dr[dc].ToString().ToLower().Contains(".png"))) { #region TIPO DI COLONNA IMMAGINE ImagePDF imageToPrint; if (dr[dc].ToString() != string.Empty) { #region Allineamento orizzontale dell'immagine float xImmagine = x; Align imageAlignX; switch (textHorizontalAlign) { case TextAlign.Center: imageAlignX = Align.Center; xImmagine = xImmagine + (element.Columns[columnIndex].Width / 2); break; case TextAlign.Left: imageAlignX = Align.Left; break; case TextAlign.Right: imageAlignX = Align.Right; xImmagine = xImmagine + element.Columns[columnIndex].Width; break; default: imageAlignX = Align.Left; break; } #endregion xTextToPrint = xImmagine + element.Columns[columnIndex].PaddingLeft; imageToPrint = new ImagePDF(TablePDF_GetXTextContent(xTextToPrint, columnIndex, element), element.Columns[columnIndex].ScaleColumnTypeImage, dr[dc].ToString(), imageAlignX, yTextToPrint + element.Columns[columnIndex].PaddingTopImage); //float deltaYOffset = 0; //switch (element.Columns[columnIndex].VerticalAlignment) //{ // case VerticalAlignmentType.Centrato: // var testElement = new Image(imageToPrint.Path, 0, 0, imageToPrint.Scale); // deltaYOffset = (rowHeight - testElement.Height) / 2; // break; //} //imageToPrint.DeltaY += deltaYOffset; WriteElement(imageToPrint); } #endregion } else if (element.Columns[columnIndex].TipoColonna == ColumnType.Objectpdf) { #region TIPO DI COLONNA OBJECTPDF var itemsList = element.Cells[columnIndex, rowIndex].ValueObjectList; if (!itemsList.Any()) if (element.Cells[columnIndex, rowIndex].ValueObject != null) itemsList.Add(element.Cells[columnIndex, rowIndex].ValueObject); // Disegno l'oggetto PDF associato alla proprietà ValuePDF dell'oggetto Cella ( RectanglePDF o CirclePDF ). // Per ora si possono aggiungere solo RectanglePDF, CirclePDF, FormattedTextAreaPDF se dovesse esserci necessità andrà migliorata la funzionalità. if (itemsList.Any()) { foreach (var item in itemsList) { var parameterType = item.GetType(); string name = parameterType.Name; switch (name.ToLower()) { case "rectanglepdf": { var rectToPrint = (RectanglePDF)item; #region Allineamento orizzontale var xObjectPdf = 0F; switch (element.Columns[columnIndex].HorizontalAlignment) { case HorizontalAlignmentType.Nonimpostato: case HorizontalAlignmentType.Sinistra: xObjectPdf = x + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Centrato: xObjectPdf = ((x + element.Columns[columnIndex].Width / 2) - (rectToPrint.Width / 2)) + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Destra: xObjectPdf = x + element.Columns[columnIndex].Width - rectToPrint.Width; break; } #endregion rectToPrint.X = xObjectPdf; rectToPrint.X += rectToPrint.DeltaX; rectToPrint.Y = yTextToPrint + rectToPrint.DeltaY; rectToPrint.AutoIncrementYWritable = false; WriteElement(rectToPrint); } break; case "circlepdf": { var circleToPrint = (CirclePDF)item; #region Allineamento orizzontale var xObjectPdf = 0F; switch (element.Columns[columnIndex].HorizontalAlignment) { case HorizontalAlignmentType.Nonimpostato: case HorizontalAlignmentType.Sinistra: xObjectPdf = x + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Centrato: break; case HorizontalAlignmentType.Destra: xObjectPdf = x + element.Columns[columnIndex].Width - circleToPrint.Width; break; } #endregion circleToPrint.X = xObjectPdf; circleToPrint.Y = yTextToPrint + circleToPrint.DeltaY; circleToPrint.AutoIncrementYWritable = false; WriteElement(circleToPrint); } break; case "formattedtextareapdf": { var formattedtextareaToPrint = (FormattedTextAreaPDF)item; #region Allineamento orizzontale var xObjectPdf = 0F; switch (element.Columns[columnIndex].HorizontalAlignment) { case HorizontalAlignmentType.Nonimpostato: case HorizontalAlignmentType.Sinistra: xObjectPdf = x + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Centrato: break; case HorizontalAlignmentType.Destra: xObjectPdf = x + element.Columns[columnIndex].Width - formattedtextareaToPrint.Width; break; } #endregion formattedtextareaToPrint.X = xObjectPdf; formattedtextareaToPrint.Y = yTextToPrint + formattedtextareaToPrint.DeltaY; formattedtextareaToPrint.AutoIncrementYWritable = false; WriteElement(formattedtextareaToPrint); } break; case "imagepdf": { var imageToPrint = (ImagePDF)item; #region Allineamento orizzontale var xObjectPdf = 0F; switch (element.Columns[columnIndex].HorizontalAlignment) { case HorizontalAlignmentType.Nonimpostato: case HorizontalAlignmentType.Sinistra: xObjectPdf = x + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Centrato: xObjectPdf = ((x + element.Columns[columnIndex].Width / 2) - (imageToPrint.Width / 2)) + element.Columns[columnIndex].PaddingLeft; break; case HorizontalAlignmentType.Destra: xObjectPdf = x + element.Columns[columnIndex].Width - imageToPrint.Width; break; } #endregion imageToPrint.X = xObjectPdf; imageToPrint.X += imageToPrint.DeltaX; imageToPrint.Y = yTextToPrint + imageToPrint.DeltaY; imageToPrint.AutoIncrementYWritable = false; WriteElement(imageToPrint); } break; } } } #endregion } #region Linee di separazione delle righe (ShowSeparationLines) if (element.ShowSeparationLines) { if (!element.IndexesOfSeparatorsToIgnore.Contains(columnIndex)) { if (!element.IndexesOfRowLinesToIgnoreSeparators.Contains(rowIndex)) { var colorSeparationLine = element.Columns[columnIndex].BackgroundGray ? ColorPDF.Bianco : ColorPDF.Standard_Grigio_SfondoColonnaTabella; if (element.Cells[columnIndex, rowIndex].HorizontalSeparatorColor != null) { colorSeparationLine = element.Cells[columnIndex, rowIndex].HorizontalSeparatorColor; } // linea separatrice var separationLine = new RectanglePDF(x, y + rowHeight, element.WidthSeparationLines, element.Columns[columnIndex].Width, colorSeparationLine) { AutoIncrementYWritable = false }; if (y < YLowerLimit) { if (element.HideLastSeparationLine) { // Non viene disegnata la linea di separazione all'ultima riga if (rowIndex != element.DataSource.Rows.Count - 1) WriteElement(separationLine); } else if (element.HideFirstSeparationLine) { if (rowIndex != 0) WriteElement(separationLine); } else WriteElement(separationLine); } } } } #endregion #region Border della riga // Disegno una riga in alto e una in basso che fanno da bordo alla riga if (element.Row[rowIndex].Border) { bool drawBorder = !element.Row[rowIndex].ShowBorderInColumnImage == false && element.Columns[columnIndex].TipoColonna == ColumnType.Immagine; if (drawBorder) { var colorBorderLine = ColorPDF.Nero; switch (element.Style) { case Style.ConsulenzaBase: case Style.ConsulenzaUnica: colorBorderLine = ColorPDF.Nero; break; case Style.Immobiliare: colorBorderLine = ColorPDF.Immobiliare_Grigio_TitoloPiccolo; break; default: break; } if (element.Columns[columnIndex].BackgroundGray || element.Columns[columnIndex].BackgroundColor != null) colorBorderLine = ColorPDF.Bianco; //Bianco if (element.Row[rowIndex].BorderType == BorderRowType.Entrambi || element.Row[rowIndex].BorderType == BorderRowType.Alto) { // Linea superiore if (rowIndexPerPage > 0) // la prima riga, essendo poco stotto la linea di chiusura della header della tabella, non viene disegnata. WriteElement(new LinePDF(x, y - element.RowsPadding / 2, (float)(x + element.Columns[columnIndex].Width), y - element.RowsPadding / 2, 0.1F, colorBorderLine) { AutoIncrementYWritable = false }); } if (element.Row[rowIndex].BorderType == BorderRowType.Entrambi || element.Row[rowIndex].BorderType == BorderRowType.Basso) { //// Linea inferiore WriteElement(new LinePDF(x, y + rowHeight + (element.RowsPadding / 2), (float)(x + element.Columns[columnIndex].Width), y + rowHeight + (element.RowsPadding / 2), 0.1F, colorBorderLine) { AutoIncrementYWritable = false }); } } } #endregion x += element.Columns[columnIndex].Width; } #endregion columnIndex++; autoincrementY = false; } // -end columnIndex = 0; if (element.ID == "debug") WriteElement(new LinePDF(element.X, y, element.X + element.Width, y, 1, ColorPDF.Rosso) { AutoIncrementYWritable = false }); // ******************* INCREMENTO DELLA Y *************************** y += rowHeight + element.RowsPadding + (element.ShowSeparationLines ? element.WidthSeparationLines + 1 : 0); // ******************* FINE INCREMENTO DELLA Y ********************** if (element.ID == "debug") WriteElement(new LinePDF(element.X, y, element.X + element.Width, y, 1, ColorPDF.Giallo) { AutoIncrementYWritable = false }); #region Salto pagina e Stampa delle Note associate alla tabella da stampare a piè di pagina #region Salto pagina forzato "CanLastRow" bool pageBreakForced = false; if (dataSourceInput != null && dataSourceInput.Columns.Contains("CanLastRow")) { // indica se la prossima riga che sarà stampata può essere l'ultima. var prossimaPuoEssereUltimaRiga = true; if (rowIndex + 1 <= dataSourceInput.Rows.Count - 1) prossimaPuoEssereUltimaRiga = Convert.ToBoolean(dataSourceInput.Rows[rowIndex + 1]["CanLastRow"]); if (prossimaPuoEssereUltimaRiga == false) { // Se la prossima riga non può essere l'ultima nella pagina devo anticipare il salto pagina e renderlo "forzato". (pageBreakForced) // Controllo dunque: // 1) la nextRowHeight abbia spazio a sufficienza per essere disegnata (*2 non è un calcolo corretto. Dovrei sapere quanto è alta la riga ancora successiva ma attualmente non è possibile.) // 2) possibile salto pagina nel caso in cui le ultime 2 righe della tabella non entrino nella pagina corrente. var altezzaProssimeRighe = rowsHeightList.Skip(rowIndex + 1).Take(2).Sum(); // Sommo l'altezza delle successive 2 righe (take 2) alla riga successiva a quella corrente (Skip rowIndex + 1) var ySaltoPagina = y + altezzaProssimeRighe + variabilePerPresenzaFooterDatasource + variabileAltezzaTabellaPerPresenzaNote + variabilePerPresenzaTitleRow + 10; pageBreakForced = (ySaltoPagina > YLowerLimit) || ((rowIndex + 2 == element.DataSource.Rows.Count - 2) && ySaltoPagina + altezzaProssimeRighe > YLowerLimit); } } #endregion // Verifico se l'altezza della prossima riga che dovrà essere scritta (nextRowHeight) supera il _ylowerlimit. // Se supera il limite aggiungo una nuova pagina al documento e il resto della tabella verrà disegnata nella nuova pagina. if ((y + nextRowHeight + 15 >= YLowerLimit && element.PageBreak) || pageBreakForced || (element.TableCantReachThisYPosition != 0 && y + nextRowHeight + 15 >= element.TableCantReachThisYPosition)) // +15 = spazio per scivere il testo di cambio pagina { if (element.ShowBorderLastLineInPageBreak) WriteElement(new LinePDF(element.X, y, element.X + element.Width, y, 0.5F, new ColorPDF(153, 148, 133))); // lineaOrizzontale if (element.ShowNotesFooterPageForAllPages) WriteNoteFooterPage(notesFooterPage); _ywritable = YLowerLimit; // effettuo il saltopagina della tabella. TablePDF_ContinuedOnNextPage(); y = _ywritable; element.Y = y; rowIndexPerPage = -1; } else if (rowIndex == element.DataSource.Rows.Count - 1) // sto stampando l'ultima riga e quindi stampo le Note associate alla tabella da stampare a piè di pagina { WriteNoteFooterPage(notesFooterPage); _ywritable = y; } #endregion #region Disegno il Border sull'ultima riga se richiesto e non è presente il footer if (element.ShowBorderLastLine && element.Footer == false && rowIndex == element.DataSource.Rows.Count - 1) { switch (element.Style) { case Style.ConsulenzaBase: WriteElement(new LinePDF(element.X, y, element.Width + element.X, y)); // lineaOrizzontale WriteElement(new LinePDF(element.X, y, element.X, y) { DeltaY2ForVerticalLine = -10 }); //lineaVerticaleSinistra WriteElement(new LinePDF(element.Width + element.X, y, element.Width + element.X, y) { DeltaY2ForVerticalLine = -10 }); // lineaVerticaleDestra break; case Style.Immobiliare: WriteElement(new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133))); // lineaOrizzontale break; case Style.ConsulenzaUnica: WriteElement(new LinePDF(element.X, element.X + element.Width, 1F, ColorPDF.Standard_Grigio_SfondoColonnaTabella)); // lineaOrizzontale break; } } else if (element.ShowBorderLastLine && element.Footer == true && rowIndex == element.DataSource.Rows.Count - 1) { switch (element.Style) { case Style.ConsulenzaBase: WriteElement(new LinePDF(element.X, y, element.Width + element.X, y)); // lineaOrizzontale WriteElement(new LinePDF(element.X, y, element.X, y) { DeltaY2ForVerticalLine = -10 }); //lineaVerticaleSinistra WriteElement(new LinePDF(element.Width + element.X, y, element.Width + element.X, y) { DeltaY2ForVerticalLine = -10 }); // lineaVerticaleDestra break; case Style.Immobiliare: WriteElement(new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133))); // lineaOrizzontale break; case Style.ConsulenzaUnica: WriteElement(new SpacePDF(5)); WriteElement(new LinePDF(element.X, element.X + element.Width, 1F, ColorPDF.Standard_Grigio_SfondoColonnaTabella)); // lineaOrizzontale break; } } #endregion #region Reset delle larghezza originale delle colonne. [Modificata se impostato ColSpan della Cella] int i = 0; foreach (var item in element.Columns) { item.Width = columnsWidthOriginal[i]; item.Visibile = item.Width > 0 ? true : false; i++; } #endregion rowIndex++; rowIndexPerPage++; } // Y iniziale su cui disegnare il testo del Footer yTextToPrint = y; #region Disegno il Footer della tabella. //#region Imposto il FooterDatasource if (element.FooterDatasource != null) { element.Footer = true; //var arrListFooter = new ArrayList(); //foreach (ColumnPDF c in element.FooterColumns) //{ // switch (c.TipoColonna) // { // case ColumnType.Testo: // case ColumnType.Decimale: // case ColumnType.Intero: // case ColumnType.Percentuale: // if (!string.IsNullOrEmpty(c.Name)) // arrListFooter.Add(c.Name); // break; // case ColumnType.Immagine: // case ColumnType.Objectpdf: // if (!string.IsNullOrEmpty(c.Id)) // arrListFooter.Add(c.Id); // break; // } // // Imposto la colonna a visible=false se la larghezza è pari a 0 // c.Visibile = c.Width != 0; //} //var strArrayFooter = (string[])arrListFooter.ToArray(typeof(string)); //var columnsEmbeddedOrObject = element.FooterColumns.FindAll(col => col.TipoColonna == ColumnType.Objectpdf || (col.TipoColonna == ColumnType.Immagine && col.Name == string.Empty)); //if (columnsEmbeddedOrObject.Count > 0) //{ // foreach (ColumnPDF column in columnsEmbeddedOrObject) // element.DataSource.Columns.Add(column.Id); //} //// imposto il datasource //element.DataSource = element.DataSource.DefaultView.ToTable(false, strArrayFooter); //if (columnsEmbeddedOrObject.Count > 0) //{ // for (int nColonna = 0; nColonna < element.FooterColumns.Count; nColonna++) // { // if (!string.IsNullOrEmpty(element.FooterCells[nColonna, 0].Value)) // element.DataSource.Rows[0][nColonna] = element.FooterCells[nColonna, 0].Value; // } //} } else { var footerDatasource = new DataTable(); for (int i = 0; i < element.FooterColumns.Count(); i++) { Type typeFooterColumn = typeof(string); switch (element.FooterColumns[i].TipoColonna) { case ColumnType.Decimale: case ColumnType.Intero: typeFooterColumn = typeof(decimal); break; case ColumnType.Immagine: typeFooterColumn = typeof(string); break; case ColumnType.Objectpdf: typeFooterColumn = typeof(ImagePDF); break; default: typeFooterColumn = typeof(string); break; } footerDatasource.Columns.Add(element.FooterColumns[i].Id, typeFooterColumn); } var rowFooterDatasource = footerDatasource.NewRow(); for (int i = 0; i < element.FooterColumns.Count(); i++) { if (element.FooterCells[i, 0] != null) rowFooterDatasource[i] = element.FooterCells[i, 0].Value; } footerDatasource.Rows.Add(rowFooterDatasource); element.FooterDatasource = footerDatasource; } #endregion if (element.Footer) { #region Style del Footer switch (element.Style) { case Style.ConsulenzaBase: if (element.ShowBorderFooter) { //Disegno un rettangolo in secondo piano che dia l'effetto cornice all'intestazione var rectangleFrame = new RectanglePDF(element.X - 1, y + (element.FooterHeight / 2) + 1, (element.FooterHeight / 2), element.Width + 2, ColorPDF.ConsulenzaBase_Grigio_BordoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false }; WriteElement(rectangleFrame); } // rettangolo contenitore grigio var rectangleFooter = new RectanglePDF(element.X, y, element.FooterHeight, element.Width, ColorPDF.ConsulenzaBase_Grigio_SfondoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false }; WriteElement(rectangleFooter); break; case Style.Immobiliare: //lineHeaderUp WriteElement(new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133))); //lineHeaderDown WriteElement(new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133)) { DeltaY = element.FooterHeight }); break; case Style.ConsulenzaUnica: //Lo stile del rettangolo grigio è definito in FooterColumns e FooterCells. La gestione è diversa in quanto per ConsulenzaUnica le tabelle possono avre il FooterDatasource impostato. break; } #endregion // Testo che sarà scritto sul footer var textToPrint = new FormattedTextAreaPDF(); if (element.FooterColumns.Count > 0) { y += element.FooterYOffset; rowIndex = 0; foreach (DataRow rigaFooter in element.FooterDatasource.Rows) { //patryk5 if (_ywritable + element.FooterHeight > YLowerLimit) { _ywritable = YLowerLimit; TablePDF_ContinuedOnNextPage(); _ywritable = YUpperLimit + 15; y = _ywritable; } float xLabelForCaptionFooter = element.X; columnIndex = 0; if (element.ShowFooterSeparationLines) { var colorSeparationLine = element.Columns[columnIndex].BackgroundGray ? ColorPDF.Bianco : ColorPDF.Standard_Grigio_SfondoColonnaTabella; // linea separatrice var separationLine = new RectanglePDF(xLabelForCaptionFooter, y + element.RowHeight, element.WidthSeparationLines, element.Width, colorSeparationLine) { AutoIncrementYWritable = false }; if (y < YLowerLimit) { if (element.HideLastSeparationLine) { // Non viene disegnata la linea di separazione all'ultima riga if (rowIndex != element.FooterDatasource.Rows.Count - 1) WriteElement(separationLine); } else if (element.HideFirstSeparationLine) { if (rowIndex != 0) WriteElement(separationLine); } else WriteElement(separationLine); } } foreach (ColumnPDF colonnaFooter in element.FooterColumns) { var colorRectangleBackground = ColorPDF.Bianco; var fontColor = ColorPDF.Nero; float fontSize; var fontBold = true; TextAlign textAlignFooter = GetTextAlign(colonnaFooter.HorizontalAlignment); #region Attributi della colonna [fontColor, fontSize, fontBold] #region Attibuti impostati a livello COLONNA [FooterColumns] // Colore fontColor = element.FooterColumns[columnIndex].FontColor != null ? element.FooterColumns[columnIndex].FontColor : ColorPDF.Nero; // Size fontSize = colonnaFooter.FontSize; // Grassetto fontBold = colonnaFooter.FontBold.HasValue ? colonnaFooter.FontBold.Value : true; #endregion #region Attibuti impostati a livello CELLA [FooterColumns] if (element.FooterCells[columnIndex, rowIndex].FontBold != null) fontBold = element.FooterCells[columnIndex, rowIndex].FontBold.HasValue ? element.FooterCells[columnIndex, rowIndex].FontBold.Value : true; #endregion #endregion #region Allineamento verticale e impostazione Y del testo switch (element.FooterTextVerticalAlign) { case VerticalAlignmentType.Alto: yTextToPrint = y + element.FooterColumns[columnIndex].DeltaYContent; break; case VerticalAlignmentType.Basso: yTextToPrint = y + (element.FooterHeight - element.FooterColumns[columnIndex].FontSize - (element.FooterColumns[columnIndex].FontSize / 2)) + element.FooterColumns[columnIndex].DeltaYContent; break; case VerticalAlignmentType.Centrato: yTextToPrint = y + ((element.FooterHeight / 2) - (element.FooterColumns[columnIndex].FontSize / 2)) + element.FooterColumns[columnIndex].DeltaYContent; break; } #endregion #region BackgroundGray e BackgroundColor della colonna // Aggiungo un rettangolo di sfondo (BackgroundGray o BackgroundColor) della COLONNA. if (element.FooterColumns[columnIndex].BackgroundGray || element.FooterColumns[columnIndex].BackgroundColor != null) { colorRectangleBackground = element.FooterColumns[columnIndex].BackgroundColor; if (element.FooterColumns[columnIndex].BackgroundGray) colorRectangleBackground = ColorPDF.Standard_Grigio_SfondoColonnaTabella; var rectangleBackground = new RectanglePDF(xLabelForCaptionFooter, y + 0.5F, element.FooterHeight - 0.5F, element.FooterColumns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; WriteElement(rectangleBackground); if (element.FooterColumns[columnIndex].BackgroundColor != null) { // Sovrascrivo le linee Up e Down del Footer nel caso in cui le colonne abbiano un BackgroundColor impostato. Le righe vengono impostate a bianco per maggiore leggibilità. var lineHeaderUp = new LinePDF(xLabelForCaptionFooter, y, xLabelForCaptionFooter + element.FooterColumns[columnIndex].Width, y, 0.5F, ColorPDF.Bianco) { AutoIncrementYWritable = false }; WriteElement(lineHeaderUp); var lineHeaderDown = new LinePDF(xLabelForCaptionFooter, y, xLabelForCaptionFooter + element.FooterColumns[columnIndex].Width, y, 0.5F, ColorPDF.Bianco) { DeltaY = element.FooterHeight + 0.5F, AutoIncrementYWritable = false }; WriteElement(lineHeaderDown); } } #endregion #region BackgroundColor della cella [Solo per ConsulenzaUnica] // Aggiungo un rettangolo di sfondo (BackgroundColor) della CELLA. if (element.FooterCells[columnIndex, rowIndex].BackgroundColor != null && element.Style == Style.ConsulenzaUnica) { colorRectangleBackground = element.FooterCells[columnIndex, rowIndex].BackgroundColor; var rectangleBackground = new RectanglePDF(xLabelForCaptionFooter, y, element.FooterHeight, element.FooterColumns[columnIndex].Width, colorRectangleBackground) { AutoIncrementYWritable = false }; WriteElement(rectangleBackground); } #endregion #region Testo del Footer switch (colonnaFooter.TipoColonna) { case ColumnType.Percentuale: case ColumnType.Intero: case ColumnType.Decimale: case ColumnType.Testo: if (string.IsNullOrEmpty(colonnaFooter.Name)) { // Non è stata impostata la proprietà "nome" che mappa la colonna del FooterDatasource dalla quale prendere il dato da stampare. // Viene quindi stampata il "Titolo" della colonna o se impostata la proprietà FooterCell, ne viene preso il rispettivo valore. if (!string.IsNullOrEmpty(colonnaFooter.HeaderText)) { textToPrint = new FormattedTextAreaPDF(colonnaFooter.HeaderText, xLabelForCaptionFooter, colonnaFooter.Width - colonnaFooter.PaddingLeft - colonnaFooter.PaddingRight, textAlignFooter) { Y = yTextToPrint, AutoIncrementYWritable = false, FontBold = fontBold, FontSize = fontSize, FontColor = fontColor }; } else if (element.FooterCells != null) { string stringTextToPrint = string.Empty; if (colonnaFooter.TipoColonna == ColumnType.Testo) stringTextToPrint = rigaFooter[columnIndex].ToString(); else if (colonnaFooter.TipoColonna == ColumnType.Decimale) stringTextToPrint = Helper.FormatCurrency(rigaFooter[columnIndex].ToString()); else if (colonnaFooter.TipoColonna == ColumnType.Intero) stringTextToPrint = Helper.FormatInteger(rigaFooter[columnIndex].ToString()); else if (colonnaFooter.TipoColonna == ColumnType.Percentuale) stringTextToPrint = Helper.FormatPercentage(rigaFooter[columnIndex].ToString(), 2); // ReplaceIfZero if (element.FooterCells[columnIndex, rowIndex].ReplaceIfZero != string.Empty) if (stringTextToPrint.Equals("0,00")) stringTextToPrint = stringTextToPrint.Replace("0,00", element.FooterCells[columnIndex, rowIndex].ReplaceIfZero); stringTextToPrint += arrayAsterischiNote_PieDiPagina[0, columnIndex] ?? string.Empty; textToPrint = new FormattedTextAreaPDF(stringTextToPrint, TablePDF_GetXTextFooter(xLabelForCaptionFooter, columnIndex, element), colonnaFooter.Width - colonnaFooter.PaddingLeft - colonnaFooter.PaddingRight, textAlignFooter) { Y = yTextToPrint, AutoIncrementYWritable = false, FontBold = fontBold, FontSize = fontSize, FontColor = fontColor }; } } //else // è stata impostata la proprietà "nome" che mappa la colonna del FooterDatasource dalla quale prendere il dato da stampare. Stampo il valore della colonna. //{ // if (element.FooterDatasource == null) // throw new Exception("Proprietà FooterDatasource della tabella non impostata"); // string stringColumnValueFooter = element.FooterDatasource.Rows[0][colonnaFooter.Name].ToString(); // textToPrint = new FormattedTextAreaPDF(stringColumnValueFooter, TablePDF_GetXTextFooter(xLabelForCaptionFooter, columnIndex, element), colonnaFooter.Width, textAlignFooter) // { // Y = yTextToPrint, // AutoIncrementYWritable = false, // FontSize = colonnaFooter.FontSize // }; //} WriteElement(textToPrint); break; case ColumnType.Immagine: case ColumnType.Objectpdf: { #region TIPO DI COLONNA FOOTER IMMAGINE ImagePDF imageToPrint; if (element.FooterCells[columnIndex, 0].Value != string.Empty) { #region Allineamento orizzontale dell'immagine float xImmagine = xLabelForCaptionFooter; Align imageAlignX; switch (textAlignFooter) { case TextAlign.Center: imageAlignX = Align.Center; xImmagine = xImmagine + (element.FooterColumns[columnIndex].Width / 2); break; case TextAlign.Left: imageAlignX = Align.Left; xImmagine = xLabelForCaptionFooter; break; case TextAlign.Right: imageAlignX = Align.Right; xImmagine = xLabelForCaptionFooter + element.FooterColumns[columnIndex].Width; break; default: imageAlignX = Align.Left; xImmagine = xLabelForCaptionFooter; break; } #endregion imageToPrint = new ImagePDF(TablePDF_GetXTextFooter(xImmagine + element.FooterColumns[columnIndex].PaddingLeft, columnIndex, element), element.FooterColumns[columnIndex].ScaleColumnTypeImage, element.FooterCells[columnIndex, 0].Value, imageAlignX, yTextToPrint); WriteElement(imageToPrint); } #endregion } break; } #endregion columnIndex++; xLabelForCaptionFooter += colonnaFooter.Width; } rowIndex++; y += element.FooterHeight; yTextToPrint += element.FooterHeight; //int rowsCountLeft = element.FooterDatasource.Rows.Count - element.FooterDatasource.Rows.IndexOf(rigaFooter) + 1; //float restOfFooter = rowsCountLeft * element.FooterHeight; //if (y >= YLowerLimit - 100) //{ // //_ywritable = YLowerLimit; // //TablePDF_ContinuedOnNextPage(); // //_ywritable = 100; // //y = _ywritable; // int test = 2; //} } } // Incremento _ywritable con l'altezza del footer _ywritable += (element.FooterHeight * element.FooterDatasource.Rows.Count); } #endregion #region Stampo le note,associate alla tabella, da inserire sotto il footer della tabella. foreach (TableNotePDF note in notesFooterTable) { WriteElement(new SpacePDF(5)); note.X = element.X; note.AsterisksNumber = GetAsterisksNumber(note); note.Width = element.Width; note.AutoIncrementYWritable = true; WriteElement(note); } #endregion _printinginnewpage = false; // AutoIncrementYWritable = false : la _ywritable è quella originale if (!element.AutoIncrementYWritable) _ywritable = originalYWritable; } /// /// Scrive l'elemento SpacePDF sul documento /// /// private void WriteElement(SpacePDF element) { _ywritable += element.Height; if (_ywritable > YLowerLimit) AddPage(); } /// /// Scrive l'elemento UnorderedListPDF sul documento /// /// private void WriteElement(UnorderedListPDF element) { element.BaseElement = new UnorderedList(element.X, element.Y, element.Width, element.Height, _reportEnvironment.FontFamily.Regular, element.FontSize) { ListItemTopMargin = element.Margin, ListItemBottomMargin = element.Margin, TextAlign = element.TextAlign }; foreach (string item in element.Items) element.BaseElement.Items.Add(item); if (element.Y == 0) element.BaseElement.Y = _ywritable; if (element.Height == 0) { element.Height = element.BaseElement.GetRequiredHeight(); element.BaseElement.Height = element.Height; } // Tipo di bullet if (element.BulletType == BulletType.Pallino) element.BaseElement.BulletStyle = UnorderedListStyle.Disc; else if (element.BulletType == BulletType.Trattino) element.BaseElement.BulletStyle = UnorderedListStyle.Dash; if (_ywritable <= YLowerLimit) _page.Elements.Add(element.ToElement()); else { // aggiunge una pagina AddPage(); element.BaseElement.Y = _ywritable; _page.Elements.Add(element.ToElement()); } if (element.AutoIncrementYWritable) _ywritable += element.Height; } /// /// Scrive l'elemento ResetterYPDF. /// Se Y = 0 _ywritable = _yupperlimit altrimenti _ywritable= Y /// /// private void WriteElement(ResetterYPDF element) { _ywritable = element.Y.Equals(0) ? YUpperLimit : element.Y; } private void WriteElement(ActionPDF element) { if (element.YPositionAction != null) { foreach (ObjectPDF obj in element.YPositionAction.Invoke(_ywritable)) { if (obj is PagePDF) { AddPage(((PagePDF)obj).Type); } else { WriteElement(obj); } } } } /// /// Scrive l'elemento CompositePDF sul documento. /// /// /// /// DA IMPLEMETARE /// private void WriteElement(CompositePDF element) { const float totalHeight = 0F; if (_ywritable + totalHeight > YLowerLimit) AddPage(); foreach (var item in element.Elements) { WriteElement(item); } } /// /// Disegna tutti gli Elements (List di ObjectPDF) di cui si compone un ChartPDF. /// Se la somma di tutti i punti delle serie è 0, il grafico non sarà disegnato. /// /// private void WriteElement(ChartPDF element) { var originalYWritable = _ywritable; //Se tutti i Point.Value aggiunti a tutte le serie sono = 0 non stampo il grafico var print = element.SeriesCollection.FindAll(o => o.Points.Sum(p => p.Value) > 0).Any(); // Se tutti i Point.Values.X o Point.Values.Y aggiunti a tutte le serie sono = 0 non stampo il grafico if (!print) print = element.SeriesCollection.FindAll(o => o.Points.Sum(p => p.Values.X) > 0 || o.Points.Sum(p => p.Values.Y) > 0).Any(); if (!print) return; #region Grafico Stacked con salto pagina bool stackedChartWithPageBreak = false; try { var stackedChart = element as StackedPDF; // grafico Stacked stackedChartWithPageBreak = stackedChart.PageBreak; } catch { stackedChartWithPageBreak = false; } #endregion if (stackedChartWithPageBreak) { #region Disegno con salto pagina per i grafici Stacked var stackedChart = element as StackedPDF; // grafico Stacked stackedChart.MaximumValueAxisY = stackedChart.GetMaximumValuePoints(); var pointsCopy = new List(stackedChart.SeriesCollection[0].Points); List pointsCopy2 = null; if (stackedChart.SeriesCollection.Count > 1) pointsCopy2 = new List(stackedChart.SeriesCollection[1].Points); int rowsIncrement = 0; int remainingRows = stackedChart.SeriesCollection[0].Points.Count; //Righe restanti do { element.ChartBase.Series.Clear(); element.SeriesCollection[0].Points.Clear(); element.Elements.Clear(); var remainingSpace = YLowerLimit - _ywritable; switch (_reportEnvironment.ReportType) { case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: case ReportType.Unica_Nucleo: case ReportType.Unica_Proposta: // stackedChart.HeightSingleBar = pointsCopy.Count < 3 ? 40 : 25; break; default: stackedChart.HeightSingleBar = stackedChart.HeightSingleBar; break; } int rowsInPage = Convert.ToInt32((remainingSpace / stackedChart.HeightSingleBar)) - 5; // aggiunto il reverse perchè con il salto di pagine scombina l'ordinamento. element.SeriesCollection[0].Points = pointsCopy.Skip(rowsIncrement).Take(rowsInPage).ToList(); if (element.SeriesCollection.Count > 1) element.SeriesCollection[1].Points = pointsCopy2.Skip(rowsIncrement).Take(rowsInPage).ToList(); int i = 0; foreach (var item in element.SeriesCollection) { element.SeriesCollection[i].Points.Reverse(); i++; } // Popola la Elements di tutti gli oggetti di cui si compone il grafico. element.ToElement(); // Disegna tutti gli Elements foreach (ObjectPDF item in element.Elements) WriteElement(item); rowsIncrement += rowsInPage; remainingRows -= rowsInPage; if (remainingRows > 0) { StackedPDF_ContinuedOnNextPage(); //AddPage(); //AddSpace(20); } } while (remainingRows > 0); #endregion } else { // Popola la Elements di tutti gli oggetti di cui si compone il grafico. int i = 0; foreach (var item in element.SeriesCollection) { element.SeriesCollection[i].Points.Reverse(); i++; } element.ToElement(); // Salto pagina nel caso in cui il grafico non possa essere contenuto in pagina. if (_ywritable + element.TotalHeight > YLowerLimit) AddPage(); // aggiungere una pagina // Disegna tutti gli Elements float _ywritableTmp = _ywritable; foreach (ObjectPDF item in element.Elements) WriteElement(item); float yWritableTmp2 = _ywritable; _ywritable = _ywritableTmp; foreach (Marker m in element.Markers) { WriteElement(new ImagePDF(((m.X < 0 ? 0 : m.X) * element.Width / (float)element.ChartBase.ChartAreas[0].AxisX.Maximum) + element.X - (m.Width * m.Scale / 2), m.Scale, m.Image) { Width = m.Width, Height = m.Height, Y = _ywritable + element.Height - (element.Height * m.Y / (float)element.ChartBase.ChartAreas[0].AxisY.Maximum) - (m.Height * m.Scale / 2), AutoIncrementYWritable = false }); } _ywritable = yWritableTmp2; } try { var stackedChart = element as StackedPDF; var max = stackedChart.GetMaximumValuePoints(); var valoreeperintervallo = Helper.Round(max) / stackedChart.IntervalNumberAxisY; var valoreultimoAsseX = (valoreeperintervallo * stackedChart.IntervalNumberAxisY); float _x = stackedChart.X; float TotalHeight = stackedChart.GetHeight(); float y1Linea = originalYWritable; float y2Linea = y1Linea + TotalHeight; foreach (VerticalMarkerWithLine marker in stackedChart.VerticalMarkersWithLines) { var valorePatrimoni = (marker.XValue * stackedChart.Width) / valoreultimoAsseX; WriteElement(new LinePDF((float)valorePatrimoni + _x, y1Linea, (float)valorePatrimoni + _x, y2Linea) { AutoIncrementYWritable = false, Color = marker.Color }); var img = new ImagePDF((float)valorePatrimoni + _x + 6, 0.50F/*0.30F*/, marker.ImagePath, ceTe.DynamicPDF.Align.Right, y1Linea) { AutoIncrementYWritable = false, DeltaY = -15 }; img.Y += marker.ImageYOffset; WriteElement(img); } } catch { } // AutoIncrementYWritable = false : la _ywritable è quella originale if (!element.AutoIncrementYWritable) _ywritable = originalYWritable; } private void WriteElement(CustomChartPDF element) { var originalYWritable = _ywritable; // Popola la Elements di tutti gli oggetti di cui si compone il grafico. element.ToElement(); // Disegna tutti gli Elements foreach (ObjectPDF item in element.Elements) { WriteElement(item); } // AutoIncrementYWritable = false : la _ywritable è quella originale if (!element.AutoIncrementYWritable) _ywritable = originalYWritable; } /// /// Ritorna l'altezza della FormattedTextArea contenente il testo passato in input. /// /// testo da scrivere /// larghezza della FormattedTextArea contenente il testo /// font size della FormattedTextArea contenente il testo /// bold della FormattedTextArea contenente il testo /// tipo di colonna contenente il testo. Di default = TESTO /// private float GetTextHeigth(string texttoprint, float width, float fontsize, bool fontbold = false, ColumnType tipocolonna = ColumnType.Testo) { if (tipocolonna == ColumnType.Immagine || width == 0 || texttoprint.Length == 0) return 0; var formattedTextArea = new FormattedTextArea(texttoprint, 0, 0, width - 3, 0, _reportEnvironment.FontFamily, fontsize, true) // sottraggo - 3 alla width per un valore più preciso dell'altezza di ritorno. { Style = { Bold = fontbold } }; return formattedTextArea.GetRequiredHeight(); } /// /// Recupera l'allineamento TextAlign a partire dal TipoAllineamentoOrizzontale della colonna. /// /// allineamento orizzontale della colonna /// private TextAlign GetTextAlign(HorizontalAlignmentType allineamentoOrizzontaleColonna) { var textAlign = new TextAlign(); switch (allineamentoOrizzontaleColonna) { case HorizontalAlignmentType.Destra: textAlign = TextAlign.Right; break; case HorizontalAlignmentType.Sinistra: textAlign = TextAlign.Left; break; case HorizontalAlignmentType.Centrato: textAlign = TextAlign.Center; break; } return textAlign; } /// /// Recupera il numero di asterischi più basso disponibile tra quelli gia inseriti nel documento. /// Ogni volta che nel documento è aggiunta una ObjectTypePDF.PAGE, il numero di asterischi viene resettato. /// /// private int GetAsterisksNumber(TableNotePDF currentNote) { int result = 1; // Indice dell'elemento corrente int indexCurrentElement = _elements.Count; // Cerco l'indice in _elements dell'ultimo ObjectPDF di tipo ObjectTypePDF.PAGE int indexLastPage = _elements.FindLastIndex(r => r.ObjectType == ObjectTypePdf.PAGE); var rangeList = _elements.GetRange(indexLastPage, indexCurrentElement - indexLastPage); // Conto quante TABLE con alemno 1 nota sono presenti in rangeList var tableList = rangeList.FindAll(r => r.ObjectType == ObjectTypePdf.TABLE && ((TablePDF)r).Notes.Count > 0); // Cliclo le TABLE trovate e per ognuno ciclo sulle proprie Note foreach (var objectPdf in tableList) { var table = (TablePDF)objectPdf; foreach (var note in table.Notes) { if (currentNote == note) return result; result++; } } return result; } /// /// Incrementa o decrementa la prima colonna se allineata a sinistra e l'ultima colonna se allineata a destra, /// del valore impostato come margine alla tabella. /// Serve per dare la spaziatura tra la prima e l'ultima colonna tra il bordo e il testo. /// /// valore della x corrente /// indice della colonna corrente /// tabella /// private float TablePDF_GetXTextContent(float xcorrente, int currentcolumn, TablePDF table) { #region Imposto il valore della proprietà Margin per la prima colonna se l'allineamento è a SINISTRA if (currentcolumn == 0 && table.Columns[currentcolumn].HorizontalAlignment == HorizontalAlignmentType.Sinistra) return xcorrente += table.Margin; #endregion #region Imposto il valore della proprietà Margin per l'ultima colonna se l'allineamento è a DESTRA if (currentcolumn == table.Columns.Count - 1 && table.Columns[currentcolumn].HorizontalAlignment == HorizontalAlignmentType.Destra) return xcorrente -= table.Margin; #endregion return xcorrente; } /// /// Incrementa o decrementa la prima colonna se allineata a sinistra e l'ultima colonna se allineata a destra, /// del valore impostato come margine alla tabella. /// Serve per dare la psaziatura tra la prima e l'ultima colonna tra il bordo e il testo. /// /// valore della x corrente /// indice della colonna corrente /// tabella /// private float TablePDF_GetXTextFooter(float xcorrente, int currentcolumn, TablePDF table) { #region Imposto il valore della proprietà Margin per la prima colonna se l'allineamento è a SINISTRA if (currentcolumn == 0 && table.FooterColumns[currentcolumn].HorizontalAlignment == HorizontalAlignmentType.Sinistra) return xcorrente + table.Margin; #endregion #region Imposto il valore della proprietà Margin per l'ultima colonna se l'allineamento è a DESTRA if (currentcolumn == table.FooterColumns.Count - 1 && table.FooterColumns[currentcolumn].HorizontalAlignment == HorizontalAlignmentType.Destra) return xcorrente - table.Margin; #endregion return xcorrente; } /// /// Disegna la riga del titolo della tabella. /// Imposta automaticamente a false la proprietà ShowBorderHeader della TablePDF (element). /// Aggiunge uno SpacePDF pari a 10. /// private bool TablePDF_DrawTitleRow(TablePDF element) { element.ShowBorderHeader = false; bool printedTitleRow = false; //// Il TitleRow della tabella deve essere stampato in una nuova pagina se lo spazio rimanente non può contenere il titlerow stesso, l'header e 2 righe della tabella. //if (element.TitleRowHeight + element.HeaderHeight + (element.CellHeight * 2) + element.TitleRowSpace > RemainingSpace) //{ // AddPage(); // element.Y = _yupperlimit; //} switch (element.TitleRowBorder) { case BorderTitleRowType.Pieno: { //Disegno un rettangolo in secondo piano che dia l'effetto cornice all'intestazione var rectangleFrame = new RectanglePDF(element.X - 1, _ywritable - 1, element.TitleRowHeight / 2, element.Width + 2, ColorPDF.ConsulenzaBase_Grigio_BordoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false }; WriteElement(rectangleFrame); // rettangolo contenitore grigio var rectangleHeader = new RectanglePDF(element.X, _ywritable, element.TitleRowHeight, element.Width, ColorPDF.ConsulenzaBase_Grigio_SfondoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false }; WriteElement(rectangleHeader); // TitleRowText var labelTitle = new FormattedTextAreaPDF(element.TitleRowText, element.X + element.Margin, element.Width); labelTitle.Y = _ywritable + ((element.TitleRowHeight / 2) - (labelTitle.Height / 2)); labelTitle.AutoIncrementYWritable = false; labelTitle.FontBold = true; //labelTitle.TextColor = element.HeaderFontColor; WriteElement(labelTitle); printedTitleRow = true; } break; case BorderTitleRowType.Nessuno: { var labelTitle = new FormattedTextAreaPDF(element.TitleRowText, element.X + element.Margin, element.Width); labelTitle.Y = _ywritable + ((element.TitleRowHeight / 2) - (labelTitle.Height / 2)); labelTitle.AutoIncrementYWritable = false; WriteElement(labelTitle); printedTitleRow = true; } break; } AddSpace(element.TitleRowHeight); // SUBTITLE if (element.SubTitleTable != null) { WriteElement(element.SubTitleTable); _printinginnewpage = true; } if (element.SubTitleElements != null) { foreach (ObjectPDF item in element.SubTitleElements) { WriteElement(item); _printinginnewpage = true; } } AddSpace(element.TitleRowSpace); return printedTitleRow; } private bool TablePDF_DrawTitleRow(TablePDF element, bool unica = true) //row unica per es. scheda 31 { element.ShowBorderHeader = false; bool printedTitleRow = false; var remainingSpace = YLowerLimit - _ywritable; if (element.TitleRowHeight + element.HeaderHeight + (element.RowHeight * 2) + element.TitleRowSpace > remainingSpace) { AddPage(); AddSpace(1); element.Y = YUpperLimit; } var rectangleHeader = new RectanglePDF(element.X, _ywritable, element.TitleRowHeight, element.Width, ColorPDF.Bianco) { AutoIncrementYWritable = false }; WriteElement(rectangleHeader); // TitleRowText var labelTitle = new FormattedTextAreaPDF(element.TitleRowText, element.X + element.Margin, element.Width) { FontSize = 11, FontColor = ColorPDF.Nero, FontBold = true }; labelTitle.Y = _ywritable + ((element.TitleRowHeight / 2) - (labelTitle.Height / 2)); labelTitle.AutoIncrementYWritable = false; WriteElement(labelTitle); printedTitleRow = true; AddSpace(element.TitleRowHeight); // SUBTITLE if (element.SubTitleTable != null) { WriteElement(element.SubTitleTable); _printinginnewpage = true; } if (element.SubTitleElements != null) { foreach (ObjectPDF item in element.SubTitleElements) { WriteElement(item); _printinginnewpage = true; } } AddSpace(element.TitleRowSpace); return printedTitleRow; } /// /// Disegna l'header della tabella. /// private void TablePDF_DrawHeader(TablePDF element, string[,] arrayAsterischiNote_Intestazione) { var yHeader = _ywritable; // recupero la posizione y su cui è stato disegnato il rettangolo dell' Header var backgroundColor = ColorPDF.ConsulenzaBase_Grigio_SfondoColonnaHeaderFooterTabella; //Grigio : standard per Proposta Consulenzabase. var fontColorHeaderColumn = ColorPDF.Nero; // Salto pagina se non c'è abbastanza spazio per stampare l'header + 2 righe if (_ywritable + element.HeaderHeight + element.AdditionalSpaceBetweenHeadersAndTable + element.HeaderMargin + ((element.RowHeight + element.RowsPadding) * 2) > _ylowerlimitoriginal || (_ywritable + element.HeaderHeight + element.AdditionalSpaceBetweenHeadersAndTable + element.HeaderMargin + ((element.RowHeight + element.RowsPadding) * 2) >= element.TableCantReachThisYPosition && element.TableCantReachThisYPosition != 0)) { AddPage(); if (element.AddSpaceBeforeTableAfterEntireTableIsMovedToNextPage) { AddSpace(5); // adds space at the very begining, so while inserting a table at the top of the page, there is a space for // a built in header } yHeader = _ywritable; element.Y = _ywritable; } if (element.HeaderNoteObjects.Count > 0) { //if (!element.HeaderTextDrawJustOnce || (element.HeaderTextDrawJustOnce && element.HeaderNoteObjectsCounter < 1)) //{ element.HeaderNoteObjectsCounter++; foreach (var e in element.HeaderNoteObjects) { WriteElement(e); } //} } // label dell'intestazione delle colonne float xLabelHeaderText = element.X; FormattedTextAreaPDF labelHeaderText; if (!string.IsNullOrEmpty(element.TableTitle))//if (!element.HeaderTextDrawJustOnce || (element.HeaderTextDrawJustOnce && element.HeaderTextCounter < 1)) { element.HeaderTextCounter++; #region stampo nell'header della tabella il testo contenuto in HeaderText. labelHeaderText = new FormattedTextAreaPDF(element.TableTitle, TablePDF_GetXTextContent(xLabelHeaderText, 0, element), element.Width, TextAlign.Left) { Y = yHeader, FontBold = true, AutoIncrementYWritable = false }; if (element.TableTitleDeltaX != 0) { labelHeaderText.X += element.TableTitleDeltaX; } if (element.TableTitleFontSize != 0) { labelHeaderText.FontSize = element.TableTitleFontSize; } if (element.TableTitleFontColor != null) { labelHeaderText.FontColor = element.TableTitleFontColor; } labelHeaderText.GetAndSetHeight(_reportEnvironment.FontFamily, labelHeaderText.FontBold); #region Allineamento verticale switch (element.HeaderTextVerticalAlign) { case VerticalAlignmentType.Alto: labelHeaderText.Y = yHeader; break; case VerticalAlignmentType.Basso: labelHeaderText.Y = yHeader + (element.HeaderHeight - labelHeaderText.Height); break; case VerticalAlignmentType.Centrato: labelHeaderText.Y = yHeader + ((element.HeaderHeight / 2) - (labelHeaderText.Height / 2)); break; } #endregion WriteElement(labelHeaderText); #endregion } _ywritable += element.HeadersObjectsHeight; yHeader += element.HeadersObjectsHeight; switch (element.Style) { case Style.ConsulenzaBase: #region ConsulenzaBase if (element.ShowBorderHeader) { //Disegno un rettangolo in secondo piano che dia l'effetto cornice all'intestazione var rectangleFrame = new RectanglePDF(element.X - 1, _ywritable - 1, element.HeaderHeight / 2, element.Width + 2, ColorPDF.ConsulenzaBase_Grigio_BordoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false }; WriteElement(rectangleFrame); } // rettangolo contenitore grigio var rectangleHeader = new RectanglePDF(element.X, _ywritable, element.HeaderHeight, element.Width, backgroundColor) { AutoIncrementYWritable = false }; WriteElement(rectangleHeader); #endregion break; case Style.Immobiliare: #region Immobiliare if (element.DrawLineHeaderUP) { var lineHeaderUp = new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133)); WriteElement(lineHeaderUp); } var lineHeaderDown = new LinePDF(element.X, element.X + element.Width, 0.5F, new ColorPDF(153, 148, 133)) { DeltaY = element.HeaderHeight }; WriteElement(lineHeaderDown); #endregion break; case Style.ConsulenzaUnica: #region ConsulenzaUnica // rettangolo contenitore grigio backgroundColor = ColorPDF.ConsulenzaUnica_Grigio_SfondoColonnaHeaderFooterTabella; WriteElement(new RectanglePDF(element.X, yHeader, element.HeaderHeight, element.Width, backgroundColor) { AutoIncrementYWritable = false }); break; #endregion } // label dell'intestazione delle colonne // float xLabelHeaderText = element.X; // FormattedTextAreaPDF labelHeaderText; if (element.HeaderText == string.Empty) { #region stampo nell'header della tabella le caption delle singole colonne della tabella int columnIndex = 0; int widthcurrent = 0; foreach (var column in element.Columns) { if (column.Visibile) { #region Aggiungo un rettangolo di sfondo (BackgroundColor). if (column.HeaderBackgroundColor != null) { var colorRectangleBackground = column.HeaderBackgroundColor; var rectangleBackground = new RectanglePDF(xLabelHeaderText, yHeader, element.HeaderHeight, column.Width, colorRectangleBackground) { AutoIncrementYWritable = false }; WriteElement(rectangleBackground); // Sovrascrivo la linea Down dell' Header nel caso in cui le colonne abbiano un BackgroundColor impostato. La riga viene impostata a bianco per maggiore leggibilità. var lineHeaderDown = new LinePDF(xLabelHeaderText, yHeader + element.HeaderHeight, xLabelHeaderText + column.Width, yHeader + element.HeaderHeight, 1F, ColorPDF.Bianco) { DeltaY = 0.5F, AutoIncrementYWritable = false }; WriteElement(lineHeaderDown); } #endregion var stringAsteriscoIntestazione = arrayAsterischiNote_Intestazione[0, columnIndex] ?? string.Empty; labelHeaderText = new FormattedTextAreaPDF(column.HeaderText + stringAsteriscoIntestazione, TablePDF_GetXTextContent(xLabelHeaderText, columnIndex, element) + column.HeaderPaddingLeft, column.Width - column.HeaderPaddingRight, GetTextAlign(column.HorizontalAlignment)) { Y = yHeader, FontBold = column.HeaderFontBold, FontSize = column.HeaderFontSize, AutoIncrementYWritable = false, TextVerticalDirection = column.HeaderTextVerticalDirection }; #region Altezza del TESTO if (labelHeaderText.TextVerticalDirection) labelHeaderText.Width = element.HeaderHeight; labelHeaderText.GetAndSetHeight(_reportEnvironment.FontFamily, labelHeaderText.FontBold); #endregion #region Direzione VERTICALE del TESTO if (labelHeaderText.TextVerticalDirection) { labelHeaderText.FixedHeight = labelHeaderText.Height; labelHeaderText.TextHorizontalAlign = TextAlign.Left; labelHeaderText.Y = (yHeader + element.HeaderHeight) - 2; if (_reportEnvironment.ReportType == ReportType.Unica_Diagnosi || _reportEnvironment.ReportType == ReportType.Unica_Monitoraggio || _reportEnvironment.ReportType == ReportType.Unica_Nucleo || _reportEnvironment.ReportType == ReportType.Unica_Proposta) labelHeaderText.X = labelHeaderText.X + (element.Columns[columnIndex].Width / 2) - (labelHeaderText.FontSize); else labelHeaderText.X = labelHeaderText.X + (element.Columns[columnIndex].Width / 2) - (labelHeaderText.FontSize / 2); } #endregion #region Colore del TESTO switch (element.Style) { case Style.ConsulenzaBase: case Style.Immobiliare: fontColorHeaderColumn = ColorPDF.Nero; break; case Style.ConsulenzaUnica: fontColorHeaderColumn = ColorPDF.ConsulenzaUnica_Rosso; break; } labelHeaderText.FontColor = fontColorHeaderColumn; if (column.HeaderFontColor != null) labelHeaderText.FontColor = column.HeaderFontColor; #endregion #region Allineamento verticale del TESTO (Recupero Y) if (!labelHeaderText.TextVerticalDirection) { switch (column.HeaderVerticalAlignment) { case VerticalAlignmentType.Alto: labelHeaderText.Y = yHeader; break; case VerticalAlignmentType.Basso: labelHeaderText.Y = yHeader + (element.HeaderHeight - labelHeaderText.Height); break; case VerticalAlignmentType.Centrato: labelHeaderText.Y = yHeader + ((element.HeaderHeight / 2) - (labelHeaderText.Height / 2)); break; } } #endregion // Incremento la X xLabelHeaderText += column.Width; // widthcurrent += xLabelHeaderText + column.Width; // Disegno la label di HeaderText WriteElement(labelHeaderText); if (element.ShowBorderHeader) { WriteElement(new RectanglePDF(xLabelHeaderText + 1, yHeader, element.HeaderHeight, 1, ColorPDF.Bianco) { AutoIncrementYWritable = false }); } } columnIndex++; } #region HeaderGroupText e HeaderGroupPathImage //Aggiungo un HeaderGroupText alle colonne che hanno impostato HeaderGroupPathImage, in modo da sfruttare il codice scritto per HeaderGroupText. element.Columns.Where(o => o.HeaderGroupPathImage != null).ToList().ForEach(i => i.HeaderGroupText = new List() { " " }); // Controllo se esiste almeno una colonna con HeaderGroupText impostato. if (element.Columns.Any(o => o.HeaderGroupText.Any())) { columnIndex = 0; xLabelHeaderText = element.X; foreach (var column in element.Columns) { if (column.Visibile) { var scostamentoX = 0F; foreach (var itemHeaderGroupText in column.HeaderGroupText) { var xHeaderGroupText = column.HeaderGroupTextVerticalDirection ? xLabelHeaderText + (column.HeaderGroupWidth / 2) + column.HeaderGroupTextDeltaX + scostamentoX : xLabelHeaderText + column.HeaderGroupTextDeltaX; var yHeaderGroupText = element.Y + element.HeaderHeight + column.HeaderGroupTextDeltaY; var labelHeaderGroupText = new FormattedTextAreaPDF( itemHeaderGroupText, xHeaderGroupText, column.HeaderGroupWidth) { FontBold = true, AutoIncrementYWritable = false, TextVerticalDirection = column.HeaderGroupTextVerticalDirection, FontColor = column.HeaderFontColor != null ? column.HeaderFontColor : ColorPDF.Nero }; #region Altezza del TESTO if (labelHeaderGroupText.TextVerticalDirection) labelHeaderGroupText.Width = element.HeaderHeight + column.HeaderGroupTextDeltaY; labelHeaderGroupText.GetAndSetHeight(_reportEnvironment.FontFamily, labelHeaderGroupText.FontBold); #endregion #region Direzione VERTICALE del TESTO HeaderGroupText if (column.HeaderGroupTextVerticalDirection) { labelHeaderGroupText.FixedHeight = labelHeaderGroupText.Height; labelHeaderGroupText.TextHorizontalAlign = TextAlign.Left; labelHeaderGroupText.Y = yHeaderGroupText; labelHeaderGroupText.X = xHeaderGroupText + labelHeaderGroupText.FontSize; } #endregion #region Allineamento verticale del TESTO (se TextVerticalDirection = false) if (!labelHeaderGroupText.TextVerticalDirection) { switch (column.HeaderVerticalAlignment) { case VerticalAlignmentType.Alto: labelHeaderGroupText.Y = element.Y + column.HeaderGroupTextDeltaY; break; case VerticalAlignmentType.Basso: labelHeaderGroupText.Y = element.Y + (element.HeaderHeight - labelHeaderGroupText.FontSize) + column.HeaderGroupTextDeltaY; break; case VerticalAlignmentType.Centrato: labelHeaderGroupText.Y = element.Y + ((element.HeaderHeight / 2) - (labelHeaderGroupText.FontSize / 2)) + column.HeaderGroupTextDeltaY; break; } } #endregion // Disegno la label di GroupHeaderText WriteElement(labelHeaderGroupText); //Disegno le immagini aggiunte a HeaderGroupPathImage if (column.HeaderGroupPathImage != null) WriteElement(new ImagePDF(labelHeaderGroupText.X, column.HeaderGroupScaleImage, column.HeaderGroupPathImage)); scostamentoX += labelHeaderGroupText.FixedHeight; //Linea di separazione in basso. if (column.HeaderGroupBorderLine) WriteElement(new LinePDF(xHeaderGroupText, yHeaderGroupText + 3, xHeaderGroupText + column.HeaderGroupWidth - column.HeaderGroupTextDeltaX, yHeaderGroupText + 3, 0.5F, new ColorPDF(153, 148, 133)) { AutoIncrementYWritable = false }); } xLabelHeaderText += column.Width; } columnIndex++; } } #endregion #endregion } else { element.HeaderTextCounter++; #region stampo nell'header della tabella il testo contenuto in HeaderText. labelHeaderText = new FormattedTextAreaPDF(element.HeaderText, TablePDF_GetXTextContent(xLabelHeaderText, 0, element), element.Width, TextAlign.Left) { Y = yHeader, FontBold = true, AutoIncrementYWritable = false }; labelHeaderText.GetAndSetHeight(_reportEnvironment.FontFamily, labelHeaderText.FontBold); #region Allineamento verticale switch (element.HeaderTextVerticalAlign) { case VerticalAlignmentType.Alto: labelHeaderText.Y = yHeader; break; case VerticalAlignmentType.Basso: labelHeaderText.Y = yHeader + (element.HeaderHeight - labelHeaderText.Height); break; case VerticalAlignmentType.Centrato: labelHeaderText.Y = yHeader + ((element.HeaderHeight / 2) - (labelHeaderText.Height / 2)); break; } #endregion WriteElement(labelHeaderText); #endregion } AddSpace(element.AdditionalSpaceBetweenHeadersAndTable); // tmp _printinginnewpage = false; } /// /// Disegna il salto pagina per l'ogetto TablePDF. /// Aggiunge una pagina. /// private void StackedPDF_ContinuedOnNextPage() { switch (_reportEnvironment.ReportType) { case ReportType.Base_Proposta: break; case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: case ReportType.Unica_Proposta: case ReportType.Unica_Nucleo: WriteElement(new ImagePDF(435, 0.15F, "changepage.png") { Y = 745 - 5, AutoIncrementYWritable = false }); WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", 450, 200) { Y = 745 - 5, FontSize = 6, AutoIncrementYWritable = false, AbsolutePosition = true }); AddPage(false); AddSpace(2); WriteElement(new ImagePDF(XLeftLimit, 0.15F, "changepage.png") { AutoIncrementYWritable = false }); WriteElement(new FormattedTextAreaPDF("continua dalla pagina precedente", XLeftLimit + 15, 200) { FontSize = 6, AutoIncrementYWritable = true }); AddSpace(20); break; case ReportType.Immobiliare_Diagnosi: case ReportType.Immobiliare_Monitoraggio: case ReportType.Immobiliare_DiagnosiNucleo: case ReportType.Immobiliare_MappaturaPreliminare: case ReportType.Immobiliare_Finalita: //#region Immobiliare //WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", XRightLimit - 200, 200) { Y = _ylowerlimitoriginal - 10, AutoIncrementYWritable = false, TextHorizontalAlign = TextAlign.Right, FontSize = 6, AbsolutePosition = true }); //AddPage(false); //#endregion break; default: throw new Exception("ReportType da gestire: [Consulenza.ReportWriter.Business.TablePDF_ContinuedOnNextPage()]"); } } /// /// Disegna il salto pagina per l'ogetto TablePDF. /// Aggiunge una pagina. /// private void TablePDF_ContinuedOnNextPage() { switch (_reportEnvironment.ReportType) { case ReportType.Base_Proposta: case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: case ReportType.Unica_Proposta: case ReportType.Unica_Nucleo: WriteElement(new ImagePDF(435, 0.15F, "changepage.png") { AutoIncrementYWritable = false }); WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", 450, 200) { FontSize = 6, AutoIncrementYWritable = false, AbsolutePosition = true }); AddPage(false); AddSpace(2); WriteElement(new ImagePDF(XLeftLimit, 0.15F, "changepage.png") { Y = YUpperLimit + 2, AutoIncrementYWritable = false }); WriteElement(new FormattedTextAreaPDF("continua dalla pagina precedente", XLeftLimit + 15, 200) { Y = YUpperLimit + 2, FontSize = 6, AutoIncrementYWritable = true, AbsolutePosition = true }); AddSpace(20); break; case ReportType.Immobiliare_Diagnosi: case ReportType.Immobiliare_DiagnosiNucleo: case ReportType.Immobiliare_MappaturaPreliminare: case ReportType.Immobiliare_Finalita: #region Immobiliare WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", XRightLimit - 200, 200) { Y = _ylowerlimitoriginal - 10, AutoIncrementYWritable = false, TextHorizontalAlign = TextAlign.Right, FontSize = 6, AbsolutePosition = true }); AddPage(false); #endregion break; case ReportType.Immobiliare_Monitoraggio: #region Immobiliare Monitoraggio //WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", XRightLimit - 350, 200) { Y = _ylowerlimitoriginal-2, AutoIncrementYWritable = false, TextHorizontalAlign = TextAlign.Right, FontSize = 6, AbsolutePosition = true }); WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", XRightLimit - 350, 200) { Y = _ylowerlimitoriginal - 8, AutoIncrementYWritable = false, TextHorizontalAlign = TextAlign.Right, FontSize = 6, AbsolutePosition = true }); AddPage(false); #endregion break; case ReportType.Immobiliare_MonitoraggioNuclei: #region Immobiliare Monitoraggio WriteElement(new FormattedTextAreaPDF("continua alla pagina successiva", XRightLimit - 350, 200) { Y = _ylowerlimitoriginal-10, AutoIncrementYWritable = false, TextHorizontalAlign = TextAlign.Right, FontSize = 6, AbsolutePosition = true }); AddPage(false); #endregion break; default: throw new Exception("ReportType da gestire: [Consulenza.ReportWriter.Business.TablePDF_ContinuedOnNextPage()]"); } } /// /// Scrive le note della tabella nel footer della pagina. /// k /// private void WriteNoteFooterPage(List notesFooterPage) { if (notesFooterPage.Count <= 0) return; var newnotesFooterPage = notesFooterPage; newnotesFooterPage.Reverse(); float yNote = (_ylowerlimitoriginal) - _spacenotefooterpagePerpage; foreach (var noteFooterPage in newnotesFooterPage) { var areatoWrite = new FormattedTextAreaPDF(noteFooterPage.Text, XLeftLimit, XRightLimit - XLeftLimit) { Y = yNote, FontSize = noteFooterPage.FontSize }; WriteElement(areatoWrite); yNote -= noteFooterPage.FontSize; _spacenotefooterpagePerpage += noteFooterPage.FontSize; } } /// /// Scrive le informazioni da riportare nel footer della pagina. /// Le informazioni vengono recuperate a questo livello dalla struttura _reportEnvironment. /// private void WriteFooterPage(ReportType reportType) { switch (reportType) { case ReportType.Base_Proposta: { #region Recupero le informazione necessarie string nomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Nome); string cognomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Cognome); string nominativoPrivateBanker = Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo); string indirizzoPrivateBanker = Helper.CapitalizeWords( _reportEnvironment.PrivateBanker.Indirizzo) + " " + _reportEnvironment.PrivateBanker.NumeroCivico + " - " + _reportEnvironment.PrivateBanker.Cap + " " + Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Citta); string telefonoPrivateBanker = "Tel. " + _reportEnvironment.PrivateBanker.PrefissoTelefono + _reportEnvironment.PrivateBanker.Telefono; #endregion #region Footer parte sinistra // Footer parte sinistra var labelProduzioneReport = new FormattedTextAreaPDF("Report prodotto per", XLeftLimit, 200, TextAlign.Left) { Y = _yendpage + 15, FontSize = 7, AutoIncrementYWritable = false }; var labelCliente = new FormattedTextAreaPDF(string.Format("{0} {1}", nomeCliente, cognomeCliente), XLeftLimit, 200, TextAlign.Left) { Y = _yendpage + 25, FontSize = 7, FontBold = true, AutoIncrementYWritable = false }; WriteElement(labelProduzioneReport); WriteElement(labelCliente); #endregion #region Footer parte destra // Footer parte destra var labelPrivateBanker = new FormattedTextAreaPDF("Private Banker", 350F, 200, TextAlign.Right) { Y = _yendpage + 15, FontSize = 7, FontBold = true, AutoIncrementYWritable = false }; var labelNomeCognomePrivateBanker = new FormattedTextAreaPDF(nominativoPrivateBanker, 350F, 200, TextAlign.Right) { Y = _yendpage + 25, FontSize = 7, FontBold = true, AutoIncrementYWritable = false }; var labelIndirizzoPrivateBanker = new FormattedTextAreaPDF(indirizzoPrivateBanker, 350F, 200, TextAlign.Right) { Y = _yendpage + 35, FontSize = 7, AutoIncrementYWritable = false }; var labelTelefonoPrivateBanker = new FormattedTextAreaPDF(telefonoPrivateBanker, 350F, 200, TextAlign.Right) { Y = _yendpage + 45, FontSize = 7, AutoIncrementYWritable = false }; WriteElement(labelPrivateBanker); WriteElement(labelNomeCognomePrivateBanker); WriteElement(labelIndirizzoPrivateBanker); WriteElement(labelTelefonoPrivateBanker); #endregion } break; case ReportType.Immobiliare_Diagnosi: case ReportType.Immobiliare_MappaturaPreliminare: case ReportType.Immobiliare_Finalita: { var nomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Nome); var cognomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Cognome); string labelCliente = _reportEnvironment.Cliente.Tipo == ClienteType.Fisico ? "Codice fiscale" : _reportEnvironment.Cliente.CodiceFiscale != "" ? "Codice fiscale" : "Partita Iva"; string datoCliente = _reportEnvironment.Cliente.Tipo == ClienteType.Fisico ? _reportEnvironment.Cliente.CodiceFiscale : _reportEnvironment.Cliente.CodiceFiscale != "" ? _reportEnvironment.Cliente.CodiceFiscale : _reportEnvironment.Cliente.PartitaIva; var cliente = new FormattedTextAreaPDF(string.Format("{0} {1} {2} - {3} {4}", "Cliente:", nomeCliente, cognomeCliente, "Codice fiscale", datoCliente), XLeftLimit) { Y = _yendpage + 40, AutoIncrementYWritable = false }; var privateBanker = new FormattedTextAreaPDF(string.Format("{0} {1}", "Private Banker:", Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo)), XLeftLimit) { Y = _yendpage + 54, AutoIncrementYWritable = false }; WriteElement(cliente); WriteElement(privateBanker); } break; case ReportType.Immobiliare_Monitoraggio: { var nomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Nome); var cognomeCliente = Helper.CapitalizeWords(_reportEnvironment.Cliente.Cognome); string labelCliente = _reportEnvironment.Cliente.Tipo == ClienteType.Fisico ? "Codice fiscale" : _reportEnvironment.Cliente.CodiceFiscale != "" ? "Codice fiscale" : "Partita Iva"; string datoCliente = _reportEnvironment.Cliente.Tipo == ClienteType.Fisico ? _reportEnvironment.Cliente.CodiceFiscale : _reportEnvironment.Cliente.CodiceFiscale != "" ? _reportEnvironment.Cliente.CodiceFiscale : _reportEnvironment.Cliente.PartitaIva; var cliente = new FormattedTextAreaPDF(string.Format("{0} {1} {2} - {3} {4}", "Cliente:", nomeCliente, cognomeCliente, "Codice fiscale", datoCliente), XLeftLimit + 4) { Y = _yendpage + 47, AutoIncrementYWritable = false, FontSize = 6 }; var privateBanker = new FormattedTextAreaPDF(string.Format("{0} {1}", "Private Banker:", Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo)), XLeftLimit + 4) { Y = _yendpage + 56, AutoIncrementYWritable = false, FontSize = 6 }; WriteElement(cliente); WriteElement(privateBanker); } break; case ReportType.Immobiliare_DiagnosiNucleo: { var nomeNucleo = Helper.CapitalizeWords(_reportEnvironment.NucleoImmobiliare.NomeNucleo); var nucleo = new FormattedTextAreaPDF(string.Format("{0} {1}", "Nucleo:", nomeNucleo), XLeftLimit) { Y = _yendpage + 40, AutoIncrementYWritable = false }; var privateBanker = new FormattedTextAreaPDF(string.Format("{0} {1}", "Private Banker:", Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo)), XLeftLimit) { Y = _yendpage + 54, AutoIncrementYWritable = false }; WriteElement(nucleo); WriteElement(privateBanker); } break; case ReportType.Immobiliare_MonitoraggioNuclei: { var nomeNucleo = Helper.CapitalizeWords(_reportEnvironment.NucleoImmobiliare.NomeNucleo); var nucleo = new FormattedTextAreaPDF(string.Format("{0} {1}", "Nucleo:", nomeNucleo), XLeftLimit + 4) { Y = _yendpage + 47, AutoIncrementYWritable = false, FontSize = 6 }; var privateBanker = new FormattedTextAreaPDF(string.Format("{0} {1}", "Private Banker:", Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo)), XLeftLimit + 4) { Y = _yendpage + 56, AutoIncrementYWritable = false, FontSize = 6 }; WriteElement(nucleo); WriteElement(privateBanker); } break; case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: case ReportType.Unica_Proposta: case ReportType.Unica_Nucleo: var reportAnonimo = _reportEnvironment.ReportStruct.GetOptionReport().ReportAnonimo; #region Colonna Sinistra var sProduzioneReport = reportAnonimo ? "Report prodotto {0}" : "Report prodotto {0} per"; var ftaProduzioneReport = new FormattedTextAreaPDF(string.Format(sProduzioneReport, DateTime.Now.ToLongDateString()), XLeftLimit, 500) { Y = YLowerLimit + 17, AutoIncrementYWritable = false, AbsolutePosition = true, FontSize = 7 }; WriteElement(ftaProduzioneReport); if (!reportAnonimo) { string nome = reportType == ReportType.Unica_Nucleo ? _reportEnvironment.Cliente.Cognome : Helper.CapitalizeWords(_reportEnvironment.Cliente.Cognome + " " + _reportEnvironment.Cliente.Nome); var ftaNominativoCliente = new FormattedTextAreaPDF(string.Format("{0}", nome), XLeftLimit, 500) { Y = YLowerLimit + 26, AutoIncrementYWritable = false, AbsolutePosition = true, FontBold = true, FontSize = 7 }; WriteElement(ftaNominativoCliente); } #endregion #region Colonna Destra var ftaPrivateBanker = new FormattedTextAreaPDF("Private Banker", XRightLimit - 300, 300) { Y = YLowerLimit + 17, AutoIncrementYWritable = false, AbsolutePosition = true, FontBold = true, TextHorizontalAlign = TextAlign.Right, FontSize = 7 }; WriteElement(ftaPrivateBanker); var ftaNominativoPrivateBanker = new FormattedTextAreaPDF(Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Nominativo), XRightLimit - 300, 300) { Y = YLowerLimit + 26, AutoIncrementYWritable = false, AbsolutePosition = true, FontBold = true, TextHorizontalAlign = TextAlign.Right, FontSize = 7 }; WriteElement(ftaNominativoPrivateBanker); var ftaIndirizzoPrivateBanker = new FormattedTextAreaPDF(string.Format("{0} {1} - {2} {3}", Helper.CapitalizeWords(_reportEnvironment.PrivateBanker.Indirizzo), _reportEnvironment.PrivateBanker.NumeroCivico, _reportEnvironment.PrivateBanker.Cap, _reportEnvironment.PrivateBanker.Citta), XRightLimit - 500, 500) { Y = YLowerLimit + 35, AutoIncrementYWritable = false, AbsolutePosition = true, TextHorizontalAlign = TextAlign.Right, FontSize = 7 }; WriteElement(ftaIndirizzoPrivateBanker); var ftaTelefonoPrivateBanker = new FormattedTextAreaPDF(string.Format("Tel. {0} - {1}", _reportEnvironment.PrivateBanker.PrefissoTelefono, _reportEnvironment.PrivateBanker.Telefono), XRightLimit - 300, 300) { Y = YLowerLimit + 44, AutoIncrementYWritable = false, AbsolutePosition = true, TextHorizontalAlign = TextAlign.Right, FontSize = 7 }; WriteElement(ftaTelefonoPrivateBanker); #endregion break; default: throw new Exception("ReportType da gestire: [Consulenza.ReportWriter.Business.WriteFooterPage()]"); } } private List> headers = new List>(); /// /// Scrive tutti gli elementi di tipo FORMATTEDTEXTAREA o IMAGE aggiunti al capitolo. /// private void WriteChapterTitle(ReportType reportType) { // ES Modifica 20190322 per Semestrale if (reportType == ReportType.Immobiliare_Monitoraggio || reportType == ReportType.Immobiliare_MonitoraggioNuclei) { // we've never encountered a problem of typing page (1/3) // the problem is, that we need now to generate all pages first and then // come back to all added elements, and see whether there are pages belonging to same chapter/section // and add strings (eg. (1/2)) // here, we add all headers to headers list and after generating all elements (and pages) // we will fix headers with proper values // keep in mind, that across entire solution, we use convention 1 chapter = 1 section int chapterId = int.Parse(_currentchapter.ToString()); var currentChapterHeader = MonitoraggioImmobiliarePageHeaderManager.GetHeader(chapterId); int xOffset = 20; if (currentChapterHeader.ImagePath != null) { var image = new ImagePDF(XLeftLimit + xOffset, 0, currentChapterHeader.ImagePath) { Width = currentChapterHeader.ImageWidth, Height = currentChapterHeader.ImageHeight, AutoIncrementYWritable = false, //Y = 14 + currentChapterHeader.DeltaY Y = 10 + currentChapterHeader.DeltaY }; WriteElement(image); xOffset += (int)image.Width; } string headerText = string.Empty; headerText += currentChapterHeader.SectionName ?? string.Empty; if (currentChapterHeader.SectionName != null && currentChapterHeader.ChapterName != null) { headerText += " - "; } headerText += currentChapterHeader.ChapterName != null ? (string.Format("{0}{1}", currentChapterHeader.ChapterName, currentChapterHeader.TextReplaceGuid)) : string.Empty; //FormattedTextAreaPDF pageHeader = new FormattedTextAreaPDF(headerText, XLeftLimit + xOffset + 6) { FontSize = 16, FontColor = ColorPDF.Immobiliare_Grigio_TitoloPiccolo, AutoIncrementYWritable = false, Width = 700, Y = 20, FixedHeight = 20 }; FormattedTextAreaPDF pageHeader = new FormattedTextAreaPDF(headerText, XLeftLimit + xOffset + 6) { FontSize = 16, FontColor = ColorPDF.Immobiliare_Grigio_TitoloPiccolo, AutoIncrementYWritable = false, Width = 700, Y = 16, FixedHeight = 20 }; headers.Add(new Tuple(currentChapterHeader, pageHeader)); WriteElement(pageHeader); } else { // Quando numberPageOnChapter = 0 non c'è bisogno di disegnare gli oggetti aggiunti al capitolo perché sara l'invocazione alla classe del capitolo stesso che lo farà. if (!_currentchapter.ChapterFacade.RepeatOnEachPage || numberPageOnChapter == 0) return; foreach (var item in _currentchapter.Elements.Where(o => o.ObjectType == ObjectTypePdf.FORMATTEDTEXTAREA || o.ObjectType == ObjectTypePdf.IMAGE)) { switch (item.ObjectType) { case ObjectTypePdf.FORMATTEDTEXTAREA: WriteElement((FormattedTextAreaPDF)item); break; case ObjectTypePdf.IMAGE: WriteElement((ImagePDF)item); break; } } } } /// /// Invoca il gestore delle classi che devono renderizzare le intestazioni di pagina (istanze di DTOPageFrameDataClassImplementation). /// /// Tipo di template da utilizzare per la pagina da aggiungere. private void AddPage(PagePDF.PagePDFType pagetype = PagePDF.PagePDFType.Generic) { _spacenotefooterpagePerpage = 0; YLowerLimit = _ylowerlimitoriginal; _ywritable = YUpperLimit; if (pagetype == PagePDF.PagePDFType.Generic) { _page = new ImportedPage(_generictemplate.GetPage(1)); switch (_reportEnvironment.ReportType) { case ReportType.Base_Proposta: _page.Elements.Add(new PageNumberingLabel("Pagina %%SP%% di %%ST%%", XLeftLimit, _yendpage, XRightLimit - XLeftLimit, 12, Font.Helvetica, 7, TextAlign.Left)); break; case ReportType.Immobiliare_Diagnosi: case ReportType.Immobiliare_DiagnosiNucleo: case ReportType.Immobiliare_MappaturaPreliminare: case ReportType.Immobiliare_Finalita: _page.Elements.Add(new PageNumberingLabel("%%SP%% di %%ST%%", XLeftLimit, _yendpage, XRightLimit - XLeftLimit, 12) { FontSize = 7 }); break; case ReportType.Immobiliare_Monitoraggio: _page.Elements.Add(new PageNumberingLabel("%%SP%% di %%ST%%", XLeftLimit + 5, _yendpage + 6, XRightLimit - XLeftLimit, 12, new OpenTypeFont("verdanab.TTF"), 6) { FontSize = 6 }); break; case ReportType.Immobiliare_MonitoraggioNuclei: _page.Elements.Add(new PageNumberingLabel("%%SP%% di %%ST%%", XLeftLimit + 5, _yendpage + 6, XRightLimit - XLeftLimit, 12, new OpenTypeFont("verdanab.TTF"), 6) { FontSize = 6 }); break; case ReportType.Unica_Proposta: string titolo = string.Empty; if (!_reportEnvironment.Adeguata) { WriteElement(new RectanglePDF(XLeftLimit, 15, 41, 220, ColorPDF.ConsulenzaUnica_Grigio_SfondoColonnaHeaderFooterTabella) { AutoIncrementYWritable = false, Y = 15 }); WriteElement(new LinePDF(XLeftLimit, 260, 1) { AutoIncrementYWritable = false, Y1 = 37, Y2 = 37, Color = ColorPDF.ConsulenzaUnica_Rosso }); titolo = "REPORT OPERAZIONI RICHIESTE"; } else titolo = "REPORT PROPOSTA"; WriteElement(new FormattedTextAreaPDF(titolo, XLeftLimit, 300) { FontBold = true, FontSize = 11, FontColor = ColorPDF.ConsulenzaUnica_Rosso, AutoIncrementYWritable = false, Y = 40 }); break; case ReportType.Unica_Nucleo: //tolta paginazione per ticket #1728 case ReportType.Unica_Diagnosi: case ReportType.Unica_Monitoraggio: //_page.Elements.Add(new PageNumberingLabel("pagina %%SP%% di %%ST%%", XRightLimit - 65, _yendpage + 80, XRightLimit - XLeftLimit, 12) { FontSize = 7 }); WriteElement(new FormattedTextAreaPDF(string.Format("REPORT {0}", HelperEnum.GetDescription(_reportEnvironment.ReportType)), XLeftLimit, 300) { FontBold = true, FontSize = 11, FontColor = ColorPDF.ConsulenzaUnica_Rosso, AutoIncrementYWritable = false, Y = 40 }); break; default: throw new Exception("ReportType da gestire: [Consulenza.ReportWriter.Business.AddPage(PagePDF.PagePDFType pagetype)]"); } WriteChapterTitle(_reportEnvironment.ReportType); WriteFooterPage(_reportEnvironment.ReportType); // Aggiungo gli elementi di _repeaterElements if (_repeaterElements != null) { foreach (var item in _repeaterElements) WriteElement(item); } } else _page = new ImportedPage(_covertemplate.GetPage(1)); _document.Pages.Add(_page); int count = _document.Pages.Count; _printinginnewpage = true; } /// /// Invoca il gestore delle classi che devono renderizzare le intestazioni di pagina /// (istanze di DTOPageFrameDataClassImplementation) ed aggiunge una nuova pagina vuota e numerata al documento. /// Se resetylowerlimit=true viene impostato _ylowerlimit=_ylowerlimitoriginal. /// /// private void AddPage(bool resetylowerlimit) { AddPage(); if (resetylowerlimit) YLowerLimit = _ylowerlimitoriginal; } /// /// Aggiunge uno spazio sull'asse y pari a space /// /// private void AddSpace(float space) { _ywritable += space; } } }