Printing Excel file - c#

xlWorkSheet.PrintOut();
This should work but according to the documentation, this is going to use the printer by default. Is it possible to give the user the ability to choose a printer like this:
In WinForms, I believe It's possible to achieve such a thing by using a PrintDialog like this:
var pd = new PrintDialog();
var settings = pd.PrinterSettings;
var name = settings.PrinterName
What's the equivalent for that in WPF? I don't see PrinterSettings/PrinterName
EDIT (more details):
I'm creating an excel file using Interop. The first code I posted will print the file using the default printer. I want from the user to be able to choose a printer. I realize there is ActivePrinter option but I will have to know the name of the printer in this case I believe.
What I want to do is make a printer dialog and get the Selected printer name and set it to ActivePrinter

Related

Change Printer preferences / Driver Settings in C#

I am trying to print an existing XPS file in GrayScale .
I tried to add a PrintTicket inside the XPS file, and also tried to change the PrintQueue property of the printer , like :
LocalPrintServer server = new LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer);
PrintQueue pq = server.GetPrintQueue("MyPrinterName");
pq.DefaultPrintTicket.OutputColor = OutputColor.Grayscale;
PrintSystemJobInfo print = pq.AddJob("myPrintJob", "MyFileToPrint.xps",false);
But still printing the file in colors ...
So , I thinking about changing the print setting in the driver settings itself , like :
So , Is it possible to change this option programmatically ??
Changing global state to solve a local problem is usually a bad idea. Submitting a print ticket with the job should allow the sort of control you are looking for. Have you tried something like this?
LocalPrintServer server = new LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer);
PrintQueue pq = server.GetPrintQueue("MyPrinterName");
var jobTicket = pq.DefaultPrintTicket;
jobTicket.OutputColor = OutputColor.Grayscale;
PrintSystemJobInfo print = pq.AddJob("myPrintJob", "MyFileToPrint.xps", false, jobTicket);

MSProject Add-In to convert .mpp in .pdf with given name and date

I am developing an Add-In for MSProject 2013 and higher.
I want to safe/convert the opened .mpp file into an .pdf file without having an additional dialog for the user. He just presses the button an gets an notification when everything is done.
I need to save it in a spacific path and user a defined start and end date.
I tried the SaveAs-methode, but since it takes an MSProject.PjFileType as input and the is no option for pdf, I can't use this. PjFileFormat Enumeration
An other approche was using the DocumentExport-methode.
app.DocumentExport(#"D:/doc_exportqwre.pdf", MSProject.PjDocExportType.pjPDF, true, true, false, System.DateTime.Now, System.DateTime.Now.AddDays(42));
But in this case i only see 3 weeks at once. It is zoomed in and haven't found a way to change this. Changing the View in MSProject, before exporting does not help.
A third way is using the Windows10 pdf-printer:
// generate a file name as the current date/time in unix timestamp format
string file = (string)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
// the directory to store the output.
string directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// initialize PrintDocument object
PrintDocument doc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
// set the printer to 'Microsoft Print to PDF'
PrinterName = "Microsoft Print to PDF",
// tell the object this document will print to file
PrintToFile = true,
// set the filename to whatever you like (full path)
PrintFileName = Path.Combine(directory, file + ".pdf"),
}
};
doc.Print();
but this way I can not give the starting and end date. This results in having way to many pages I do not need.
Is there any chance to achieve my goal with changing one of my solutions or is there any other option?
After not finding a proper solution, i used the windows 10 Printer and simulated keyboard events to insert the path in the dialog, which opens. With Enter i start the printing.
I know it is not a nice solution, but it is the onlyway i got it to work

Using File.Copy to send PDF to Printer by Printer Name

I am trying to send an PDF file to a printer using the File.Copy method in C#. When I reference the printer by name however, it always responds with
'Could not find a part of the path'
The printer name is fully qualified. The user is selecting from a combo box that displays all the systems printers using the PrinterSettings.InstalledPrinters values.
Am I missing something simple?
Example:
File.Copy(FileInfo.FullName, "\\\\ServerName\\PrinterName", true);
The "\\\\ServerName\\PrinterName" is directly one of the names from PrinterSettings.InstalledPrinters collection.
Use one of the printer names that comes out of the printer classes.
foreach (String printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
textBox1.Text += printer.ToString() + System.Environment.NewLine;
}
See all the printers that are listed in this text box, copy and paste the printer name in the file.copy method.
File.Copy(FileInfo.FullName, **Printer name here**, true);

Sending file to print not working using System.Drawing.Printing

I'm trying to send a file to print without opening it trough Adobe as suggested by several Answers here; instead, I'm using the PrintQueue library (from System.Drawing.Printing).
What I've accomplished so far:
I have the correct PrintQueue referenced as pq:
PrintQueue pq; //Assume it's correct. The way to get here it isn't easy and it is not needed for the question.
// Call AddJob
PrintSystemJobInfo myPrintJob = pq.AddJob();
// Write a Byte buffer to the JobStream and close the stream
Stream myStream = myPrintJob.JobStream;
Byte[] myByteBuffer = ObjectIHave.ToArray(); //Ignore the ObjectIhave, it actually is Linq object which is correct as well.
myStream.Write(myByteBuffer, 0, myByteBuffer.Length);
myStream.Close();
As I understood from the Microsoft Library it's correctly done but it is not working. Any ideas?
EDIT: Debugging the code I can see that something is being send to the printer but it seems the file is not sent.
You need to render your PDF to the printer. Calling the shell print verb on the file would be the ideal means to do that. If you insist on doing the low level rendering yourself then I recommend using a library like Ghostscript.NET and choose the mswinpr2 device as output.
The mswinpr2 device uses MS Windows printer drivers, and thus should work with any printer with device-independent bitmap (DIB) raster capabilities. The printer resolution cannot be selected directly using PostScript commands from Ghostscript: use the printer setup in the Control Panel instead.
See SendToPrinterSample.cs for example:
string printerName = "YourPrinterName";
string inputFile = #"E:\__test_data\test.pdf";
using (GhostscriptProcessor processor = new GhostscriptProcessor())
{
List<string> switches = new List<string>();
switches.Add("-empty");
switches.Add("-dPrinted");
switches.Add("-dBATCH");
switches.Add("-dNOPAUSE");
switches.Add("-dNOSAFER");
switches.Add("-dNumCopies=1");
switches.Add("-sDEVICE=mswinpr2");
switches.Add("-sOutputFile=%printer%" + printerName);
switches.Add("-f");
switches.Add(inputFile);
processor.StartProcessing(switches.ToArray(), null);
}
If the file has to be printed in both sides you just need to add:
switches.Add("-dDuplex");
switches.Add("-dTumble=0");
You can not just write PDF bytes to a print job. The printer doesn't know how to handle it. The RAW data you send to the printer must describe the document in a printer language specific to the printer. That's what the printer driver does.
You can not print a PDF by just sending it to the printer. You need some piece of software that renders the PDF and then sends the rendered image to the printer.
As the documentation states:
Use this method to write device specific information, to a spool file, that is not automatically included by the Microsoft Windows spooler.
I enhanced the important part of this information.

how to print on a particular printer [duplicate]

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

Categories