// // Class: Document // Current CLR: 4.0.30319.34209 // System: Microsoft Visual Studio 10.0 // Author: dani // Created: 5/27/2015 8:52:50 PM // // Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved. using System; using System.Collections.Generic; using System.IO; using MigraDoc; using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Shapes; using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.Rendering; using bsmd.database; namespace bsmd.ReportGenerator { public class BSMDDocument { #region create document public static Document CreateDocument(string title, string subject, string author, Dictionary coverInfos, bool isUpdate) { // Create a new MigraDoc document Document document = new Document(); if(title != null) document.Info.Title = title; if(subject != null) document.Info.Subject = subject; if(author != null) document.Info.Author = author; BSMDDocument.DefineStyles(document); BSMDDocument.DefineCover(document, coverInfos, isUpdate); BSMDDocument.DefineContentSection(document, Orientation.Portrait, true); //TableOfContents.DefineTableOfContents(document); //DefineContentSection(document); //Paragraphs.DefineParagraphs(document); //Tables.DefineTables(document); //Charts.DefineCharts(document); return document; } /// /// create the final output document /// /// document to render /// full path of bla.pdf output file public static void RenderDocument(Document document, string filename) { // wozu braucht man das hier? string filenameCore = Path.GetFileNameWithoutExtension(filename); string migraTempFile = string.Format("{1}\\{0}.mdddl", filenameCore, Path.GetDirectoryName(filename)); MigraDoc.DocumentObjectModel.IO.DdlWriter.WriteToFile(document, migraTempFile); // TODO Test font embedding (-> filesize!) PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.None); renderer.Document = document; renderer.RenderDocument(); renderer.PdfDocument.Save(filename); } #endregion #region Style public static void DefineStyles(Document document) { // Get the predefined style Normal. Style style = document.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 = "Times New Roman"; // Heading1 to Heading9 are predefined styles with an outline level. An outline level // other than OutlineLevel.BodyText automatically creates the outline (or bookmarks) // in PDF. style = document.Styles["Heading1"]; style.Font.Name = "Tahoma"; style.Font.Size = 14; style.Font.Bold = true; style.Font.Color = Colors.DarkBlue; style.ParagraphFormat.PageBreakBefore = true; style.ParagraphFormat.SpaceAfter = 6; style = document.Styles["Heading2"]; style.Font.Size = 12; style.Font.Bold = true; style.ParagraphFormat.PageBreakBefore = false; style.ParagraphFormat.SpaceBefore = 6; style.ParagraphFormat.SpaceAfter = 6; style = document.Styles["Heading3"]; style.Font.Size = 10; style.Font.Bold = true; style.Font.Italic = true; style.ParagraphFormat.SpaceBefore = 6; style.ParagraphFormat.SpaceAfter = 3; style = document.Styles[StyleNames.Header]; style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right); style = document.Styles[StyleNames.Footer]; style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center); // Create a new style called TextBox based on style Normal style = document.Styles.AddStyle("TextBox", "Normal"); style.ParagraphFormat.Alignment = ParagraphAlignment.Justify; style.ParagraphFormat.Borders.Width = 2.5; style.ParagraphFormat.Borders.Distance = "3pt"; style.ParagraphFormat.Shading.Color = Colors.SkyBlue; // Create a new style called TOC based on style Normal style = document.Styles.AddStyle("TOC", "Normal"); style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right, TabLeader.Dots); style.ParagraphFormat.Font.Color = Colors.Blue; } #endregion #region Cover /// /// Defines the cover page. /// public static void DefineCover(Document document, Dictionary coverInfos, bool isUpdate) { Section section = document.AddSection(); Paragraph paragraph = section.AddParagraph(); paragraph.Format.SpaceAfter = "3cm"; Image image = section.AddImage(Properties.Settings.Default.LogoPath); image.Width = "3cm"; if (isUpdate) section.AddParagraph("EU-NOAD data UPDATE"); else paragraph = section.AddParagraph("EU-NOAD incoming data receipt"); paragraph.Format.Font.Size = 16; paragraph.Format.Font.Color = Colors.DarkRed; paragraph.Format.SpaceBefore = Unit.FromCentimeter(4); paragraph = section.AddParagraph("Rendering date: "); paragraph.Format.SpaceAfter = Unit.FromCentimeter(3); paragraph.AddDateField(); Table table = document.LastSection.AddTable(); table.Format.Font.Size = 14; Column column = table.AddColumn(); column.Width = Unit.FromCentimeter(4); column = table.AddColumn(); column.Width = Unit.FromCentimeter(8); foreach (string key in coverInfos.Keys) { Row row = table.AddRow(); row.Cells[0].AddParagraph(key); row.Cells[1].AddParagraph(coverInfos[key] ?? string.Empty); } } #endregion #region setup, header and footers /// /// Defines page setup, headers, and footers. /// public static void DefineContentSection(Document document, Orientation orientation, bool isInitialSection) { Section section = document.AddSection(); section.PageSetup.OddAndEvenPagesHeaderFooter = true; if(isInitialSection) section.PageSetup.StartingNumber = 1; section.PageSetup.Orientation = orientation; HeaderFooter header = section.Headers.Primary; header.AddParagraph("\tEU-NOAD receive receipt"); header = section.Headers.EvenPage; header.AddParagraph("EU-NOAD receive receipt"); // Create a paragraph with centered page number. See definition of style "Footer". Paragraph paragraph = new Paragraph(); paragraph.AddTab(); paragraph.AddPageField(); // Add paragraph to footer for odd pages. section.Footers.Primary.Add(paragraph); // Add clone of paragraph to footer for odd pages. Cloning is necessary because an object must // not belong to more than one other object. If you forget cloning an exception is thrown. section.Footers.EvenPage.Add(paragraph.Clone()); } #endregion #region NSW data public static void AddNSWMessageParagraph(Document document, IMessageParagraph messageParagraph) { Message message = messageParagraph as Message; // Einzelne Seite in Landscape für CREW Meldung if ((message != null) && (message.MessageNotificationClass == Message.NotificationClass.CREW)) { // Landscape! BSMDDocument.DefineContentSection(document, Orientation.Landscape, false); document.LastSection.AddParagraph(messageParagraph.Title, "Heading2"); document.LastSection.AddParagraph(messageParagraph.Subtitle, "Heading3"); BSMDDocument.CreateCrewTable(document, message); BSMDDocument.DefineContentSection(document, Orientation.Portrait, false); return; } document.LastSection.AddParagraph(messageParagraph.Title, "Heading2"); document.LastSection.AddParagraph(messageParagraph.Subtitle, "Heading3"); // Spezialbehandlung WAS Meldung if ((message != null) && (message.MessageNotificationClass == Message.NotificationClass.WAS)) { BSMDDocument.CreateWASTable(document, message); return; } if((message != null) && (message.MessageNotificationClass == Message.NotificationClass.BKRD)) { BSMDDocument.CreateBKRDTable(document, message); return; } if ((message != null) && (message.MessageNotificationClass == Message.NotificationClass.BKRA)) { BSMDDocument.CreateBKRATable(document, message); return; } if((message != null) && (message.MessageNotificationClass == Message.NotificationClass.LADG)) { BSMDDocument.CreateLADGTable(document, message); return; } if (messageParagraph.MessageText != null) // komplette Nachricht (z.B. STAT) BSMDDocument.AddActualTableParagraph(document, messageParagraph.MessageText, false); if((message != null) && (message.MessageNotificationClass == Message.NotificationClass.SEC)) { BSMDDocument.CreateLast10PortFacilitiesTable(document, message); return; } if((message != null) && (message.MessageNotificationClass == Message.NotificationClass.MDH)) { BSMDDocument.CreatePoCLast30DaysTable(document, message); return; } if (messageParagraph.ChildParagraphs != null) // 1:n message (CREW, PAS,..) { foreach (IMessageParagraph childParagraph in messageParagraph.ChildParagraphs) { BSMDDocument.AddActualTableParagraph(document, childParagraph.MessageText, true); } } } #region CREW private static void CreateCrewTable(Document document, Message message) { Table table = document.LastSection.AddTable(); table.Rows.VerticalAlignment = VerticalAlignment.Center; table.Borders.Visible = true; Column column = table.AddColumn(); column.Width = Unit.FromCentimeter(1); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(1); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3); Row hRow = table.AddRow(); hRow.Cells[1].AddParagraph("Last name"); hRow.Cells[2].AddParagraph("First name"); hRow.Cells[3].AddParagraph("Place of birth"); hRow.Cells[4].AddParagraph("Date of birth"); hRow.Cells[5].AddParagraph("Gender"); hRow.Cells[6].AddParagraph("Nat."); hRow.Cells[7].AddParagraph("Id doc. type"); hRow.Cells[8].AddParagraph("Id doc. number"); hRow.Cells[9].AddParagraph("Visa number"); hRow.Cells[10].AddParagraph("Duty"); for (int i = 0; i < message.Elements.Count; i++) { CREW crew = message.Elements[i] as CREW; Row row = table.AddRow(); row.Cells[0].AddParagraph((i + 1).ToString()); row.Cells[1].AddParagraph(crew.CrewMemberLastName ?? ""); row.Cells[2].AddParagraph(crew.CrewMemberFirstName ?? ""); row.Cells[3].AddParagraph(crew.CrewMemberPlaceOfBirth ?? ""); row.Cells[4].AddParagraph(crew.CrewMemberDateOfBirthDisplay); row.Cells[5].AddParagraph(crew.CrewMemberGenderDisplay); row.Cells[6].AddParagraph(crew.CrewMemberNationality ?? ""); row.Cells[7].AddParagraph(crew.CrewMemberIdentityDocumentTypeDisplay); row.Cells[8].AddParagraph(crew.CrewMemberIdentityDocumentId ?? ""); row.Cells[9].AddParagraph(crew.CrewMemberVisaNumber ?? ""); row.Cells[10].AddParagraph(crew.CrewMemberDuty ?? ""); } } #endregion #region MDH private static void CreatePoCLast30DaysTable(Document document, Message message) { MDH mdh = message.Elements[0] as MDH; if (mdh.PortOfCallLast30Days.Count > 0) { document.LastSection.AddParagraph("Port of call last 30 days", "Heading3"); Table table = document.LastSection.AddTable(); table.Rows.VerticalAlignment = VerticalAlignment.Center; table.Borders.Visible = true; Column column = table.AddColumn(); column.Width = Unit.FromCentimeter(1); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(9); Row hRow = table.AddRow(); hRow.Cells[1].AddParagraph("LoCode"); hRow.Cells[2].AddParagraph("Date of departure"); hRow.Cells[3].AddParagraph("Crew members joined"); hRow.Cells[4].AddParagraph("Names of joining crew"); for (int i = 0; i < mdh.PortOfCallLast30Days.Count; i++) { Row row = table.AddRow(); BSMDDocument.SetPoCLast30Days((i + 1), mdh.PortOfCallLast30Days[i], row); } } } private static void SetPoCLast30Days(int p, PortOfCallLast30Days portOfCallLast30Days, Row row) { row.Cells[0].AddParagraph(p.ToString()); row.Cells[1].AddParagraph(portOfCallLast30Days.PortOfCallLast30DaysLocode ?? ""); row.Cells[2].AddParagraph(portOfCallLast30Days.PortOfCallLast30DaysDateOfDeparture.HasValue ? portOfCallLast30Days.PortOfCallLast30DaysDateOfDeparture.Value.ToShortDateString() : ""); row.Cells[3].AddParagraph(portOfCallLast30Days.PortOfCallLast30DaysCrewMembersJoined.HasValue ? portOfCallLast30Days.PortOfCallLast30DaysCrewMembersJoined.Value ? "True" : "False" : ""); for (int i = 0; i < portOfCallLast30Days.CrewJoinedShip.Count; i++) { row.Cells[4].AddParagraph(portOfCallLast30Days.CrewJoinedShip[i].PortOfCallLast30DaysCrewJoinedShipName ?? ""); } } #endregion #region LADG private static void CreateLADGTable(Document document, Message message) { Table table = document.LastSection.AddTable(); table.Rows.VerticalAlignment = VerticalAlignment.Center; table.Borders.Visible = true; Column column = table.AddColumn(); column.Width = Unit.FromCentimeter(1); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(7); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(4); Row hRow = table.AddRow(); hRow.Cells[1].AddParagraph("handling type"); hRow.Cells[2].AddParagraph("Code (NST2007)"); hRow.Cells[1].AddParagraph("Number of items"); hRow.Cells[2].AddParagraph("Gross quantity (tons)"); for (int i = 0; i < message.Elements.Count; i++) { Row row = table.AddRow(); LADG ladg = message.Elements[i] as LADG; row.Cells[0].AddParagraph((i + 1).ToString()); row.Cells[1].AddParagraph(ladg.CargoHandlingType.HasValue ? (ladg.CargoHandlingType.Value == 0) ? "Load" : "Discharge" : ""); row.Cells[2].AddParagraph(ladg.CargoCodeNST ?? ""); row.Cells[3].AddParagraph(ladg.CargoNumberOfItems.HasValue ? ladg.CargoNumberOfItems.Value.ToString() : ""); row.Cells[4].AddParagraph(ladg.CargoGrossQuantity_TNE.HasValue ? ladg.CargoGrossQuantity_TNE.Value.ToString() : ""); } } #endregion #region SEC private static void CreateLast10PortFacilitiesTable(Document document, Message message) { SEC sec = message.Elements[0] as SEC; if (sec.LastTenPortFacilitesCalled.Count > 0) { document.LastSection.AddParagraph("Last 10 port facilites called", "Heading3"); Table table = document.LastSection.AddTable(); table.Format.Font.Size = 8; table.Rows.VerticalAlignment = VerticalAlignment.Center; table.Borders.Visible = true; Column column = table.AddColumn(); column.Width = Unit.FromCentimeter(0.8); column = table.AddColumn(); column.Width = Unit.FromCentimeter(3.9); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(1.5); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(0.8); column = table.AddColumn(); column.Width = Unit.FromCentimeter(2); column = table.AddColumn(); column.Width = Unit.FromCentimeter(1); Row hRow = table.AddRow(); hRow.Cells[0].AddParagraph("No."); hRow.Cells[1].AddParagraph("Port name"); hRow.Cells[2].AddParagraph("Country"); hRow.Cells[3].AddParagraph("LoCode"); hRow.Cells[4].AddParagraph("Arr."); hRow.Cells[5].AddParagraph("Dep."); hRow.Cells[6].AddParagraph("Ship sec. level"); hRow.Cells[7].AddParagraph("sec. matter to report"); hRow.Cells[8].AddParagraph("GISIS"); for(int i=0;i> messageText, bool isSubTable) { Table table = document.LastSection.AddTable(); // table.LeftPadding = new Unit(0.5, UnitType.Centimeter); Column leadColumn = table.AddColumn(Unit.FromCentimeter(8)); leadColumn.Format.Alignment = ParagraphAlignment.Left; Column mainColumn = table.AddColumn(Unit.FromCentimeter(8)); mainColumn.Format.Alignment = ParagraphAlignment.Left; for (int i = 0; i < messageText.Count; i++) { KeyValuePair elem = messageText[i]; Row row = table.AddRow(); Cell cell = row.Cells[0]; cell.AddParagraph(elem.Key); row.Cells[1].AddParagraph(elem.Value); } if (isSubTable) { table.SetEdge(0, 0, 2, messageText.Count, Edge.Box, BorderStyle.DashLargeGap, new Unit(1.0, UnitType.Point)); } document.LastSection.AddParagraph(); } #endregion } }