using DataClients; using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.Rendering; using PdfSharp.Drawing; using PdfSharp.Fonts; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace Mailing { public static class GenSZO { private static DateTime timeStart = DateTime.Now.AddDays(-1); private static DateTime timeEnd = DateTime.Now; private static Dictionary> resFull = new Dictionary>(); public static void GetPDF(DateTime time) { timeStart = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0); timeEnd = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0).AddDays(1); GetData(); PDFGenSZO.AddHeader("Контроль работы водокольцевых насосов SZO ", timeStart, timeEnd); foreach (var e in resFull) PDFGenSZO.AddSZOTable(e.Key, e.Value); PDFGenSZO.AddTotalTime(); PDFGenSZO.Print(time); } private static void GetData() { var a = new STPClient(); for (ushort i = 1; i <= 50; i++) { var tc = a.GetTechCycle(timeStart, timeEnd, i); var ad = a.GetAnalogDiscret(timeStart, timeEnd, i); foreach (var e in tc) { int[] chk1 = { (int)TechCycle.Operation.cooling_ingot, (int)TechCycle.Operation.cooling_reflow, (int)TechCycle.Operation.cooling_welding }; int[] chk2 = { (int)TechCycle.Operation.end_tech_cycle, (int)TechCycle.Operation.unloading_loading, (int)TechCycle.Operation.looking_welding, (int)TechCycle.Operation.unloading_kit }; if (!chk1.Contains((int)e.index) && !chk2.Contains((int)e.index)) continue; if (chk1.Contains((int)e.index)) { var test = (from l in ad.an[13] where l.Item1 >= e.start && l.Item1 <= e.end && l.Item2 >= 30 select l).ToArray(); if (test.Length == 0) continue; } var currstat = new Tuple(e.start, null); foreach (var d in ad.di[22]) { if ( currstat.Item1 <= e.end && d.Item1 >= e.start && currstat.Item2.HasValue && currstat.Item2.Value ) { var t1 = currstat.Item1 > e.start ? currstat.Item1 : e.start; var t2 = d.Item1 > e.end ? e.end : d.Item1; var res = t2 - t1; currstat = d; if (chk1.Contains((int)e.index) && res.TotalMinutes < 15) continue; if (!resFull.ContainsKey(i)) resFull.Add(i, new List()); resFull[i].Add(new SZOWork() { oper = e.index, techCycleStart = e.start, WorkTime = res }); } currstat = d; } } } } public class SZOWork { public TechCycle.Operation oper = TechCycle.Operation.unloading_loading; public DateTime techCycleStart = DateTime.Now; public TimeSpan WorkTime = new TimeSpan(); } } public static class PDFGenSZO { private static TimeSpan totalTime = new TimeSpan(); private static Document doc = new Document(); public static void AddHeader(string name, DateTime start, DateTime end) { EZFontResolver fontRes = EZFontResolver.Get; GlobalFontSettings.FontResolver = fontRes; fontRes.AddFont("TNR", XFontStyle.Regular, @"./times.ttf"); fontRes.AddFont("TNR", XFontStyle.Bold, @"./timesbd.ttf"); fontRes.AddFont("TNR", XFontStyle.BoldItalic, @"./timesbi.ttf"); fontRes.AddFont("TNR", XFontStyle.Italic, @"./timesi.ttf"); Section page = AddPage(); var title = page.AddParagraph(); title.Format.Alignment = ParagraphAlignment.Center; title.Format.Font.Size = 14; title.Format.Font.Name = "TNR"; title.Format.SpaceAfter = new Unit(10, UnitType.Millimeter); title.AddText(name + "\n"); end = end.AddSeconds(-1); title.AddText("за период с " + start.ToString("dd.MM.yyyy") + " по " + end.ToString("dd.MM.yyyy") + "\n"); } public static void AddSZOTable(int vdp, List res) { var title = doc.LastSection.AddParagraph(); title.Format.Alignment = ParagraphAlignment.Left; title.Format.Font.Size = 12; title.Format.Font.Name = "TNR"; title.Format.SpaceAfter = new Unit(2, UnitType.Millimeter); title.AddText("Работа SZO печи №" + vdp.ToString("D2") + "\n"); var table = doc.LastSection.AddTable(); table.Format.Alignment = ParagraphAlignment.Center; table.Format.Font.Size = 12; table.Format.Font.Name = "TNR"; table.Rows.LeftIndent = 0; int[] colSize = { 5, 8, 4 }; foreach (var e in colSize) { var col = table.AddColumn(new Unit(e, UnitType.Centimeter)); col.Borders.Left.Color = new Color(0, 0, 0); col.Borders.Left.Width = 0.25; col.Borders.Right.Color = new Color(0, 0, 0); col.Borders.Right.Width = 0.25; } var row = table.AddRow(); row.Borders.Top.Color = new Color(0, 0, 0); row.Borders.Top.Width = 0.25; row.Borders.Bottom.Color = new Color(0, 0, 0); row.Borders.Bottom.Width = 0.25; row.HeadingFormat = true; row.VerticalAlignment = VerticalAlignment.Center; row.Cells[0].AddParagraph("Время начала операции"); row.Cells[1].AddParagraph("Название операции"); row.Cells[2].AddParagraph("Время работы SZO"); var totalVDP = new TimeSpan(); foreach (var e in res) { row = table.AddRow(); row.Borders.Bottom.Color = new Color(0, 0, 0); row.Borders.Bottom.Width = 0.25; row.VerticalAlignment = VerticalAlignment.Center; row.Cells[0].AddParagraph(e.techCycleStart.ToString(@"yyyy.MM.dd HH:mm:ss.ff")); row.Cells[1].AddParagraph(Names.techCycle[(int)e.oper]); row.Cells[2].AddParagraph(e.WorkTime.ToString(@"hh\:mm\:ss")); totalVDP = totalVDP.Add(e.WorkTime); } title = doc.LastSection.AddParagraph(); title.Format.Alignment = ParagraphAlignment.Right; title.Format.Font.Size = 12; title.Format.Font.Name = "TNR"; title.Format.SpaceAfter = new Unit(10, UnitType.Millimeter); title.AddText( "Общее время работы SZO печи №" + vdp.ToString("D2") + ": " + totalVDP.ToString(@"hh\:mm\:ss") ); totalTime = totalTime.Add(totalVDP); } public static void AddTotalTime() { AddTotalTime(totalTime); } public static void AddTotalTime(TimeSpan time) { var title = doc.LastSection.AddParagraph(); title.Format.Alignment = ParagraphAlignment.Left; title.Format.Font.Size = 12; title.Format.Font.Name = "TNR"; title.Format.SpaceAfter = new Unit(10, UnitType.Millimeter); title.AddText("Общее время работы SZO: " + time.ToString(@"%d\.hh\:mm\:ss")); } public static void Print(DateTime time) { var file = Directory.GetCurrentDirectory() + '/' + time.ToString("yyyy-MM-dd") + ".pdf"; if (File.Exists(file)) File.Delete(file); var pdfRenderer = new PdfDocumentRenderer(true) { Document = doc }; pdfRenderer.RenderDocument(); pdfRenderer.PdfDocument.Save(file); } private static Section AddPage() { Section section = doc.AddSection(); section.PageSetup.PageFormat = PageFormat.A4; section.PageSetup.Orientation = Orientation.Portrait; section.PageSetup.BottomMargin = new Unit(20, UnitType.Millimeter); section.PageSetup.TopMargin = new Unit(20, UnitType.Millimeter); section.PageSetup.LeftMargin = new Unit(30, UnitType.Millimeter); section.PageSetup.RightMargin = new Unit(15, UnitType.Millimeter); return section; } } /// /// EZFontResolver is a generic font resolver for PDFsharp. /// It implement IFontResolver internally. /// To use it, just pass your fonts as filename or byte[] /// in calls to AddFont. /// public class EZFontResolver : IFontResolver { EZFontResolver() { } /// /// Gets the one and only EZFontResolver object. /// public static EZFontResolver Get { get { return _singleton ?? (_singleton = new EZFontResolver()); } } private static EZFontResolver _singleton; /// /// Adds the font passing a filename. /// /// Name of the font family. /// The style. /// The filename. /// if set to true bold will be simulated. /// if set to true italic will be simulated. /// /// Font file is too big. /// or /// Reading font file failed. /// public void AddFont(string familyName, XFontStyle style, string filename, bool simulateBold = false, bool simulateItalic = false) { using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { var size = fs.Length; if (size > int.MaxValue) throw new Exception("Font file is too big."); var length = (int)size; var data = new byte[length]; var read = fs.Read(data, 0, length); if (length != read) throw new Exception("Reading font file failed."); AddFont(familyName, style, data, simulateBold, simulateItalic); } } /// /// Adds the font passing a byte array containing the font. /// /// Name of the font family. /// The style. /// The data. /// if set to true bold will be simulated. /// if set to true italic will be simulated. public void AddFont(string familyName, XFontStyle style, byte[] data, bool simulateBold = false, bool simulateItalic = false) { // Add the font as we get it. AddFontHelper(familyName, style, data, false, false); // If the font is not bold and bold simulation is requested, add that, too. if (simulateBold && (style & XFontStyle.Bold) == 0) { AddFontHelper(familyName, style | XFontStyle.Bold, data, true, false); } // Same for italic. if (simulateItalic && (style & XFontStyle.Italic) == 0) { AddFontHelper(familyName, style | XFontStyle.Italic, data, false, true); } // Same for bold and italic. if (simulateBold && (style & XFontStyle.Bold) == 0 && simulateItalic && (style & XFontStyle.Italic) == 0) { AddFontHelper(familyName, style | XFontStyle.BoldItalic, data, true, true); } } void AddFontHelper(string familyName, XFontStyle style, byte[] data, bool simulateBold, bool simulateItalic) { // Currently we do not need FamilyName and Style. // FaceName is a combination of FamilyName and Style. var fi = new EZFontInfo { //FamilyName = familyName, FaceName = familyName.ToLower(), //Style = style, Data = data, SimulateBold = simulateBold, SimulateItalic = simulateItalic }; if ((style & XFontStyle.Bold) != 0) { // TODO Create helper method to prevent having duplicate string literals? fi.FaceName += "|b"; } if ((style & XFontStyle.Italic) != 0) { fi.FaceName += "|i"; } // Check if we already have this font. var test = GetFont(fi.FaceName); if (test != null) throw new Exception("Font " + familyName + " with this style was already registered."); _fonts.Add(fi.FaceName.ToLower(), fi); } #region IFontResolver public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic) { string faceName = familyName.ToLower() + (isBold ? "|b" : "") + (isItalic ? "|i" : ""); EZFontInfo item; if (_fonts.TryGetValue(faceName, out item)) { var result = new FontResolverInfo(item.FaceName, item.SimulateBold, item.SimulateItalic); return result; } return null; } public byte[] GetFont(string faceName) { EZFontInfo item; if (_fonts.TryGetValue(faceName, out item)) { return item.Data; } return null; } #endregion private readonly Dictionary _fonts = new Dictionary(); struct EZFontInfo { //internal string FamilyName; internal string FaceName; //internal XFontStyle Style; internal byte[] Data; internal bool SimulateBold; internal bool SimulateItalic; } } }