CSharp:CSharp for PDF
From Aino Wiki
Contents
Librerie per generare PDF
PDF Sharp
Qui pdfsharp.net
- Esempio Creazione di una fattura Da pdfsharp
- Esempio gestione multi pagine Da pdfsharp
- FORUM MiraDoc PDF sharp: [1]
Esempio generazione Report Multipagina
Esempio completo con più esempi di produzione PDF Portait e LandScape qui: Web API di Report PDF
using efabbisognoweb.common; using efabbisognoweb.DAL; using efabbisognoweb.Interfaces; using log4net; using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Shapes; using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.Rendering; using PdfSharp; using PdfSharp.Pdf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Web.Http; using System.Web.UI; using TheArtOfDev.HtmlRenderer.PdfSharp; namespace efabbisognoweb.api { public class StampeController : ApiController { #region Costanti private static readonly ILog log = LogManager.GetLogger(typeof(StampeController)); private static readonly string c_logo_RelativePath = "\\content\\xxx_logo.jpg"; private static readonly string c_PDF_RelativeOutputPath = "\\DocRepository\\"; // RGB colors Color c_TableBorder = new Color(81, 125, 192); Color c_TableBlue = new Color(235, 240, 249); // Colore dell'intestazione Color c_TableGray = new Color(242, 242, 242); // Colore delle righe pari #endregion string m_logoFullPath = string.Empty; #region Stampa Anteprima Ordini Fornitori /// <summary> /// Dato un JSON in input costruisce un report PDF ponendolo in una cartella convenzionata (dove il clinet si aspetta che ci sia). /// Se tutto va bene in output fornisce il percorso relativo, comprensivo del nome file generato, /// altrimenti fornisce l'errore generato /// </summary> /// <param name="aof">JSON in input</param> /// <returns>percorso relativo, comprensivo del nome file, dove è collocato il file generato</returns> [ActionName("stampa-menu-anteprimaordini")] [Route("stampa-menu-anteprimaordini")] [HttpPost] public HttpResponseMessage Post_Stampa_menu_anteprimaordini_HttpResponse(AnteprimaOrdiniFornitoriIN aof) { log4net.Config.XmlConfigurator.Configure(); HttpResponseMessage cResponse; string fileNameRelativePath = string.Empty; string pdfFileNameFullPath = string.Empty; try { if (aof == null) { throw new Exception("Il JSON di Input risulta vuoto."); } log.InfoFormat("Impianto {0}, dal {1}, al {2}, Nr fornitori {3}, Totale Ordini {4}, User account '{5}'.", aof.codice_impianto, aof.data_dal, aof.data_al, aof.numero_fornitori, aof.totale_ordini, aof.account); // Pulizia fiels vecchi di precedenti elaborazioni int maxMinutesOld = 10; string pathPDF = System.Web.HttpRuntime.AppDomainAppPath + c_PDF_RelativeOutputPath; FileSystemHelper fsh = new FileSystemHelper(log); fsh.PuliziaVecchiFile(pathPDF, "PDF", maxMinutesOld); #region Verifica informazioni propedeutiche if (string.IsNullOrWhiteSpace(aof.codice_impianto)) { throw new Exception("Non è stato indicato in input il codcie impianto."); } if (aof.ordini == null || aof.ordini.Length == 0) { throw new Exception("Non risultano ordini di cui produrre anteprima."); } #endregion CostruisciPDF_AnteprimaOrdini(aof, ref pdfFileNameFullPath); // <-- ! fileNameRelativePath = string.Format("{0}{1}", c_PDF_RelativeOutputPath, Path.GetFileName(pdfFileNameFullPath)); cResponse = new HttpResponseMessage(HttpStatusCode.OK); cResponse.Content = new StringContent(fileNameRelativePath, System.Text.Encoding.Unicode, "text/html"); } catch (Exception e) { string errorMessage = string.Format("Path relativo PDF: '{0}'. Errore generico {1}, {2}", pdfFileNameFullPath, e.HResult, e.Message); log.ErrorFormat(errorMessage); cResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError); cResponse.Content = new StringContent(errorMessage, System.Text.Encoding.Unicode, "text/html"); } return cResponse; } private MemoryStream CostruisciPDF_AnteprimaOrdini(AnteprimaOrdiniFornitoriIN aof, ref string pdfFileNameFullPath, bool pdfStreamOut = false) { MemoryStream stream = new MemoryStream(); try { InfoColonna[] infoTabColonne; #region Definizione array delle colonne delle tabelle di dati infoTabColonne = new InfoColonna[] { new InfoColonna { Label = "Cod.Art.", Ampiezza = "2.2cm", AllineamentoOrizzontale = ParagraphAlignment.Center, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "Articolo", Ampiezza = "7.3cm", AllineamentoOrizzontale = ParagraphAlignment.Left, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "U.M.", Ampiezza = "1.2cm", AllineamentoOrizzontale = ParagraphAlignment.Center, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "M.Imb.", Ampiezza = "2cm", AllineamentoOrizzontale = ParagraphAlignment.Right, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "Prezzo", Ampiezza = "2.3cm", AllineamentoOrizzontale = ParagraphAlignment.Right, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "Q.tà", Ampiezza = "1.7cm", AllineamentoOrizzontale = ParagraphAlignment.Right, AllineamentoVerticale = VerticalAlignment.Center }, new InfoColonna { Label = "Costo", Ampiezza = "2.7cm", AllineamentoOrizzontale = ParagraphAlignment.Right, AllineamentoVerticale = VerticalAlignment.Center } }; #endregion var currentApp = System.Web.HttpRuntime.AppDomainAppPath; m_logoFullPath = currentApp + c_logo_RelativePath; Document pdfDocument = new Document(); pdfDocument.Info.Title = "Anteprima Ordini"; pdfDocument.Info.Subject = string.Format("Anteprima ordini del {0}. Utente '{1}'", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff"), aof.account); pdfDocument.Info.Author = "yyy"; string codiceImpianto = aof.codice_impianto; Section section = new Section(); //----------------------------------------------------------------------- DefineStyles(ref pdfDocument); CreatePage(ref pdfDocument, ref section, infoTabColonne, codiceImpianto); FillContent(aof, ref section, infoTabColonne); //----------------------------------------------------------------------- // Create a renderer for PDF that uses Unicode font encoding PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(true); // Set the MigraDoc document pdfRenderer.Document = pdfDocument; // Create the PDF document pdfRenderer.RenderDocument(); string nomeFilePDF = string.Format("AnteprimaOrdini_{0}.pdf", Guid.NewGuid()); pdfFileNameFullPath = string.Format("{0}{1}{2}", currentApp, c_PDF_RelativeOutputPath, nomeFilePDF); #region Salva il PDF if (pdfStreamOut) { // Salva nel memory stream pdfRenderer.Save(stream, false); // Salva su FileSystem using (var fileStream = new FileStream(pdfFileNameFullPath, FileMode.CreateNew)) { // write to just created file stream.WriteTo(fileStream); } } else { pdfRenderer.Save(pdfFileNameFullPath); } #endregion } catch (Exception e) { log.ErrorFormat("Errore generico {0}, {1}", e.HResult, e.Message); throw; } return stream; } #region PDF Anteprima Ordini private void DefineStyles(ref Document pdfDocument) { // Si allargano i margini utili pdfDocument.DefaultPageSetup.LeftMargin = 20; pdfDocument.DefaultPageSetup.RightMargin = 20; //pdfDocument.DefaultPageSetup.HeaderDistance = "6.3cm"; // 1.3 Distance between header and pageTop of the pages //pdfDocument.DefaultPageSetup.PageHeight = "10cm"; // E' l'altezza complessiva della pagina // Get the predefined style Normal. Style style = pdfDocument.Styles["Normal"]; // Because all styles are derived from Normal, the next line changes the // font of the whole document. Or, more exactly, it changes the font of // all styles and paragraphs that do not redefine the font. style.Font.Name = "Verdana"; style = pdfDocument.Styles[StyleNames.Header]; style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right); // Cos'è un TabStop ?????????????????? style = pdfDocument.Styles[StyleNames.Footer]; style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center); // Create a new style called Table based on style Normal style = pdfDocument.Styles.AddStyle("Table", "Normal"); style.Font.Name = "Verdana"; style.Font.Size = 9; // Create a new style called Reference based on style Normal style = pdfDocument.Styles.AddStyle("Reference", "Normal"); style.ParagraphFormat.SpaceBefore = "5mm"; style.ParagraphFormat.SpaceAfter = "5mm"; style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right); } private void CreatePage(ref Document pdfDocument, ref Section section, InfoColonna[] infoTabColonne, string codiceImpianto) { #region doc /* Document * L-> Section * | * Headers.Primary * +--> Image (LOGO) * +--> TextFrame * +--> Paragraph (TITOLO) * +--> Text * +--> Table (Tabella di inizioPagina) * | * +--> Table (Prima tabella nel corpo della prima pagina) * | * Footers.Primary * +--> Paragraph * +--> Text (PIEDE PAGINA) */ #endregion try { // Each MigraDoc document needs at least one SECTION !!! section = pdfDocument.AddSection(); // You have to set the TopMargin of the PageSetup to reserve space for the header. section.PageSetup.TopMargin = Unit.FromCentimeter(3.97); // http://forum.pdfsharp.net/viewtopic.php?p=3077 // [Section].PageSetup.BottomMargin = Unit.FromCentimeter(x) #region Intestazione #region LOGO // Put a logo in the header Image imageLogo = section.Headers.Primary.AddImage(m_logoFullPath); // Ex.: "../../PowerBooks.png"); imageLogo.Height = "1.7cm"; // Ex 2.5cm imageLogo.LockAspectRatio = true; // Proprorzioni dell'immagine imageLogo.RelativeVertical = RelativeVertical.Line; imageLogo.RelativeHorizontal = RelativeHorizontal.Margin; imageLogo.Top = ShapePosition.Top; imageLogo.Left = ShapePosition.Left; // Ex. ShapePosition.Right; imageLogo.WrapFormat.Style = WrapStyle.TopBottom; // ex. WrapStyle.Through; #endregion #region Aggiunta TITOLO: Nome doc + Intestazione tabella TextFrame titoloFrame = section.Headers.Primary.AddTextFrame(); titoloFrame.WrapFormat.Style = WrapStyle.Through;// <--- tentativo per evitare la sovrascrittura in seconda pagina titoloFrame.Height = "5.0cm"; // Ex.: 3.0cm titoloFrame.Width = "19.6cm"; //Ex. 7.0cm titoloFrame.Left = ShapePosition.Center; // Ex.: ShapePosition.Left; titoloFrame.RelativeHorizontal = RelativeHorizontal.Margin; titoloFrame.Top = "2.3cm"; // Distanza dal TOP // Ex.: "5.0cm" OK 2.6cm titoloFrame.RelativeVertical = RelativeVertical.Page; // Riempimento del Titolo text frame Paragraph paragraphTitolo = titoloFrame.AddParagraph(); paragraphTitolo.Format.Font.Bold = true; paragraphTitolo.Format.Font.Size = 12; paragraphTitolo.Format.Alignment = ParagraphAlignment.Center; paragraphTitolo.AddText("Anteprima Ordini"); paragraphTitolo.AddLineBreak(); Font fontCodImpiantolABEL = new Font(); // ToDo Togliere da qui e mettere nel metodo DefineStyles fontCodImpiantolABEL.Bold = true; fontCodImpiantolABEL.Size = 9; paragraphTitolo.AddFormattedText("Impianto: ", fontCodImpiantolABEL); Font fontCodImpianto = new Font(); // ToDo Togliere da qui e mettere nel metodo DefineStyles fontCodImpianto.Bold = false; fontCodImpianto.Size = 10; paragraphTitolo.AddFormattedText(codiceImpianto, fontCodImpianto); // objAnteprimaOrdini.codice_impianto, fontCodImpianto); #endregion //----------------------- //ex Table tabellaHeader = section.Headers.Primary.AddTable(); Table tabellaHeader = titoloFrame.AddTable(); DefinizioneIntestazioneTabella(ref tabellaHeader, infoTabColonne); double topPadding = 3.8; RiempieIntestazioneTabellaHeader(ref tabellaHeader, infoTabColonne, topPadding); #endregion #region Pie' di pagina: Data e nr Pagina // Create footer Paragraph paragraph = section.Footers.Primary.AddParagraph(); paragraph.Format.Alignment = ParagraphAlignment.Left; paragraph.AddText(string.Format("{0}", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"))); // Ex.: "PowerBooks Inc · Sample Street 42 · 56789 Cologne · Germany"); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddTab(); paragraph.AddText("Pagina "); paragraph.AddPageField(); paragraph.AddText(" di "); paragraph.AddNumPagesField(); paragraph.Format.Font.Size = 9; #endregion } catch (Exception e) { log.ErrorFormat("Errore {0}, {1}", e.HResult, e.Message); throw; } } private void FillContent(AnteprimaOrdiniFornitoriIN aof, ref Section section, InfoColonna[] infoTabColonne) { string codiceFornitore = string.Empty; string dataConsegna = string.Empty; try { IFormatProvider culture = new System.Globalization.CultureInfo("it-IT", true); int numero_fornitori = aof.numero_fornitori; decimal totale_ordini= aof.totale_ordini; Table table = new Table(); Paragraph paragrafoRighaVuota = new Paragraph(); // Per ogni ordine a fornitore (ci posson essere +ordini per stesso fornitore, l'ordinamento è per data) foreach (OrdineFornitore of in aof.ordini.OrderBy(x => DateTime.Parse(x.data_consegna, culture, System.Globalization.DateTimeStyles.AssumeLocal))) { table = section.AddTable(); DefinizioneIntestazioneTabella(ref table, infoTabColonne); RiempieIntestazioneTabellaDati(ref table, of); codiceFornitore = of.codice_fornitore; dataConsegna = of.data_consegna; RiempieTabellaDati(ref table, codiceFornitore, dataConsegna, of); paragrafoRighaVuota = table.Section.AddParagraph(" "); } #region Tabella RIEPILOGO table = section.AddTable(); DefinizioneIntestazioneTabella(ref table, infoTabColonne); Row row = table.AddRow(); row.Format.Font.Bold = true; row.Shading.Color = c_TableBlue; // Colore di sfondo della intestazione row.Cells[0].AddParagraph(string.Format("Nr Fornitori: {0}", aof.numero_fornitori)); row.Cells[0].MergeRight = 3; // Unisce sino alla colonna 3 ovvero del M.Imb row.Cells[0].Format.Alignment = ParagraphAlignment.Left; row.Cells[0].Format.Borders.Right.Visible = false; // Non funziona row.Cells[4].AddParagraph(string.Format("Totale Ordini")); row.Cells[4].MergeRight = 1; // Unisce sino alla colonna 5 ovvero del Q.tà row.Cells[4].Format.Alignment = ParagraphAlignment.Right; row.Cells[4].Format.Borders.Left.Visible = false; // Non funziona row.Cells[6].AddParagraph(aof.totale_ordini.ToString("0.0000")); row.Cells[6].Format.Alignment = ParagraphAlignment.Right; row.Cells[6].Format.Borders.Left.Visible = false; // Non funziona #endregion } catch (Exception e) { log.ErrorFormat("Codice Fornitore {0}, DataConsegna {1}. Errore {0}, {1}", codiceFornitore, dataConsegna, e.HResult, e.Message); throw; } } #region Metodi di servizio /// <summary> /// Assegna lo stile generale della tabella e poi definisce le colonne in base a "infoTabColonne", /// per ciascuna colonna si definisce l'ampiezza e l'allineamento. /// La tabella occuperà l'intero rigo utile della pagina che si presume sia 19.5 centimetri /// </summary> /// <param name="table"></param> /// <param name="infoTabColonne"></param> private void DefinizioneIntestazioneTabella(ref Table table, InfoColonna[] infoTabColonne) { try { // ATTENZIONE la posizione della seguuente tabella dipende dal fatto // che nelle istruzioni che precedono si sia aggiuto un PARAGRAFO // Create the item table table.Style = "Table"; table.Borders.Color = c_TableBorder; table.Borders.Width = 0.25; table.Borders.Left.Width = 0.5; table.Borders.Right.Width = 0.5; table.Rows.LeftIndent = 0; // Before you can add a row, you must define the columns // ATTENZIONE attualmente l'ampiezza della pagina è di 19.5cm #region Aggiunta delle colonne alla tabella Column column; for (int i = 0; i < infoTabColonne.Length; i++) { column = table.AddColumn(infoTabColonne[i].Ampiezza); column.Format.Alignment = infoTabColonne[i].AllineamentoOrizzontale; } #endregion } catch (Exception e) { log.ErrorFormat("Errore {0}, {1}", e.HResult, e.Message); throw; } } private void RiempieIntestazioneTabellaHeader(ref Table table, InfoColonna[] infoTabColonne, double padding = 1.5) { try { // Create the header of the table #region Riga INTESTAZIONE Tabella // PRIMO RIGO rigo di intestazione Row row = table.AddRow(); row.HeadingFormat = true; // <-- if you set this, for the first n rows of your table, you mark this rows as header rows !!! row.Format.Alignment = ParagraphAlignment.Center; row.Format.Font.Bold = true; row.Shading.Color = c_TableBlue; // Colore di sfondo della intestazione if (padding != 1.5) { row.TopPadding = padding; row.BottomPadding = padding; } for (int i = 0; i < infoTabColonne.Length; i++) { row.Cells[i].AddParagraph(infoTabColonne[i].Label); // Testo intestazione row.Cells[i].Format.Alignment = infoTabColonne[i].AllineamentoOrizzontale; row.Cells[i].VerticalAlignment = infoTabColonne[i].AllineamentoVerticale; } #endregion // Impostazione del bordo table.SetEdge(0, 0, infoTabColonne.Length, 1, Edge.Box, BorderStyle.Single, 0.75, Color.Empty); } catch (Exception e) { log.ErrorFormat("Errore {0}, {1}", e.HResult, e.Message); } } private void RiempieIntestazioneTabellaDati(ref Table table, OrdineFornitore of) { try { // Create the header of the table #region Riga INTESTAZIONE Tabella // PRIMO RIGO rigo di intestazione Row row = table.AddRow(); row.HeadingFormat = true; // <-- if you set this, for the first n rows of your table, you mark this rows as header rows !!! row.Format.Alignment = ParagraphAlignment.Center; row.Format.Font.Bold = true; row.Shading.Color = c_TableBlue; // Colore di sfondo della intestazione row.Cells[0].AddParagraph(string.Format("{0} - {1}", of.codice_fornitore, of.descrizione_fornitore)); row.Cells[0].MergeRight = 5; // Unisce sino alla colonna 5 ovvero del Costo row.Cells[0].Format.Alignment = ParagraphAlignment.Left; row.Cells[0].Format.Borders.Right.Visible = false; // Non funziona row.Cells[6].AddParagraph(string.Format("{0}", of.data_consegna)); row.Cells[6].Format.Alignment = ParagraphAlignment.Right; row.Cells[6].Format.Borders.Left.Visible = false; // Non funziona #endregion // Impostazione del bordo table.SetEdge(0, 0, 7, 1, Edge.Box, BorderStyle.Single, 0.75, Color.Empty); } catch (Exception e) { log.ErrorFormat("Errore {0}, {1}", e.HResult, e.Message); //throw; } } private void RiempieTabellaDati(ref Table table, string codiceFornitore, string dataConsegna, OrdineFornitore of) { string ultimoCodiceArticolo = string.Empty; int rigo = 0; try { foreach (ArticoloFornitore a in of.articoli) { rigo++; Row row = table.AddRow(); ultimoCodiceArticolo = a.codice_articolo; // Le pagine pari avranno lo sfondo in grigio per facilitare la lettura if (rigo % 2 == 0) { row.Shading.Color = c_TableGray; // Colore di sfondo } row.Cells[0].AddParagraph(a.codice_articolo); // Codice Articolo row.Cells[0].Format.Alignment = ParagraphAlignment.Center; row.Cells[1].AddParagraph(a.descrizione_articolo); // Descrizione articolo row.Cells[1].Format.Alignment = ParagraphAlignment.Left; row.Cells[2].AddParagraph(a.unita_misura); // UM row.Cells[2].Format.Alignment = ParagraphAlignment.Center; row.Cells[3].AddParagraph(a.imballo_minimo.ToString("0.00")); // M.Imb. row.Cells[3].Format.Alignment = ParagraphAlignment.Right; row.Cells[4].AddParagraph(a.prezzo.ToString("0.00")); // Prezzo row.Cells[4].Format.Alignment = ParagraphAlignment.Right; row.Cells[5].AddParagraph(a.quantita_ordine.ToString("0.00")); // Quantità row.Cells[5].Format.Alignment = ParagraphAlignment.Right; row.Cells[6].AddParagraph(a.costo_totale.ToString("0.0000")); // Costo row.Cells[6].Format.Alignment = ParagraphAlignment.Right; // Impostazione del bordo //table.SetEdge(0, table.Rows.Count - 1, 7, 2, Edge.Box, BorderStyle.Single, 0.75); } // Ultima riga con il totale Row rowRecap = table.AddRow(); rowRecap.Cells[0].AddParagraph(string.Format("Totale ordine Fornitore:")); rowRecap.Cells[0].MergeRight = 5; // Unisce sino alla colonna 5 ovvero del Costo rowRecap.Cells[0].Format.Alignment = ParagraphAlignment.Right; rowRecap.Cells[0].Format.Borders.Right.Visible = false; // Non funziona rowRecap.Cells[6].AddParagraph(string.Format("{0}", of.totale_ordine_fornitore.ToString("0.0000"))); rowRecap.Cells[6].Format.Alignment = ParagraphAlignment.Right; rowRecap.Cells[6].Format.Borders.Left.Visible = false; // Non funziona // Impostazione del bordo table.SetEdge(0, table.Rows.Count - 1, 7, 1, Edge.Box, BorderStyle.Single, 0.75, Color.Empty); } catch (Exception e) { log.ErrorFormat("Fornitore {0}, DataConsegna {1}, Ultimo Articolo {2}. Errore {3}, {4}", codiceFornitore, dataConsegna, ultimoCodiceArticolo, e.HResult, e.Message); } } #endregion #endregion #endregion #region Oggetti per le tabelle PDF MigraDoc private class InfoColonna { public string Label { get; set; } /// <summary> /// With della colonna, es.: "1.7cm" /// </summary> public string Ampiezza { get; set; } public ParagraphAlignment AllineamentoOrizzontale { get; set; } public VerticalAlignment AllineamentoVerticale { get; set; } } #endregion } }
Mappa e Link
C# | Librerie di terze parti PlugIn
Visual Studio | Sistemi di Reporting
Parole chiave: