I have a report that I want to fire off based on a button in a GridView. This will generate a label and send it to an attached (local) Zebra printer. When I run this locally, it works fine. The printer doesn't even have to be the default. When I copy the files to the server, and click the Print button nothing happens.
CrystalReportSource CrystalReportSource1 = new CrystalReportSource();
CrystalReportViewer CrystalReportViewer1 = new CrystalReportViewer();
CrystalReportViewer1.HasPrintButton = true;
// CrystalReportViewer1.PrintMode = "ActiveX";
CrystalReportViewer1.ReportSource = CrystalReportSource1;
CrystalReportViewer1.EnableParameterPrompt = false;
CrystalReportSource1.Report.FileName = "BinLocation2.rpt";
TableLogOnInfo logOnInfo = new TableLogOnInfo();
CrystalReportSource1.ReportDocument.SetParameterValue(0, Item);
CrystalReportSource1.ReportDocument.SetParameterValue(1, binlocation);
CrystalReportSource1.ReportDocument.SetParameterValue(2, Lot);
CrystalReportSource1.ReportDocument.SetParameterValue(3, expiredate);
CrystalReportSource1.ReportDocument.SetParameterValue(4, NDC);
logOnInfo.ConnectionInfo.ServerName = ConfigurationManager.AppSettings["SalesReportServerName"];
logOnInfo.ConnectionInfo.DatabaseName = ConfigurationManager.AppSettings["SalesReportDatabaseName"];
logOnInfo.ConnectionInfo.UserID = ConfigurationManager.AppSettings["SalesReportUserID"];
logOnInfo.ConnectionInfo.Password = ConfigurationManager.AppSettings["SalesReportPassword"];
TableLogOnInfos infos = new TableLogOnInfos();
infos.Add(logOnInfo);
CrystalReportViewer1.LogOnInfo = infos;
try
{
CrystalReportSource1.ReportDocument.PrintToPrinter(1, false, 0, 0);
}
I installed the redist packages for Visual Studio. Compared the web.config files. The printer is not installed on the server, but I want this done on the client side (with no prompt to print). Is there a better way to go about doing this? What am I missing?
Firstly, this is how I've achieved this functionality (explanations will follow):
// get the user selected printer
var printerName = Settings.Instance[profile].DirectPrinter;
// enumerate the printers visible to the application
var allPrinters = PrinterSettings.InstalledPrinters.OfType<string>().OrderBy(p => p).ToList();
// Strip out PDF, XPS and any file based printers. These cause havoc on a server based print
var acceptablePrinters = allPrinters.Except(allPrinters
.Where(s => Settings.Instance[profile].PrintersToIgnore
.Any(u => s.ToLower().Contains(u)))).ToList();
if (acceptablePrinters.Contains(printerName))
{
report.PrintOptions.PrinterName = printerName;
report.PrintToPrinter(copies, collate, 0, 0);
}
else
{
// Log the reason why the printer was rejected
// Or you may choose to just print to default
}
Explanation
The PrintToPrinter method runs on the server side, so it will only work with printers that the server and the IIS application pool identity can 'see'.
Most Zebra printers will be networked, so with configuration can be made visible across the entire network. However, you need to allow configuration in your asp.net application to set a printer name at runtime (even if it's always the same), and then you can call PrintToPrinter that will print to a networked printer.
Printing to client without a prompt is practically impossible, and ill advised. For that I allow the user to choose to print to client and then export to PDF, and the standard PDF print dialog box prompts the user for his printer settings. This was added to allow printing to non-networked printers.
Related
After struggling whole day, I identified the issue but this didn't solve my problem.
On short:
I need to open a PDF, convert to BW (grayscale), search some words and insert some notes nearby found words. At a first look it seems easy but I discovered how hard PDF files are processed (having no "words" concepts and so on).
Now the first task, converting to grayscale just drove me crazy. I didn't find a working solution either commercial or free. I came up with this solution:
open the PDF
print with windows drivers, some free PDF printers
This is quite ugly since I will force the C# users to install such 3'rd party SW but.. that is fpr the moment. I tested FreePDF, CutePDF and PDFCreator. All of them are working "stand alone" as expected.
Now when I tried to print from C#, obviously, I don't want the print dialog, just select BW option and print (aka. convert)
The following code just uses a PDF library, shown for clarity only.
Aspose.Pdf.Facades.PdfViewer viewer = new Aspose.Pdf.Facades.PdfViewer();
viewer.BindPdf(txtPDF.Text);
viewer.PrintAsGrayscale = true;
//viewer.RenderingOptions = new RenderingOptions { UseNewImagingEngine = true };
//Set attributes for printing
//viewer.AutoResize = true; //Print the file with adjusted size
//viewer.AutoRotate = true; //Print the file with adjusted rotation
viewer.PrintPageDialog = true; //Do not produce the page number dialog when printing
////PrinterJob printJob = PrinterJob.getPrinterJob();
//Create objects for printer and page settings and PrintDocument
System.Drawing.Printing.PrinterSettings ps = new System.Drawing.Printing.PrinterSettings();
System.Drawing.Printing.PageSettings pgs = new System.Drawing.Printing.PageSettings();
//System.Drawing.Printing.PrintDocument prtdoc = new System.Drawing.Printing.PrintDocument();
//prtdoc.PrinterSettings = ps;
//Set printer name
//ps.PrinterName = prtdoc.PrinterSettings.PrinterName;
ps.PrinterName = "CutePDF Writer";
ps.PrintToFile = true;
ps.PrintFileName = #"test.pdf";
//
//ps.
//Set PageSize (if required)
//pgs.PaperSize = new System.Drawing.Printing.PaperSize("A4", 827, 1169);
//Set PageMargins (if required)
//pgs.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0);
//Print document using printer and page settings
viewer.PrintDocumentWithSettings(ps);
//viewer.PrintDocument();
//Close the PDF file after priting
What I discovered and seems to be little explained, is that if you select
ps.PrintToFile = true;
no matter C# PDF library or PDF printer driver, Windows will just skip the PDF drivers and instead of PDF files will output PS (postscript) ones which obviously, will not be recognized by Adobe Reader.
Now the question (and I am positive that others who may want to print PDFs from C# may be encountered) is how to print to CutePDF for example and still suppress any filename dialog?
In other words, just print silently with programmatically selected filename from C# application. Or somehow convince "print to file" to go through PDF driver, not Windows default PS driver.
Thanks very much for any hints.
I solved conversion to grayscale with a commercial component with this post and I also posted there my complete solution, in care anyone will struggle like me.
Converting PDF to Grayscale pdf using ABC PDF
This days I've been developing a service that sends a PDF file to a network printer and effectively print it using C# and the GhostscriptProcessor library.
But now I'm really stuck with the next (and last) step I want to make. I need to know wether or not the file was really printed. I tried everything I could (for instance I tried implementing this powershell script but I'm not familiar at all with powershell and I got depressed since I got too many errors I can't solve) but I can't find the answer.
Is there ANY way using C# (any library) to retrieve if a document has been printed. Or retrieve the whole log of documents printed? Any script I can call through C# (or not, I am able to circumvent that) that tells me the information I need?
I'd like to add that I have access to the printer using the System.Drawing.Printing library as follows:
var printServer = new PrintServer();
var myPrintQueues = printServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
foreach (PrintQueue pq in myPrintQueues)
{
pq.Refresh();
string printerName = "ES7470 MFP(PCL)";
if (!pq.Name.ToUpper().Contains(printerName.ToUpper())) break;
PrintJobInfoCollection jobs = pq.GetPrintJobInfoCollection();
//And here I can use pq or jobs but I can't retrieve the log at all.
}
I think the problem is the PrintServer, I'm not in your environment so I cant tell your setup but LocalPrintServer.GetPrintQueue should do the trick.
string printerName = "ES7470 MFP(PCL)";
LocalPrintServer localPrintServer = new LocalPrintServer();
PrintQueueCollection printQueues = localPrintServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
if (printQueues == null) return false;
PrintQueue queue = printQueues.Where(x => x.Name.Equals(printerName)).FirstOrDefault();
I'm guessing your application will know if someone printed something, otherwise you'll have to poll the Printer Queue each second or two to find out if a job went to the printer...
I'm creating a RDLC report and printing it from ASP.Net. When i try this in local machine it works fine. But when deploying in the server the printer settings are not valid.
//Code
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
// printDoc.PrinterSettings.PrinterName = "HP LaserJet 3055 PCL5";
if (!printDoc.PrinterSettings.IsValid)
{
throw new Exception("Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
From the above code it throws me an exception "cannot find default printer". Tried to add the printer name which exists in the client machine but still didn't work.
I need to print the report in the client machine.
Don't know where to change. Any help?
I belive that you are doing something you arent' supposed to do.
If you have a ASP.NET Website, that has a RDLC report in the site. If I, access that report, I would like to print in my machine, not in the server. Are you sure, that you want to make the server to print the report? Shouldn't the client/browser to issue the print command?
If your server is in a datacenter, and I'm at my home, where should the printing be done? Unless you want to print in the server (Mail Merge stickers, for example).
As far as I know it is not possible to access the client's printer settings. What you are doing is access the servers printer, which, if I am right, is not installed.
You can print accesing browser/ javascript functionality by calling window.print() in javascript,because the browser is running client-side and has access to the printers. But accessing the clients system resources directly would be a huge security flaw.
Maybe there is an obscure workaround/hack, but it would be a bad solution
I am making one application where user will print invoices which I am displaying using Crystal Report.
The user showed me his current application made using ForPro. In that application, under Printer Options form, one can see all the printers currently installed and the user could select default printer. When the invoice is made, the user presses the print button, then there is one dialog asking for no. of copies. When it's entered, the invoice gets printed directly, without any Print Dialog Box. If the user wants to change the printer again he/she will change it in the Printer Option form.
I want to know if similar thing is possible in Crystal Report and need guidance on how to approach for it.
Take a look at the ReportDocument.PrintToPrinter SAP Docs or MSDN Docs for how to specify the PrinterName and then Print using the ReportDocument object.
If you can try and get away from how the FoxPro app UI for printer selection. Instead use the standard print dialog box to select the printer.
You should note that if you don't set the PrinterName before sending the report to the printer it will use the default on the crystal file. Not to be confused with the user's OS default printer.
Here's an example of showing the PrintDialog settings some parameters using the SetParameterValue method and then sending the report document to a printer
// Note: untested
var dialog = new PrintDialog();
Nullable<bool> print = dialog.ShowDialog();
if (print.HasValue && print.Value)
{
var rd = new ReportDocument();
rd.Load("ReportFile.rpt");
rd.SetParameter("Parameter1", "abc");
rd.SetParameter("Parameter2", "foo");
rd.PrintOptions.PrinterName = dialog.PrinterSettings.PrinterName;
rd.PrintToPrinter(1, false, 0, 0);
}
The code above no longer works as advertised which has been admitted by SAP
You need to set the report document to an ISCDReportClientDocument and then print it. This is a more robust way of making sure the print job doesn't go to the default printer. The last two lines can be replaced with this code.
CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions printReportOptions = new CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions();
CrystalDecisions.ReportAppServer.Controllers.PrintOutputController printOutputController = new CrystalDecisions.ReportAppServer.Controllers.PrintOutputController();
CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rptClientDoc;
rptClientDoc = cryRtp.ReportClientDocument;
printReportOptions.PrinterName = pDialog.PrinterSettings.PrinterName;
rptClientDoc.PrintOutputController.PrintReport(printReportOptions);
Here is another good link
http://mattruma.azurewebsites.net/?p=258
I have a webpage that activates a print job on a printer. This works in the localhost environment but does not work when the application is deployed to the webserver. I'm using the PrintDocument class from the .net System.Drawing.Print namespace. I'm now assuming the printer has to be available to the application on the remote server? Any suggestions on how I would get this to work?
PrintDocument pd = new PrintDocument();
PaperSource ps = new PaperSource();
pd.DefaultPageSettings.PaperSize =
new System.Drawing.Printing.PaperSize("Custom", 1180, 850);
pd.PrintPage += new PrintPageEventHandler
(this.pd_PrintPage);
// Set your printer's name. Obtain from
// System's Printer Dialog Box.
pd.PrinterSettings.PrinterName =
"Okidata ML 321 Turbo/D (IBM)";
//PrintPreviewDialog dlgPrintPvw = new PrintPreviewDialog();
//dlgPrintPvw.Document = pd;
//dlgPrintPvw.Focus();
//dlgPrintPvw.ShowDialog();
pd.Print();
The printer is on a different computer. PrintDocument is for use in desktop applications, not web applications.
To print on the client, you would need to use JavaScript, and you would only be able to print documents already on the client machine. I don't know for sure that there is a way to print on the client. You may be able to display a "Print" dialog and have the user print the file himself.
I was having the same issues. I was told to put your code inside of this:
using (WindowsIdentity.GetCurrent().Impersonate())
{
// code here
}
It allows for specific user settings to be used instead of the ASP.NET settings for that particular printer.
This code got it to the printer, but now I'M having issues with multiple copies of one webform hitting the printer.