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.Text; namespace Mailing { public static class CreatePDF { public static void PDFSZO(List> data, DateTime date) { //Create Documents Document doc = new Document(); //Create Fonts 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"); //Create page Section page = doc.AddSection(); page.PageSetup.PageFormat = PageFormat.A4; page.PageSetup.Orientation = Orientation.Portrait; page.PageSetup.BottomMargin = new Unit(20, UnitType.Millimeter); page.PageSetup.TopMargin = new Unit(20, UnitType.Millimeter); page.PageSetup.LeftMargin = new Unit(30, UnitType.Millimeter); page.PageSetup.RightMargin = new Unit(15, UnitType.Millimeter); //Create Format 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); //Header title.AddText("Контроль работы водокольцевых насосов SZO\n"); title.AddText("за " + date.ToString("dd.MM.yyyy") + "\n"); var totalTime = new TimeSpan(); for (var i = 0; i < data.Count; i++) { if (i==9 || i == 18 || i == 21 || i == 24 || i == 46 || i == 30) continue; if (data[i].Count == 0) continue; //Create Format 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); //Add Title for Table title.AddText("Работа SZO печи №" + (i + 1).ToString("D2") + "\n"); //Create Table var table = doc.LastSection.AddTable(); table.Format.Alignment = ParagraphAlignment.Center; table.Format.Font.Size = 12; table.Format.Font.Name = "TNR"; table.Style = "Table"; table.Borders.Color = new Color(0, 0, 0); table.Borders.Width = 0.25; table.Borders.Left.Width = 0.5; table.Borders.Right.Width = 0.5; table.Rows.LeftIndent = 0; double[] colSize = { 5 , 4, 5, 3 }; foreach (var e in colSize) table.AddColumn(new Unit(e, UnitType.Centimeter)); //Add Header for Table var row = table.AddRow(); row.HeadingFormat = true; row.VerticalAlignment = VerticalAlignment.Center; row.Format.Font.Bold = true; row.Cells[0].AddParagraph("Начало тех. цикла"); row.Cells[1].AddParagraph("Название тех. цикла"); row.Cells[1].MergeDown = 1; row.Cells[2].AddParagraph("Начало работы SZO"); row.Cells[3].AddParagraph("Время работы SZO"); row.Cells[3].MergeDown = 1; row = table.AddRow(); row.HeadingFormat = true; row.VerticalAlignment = VerticalAlignment.Center; row.Format.Font.Bold = true; row.Cells[0].AddParagraph("Конец тех. цикла"); row.Cells[2].AddParagraph("Конец работы SZO"); //Add Row in Table var totalTimeVDP = new TimeSpan(); for (var j = 0; j < data[i].Count;) { var currCycle = data[i][j].tc; var currSZO = new List(); while (j < data[i].Count) { if (data[i][j].tc != currCycle) break; totalTimeVDP = totalTimeVDP.Add(data[i][j].workTime.Subtract(new TimeSpan(00, 15, 00))); currSZO.Add(data[i][j]); j++; } for (var k = 0; k < currSZO.Count; k++) { row = table.AddRow(); row.HeadingFormat = true; row.VerticalAlignment = VerticalAlignment.Center; if (k == 0) { row.Cells[0].AddParagraph(currCycle.start.ToString(@"yyyy.MM.dd HH:mm:ss")); if (currSZO.Count > 1) row.Cells[0].MergeDown = currSZO.Count - 1; row.Cells[1].AddParagraph(Names.techCycle[(int)currCycle.index]); row.Cells[1].MergeDown = currSZO.Count * 2 - 1; } row.Cells[2].AddParagraph(currSZO[k].tStart.ToString(@"HH\:mm\:ss")); row.Cells[3].AddParagraph(currSZO[k].workTime.Subtract(new TimeSpan(00, 15, 00)).ToString(@"hh\:mm\:ss")); row.Cells[3].MergeDown = 1; if (currSZO.Count / 2 == k && currSZO.Count % 2 == 0) { row.Cells[0].AddParagraph(currCycle.end.ToString(@"yyyy.MM.dd HH:mm:ss")); if (currSZO.Count > 1) row.Cells[0].MergeDown = currSZO.Count - 1; } row = table.AddRow(); row.HeadingFormat = true; row.VerticalAlignment = VerticalAlignment.Center; if (currSZO.Count / 2 == k && currSZO.Count % 2 == 1) { row.Cells[0].AddParagraph(currCycle.end.ToString(@"yyyy.MM.dd HH:mm:ss")); if (currSZO.Count > 1) row.Cells[0].MergeDown = currSZO.Count - 1; } row.Cells[2].AddParagraph(currSZO[k].tEnd.ToString(@"HH\:mm\:ss")); } } //Add Footer for Table 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 печи №" + (i + 1).ToString("D2") + ": " + totalTimeVDP.ToString(@"hh\:mm\:ss") ); totalTime = totalTime.Add(totalTimeVDP); } 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: " + totalTime.ToString(@"%d\.hh\:mm\:ss")); Print(date, doc, "SZO"); } public static void Print(DateTime time, Document doc, string type) { Directory.CreateDirectory(Directory.GetCurrentDirectory() + '/' + type); var file = Directory.GetCurrentDirectory() + '/' + type + '/' + 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); } /// /// 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; } } } }