/// <summary> /// Implementation to execute when replace action. /// </summary> /// <param name="input">stream input</param> /// <param name="context">Input context</param> /// <returns> /// <para> /// A <see cref="ReplaceResult"/> reference that contains the result of the operation, to check if the operation is correct, the <b>Success</b> /// property will be <b>true</b> and the <b>Value</b> property will contain the value; Otherwise, the the <b>Success</b> property /// will be false and the <b>Errors</b> property will contain the errors associated with the operation, if they have been filled in. /// </para> /// <para> /// The type of the return value is <see cref="ReplaceResultData"/>, which contains the operation result /// </para> /// </returns> protected override ReplaceResult ReplaceImpl(Stream input, IInput context) { if (Style == null) { Style = PdfTableStyle.Default; } return(ReplaceImpl(context, input, Text, ReplaceOptions, Table, FixedWidth, TableOffset, Style, UseTestMode)); }
private void button1_Click(object sender, EventArgs e) { String[] data = { "Name;Capital;Continent;Area;Population", "Argentina;Buenos Aires;South America;2777815;32300003", "Bolivia;La Paz;South America;1098575;7300000", "Brazil;Brasilia;South America;8511196;150400000", "Canada;Ottawa;North America;9976147;26500000", "Chile;Santiago;South America;756943;13200000", "Colombia;Bagota;South America;1138907;33000000", "Cuba;Havana;North America;114524;10600000", "Ecuador;Quito;South America;455502;10600000", "El Salvador;San Salvador;North America;20865;5300000", "Guyana;Georgetown;South America;214969;800000", "Jamaica;Kingston;North America;11424;2500000", "Mexico;Mexico City;North America;1967180;88600000", "Nicaragua;Managua;North America;139000;3900000", "Paraguay;Asuncion;South America;406576;4660000", "Peru;Lima;South America;1285215;21600000", "United States of America;Washington;North America;9363130;249200000", "Uruguay;Montevideo;South America;176140;3002000", "Venezuela;Caracas;South America;912047;19700000" }; String[][] dataSource = new String[data.Length][]; for (int i = 0; i < data.Length; i++) { dataSource[i] = data[i].Split(';'); } //Create a pdf document PdfDocument doc = new PdfDocument(); doc.LoadFromFile(@"..\..\..\..\..\..\Data\TableBorder.pdf"); PdfPageBase page = doc.Pages[0]; //Create a pdf table PdfTable table = new PdfTable(); //Set data source of the pdf table table.DataSource = dataSource; //Set the color of table border PdfTableStyle style = new PdfTableStyle(); style.CellPadding = 2; style.BorderPen = new PdfPen(Color.Gray, 1f); table.Style = style; //Add custom method to BeginRowLayout event table.BeginRowLayout += new BeginRowLayoutEventHandler(table_BeginRowLayout); //Draw the pdf table into pdf document table.Draw(page, new PointF(60, 320)); string output = "TableBorder.pdf"; //Save pdf document doc.SaveToFile(output); //Launch the Pdf file PDFDocumentViewer(output); }
//////////////////////////////////////////////////////////////////// // Create charting examples PDF document //////////////////////////////////////////////////////////////////// public void CreateStockTable() { const Int32 ColDate = 0; const Int32 ColOpen = 1; const Int32 ColHigh = 2; const Int32 ColLow = 3; const Int32 ColClose = 4; const Int32 ColVolume = 5; // Add new page Page = new PdfPage(Document); // Add contents to page Contents = new PdfContents(Page); // create stock table PdfTable StockTable = new PdfTable(Page, Contents, NormalFont, 9.0); // divide columns width in proportion to following values StockTable.SetColumnWidth(1.2, 1.0, 1.0, 1.0, 1.0, 1.2); // set all borders StockTable.Borders.SetAllBorders(0.012, Color.DarkGray, 0.0025, Color.DarkGray); // make some changes to default header style StockTable.DefaultHeaderStyle.Alignment = ContentAlignment.BottomRight; // create private style for header first column StockTable.Header[ColDate].Style = StockTable.HeaderStyle; StockTable.Header[ColDate].Style.Alignment = ContentAlignment.MiddleLeft; StockTable.Header[ColDate].Value = "Date"; StockTable.Header[ColOpen].Value = "Open"; StockTable.Header[ColHigh].Value = "High"; StockTable.Header[ColLow].Value = "Low"; StockTable.Header[ColClose].Value = "Close"; StockTable.Header[ColVolume].Value = "Volume"; // make some changes to default cell style StockTable.DefaultCellStyle.Alignment = ContentAlignment.MiddleRight; StockTable.DefaultCellStyle.Format = "#,##0.00"; // create private style for date column StockTable.Cell[ColDate].Style = StockTable.CellStyle; StockTable.Cell[ColDate].Style.Alignment = ContentAlignment.MiddleLeft; StockTable.Cell[ColDate].Style.Format = null; // create private styles for volumn column PdfTableStyle GoingUpStyle = StockTable.CellStyle; GoingUpStyle.BackgroundColor = Color.LightGreen; GoingUpStyle.Format = "#,##0"; PdfTableStyle GoingDownStyle = StockTable.CellStyle; GoingDownStyle.BackgroundColor = Color.LightPink; GoingDownStyle.Format = "#,##0"; // open stock daily price // takem from Yahoo Financial StreamReader Reader = new StreamReader("SP500.csv"); // ignore header Reader.ReadLine(); // read all daily prices for (;;) { String TextLine = Reader.ReadLine(); if (TextLine == null) { break; } String[] Fld = TextLine.Split(new Char[] { ',' }); StockTable.Cell[ColDate].Value = Fld[ColDate]; StockTable.Cell[ColOpen].Value = Double.Parse(Fld[ColOpen], NFI.PeriodDecSep); StockTable.Cell[ColHigh].Value = Double.Parse(Fld[ColHigh], NFI.PeriodDecSep); StockTable.Cell[ColLow].Value = Double.Parse(Fld[ColLow], NFI.PeriodDecSep); StockTable.Cell[ColClose].Value = Double.Parse(Fld[ColClose], NFI.PeriodDecSep); StockTable.Cell[ColVolume].Value = Int32.Parse(Fld[ColVolume]); StockTable.Cell[ColVolume].Style = (Double)StockTable.Cell[ColClose].Value >= (Double)StockTable.Cell[ColOpen].Value ? GoingUpStyle : GoingDownStyle; StockTable.DrawRow(); } StockTable.Close(); // exit return; }
// Generates document public static void Generate(ILogger logger) { #region image style logger.Info(" > Working with image styles"); var imageStyle = new PdfImageStyle { Name = "ImageStyle", Borders = { new BaseBorder { Color = "Red", Show = YesNo.Yes, Position = KnownBorderPosition.Right }, new BaseBorder { Color = "Yellow", Show = YesNo.Yes, Position = KnownBorderPosition.Top } }, Content = { Color = "Blue", Alignment = { Horizontal = KnownHorizontalAlignment.Right }, Properties = new Properties { new Property { Name = "p001",Value = "v001" }, new Property { Name = "p002",Value = "v002" } } } }; // Save image style to disk var imageStyleAsXmlResult = imageStyle.SaveToFile("~/Output/Sample12/ImageStyle"); if (!imageStyleAsXmlResult.Success) { logger.Info(" > Error while saving image style as xml to disk"); logger.Info($" > Error: {imageStyleAsXmlResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved image style as xml to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/ImageStyle.xml"); } var imageStyleAsJsonResult = imageStyle.SaveToFile("~/Output/Sample12/ImageStyle", KnownFileFormat.Json); if (!imageStyleAsJsonResult.Success) { logger.Info(" > Error while saving image style as json to disk"); logger.Info($" > Error: {imageStyleAsJsonResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved image style as json to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/ImageStyle.json"); } // New image style instances from disk var imageStyleFromXml = PdfImageStyle.LoadFromFile("~/Output/Sample12/ImageStyle.xml"); logger.Info(imageStyleFromXml == null ? " > Error while loading image style from xml file" : " > Image style loaded correctly from xml '~/Output/Sample12/ImageStyle.xml' file"); var imageStyleFromJson = PdfImageStyle.LoadFromFile("~/Output/Sample12/ImageStyle.json", KnownFileFormat.Json); logger.Info(imageStyleFromJson == null ? " > Error while loading image style from json file" : " > Image style loaded correctly from json '~/Output/Sample12/ImageStyle.json' file"); #endregion #region text style logger.Info(""); logger.Info(" > Working with text styles"); var textStyle = new PdfTextStyle { Name = "NormalStyle", Font = { Bold = YesNo.Yes, Italic = YesNo.Yes, Color = "Yellow", Underline = YesNo.No }, Borders = { new BaseBorder { Color = "Red", Show = YesNo.Yes, Position = KnownBorderPosition.Right }, new BaseBorder { Color = "Yellow", Show = YesNo.Yes, Position = KnownBorderPosition.Top } }, Content = { Color = "Blue", Alignment = { Vertical = KnownVerticalAlignment.Top, Horizontal = KnownHorizontalAlignment.Right }, Properties = new Properties { new Property { Name = "p001", Value = "v001" }, new Property { Name = "p002", Value = "v002" } } } }; // Save text style to disk var textStyleAsXmlResult = textStyle.SaveToFile("~/Output/Sample12/TextStyle"); if (!textStyleAsXmlResult.Success) { logger.Info(" > Error while saving text style as xml to disk"); logger.Info($" > Error: {textStyleAsXmlResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved text style as xml to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/TextStyle.xml"); } var textStyleAsJsonResult = textStyle.SaveToFile("~/Output/Sample12/TextStyle", KnownFileFormat.Json); if (!textStyleAsJsonResult.Success) { logger.Info(" > Error while saving text style as json to disk"); logger.Info($" > Error: {textStyleAsJsonResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved text style as json to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/TextStyle.json"); } // New text style instances from disk var textStyleFromXml = PdfTextStyle.LoadFromFile("~/Output/Sample12/TextStyle.xml"); logger.Info(textStyleFromXml == null ? " > Error while loading text style from xml file" : " > Text style loaded correctly from xml '~/Output/Sample12/TextStyle.xml' file"); var textStyleFromJson = PdfTextStyle.LoadFromFile("~/Output/Sample12/TextStyle.json", KnownFileFormat.Json); logger.Info(textStyleFromJson == null ? " > Error while loading text style from json file" : " > Text style loaded correctly from json '~/Output/Sample12/TextStyle.json' file"); #endregion #region table style logger.Info(""); logger.Info(" > Working with table styles"); var tableStyle = new PdfTableStyle { Name = "NormalStyle", Alignment = { Vertical = KnownVerticalAlignment.Top }, Borders = { new BaseBorder { Color = "Red", Show = YesNo.Yes, Position = KnownBorderPosition.Right }, new BaseBorder { Color = "Yellow", Show = YesNo.Yes, Position = KnownBorderPosition.Top } }, Content = { Color = "Blue", Show = YesNo.Yes, Properties = new Properties { new Property { Name = "p001", Value = "v001" }, new Property { Name = "p002", Value = "v002" } } } }; // Save table style to disk var tableStyleAsXmlResult = tableStyle.SaveToFile("~/Output/Sample12/TableStyle"); if (!tableStyleAsXmlResult.Success) { logger.Info(" > Error while saving table style as xml to disk"); logger.Info($" > Error: {tableStyleAsXmlResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved table style as xml to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/TableStyle.xml"); } var tableStyleAsJsonResult = tableStyle.SaveToFile("~/Output/Sample12/TableStyle", KnownFileFormat.Json); if (!tableStyleAsJsonResult.Success) { logger.Info(" > Error while saving table style as json to disk"); logger.Info($" > Error: {tableStyleAsJsonResult.Errors.AsMessages().ToStringBuilder()}"); } else { logger.Info(" > Saved table style as json to disk correctly"); logger.Info(" > Path: ~/Output/Sample12/TableStyle.json"); } // New table style instances from disk var tableStyleFromXml = PdfTableStyle.LoadFromFile("~/Output/Sample12/TableStyle.xml"); logger.Info(tableStyleFromXml == null ? " > Error while loading table style from xml file" : " > Table style loaded correctly from xml '~/Output/Sample12/TableStyle.xml' file"); var tableStyleFromJson = PdfTableStyle.LoadFromFile("~/Output/Sample12/TableStyle.json", KnownFileFormat.Json); logger.Info(tableStyleFromJson == null ? " > Error while loading table style from json file" : " > Table style loaded correctly from json '~/Output/Sample12/TableStyle.json' file"); #endregion }
private static ReplaceResult ReplaceImpl(IInput context, Stream input, string oldText, ReplaceTextOptions options, PdfTable table, float fixedWidth, PointF tableOffset, PdfTableStyle style, YesNo useTestMode) { var outputStream = new MemoryStream(); try { using (var reader = new PdfReader(input)) using (var stamper = new PdfStamper(reader, outputStream)) { var pages = reader.NumberOfPages; for (var page = 1; page <= pages; page++) { var strategy = new CustomLocationTextExtractionStrategy(); var cb = stamper.GetOverContent(page); // Send some data contained in PdfContentByte, looks like the first is always cero for me and the second 100, // but i'm not sure if this could change in some cases. strategy.UndercontentCharacterSpacing = cb.CharacterSpacing; strategy.UndercontentHorizontalScaling = cb.HorizontalScaling; // It's not really needed to get the text back, but we have to call this line ALWAYS, // because it triggers the process that will get all chunks from PDF into our strategy Object var allStrings = PdfTextExtractor.GetTextFromPage(reader, page, strategy); var stringsArray = allStrings.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); // The real getter process starts in the following line var textMatchesFound = strategy.GetExtendedTextLocations(oldText, options).ToList(); // MatchesFound contains all text with locations foreach (var match in textMatchesFound) { // Delete tag var bColor = BaseColor.WHITE; cb.SetColorFill(bColor); cb.Rectangle(match.Rect.Left, match.Rect.Bottom, match.Rect.Width, match.Rect.Height); cb.Fill(); // Calculates new rectangle var deltaY = CalculatesVerticalDelta(options, match.Rect); var cellHeight = CalculatesCellHeight(match, oldText, strategy, cb, (string[])stringsArray.Clone(), options, deltaY); var r = BuildRectangleByStrategies(match, oldText, strategy, cb, (string[])stringsArray.Clone(), options); // Width strategy to use var safeFixedWidth = fixedWidth; var useFixedWidth = !fixedWidth.Equals(DefaultFixedWidth); if (useFixedWidth) { if (fixedWidth > r.Width) { safeFixedWidth = r.Width; } } else { safeFixedWidth = r.Width; } // Creates aligned table by horizontal alignment value (this table contains the user table parameter) var outerBorderTable = new PdfPTable(1) { TotalWidth = safeFixedWidth, HorizontalAlignment = Element.ALIGN_LEFT }; var outerCell = PdfHelper.CreateEmptyWithBorderCell(style.Borders); outerCell.MinimumHeight = cellHeight; outerCell.VerticalAlignment = style.Alignment.Vertical.ToVerticalTableAlignment(); outerCell.BackgroundColor = new BaseColor(ColorHelper.GetColorFromString(style.Content.Color)); //table.Table.HorizontalAlignment = Element.ALIGN_LEFT; table.Table.TotalWidth = safeFixedWidth - (outerCell.EffectivePaddingRight + outerCell.EffectivePaddingLeft) * 2; table.Table.LockedWidth = true; // options.StartStrategy.Equals(StartLocationStrategy.LeftMargin) && options.EndStrategy.Equals(EndLocationStrategy.RightMargin); outerCell.AddElement(table.Table); outerBorderTable.AddCell(outerCell); // Creates strategy table (for shows testmode rectangle) var useTestModeTable = new PdfPTable(1) { TotalWidth = safeFixedWidth }; var useTestCell = PdfHelper.CreateEmptyCell(useTestMode); if (table.Configuration.HeightStrategy == TableHeightStrategy.Exact) { useTestCell.FixedHeight = table.Table.TotalHeight; } useTestCell.AddElement(outerBorderTable); useTestModeTable.AddCell(useTestCell); useTestModeTable.WriteSelectedRows(-1, -1, r.X + tableOffset.X, r.Y - tableOffset.Y - deltaY, cb); cb.Fill(); } cb.Stroke(); } stamper.Close(); reader.Close(); } return(ReplaceResult.CreateSuccessResult(new ReplaceResultData { Context = context, InputStream = input, OutputStream = new MemoryStream(outputStream.GetBuffer()) })); } catch (Exception ex) { return(ReplaceResult.FromException( ex, new ReplaceResultData { Context = context, InputStream = input, OutputStream = input })); } }
private static void DrawPage(PdfPageBase page, CFDIXML cfdi) { float pageWidth = page.Canvas.ClientSize.Width; float y = 0; float leftMargin = 5; float midPage = pageWidth / 2; float topWritingArea = 0; int sectionSpacing = 15; float qrSize = 100; //Fonts string fontName = "Arial Condensed"; PdfTrueTypeFont font7Bold = new PdfTrueTypeFont(new Font(fontName, 7f, System.Drawing.FontStyle.Bold)); PdfTrueTypeFont font7 = new PdfTrueTypeFont(new Font(fontName, 7f, System.Drawing.FontStyle.Regular)); PdfTrueTypeFont font6Italic = new PdfTrueTypeFont(new Font(fontName, 6f, System.Drawing.FontStyle.Italic)); //Colors PdfRGBColor lightBlack = new PdfRGBColor(17, 17, 17); //Pen PdfPen penLightGray1p = new PdfPen(System.Drawing.Color.LightGray, 1f); PdfPen penLightGray05p = new PdfPen(System.Drawing.Color.LightGray, 0.5f); PdfPen penLightBlack10p = new PdfPen(lightBlack, 10f); //Brushes PdfBrush brushBlack = new PdfSolidBrush(System.Drawing.Color.Black); PdfBrush brushLightGray = new PdfSolidBrush(System.Drawing.Color.LightGray); //Format Alignments PdfStringFormat formatRight = new PdfStringFormat(PdfTextAlignment.Right); PdfStringFormat formatMiddle = new PdfStringFormat(PdfTextAlignment.Center, PdfVerticalAlignment.Middle); PdfStringFormat formatLeft = new PdfStringFormat(PdfTextAlignment.Left) { CharacterSpacing = 0.4f }; //Page header String text = "Factura version " + cfdi.Version; page.Canvas.DrawString(text, font6Italic, brushLightGray, pageWidth, y, formatRight); SizeF size = font6Italic.MeasureString(text, formatRight); y = y + size.Height + 1; page.Canvas.DrawLine(penLightGray1p, 0, y, pageWidth, y); y = y + 5; topWritingArea = y; //Issuerinfo //Name DrawToPage(page, cfdi.Emisor.Nombre, font7Bold, brushBlack, formatLeft, leftMargin, y, out y); //RFC DrawToPage(page, cfdi.Emisor.Rfc, font7Bold, brushBlack, formatLeft, leftMargin, y, out y); //Fiscal Regime DrawToPage(page, cfdi.Emisor.RegimenFiscal, font7, brushBlack, formatLeft, leftMargin, y, out y); //Address text = "Calle:" + cfdi.Emisor.Domicilio.Calle + " No:" + cfdi.Emisor.Domicilio.NoExterior; if (cfdi.Emisor.Domicilio.NoInterior != null) { text += "-" + cfdi.Emisor.Domicilio.NoInterior; } text += " Col:" + cfdi.Emisor.Domicilio.Colonia + ", Localidad:" + cfdi.Emisor.Domicilio.Localidad + ", Municipio:" + cfdi.Emisor.Domicilio.Municipio + ", Estado:" + cfdi.Emisor.Domicilio.Estado + ", CP:" + cfdi.Emisor.Domicilio.Cp; RectangleF area = new RectangleF(leftMargin, y, midPage - 10, 30); DrawToPage(page, text, font7, brushBlack, formatLeft, area, y, out y, false); DrawToPage(page, "Pais:" + cfdi.Emisor.Domicilio.Pais, font7, brushBlack, formatLeft, leftMargin, y, out y); //Invoice data y = topWritingArea; //Invoice header y += 5; page.Canvas.DrawLine(penLightBlack10p, midPage, y, pageWidth, y); text = "Factura"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, pageWidth - size.Width - 10, y, out y); //Invoice number DrawToPageWithHeader(page, "Folio:", cfdi.Folio, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "Serie:", cfdi.Serie ?? "", font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "Folio Fiscal:", cfdi.TimbreFiscal.UUID, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "Serie CSD del SAT:", cfdi.TimbreFiscal.NoCertificadoSAT, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "No. Certificado:", cfdi.NoCertificado, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "Fecha emsión:", cfdi.Fecha, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPageWithHeader(page, "Fecha certificación:", cfdi.TimbreFiscal.FechaTimbrado, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); //Issue place y += 5; DrawToPageWithHeader(page, "Lugar de expedición:", cfdi.LugarExpedicion, font7Bold, font7, brushBlack, formatLeft, leftMargin, y, out y); //Reciever data //Reciever header y += sectionSpacing; page.Canvas.DrawLine(penLightBlack10p, leftMargin, y, pageWidth, y); text = "Receptor"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, midPage - (size.Width / 2), y, out y); //Reciever name DrawToPageWithHeader(page, "Receptor: ", cfdi.Receptor.Nombre, font7Bold, font7, brushBlack, formatLeft, leftMargin, y, out y, true); //Reciever address text = "Calle: " + cfdi.Receptor.Domicilio.Calle + " No:" + cfdi.Receptor.Domicilio.NoExterior; if (cfdi.Receptor.Domicilio.NoInterior != null) { text += "-" + cfdi.Receptor.Domicilio.NoInterior; } DrawToPageWithHeader(page, "Domicilio: ", text, font7Bold, font7, brushBlack, formatLeft, midPage, y, out y); //RFC DrawToPageWithHeader(page, "R.F.C.:", cfdi.Receptor.Rfc, font7Bold, font7, brushBlack, formatLeft, leftMargin, y, out y, true); //Next line address text = " Col:" + cfdi.Receptor.Domicilio.Colonia + ", Localidad:" + cfdi.Receptor.Domicilio.Localidad + ", Municipio:" + cfdi.Receptor.Domicilio.Municipio; area = new RectangleF(midPage, y, midPage - 10, 20); DrawToPage(page, text, font7, brushBlack, formatLeft, area, y, out y, false); text = " Estado:" + cfdi.Receptor.Domicilio.Estado + ", CP:" + cfdi.Receptor.Domicilio.Cp; DrawToPage(page, text, font7, brushBlack, formatLeft, midPage, y, out y); DrawToPage(page, "Pais:" + cfdi.Receptor.Domicilio.Pais, font7, brushBlack, formatLeft, midPage, y, out y); //Products y += sectionSpacing; //Prepare data String[][] dataSource = new String[cfdi.Conceptos.Count + 1][]; String headers = "Cant.;Unidad;Clave;Descripción;Valor unitario;Importe"; int i = 0; dataSource[i] = headers.Split(';'); foreach (Concepto product in cfdi.Conceptos) { i++; String[] content = new String[6]; content[0] = product.Cantidad.ToString(); content[1] = product.Unidad; content[2] = product.NoIdentificacion; content[3] = product.Descripcion; content[4] = String.Format("{0:N1}", product.ValorUnitario); content[5] = String.Format("{0:C2}", product.Importe); dataSource[i] = content; } //Generate table PdfTable productsTable = new PdfTable(); PdfTableStyle style = new PdfTableStyle() { BorderPen = new PdfPen(lightBlack, 0.5f), CellPadding = 2, HeaderSource = PdfHeaderSource.Rows, HeaderRowCount = 1, ShowHeader = true, HeaderStyle = new PdfCellStyle() { BackgroundBrush = new PdfSolidBrush(System.Drawing.Color.Black), TextBrush = brushLightGray, StringFormat = formatMiddle } }; productsTable.Style = style; productsTable.DataSource = dataSource; productsTable.Columns[0].Width = 8; productsTable.Columns[3].Width = 30; foreach (PdfColumn column in productsTable.Columns) { column.StringFormat = formatLeft; } PdfLayoutResult result = productsTable.Draw(page, new PointF(leftMargin, y)); y = y + result.Bounds.Height + 5; //Total in letter and number page.Canvas.DrawLine(penLightBlack10p, leftMargin, y, pageWidth, y); text = "Total con Letra"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, leftMargin, y, out y); DrawToPage(page, Conv.Enletras(cfdi.Total.ToString()) + "M.N.", font7, brushBlack, formatLeft, leftMargin, y, out y, true); DrawToPageWithHeader(page, "Subtotal:", String.Format(" {0:C2}", cfdi.SubTotal), font7Bold, font7, brushBlack, formatLeft, midPage + (midPage / 2), y, out y); DrawToPageWithHeader(page, "Total:", String.Format(" {0:C2}", cfdi.Total), font7Bold, font7, brushBlack, formatLeft, midPage + (midPage / 2), y, out y); //QR Code with basic data QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(String.Format("?re={0}&rr={1}&tt={2:N1}&id={3}", cfdi.Emisor.Rfc, cfdi.Receptor.Rfc, cfdi.Total, cfdi.TimbreFiscal.UUID), QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(20); float qrPosition = y; PdfImage image = PdfImage.FromImage(qrCodeImage); page.Canvas.DrawImage(image, leftMargin, y, qrSize, qrSize); //Payment info y = qrPosition + sectionSpacing; DrawToPageWithHeader(page, "Método de pago: ", cfdi.MetodoDePago, font7Bold, font7, brushBlack, formatLeft, leftMargin + qrSize, y, out y); DrawToPageWithHeader(page, "Cuenta: ", cfdi.NumCtaPago ?? "", font7Bold, font7, brushBlack, formatLeft, leftMargin + qrSize, y, out y); DrawToPageWithHeader(page, "Forma de pago: ", cfdi.FormaDePago, font7Bold, font7, brushBlack, formatLeft, leftMargin + qrSize, y, out y); DrawToPageWithHeader(page, "Condiciones de pago: ", cfdi.CondicionesDePago ?? "", font7Bold, font7, brushBlack, formatLeft, leftMargin + qrSize, y, out y); y = qrPosition + qrSize + sectionSpacing; page.Canvas.DrawLine(penLightBlack10p, leftMargin, y, pageWidth, y); text = "Cadena original del complemento de certificación del SAT"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, leftMargin, y, out y); area = new RectangleF(leftMargin, y, pageWidth - 5, 100); DrawToPage(page, String.Format("||{0}|{1}|{2}|{3}|{4}", cfdi.TimbreFiscal.Version, cfdi.TimbreFiscal.UUID, cfdi.TimbreFiscal.FechaTimbrado, cfdi.Sello, cfdi.TimbreFiscal.NoCertificadoSAT), font7Bold, brushBlack, formatLeft, area, y, out y, false); y += sectionSpacing; page.Canvas.DrawLine(penLightBlack10p, leftMargin, y, pageWidth, y); text = "Sello digital del SAT"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, leftMargin, y, out y); area = new RectangleF(leftMargin, y, pageWidth - 5, 100); DrawToPage(page, cfdi.TimbreFiscal.SelloSAT, font7Bold, brushBlack, formatLeft, area, y, out y, false); y += sectionSpacing; page.Canvas.DrawLine(penLightBlack10p, leftMargin, y, pageWidth, y); text = "Sello digital del contribuyente que lo expide"; size = font7Bold.MeasureString(text, formatLeft); y -= 4; DrawToPage(page, text, font7Bold, brushLightGray, formatLeft, leftMargin, y, out y); area = new RectangleF(leftMargin, y, pageWidth - 5, 100); DrawToPage(page, cfdi.Sello, font7Bold, brushBlack, formatLeft, area, y, out y, false); //Footer DrawToPage(page, "Este documento es una representación impresa de un CFDI", font7, brushBlack, formatLeft, midPage, page.Canvas.ClientSize.Height - 30, out y, false); }