using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Drawing.Imaging; using System.Drawing.Printing; using System.Windows.Forms; using Microsoft.Reporting.WinForms; using System.Configuration; using SteamWare; using C2P_Data; using System.Net; using System.Web; /// /// Classe che si occupa di stampare report da reportViewer via printer 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); 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(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, int ticket) { DataTable tab = new DataTable(); switch (tipoReport) { case reportRichiesto.ReportOffers: tab = (DataTable)DtProxy.man.taPQuot.GetData(ticket, ""); break; //case reportRichiesto.ReportSimulation: // tab = (DataTable)DtProxy.man.taQFQ.repOffersByTicket(ticket); // break; case reportRichiesto.Vocabolario: tab = (DataTable)SteamWare.selDataVoc.mgr.getVocabolarioByLemma(SteamWare.user_std.UtSn.lingua, "C2P_prt1"); 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, int ticket, devInfoParam deviceInfoParam) { LocalReport report = new LocalReport(); report.EnableExternalImages = true; string deviceInfo = ""; switch (tipoReport) { case reportRichiesto.ReportOffers: report.ReportPath = System.Web.HttpContext.Current.Server.MapPath(@".\Reports\ReportOffers.rdlc"); // 2) caricamento tab dati DataTable tabVoc = new DataTable(); DataTable tabQuote = new DataTable(); tabVoc = (DataTable)SteamWare.selDataVoc.mgr.getVocabolarioByLemma(SteamWare.user_std.UtSn.lingua, "C2P_prt1"); tabQuote = (DataTable)DtProxy.man.taPQuot.GetData(ticket, ""); // 3) inserimento dataset nel report report.DataSources.Add(new ReportDataSource("dsVocabolario", tabVoc)); report.DataSources.Add(new ReportDataSource("dsQuoteFull_Q_Data", tabQuote)); //report.DataSources.Add(new ReportDataSource("dsQuoteFull_Q_Data", caricaDati(tipoReport, ticket))); //report.DataSources.Add(new ReportDataSource("dsVocabolario", caricaDati(reportRichiesto.Vocabolario, ticket))); break; //case reportRichiesto.ReportSimulation: // report.ReportPath = @".\Reports\ReportSimulation.rdlc"; // report.DataSources.Add(new ReportDataSource(memLayer.ML.confReadString("RepDsSimulation"), caricaDati(tipoReport, ticket))); // 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 stampaReport(reportRichiesto tipoReport, int ticket, string printerName) { bool answ = false; int idxPrintJob = 0; // gestione coda: SE abilitata... if (memLayer.ML.confReadBool("enableQueue")) { // disabilitata COMUNQUE coda (per ora) #if false // incomincio con gestione della coda di stampa... inserisco in tab la richiesta di stampa... DataProxy.obj.taPJQ.insertQuery(tipoReport.ToString(), UDC, printerName); // faccio un ciclo while... finchè non sono "in testa" alla coda delle esecuzioni aspetto... string nextUdc = "ND"; try { nextUdc = DataProxy.obj.taPJQ.getNext()[0].UDC; } catch { nextUdc = "ND"; } // verifico eventuali processi zombie: quelli in stato 0 con LastTry superiore a data attuale meno zombieMsTime DataProxy.obj.taPJQ.chiudiZoombie(DateTime.Now.AddMilliseconds(-memLayer.ML.confReadInt("zombieMsTime"))); // ora inizio a fare le mie stampe... Random rand = new Random(); int msWait = 200; while (nextUdc != UDC) { // indico che ho fatto un tentativo di stampa aggiornando dtLastTry DataProxy.obj.taPJQ.updateLastTry(UDC); // aspetto... msWait = rand.Next(memLayer.ML.confReadInt("minWait"), memLayer.ML.confReadInt("maxWait")); System.Threading.Thread.Sleep(msWait); // leggo prox record da coda nextUdc = DataProxy.obj.taPJQ.getNext()[0].UDC; } // salvo idx job... idxPrintJob = DataProxy.obj.taPJQ.getNext()[0].IdxPrintJob; #endif } string outForm = ""; string pagWidth = ""; string pagHeigth = ""; string margin = ""; string tipo = ""; switch (tipoReport) { case reportRichiesto.ReportOffers: tipo = "Offers"; break; //case reportRichiesto.ReportOffers: // tipo = "Offers"; // break; default: break; } // carico di dati con lettura da web.config parametrica if (printerName == "") { printerName = memLayer.ML.confReadString(string.Format("printer{0}", tipo)); } outForm = "EMF"; pagWidth = memLayer.ML.confReadString(string.Format("PageWidth{0}", tipo)); pagHeigth = memLayer.ML.confReadString(string.Format("PageHeight{0}", tipo)); margin = memLayer.ML.confReadString(string.Format("Margin{0}", tipo)); // compongo parametri stampa devInfoParam deviceInfo = new devInfoParam(outForm, pagHeigth, pagWidth, margin, margin, margin, margin); answ = printAndLog(ticket, printerName, answ, tipoReport, deviceInfo); // gestione coda: SE abilitata... if (memLayer.ML.confReadBool("enableQueue")) { // disabilitata COMUNQUE coda (per ora) #if false if (answ) { // registro stampato in tabella queue... DataProxy.obj.taPJQ.updateStato(idxPrintJob, 1); } else { // registro annullato in tab queue... DataProxy.obj.taPJQ.updateStato(idxPrintJob, -1); } #endif } return answ; } /// /// effettua la vera e propria fase di stampa /// /// /// /// /// /// /// private bool printAndLog(int ticket, 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, ticket, 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.confReadInt("_logLevel"); doPdfCopy = memLayer.ML.confReadBool("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.confReadInt("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 } /// /// tipologia di report ammessi alla stampa... /// public enum reportRichiesto { ReportOffers //, ReportSimulation , Vocabolario }