ASCU_ALL/Mailing/CreatePDF.cs
2021-11-12 15:00:41 +05:00

364 lines
12 KiB
C#

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;
using System.Linq;
namespace Mailing
{
public static class CreatePDF
{
public static void PDFSZO(List<List<SZOWork>> 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++)
{
var vdp = i + 1;
var skip_vdp = new int[] { 10, 19, 22, 25, 31, 41, 47 };
if (skip_vdp.Contains(vdp))
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<SZOWork>();
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);
}
/// <summary>
/// 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.
/// </summary>
public class EZFontResolver : IFontResolver
{
EZFontResolver()
{ }
/// <summary>
/// Gets the one and only EZFontResolver object.
/// </summary>
public static EZFontResolver Get
{
get { return _singleton ?? (_singleton = new EZFontResolver()); }
}
private static EZFontResolver _singleton;
/// <summary>
/// Adds the font passing a filename.
/// </summary>
/// <param name="familyName">Name of the font family.</param>
/// <param name="style">The style.</param>
/// <param name="filename">The filename.</param>
/// <param name="simulateBold">if set to <c>true</c> bold will be simulated.</param>
/// <param name="simulateItalic">if set to <c>true</c> italic will be simulated.</param>
/// <exception cref="Exception">
/// Font file is too big.
/// or
/// Reading font file failed.
/// </exception>
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);
}
}
/// <summary>
/// Adds the font passing a byte array containing the font.
/// </summary>
/// <param name="familyName">Name of the font family.</param>
/// <param name="style">The style.</param>
/// <param name="data">The data.</param>
/// <param name="simulateBold">if set to <c>true</c> bold will be simulated.</param>
/// <param name="simulateItalic">if set to <c>true</c> italic will be simulated.</param>
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<string, EZFontInfo> _fonts = new Dictionary<string, EZFontInfo>();
struct EZFontInfo
{
//internal string FamilyName;
internal string FaceName;
//internal XFontStyle Style;
internal byte[] Data;
internal bool SimulateBold;
internal bool SimulateItalic;
}
}
}
}