Domanda

In questo momento sto lavorando a un progetto che prevede la ricezione di un messaggio da un'altra applicazione, la formattazione del contenuto di quel messaggio e l'invio a una stampante.La tecnologia scelta è il servizio Windows C#.L'output potrebbe essere chiamato report, suppongo, ma un motore di reporting non è necessario.Un semplice motore di template, come StringTemplate, o anche XSLT che genera output HTML andrebbe bene.Il problema che sto riscontrando è trovare un modo gratuito per stampare questo tipo di output da un servizio.Da quel momento sembra che funzionerà, sto lavorando su un prototipo utilizzando RDLC di Microsoft, compilando un report locale e quindi rendendolo come immagine in un flusso di memoria, che poi stamperò.I problemi con questo sono:

  • La stampa di più pagine sarà un grosso grattacapo.
  • Devo ancora utilizzare PrintDocument per stampare il flusso di memoria, che non è supportato in un servizio Windows (anche se potrebbe funzionare: non sono ancora arrivato così lontano con il prototipo)
  • Se i dati rilevati cambiano, devo modificare il set di dati e la classe in cui i dati vengono deserializzati.male male male.

Qualcuno ha dovuto fare qualcosa di remotamente simile?Qualche consiglio?Ho già postato una domanda sulla stampa di HTML senza l'input dell'utente e, dopo aver sprecato circa 3 giorni, sono giunto alla conclusione che non è possibile farlo, almeno non con nessuno strumento disponibile gratuitamente.

Tutto l'aiuto è apprezzato.

MODIFICARE:Siamo alla versione 2.0 del framework .NET.

È stato utile?

Soluzione

Credimi, spenderai più soldi cercando di cercare/sviluppare una soluzione rispetto all'acquisto di un componente di terze parti.Non reinventare la ruota e scegli la soluzione a pagamento.

La stampa è un problema complesso e mi piacerebbe vedere il giorno in cui verrà aggiunto un migliore supporto quadro per questo.

Altri suggerimenti

La stampa da un servizio Windows è davvero dolorosa.Sembra che funzioni...A volte...ma alla fine si blocca o genera un'eccezione di tanto in tanto, senza una ragione chiara.È davvero senza speranza.Ufficialmente è pari non supportato, senza alcuna spiegazione, né alcuna proposta di soluzione alternativa.

Recentemente mi sono confrontato con il problema e dopo diverse prove e sperimentazioni infruttuose, sono finalmente arrivato a due soluzioni praticabili:

  • Scrivi la tua DLL di stampa utilizzando l'API Win32 (ad esempio in C/C++), quindi utilizzala dal tuo servizio con P/Invoke (funziona bene)
  • Scrivi il tuo componente COM+ di stampa, quindi utilizzalo dal tuo servizio.Ho scelto questa soluzione con successo di recente (ma era un componente COM+ di terze parti, non scritto da me). Funziona anche perfettamente.

L'ho fatto.È una rottura di palle.Il problema è che la stampa richiede la presenza del motore GDI, il che normalmente significa che devi avere il desktop, che si carica solo quando sei loggato.Se stai tentando di farlo da un servizio su un server, normalmente non hai effettuato l'accesso.

Quindi per prima cosa non puoi eseguire come normale utente del servizio, ma invece come un utente reale che dispone di diritti di accesso interattivi.Quindi devi modificare le voci del registro del servizio (non ricordo come al momento, dovrei trovare il codice, cosa che posso fare stasera se sei veramente interessato).Infine bisogna pregare.

Il tuo più grande grattacapo a lungo termine riguarderà i driver di stampa.Se si esegue come servizio senza un utente registrato, alcuni driver di stampa preferiscono visualizzare di tanto in tanto delle finestre di dialogo.Cosa succede quando la stampante esaurisce il toner?O senza carta?Il driver potrebbe far apparire una finestra di dialogo che non verrà mai vista e bloccare la coda della stampante perché nessuno ha effettuato l'accesso!

Stampare da un servizio è una cattiva idea.Le stampanti di rete sono collegate "per utente".È possibile contrassegnare il servizio in modo che venga eseguito come un utente particolare, ma lo considererei una cattiva pratica di sicurezza.Potresti essere in grado di connetterti a una stampante locale, ma esiterei comunque prima di seguire questa strada.

L'opzione migliore è fare in modo che il servizio memorizzi i dati e che un'applicazione avviata dall'utente esegua la stampa richiedendo i dati al servizio.Oppure una posizione comune in cui vengono archiviati i dati, come un database.

Se è necessario che i dati vengano stampati a intervalli regolari, impostare un evento Attività tramite l'Utilità di pianificazione.L'avvio di un processo da un servizio richiederà la conoscenza del nome utente e della password, il che, ancora una volta, è una cattiva pratica di sicurezza.

