From 1c35b5e0c5d98e5672b7911e280e046ef654e212 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli" Date: Wed, 12 Feb 2020 10:06:27 +0100 Subject: [PATCH] inizio gestione download rdlc + print locale --- LPA/LPA.csproj | 16 +- LPA/MainForm.Designer.cs | 13 -- LPA/MainForm.cs | 72 +++++- LPA/logs/.placeholder | 1 + LPA/packages.config | 3 +- LPA/reportPrinter.cs | 485 +++++++++++++++++++++++++++++++++++++++ LPA/reports/.placeholder | 1 + LPA/temp/.placeholder | 1 + 8 files changed, 567 insertions(+), 25 deletions(-) create mode 100644 LPA/logs/.placeholder create mode 100644 LPA/reportPrinter.cs create mode 100644 LPA/reports/.placeholder create mode 100644 LPA/temp/.placeholder diff --git a/LPA/LPA.csproj b/LPA/LPA.csproj index edceff3..5af06af 100644 --- a/LPA/LPA.csproj +++ b/LPA/LPA.csproj @@ -55,6 +55,18 @@ ..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll + + ..\packages\Microsoft.ReportViewer.Runtime.Common.12.0.2402.15\lib\Microsoft.ReportViewer.Common.dll + + + ..\packages\Microsoft.ReportViewer.Runtime.Common.12.0.2402.15\lib\Microsoft.ReportViewer.DataVisualization.dll + + + ..\packages\Microsoft.ReportViewer.Runtime.Common.12.0.2402.15\lib\Microsoft.ReportViewer.ProcessingObjectModel.dll + + + ..\packages\Microsoft.ReportViewer.Runtime.WinForms.12.0.2402.15\lib\Microsoft.ReportViewer.WinForms.dll + ..\packages\MongoDB.Bson.2.10.1\lib\net452\MongoDB.Bson.dll @@ -82,9 +94,6 @@ ..\packages\Pipelines.Sockets.Unofficial.2.1.1\lib\net461\Pipelines.Sockets.Unofficial.dll - - ..\packages\RawPrint.0.5.0\lib\net40\RawPrint.dll - ..\packages\SharpCompress.0.24.0\lib\net45\SharpCompress.dll @@ -154,6 +163,7 @@ + MainForm.cs diff --git a/LPA/MainForm.Designer.cs b/LPA/MainForm.Designer.cs index 9883fd7..27a0237 100644 --- a/LPA/MainForm.Designer.cs +++ b/LPA/MainForm.Designer.cs @@ -35,7 +35,6 @@ this.txtFileSel = new System.Windows.Forms.TextBox(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.btnPrint = new System.Windows.Forms.Button(); - this.btnRawPrint = new System.Windows.Forms.Button(); this.SuspendLayout(); // // lbPrinters @@ -102,22 +101,11 @@ this.btnPrint.UseVisualStyleBackColor = true; this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click); // - // btnRawPrint - // - this.btnRawPrint.Location = new System.Drawing.Point(9, 192); - this.btnRawPrint.Name = "btnRawPrint"; - this.btnRawPrint.Size = new System.Drawing.Size(75, 23); - this.btnRawPrint.TabIndex = 8; - this.btnRawPrint.Text = "Raw Print"; - this.btnRawPrint.UseVisualStyleBackColor = true; - this.btnRawPrint.Click += new System.EventHandler(this.btnRawPrint_Click); - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(785, 509); - this.Controls.Add(this.btnRawPrint); this.Controls.Add(this.btnPrint); this.Controls.Add(this.statusStrip1); this.Controls.Add(this.txtFileSel); @@ -140,7 +128,6 @@ private System.Windows.Forms.TextBox txtFileSel; private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.Button btnPrint; - private System.Windows.Forms.Button btnRawPrint; } } diff --git a/LPA/MainForm.cs b/LPA/MainForm.cs index 7cec443..3de3306 100644 --- a/LPA/MainForm.cs +++ b/LPA/MainForm.cs @@ -8,12 +8,20 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -using RawPrint; +using SteamWare; namespace LPA { public partial class MainForm : Form { + /// + /// Lista delle code di stampa da gestire + /// + protected List printQueue; + + /// + /// Classe apertura + /// public MainForm() { InitializeComponent(); @@ -23,6 +31,9 @@ namespace LPA private void myInit() { setupPrintersList(); + // fare elggere conf da json locale... + printQueue = new List(); + printQueue.Add("default"); } private void setupPrintersList() @@ -78,14 +89,59 @@ namespace LPA } - private void btnRawPrint_Click(object sender, EventArgs e) + + + + + + + /// + /// Effettua download file rdlc da + /// + private void doConfDownload() { - string printName = lbPrinters.SelectedItem.ToString(); - string filePath = txtFileSel.Text; - - IPrinter printer = new Printer(); - - printer.PrintRawFile(printName, filePath); + // ciclo su IOB configurati + foreach (var currIob in printQueue) + { +#if false + fileEmbed objFiles = new fileEmbed(); + string rawData = ""; + string url2call = ""; + if (utils.CRB("ConfToCloud")) + { + // invio su cloud... + url2call = $"{urlDownloadFileCloud}{currIob}"; + } + else + { + // invio in locale! + url2call = $"{urlDownloadFile}{currIob}"; + } + rawData = utils.callUrlNow(url2call); + if (!string.IsNullOrEmpty(rawData)) + { + // deserializzo + objFiles = JsonConvert.DeserializeObject(rawData); + if (objFiles != null) + { + // salvo! + foreach (var item in objFiles.fileList) + { + fileMover.obj.salvaFileString(utils.confDir, item.fileName, item.content); + } + displayTaskAndLog("Download conf files aggiornati"); + } + else + { + displayTaskAndLog($"Error: invalid file data received, deserialized to null ({rawData})"); + } + } + else + { + displayTaskAndLog("Error: no file data downloaded"); + } +#endif + } } } } diff --git a/LPA/logs/.placeholder b/LPA/logs/.placeholder new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/LPA/logs/.placeholder @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LPA/packages.config b/LPA/packages.config index de9bd58..8609276 100644 --- a/LPA/packages.config +++ b/LPA/packages.config @@ -10,6 +10,8 @@ + + @@ -19,7 +21,6 @@ - diff --git a/LPA/reportPrinter.cs b/LPA/reportPrinter.cs new file mode 100644 index 0000000..d7d7565 --- /dev/null +++ b/LPA/reportPrinter.cs @@ -0,0 +1,485 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Reporting.WinForms; +using SteamWare; +using System.Data; +using System.Drawing.Imaging; +using System.Drawing.Printing; +using System.IO; + +namespace LPA +{ + /// + /// Classe che si occupa di stampare report da reportViewer via printer locale/remota + /// + public class reportPrinter + { + #region area codice da non modificare + + private int m_currentPageIndex; + protected int logLevel = 0; + protected bool doPdfCopy = false; + /// + /// stream del report... + /// + private IList m_streams; + /// + /// ciclo da fornire al renderizzatore dei report, per salvare 1 immagine da ogni pagina del report + /// + /// + /// + /// + /// + /// + /// + private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) + { + // creo files con nomi univoci... + string filePathName = string.Format(@"~\temp\{0}_{1:HHmmss}_{1:ffff}.{2}", name, DateTime.Now, fileNameExtension); + Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(filePathName), FileMode.Create); + //Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(@"~\temp\" + name + "." + fileNameExtension), FileMode.Create); + m_streams.Add(stream); + return stream; + } + /// + /// ciclo da fornire al renderizzatore dei report, per salvare 1 pdf da ogni pagina del report + /// + /// + /// + /// + /// + /// + /// + private Stream CreateStreamPdf(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) + { + // creo Directory se non c'è + SteamWare.fileMover fm = new fileMover(string.Format(@"{0}\{1:yyyy}\{1:MM}\{1:dd}\", memLayer.ML.confReadString("PdfFolder"), DateTime.Now), ""); + fm.checkDir(); + string pdfPathName = string.Format(@"{0}\{1:yyyy}\{1:MM}\{1:dd}\{2}_{1:HHmmss}_{1:ffff}.{3}", memLayer.ML.confReadString("PdfFolder"), DateTime.Now, name, fileNameExtension); + //Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(@"~\temp\" + name + "." + fileNameExtension), FileMode.Create); + Stream stream = new FileStream(SteamWare.SteamwareStrings.getFilePath(pdfPathName), FileMode.Create); + m_streams.Add(stream); + return stream; + } + /// + /// Handler per PrintPageEvents + /// + /// + /// + private void PrintPage(object sender, PrintPageEventArgs ev) + { + Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); + ev.Graphics.DrawImage(pageImage, ev.PageBounds); + m_currentPageIndex++; + ev.HasMorePages = (m_currentPageIndex < m_streams.Count); + } + /// + /// funzione di stampa... + /// + private void Print(string printerName) + { + //const string printerName = "Microsoft Office Document Image Writer"; + //const string printerName = "Brother HL-2170W series"; + if (m_streams == null || m_streams.Count == 0) + return; + PrintDocument printDoc = new PrintDocument(); + printDoc.PrinterSettings.PrinterName = printerName; + if (!printDoc.PrinterSettings.IsValid) + { + logger.lg.scriviLog(String.Format("Impostazioni non valide per la stampante \"{0}\".", printerName), tipoLog.ERROR); + return; + } + printDoc.PrintPage += new PrintPageEventHandler(PrintPage); + printDoc.Print(); + } + /// + /// Export del report come EMF (Enhanced Metafile) file. + /// + /// + private void Export(LocalReport report, string deviceInfo) + { + Warning[] warnings; + m_streams = new List(); + report.Render("Image", deviceInfo, CreateStream, out warnings); + foreach (Stream stream in m_streams) stream.Position = 0; + } + /// + /// Export del report come PDF file. + /// + /// + private void ExportPDF(LocalReport report, string deviceInfo) + { + Warning[] warnings; + m_streams = new List(); + report.Render("PDF", deviceInfo, CreateStreamPdf, out warnings); + foreach (Stream stream in m_streams) stream.Position = 0; + } + /// + /// dispone l'applicazione e rilascia le risorse + /// + public void Dispose() + { + if (m_streams != null) + { + foreach (Stream stream in m_streams) + stream.Close(); + m_streams = null; + } + } + + #endregion + + #region area codice da modificare + + /// + /// carica i dati richiesti dal report dalla StoredProcedure (filtrando quindi...) + /// + /// + /// cod UDC + /// tabella dati + private DataTable caricaDati(reportRichiesto tipoReport, string keyParam) + { + int intIdx = 0; + DataTable tab = new DataTable(); + switch (tipoReport) + { + case reportRichiesto.cartLabel: + // int.TryParse(keyParam, out intIdx); + // tab = (DataTable)DataLayer.man.taRepStack.GetData(intIdx); + break; + case reportRichiesto.paintLabelPre: + // int.TryParse(keyParam, out intIdx); + // tab = (DataTable)DataLayer.man.taRepStack.GetData(intIdx); + break; + case reportRichiesto.paintLabelPost: + // int.TryParse(keyParam, out intIdx); + // tab = (DataTable)DataLayer.man.taRepStack.GetData(intIdx); + break; + case reportRichiesto.partLabel: + int.TryParse(keyParam, out intIdx); + tab = (DataTable)DataLayer.man.taIL.getByKey(intIdx); + break; + case reportRichiesto.stackLabel: + int.TryParse(keyParam, out intIdx); + tab = (DataTable)DataLayer.man.taRepStack.GetData(intIdx); + break; + default: + break; + } + return tab; + } + /// + /// Crea un report locale da file rdlc, carica i dati, esporta report come EMF file e quindi lo invia alla stampante + /// + /// report ammessi: ElencoMacchine / RichiestaIntervento + /// nome completo stampante (rispetto al server) + /// cod UDC + /// parametri "device input" + public void printReport(reportRichiesto tipoReport, string printerName, string keyParam, devInfoParam deviceInfoParam) + { + LocalReport report = new LocalReport(); + report.EnableExternalImages = true; + string deviceInfo = ""; + string repoBasePath = utils.getPath(memLayer.ML.cdv("ReportBasePath")); + repoBasePath = repoBasePath.Replace("\\site", ""); + switch (tipoReport) + { + case reportRichiesto.cartLabel: + report.ReportPath = string.Format(@"{0}\CartLabel.rdlc", repoBasePath); + report.DataSources.Add(new ReportDataSource(memLayer.ML.cdv("ReportDS_DocCart"), caricaDati(tipoReport, keyParam))); + break; + case reportRichiesto.paintLabelPre: + report.ReportPath = string.Format(@"{0}\PaintPreLabel.rdlc", repoBasePath); + report.DataSources.Add(new ReportDataSource(memLayer.ML.cdv("ReportDS_DocPaintPre"), caricaDati(tipoReport, keyParam))); + break; + case reportRichiesto.paintLabelPost: + report.ReportPath = string.Format(@"{0}\PaintPreLabel.rdlc", repoBasePath); + report.DataSources.Add(new ReportDataSource(memLayer.ML.cdv("ReportDS_DocPaintPre"), caricaDati(tipoReport, keyParam))); + break; + case reportRichiesto.partLabel: + report.ReportPath = string.Format(@"{0}\PartLabel.rdlc", repoBasePath); + report.DataSources.Add(new ReportDataSource(memLayer.ML.cdv("ReportDS_DocPart"), caricaDati(tipoReport, keyParam))); + break; + case reportRichiesto.stackLabel: + report.ReportPath = string.Format(@"{0}\StackLabel.rdlc", repoBasePath); + report.DataSources.Add(new ReportDataSource(memLayer.ML.cdv("ReportDS_DocStack"), caricaDati(tipoReport, keyParam))); + break; + } + deviceInfo = deviceInfoParam.xmlParam; + doEmfPrint(printerName, report, deviceInfo); + // controllo se devo fare copia PDF... stampiamo ANCHE su pdf su una folder locale + if (doPdfCopy) + { + deviceInfoParam.OutputFormat = "PDF"; + deviceInfo = deviceInfoParam.xmlParam; + doLocalPdfPrint(report, deviceInfo); + } + } + /// + /// esegue print vero e proprio + /// + /// + /// + /// + private void doEmfPrint(string printerName, LocalReport report, string deviceInfo) + { + // export in EMF + Export(report, deviceInfo); + m_currentPageIndex = 0; + // stampo + Print(printerName); + // do dispose? + Dispose(); + } + /// + /// effettua stampa in PDF dei vari report in una cartella Anno/Mese/Giorno + /// + /// + /// + private void doLocalPdfPrint(LocalReport report, string deviceInfo) + { + // export in PDF + ExportPDF(report, deviceInfo); + m_currentPageIndex = 0; + // do dispose? + Dispose(); + } + /// + /// effettua la stampa del cartellino indicato + /// + /// + /// + /// indirizzo di rete completo stampante del tipo \\nomePc\nomeStampante, oppure "" x default + /// + public bool stampaCartellino(tipoDocumento documento, string keyParam, string printerName) + { + bool answ = false; + int idxPrintJob = 0; + DataLayer dtProx = new DataLayer(); + // gestione coda stampa... + + // incomincio con gestione della coda di stampa... inserisco in tab la richiesta di stampa... + if (memLayer.ML.CRB("disable_singleton")) + { + dtProx.taPJQ.insertQuery(documento.ToString(), keyParam, printerName); + } + else + { + DataLayer.man.taPJQ.insertQuery(documento.ToString(), keyParam, printerName); + } + // faccio un ciclo while... finchè non sono "in testa" alla coda delle esecuzioni aspetto... + string nextJob = "ND"; + try + { + if (memLayer.ML.CRB("disable_singleton")) + { + nextJob = dtProx.taPJQ.getNext()[0].KeyParam; + } + else + { + nextJob = DataLayer.man.taPJQ.getNext()[0].KeyParam; + } + } + catch + { + nextJob = "ND"; + } + // verifico eventuali processi zombie: quelli in stato 0 con LastTry superiore a data attuale meno zombieMsTime + if (memLayer.ML.CRB("disable_singleton")) + { + dtProx.taPJQ.chiudiZoombie(DateTime.Now.AddMilliseconds(-memLayer.ML.CRI("zombieMsTime"))); + } + else + { + DataLayer.man.taPJQ.chiudiZoombie(DateTime.Now.AddMilliseconds(-memLayer.ML.CRI("zombieMsTime"))); + } + // ora inizio a fare le mie stampe... + Random rand = new Random(); + int msWait = 200; + while (nextJob != keyParam) + { + // indico che ho fatto un tentativo di stampa aggiornando dtLastTry + if (memLayer.ML.CRB("disable_singleton")) + { + dtProx.taPJQ.updateLastTry(keyParam); + } + else + { + DataLayer.man.taPJQ.updateLastTry(keyParam); + } + // aspetto... + msWait = rand.Next(memLayer.ML.confReadInt("minWait"), memLayer.ML.confReadInt("maxWait")); + System.Threading.Thread.Sleep(msWait); + // leggo prox record da coda + if (memLayer.ML.CRB("disable_singleton")) + { + nextJob = dtProx.taPJQ.getNext()[0].KeyParam; + } + else + { + nextJob = DataLayer.man.taPJQ.getNext()[0].KeyParam; + } + } + // salvo idx job... + try + { + if (memLayer.ML.CRB("disable_singleton")) + { + idxPrintJob = dtProx.taPJQ.getNext()[0].IdxPrintJob; + } + else + { + idxPrintJob = DataLayer.man.taPJQ.getNext()[0].IdxPrintJob; + } + } + catch (Exception exc) + { + logger.lg.scriviLog($"Errore in recupero IdxPrint Job:{exc}", tipoLog.EXCEPTION); + } + + // dimensioni pagina + string outForm = ""; + string pagWidth = ""; + string pagHeigth = ""; + string margin = ""; + reportRichiesto report = reportRichiesto.stackLabel; + string tipo = ""; + + switch (documento) + { + case tipoDocumento.docBinPre: + tipo = "DocPaint"; + report = reportRichiesto.paintLabelPre; + break; + case tipoDocumento.docBinPost: + tipo = "DocPaintPost"; + report = reportRichiesto.paintLabelPost; + break; + case tipoDocumento.docCart: + tipo = "DocCart"; + report = reportRichiesto.cartLabel; + break; + case tipoDocumento.docPart: + tipo = "DocPart"; + report = reportRichiesto.partLabel; + break; + case tipoDocumento.docStack: + tipo = "DocStack"; + report = reportRichiesto.stackLabel; + break; + default: + break; + } + // carico di dati con lettura da web.config parametrica + if (string.IsNullOrEmpty(printerName)) + { + printerName = memLayer.ML.cdv(string.Format("printer{0}", tipo)); + } + outForm = "EMF"; + pagWidth = memLayer.ML.cdv(string.Format("PageWidth{0}", tipo)); + pagHeigth = memLayer.ML.cdv(string.Format("PageHeight{0}", tipo)); + margin = memLayer.ML.cdv(string.Format("Margin{0}", tipo)); + // compongo parametri stampa + devInfoParam deviceInfo = new devInfoParam(outForm, pagHeigth, pagWidth, margin, margin, margin, margin); + answ = printAndLog(keyParam, printerName, answ, report, deviceInfo); + if (answ) + { + // registro stampato in tabella queue... + if (memLayer.ML.CRB("disable_singleton")) + { + dtProx.taPJQ.updateStato(idxPrintJob, 1); + } + else + { + DataLayer.man.taPJQ.updateStato(idxPrintJob, 1); + } + } + else + { + // registro annullato in tab queue... + if (memLayer.ML.CRB("disable_singleton")) + { + dtProx.taPJQ.updateStato(idxPrintJob, -1); + } + else + { + DataLayer.man.taPJQ.updateStato(idxPrintJob, -1); + } + + } + return answ; + } + /// + /// effettua la vera e propria fase di stampa + /// + /// + /// + /// + /// + /// + /// + private bool printAndLog(string keyParam, string printerName, bool answ, reportRichiesto report, devInfoParam deviceInfo) + { + try + { + if (logLevel > 5) logger.lg.scriviLog(String.Format("Sto per inviare un report alla stampante {0}", printerName), tipoLog.INFO); + reportPrinter.obj.printReport(report, printerName, keyParam, deviceInfo); + if (logLevel > 5) logger.lg.scriviLog(String.Format("inviato comando print alla stampante {0}", printerName), tipoLog.INFO); + answ = true; + } + catch (Exception e) + { + logger.lg.scriviLog(String.Format("Errore in fase di creazione e stampa report: stampante {0}, errore riscontrato {1}", printerName, e), tipoLog.EXCEPTION); + } + return answ; + } + /// + /// oggetto protected + /// + /// + protected reportPrinter() + { + logLevel = memLayer.ML.CRI("_logLevel"); + doPdfCopy = memLayer.ML.CRB("doPdfCopy"); + } + /// + /// singleton pubblico + /// + public static reportPrinter obj = new reportPrinter(); + /// + /// effettua pulizia della cartella temp x i files più vecchi di X ore (web.config) + /// + public void pulisciDir() + { + // num max ore di età x files "vecchi" da tenere in temp area... + int maxOre = memLayer.ML.CRI("maxAgeTempAreaHours"); + int eliminati = 0; + // ottengo elenco files *.emf + fileMover.obj.setDirectory(@"~\temp\"); + FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.emf"); + bool fatto = false; + foreach (FileInfo _file in _fis) + { + if (_file.CreationTime < DateTime.Now.AddHours(-maxOre)) // elimino files vecchi... + { + fatto = fileMover.obj.eliminaFile(_file); + if (fatto) + { + logger.lg.scriviLog(String.Format("Eliminato file {0}", _file.Name), tipoLog.INFO); + eliminati++; + } + } + } + // salvo il log degli update + if (eliminati > 0) + { + logger.lg.scriviLog(String.Format("Eliminati {0} files temporanei da area temp", eliminati), tipoLog.INFO); + } + } + + #endregion + } +} diff --git a/LPA/reports/.placeholder b/LPA/reports/.placeholder new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/LPA/reports/.placeholder @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/LPA/temp/.placeholder b/LPA/temp/.placeholder new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/LPA/temp/.placeholder @@ -0,0 +1 @@ + \ No newline at end of file