tags:

views:

4503

answers:

6

I've been given a requirement for an internal web application to send documents to a printer transparently. The idea would be that the user can select their nearest printer, and the web application would send their print jobs to the printer they selected.

The first printer we have to roll out against are Canons, so my questions is: How would I go about sending a document to print aross the network to a specific Canon? The type of Cannon is question is an iR5570 and the documents that will be said will mainly be Word and PDFs

I'm currently working my way through the terrible, IE only Canon Developer site, but I'm kinda hoping someone can point me in the right direction or point me at a 3rd party assembly :)

A: 

If the document types in question are known to windows (as DOC and PDF should be), can you use the windows verbs to do it?

Codeproject PDF example : Automated PDF Conversion using the PDF995 and FreePDF_XP Freeware Printers MSDN : Verbs and File Associations

Craig.Nicol
+1  A: 

The PrintDocument documentation contains a detailed example of printing from C#. The printer name should point to a local printer or a printer share. See printing-to-a-pdf-printer-programatically for printing PDF docs.

gimel
+1  A: 

Something has to translate your Word and PDF documents into something that the printer understands. Normally this would be Word itself for the former, and some kind of PDF viewer for the latter. Those programs then need to be instructed on which printer to send the output to.

One possible way to go would be to save the documents as Postscript files. Then they could be sent to a Postscript capable printer directly from a C# application. That would probably be the easiest way to do it.

Jeffrey L Whitledge
+1  A: 

It might be worth 5 minutes to check through the capabilities of sql reporting service. I have used it in the past to render pdf straight to print.

http://blogs.msdn.com/bryanke/articles/71491.aspx

MBoy
+5  A: 

The key phrase in that question is 'web application'.

In a normal web app using only HTML+Javascript over HTTP, you can't just send a document directly to a printer. That's one of the reasons web browsers exist, and without that functionality everyone's printer would collect the same kind of junk that a public fax machine does.

So you need some kind of work-around. One option is to build on a common plug-in, like flash, silverlight, java applet, or even something like greasemonkey. Another is a custom plug-in, like a hosted winforms control or custom browser extension.

You are very fortunate, in that it looks like you have complete control (or knowlege of) the deployment environment, and that this environment if fairly homogenous. This means you have an additional option that others have started to explore. If you can install all of the printers in your environment to the web server, then it's fairly easy using the built-in .Net printer classes (in the System.Drawing.Printing namespace) to list out those printer, either show them to the user so they can pick or keep some kind of IP to Printer mapping table, and then print directly to that printer from your web app. Note that this scheme may require your app to run at a higher level of trust than would otherwise be required.

Now it comes to actually printing your PDF's and word documents. For acrobat, check this link:
http://support.adobe.com/devsup/devsup.nsf/docs/52080.htm
Note that it's a little dated, but I believe the concept is still valid. You'll have to experiment some to make sure it works as expected.

For Word, I'm not normally a fan of Office interop/automation in a web app. But in this case you're not editing any documents: just loading it up long enough to print. And the fact that you're relying on another scarce resource (the printers) should keep this from scaling beyond what your web server could cope with. So you may have a rare case where Office automation in a web project makes sense.

Joel Coehoorn
I have full control of the deployment enviroment, it's an internal intranet application. Office interop/autmation is horrible, and while the documents are generated by C#, we use Aspose.Words. I can accept using interop.automation for printing, going to give it a try.
Chris Canal
If you already have Aspose, then you might check if it supports printing.
Joel Coehoorn
But definitely agree that in 99% of cases office interop is horrible.
Joel Coehoorn
I'm an idiot, I should have checked the Aspose documentation! Thanks
Chris Canal
+4  A: 

Many printers and multifunction devices today support the printing of PDFs directly, this may solve one of your problems. Simply have the PDF sent to the printer. In fact, some even support the sending of a URL and the printer will then go get the document and print it. Lexmark for sure does this and I think a few other vendors do as well. This still mean you have to deal with the Word document. Word 2007 supports PDF (with the add-in installed from Microsoft) and I've used this function programatically with great success in C#.

Here's the code for that:

Microsoft.Office.Interop.Word.ApplicationClass msWord = new Microsoft.Office.Interop.Word.ApplicationClass();

object paramUnknown = Type.Missing;
object missing = Type.Missing;
object paramSaveChangesNo = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;
//object paramFonts = Microsoft.Office.Interop.Word.wde
object paramFormatPDF = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatPDF;
object paramTrue = true;
object paramReadOnly = true;  
object sourceDoc = @"c:\input.doc"                              
object target = @"c:\output.pdf";

msWord.Visible = false;

//open .doc
msWord.Documents.Open(ref sourceDoc, ref paramUnknown, ref paramReadOnly, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown);

//so it won't show on the taskbar
msWord.Application.Visible = false;
msWord.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateMinimize;

//save .doc to new target name and format
msWord.ActiveDocument.SaveAs(ref targetDoc, ref paramFormatPDF, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramTrue, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown, ref paramUnknown);

msWord.ActiveDocument.Close(ref missing, ref missing, ref missing);

msWord.Quit(ref paramSaveChangesNo, ref paramUnknown, ref paramUnknown);

Lastly, if your device doesn't support PDF printing then you could use Ghostscript or other tools to convert your PDF to PS or even PCL. Not the greatest as this mean running a little unmanaged code or worst case, shelling out and executing the GS command line, that being said, we currently do this in one of our web apps and it works well. As an aside, we don't do it for print but rather the joining of a number of PDFs togheter, but in the end it will work the same.

Douglas Anderson