Per quanto riguarda la stampa stessa, utilizzare uno strumento di terze parti per generare il report sarà la soluzione più semplice.

Per rispondere alla tua prima domanda, questo può essere abbastanza semplice a seconda dei dati.Disponiamo di una varietà di applicazioni basate su servizi che fanno esattamente ciò che chiedi.In genere, analizziamo il file in arrivo e lo avvolgiamo attorno al nostro Postscript o PCL.Se il layout è abbastanza semplice, ci sono alcuni codici PCL di base con cui puoi racchiuderlo per fornire il layout di carattere/stampa che desideri (sarei più che felice di darti qualche guida qui offline).

Una volta che hai un file pronto per la stampa, puoi inviarlo a una stampante UNC condivisa, direttamente a una stampante installata localmente o anche all'IP del dispositivo (dati di tipo RAW o LPR).

Se, tuttavia, stai seguendo il percorso PDF, il metodo più semplice è inviare l'output PDF a una stampante che supporti la stampa PDF diretta (molti lo fanno ora).In questo caso basta inviare il PDF al dispositivo e subito verrà stampato.

L'altra opzione è avviare Ghostscript che dovrebbe essere gratuito per le tue esigenze (controlla la licenza poiché hanno alcune versioni diverse, alcune GNU, alcune GPL ecc.) e usa la sua funzione di stampa integrata o semplicemente converti in Postscript e invia al dispositivo.Ho utilizzato Ghostscript molte volte nelle app di servizio, ma non sono un grande fan poiché sostanzialmente sborserai ed eseguirai un'app da riga di comando per eseguire la conversione.Detto questo, è un'app stabile che tende a fallire con garbo

Questo potrebbe non essere quello che stai cercando, ma se avessi bisogno di farlo in modo veloce e sporco, lo farei:

  1. Crea un'applicazione WPF separata (in modo da poter utilizzare la gestione dei documenti integrata)
  2. Dai al servizio la possibilità di interagire con il desktop (nota che in realtà non è necessario mostrare nulla sul desktop o essere loggato affinché funzioni)
  3. Chiedi al servizio di eseguire l'applicazione e di fornirgli i dati da stampare.

Probabilmente potresti anche stamparlo da un browser Web eseguito dal servizio (anche se consiglierei di creare la tua shell IE, anziché utilizzare un browser completo).

Per una soluzione più dettagliata (anche gratuita), la soluzione migliore è probabilmente formattare manualmente il documento da soli (utilizzando GDI+ per eseguire il layout per te).Questo è noioso, soggetto a errori, richiede tempo e spreca molta carta durante lo sviluppo, ma ti dà anche il massimo controllo su ciò che va alla stampante.

Se è possibile eseguire l'output in post script, alcune stampanti stamperanno tutto ciò che viene inviato tramite FTP in una determinata directory su di esse.

L'abbiamo usato per superare i crediti di stampa che la nostra università ci ha esposto, ma se il tuo servizio viene inviato a ps, puoi semplicemente inviare il file ps alla stampante tramite ftp.

Stiamo usando XtraReports di DevExpress stampare da un servizio senza problemi.Il loro modello di report è simile a quello di Windows Form, quindi puoi inserire dinamicamente elementi di testo e quindi eseguire il comando di stampa.

Penso che seguiremo la strada dei terzi.Mi piace il flusso XSL -> HTML -> PDF -> Stampante...Winnovative Da HTML a PDF sembra buono per la prima parte, ma sto incontrando difficoltà nel trovare una buona soluzione per la stampa di PDF...eventuali suggerimenti?Idealmente la licenza sarebbe su base sviluppatore, non su base runtime distribuita.

In risposta alla tua domanda sulla stampa PDF, non ho trovato una soluzione elegante.Stavo inviando "shell" ad Adobe, il che era inaffidabile e richiedeva che un utente effettuasse l'accesso in ogni momento.Per risolvere questo problema specifico, ho richiesto che i file che elaboriamo (fatture) siano invece formattati come file Tiff multipagina che possono essere divisi e stampati utilizzando le funzioni di stampa native di .NET.La posizione di Adobe sembra essere "convincere l'utente a visualizzare il file in Adobe Reader e a fare clic su Stampa".Inutile.

Sono ancora desideroso di trovare un buon modo per produrre report di qualità che possano essere generati dal server web...

La stampa utilizzando System.Drawing.Printing non è supportata da MS, secondo la risposta di Yann Trevin.Tuttavia, potresti essere in grado di utilizzare il nuovo System.Printing (I pensare)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top