I am printing a 3 inch receipt using a LocalReport with code from "Walkthrough: Printing a Local Report without Preview"
Some printers require the DeviceInfo PageWidth to be 8.5in to work correctly and some require 3.0in. Its appears that the report is being stretched to fill a wrong sized page. I have tried to adjust both the Report Paper Size and the Printer Paper size but can't seem to get the right combination.
Has anybody experienced this?
I figured this out. You need to account for the printer dpi.
Get the Printer Default Page Settings:
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = printerName;
this.defaultPageSettings = ps.DefaultPageSettings;
The Build the DeviceInfo Xml with that info:
private string BuildDeviceInfo()
{
StringBuilder returnValue;
System.Xml.XmlWriter writer;
returnValue = new StringBuilder(1024);
writer = System.Xml.XmlWriter.Create(returnValue);
writer.WriteStartElement("DeviceInfo");
writer.WriteElementString("OutputFormat", "EMF");
if (defaultPageSettings != null)
{
// DPI will keep the output from scaling in weird ways
writer.WriteElementString("PrintDpiX", defaultPageSettings.PrinterResolution.X.ToString());
writer.WriteElementString("PrintDpiY", defaultPageSettings.PrinterResolution.Y.ToString());
writer.WriteElementString("PageWidth", (defaultPageSettings.PaperSize.Width / 100m).ToString("F2") + "in");
writer.WriteElementString("PageHeight", (defaultPageSettings.PaperSize.Height / 100m).ToString("F2") + "in");
}
writer.Close();
return returnValue.ToString();
}
This worked for me. I'm printing from a WPF app to a STAR TSP100 receipt printer. When I set the margins & page size myself it came out huge, but when I calculated the minimum margins and page size as well as set the dpi from default printer settings the receipts printed correctly.
I used this to figure out the minimum margins: (H/T http://www.dreamincode.net/forums/topic/135864-printing-with-minimum-margins-specified-by-the-printer/)
Dim minimumMarginLeft, minimumMarginRight, minimumMarginTop,
minimumMarginBottom As Single
minimumMarginLeft = PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Left
minimumMarginRight = PrintDialog1.PrinterSettings.DefaultPageSettings.PaperSize.Width - _
PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Right
minimumMarginTop = PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Top
minimumMarginBottom = PrintDialog1.PrinterSettings.DefaultPageSettings.PaperSize.Height - _
PrintDialog1.PrinterSettings.DefaultPageSettings.PrintableArea.Bottom
-I figured this out. You need to account for the printer dpi.
-Get the Printer Default Page Settings:
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = printerName;
this.defaultPageSettings = ps.DefaultPageSettings; The Build the DeviceInfo Xml with that info:
private string BuildDeviceInfo()
{
StringBuilder returnValue;
System.Xml.XmlWriter writer;
returnValue = new StringBuilder(1024);
writer = System.Xml.XmlWriter.Create(returnValue);
writer.WriteStartElement("DeviceInfo");
writer.WriteElementString("OutputFormat", "EMF");
if (defaultPageSettings != null)
{
// DPI will keep the output from scaling in weird ways
writer.WriteElementString("PrintDpiX", defaultPageSettings.PrinterResolution.X.ToString());
writer.WriteElementString("PrintDpiY", defaultPageSettings.PrinterResolution.Y.ToString());
writer.WriteElementString("PageWidth", (defaultPageSettings.PaperSize.Width / 100m).ToString("F2") + "in");
writer.WriteElementString("PageHeight", (defaultPageSettings.PaperSize.Height / 100m).ToString("F2") + "in");
}
writer.Close();
return returnValue.ToString();
}
Related
I am trying to print a crystal report in WPF C# by sending it directly to printer without a viewer .The user can select different printers based on a drop down .However when i try to set PrinterSettings.PrinterName="PrinterName" ,the printer is printing junk values
My code is
ReportDocument ObjDoc = new ReportDocument();
System.Drawing.Printing.PrintDocument pDoc = new System.Drawing.Printing.PrintDocument();
CrystalDecisions.Shared.PrintLayoutSettings PrintLayout = new CrystalDecisions.Shared.PrintLayoutSettings();
System.Drawing.Printing.PrinterSettings printerSettings = new System.Drawing.Printing.PrinterSettings();
System.Drawing.Printing.PageSettings pSettings = new System.Drawing.Printing.PageSettings(printerSettings);
System.Drawing.Printing.PageSettings pageSettings = new System.Drawing.Printing.PageSettings(printerSettings);
//Fetch Values in dataset cdtUTDocEng
ObjDoc.Load("//ServerName//Crystal_Reports//VHRSSALEFDE002.rpt");
if (cdtUTDocEng.Rows.Count > 0)
ObjDoc.SetDataSource(cdtUTDocEng);
else
{
lsPrintMessage = "Printing Failed -Failed to fetch Undertaking English details";
break;
}
if (cEnvironment.Production == psEnvironment)
{
ObjDoc.PrintOptions.PrinterDuplex = PrinterDuplex.Default;
lsPrinterName = cmbPrinter.SelectedValue.ToString().Trim();
if (CheckifPrinterInstalled(cmbPrinter.SelectedValue.ToString().Trim()) == true)
{
System.Drawing.Printing.PrinterSettings.PrinterName =cmbPrinter.SelectedValue.ToString().Trim();
ObjDoc.PrintToPrinter(printerSettings, pSettings, false, PrintLayout);
ObjDoc.Dispose();
lsPrintMessage = lsPrintMessage + "Full documentation English " + pdtPrintDetails.Rows[lirow]["COPY_TYPE"].ToString().Trim() + " has been sent to printer " + cmbPrinter.SelectedValue.ToString().Trim() + Environment.NewLine;
}
else
lsPrintMessage = "This printer " + cmbPrinter.SelectedValue.ToString().Trim() + " is not installed on server,cannot print";
}
This line causes the issues
System.Drawing.Printing.PrinterSettings.PrinterName =cmbPrinter.SelectedValue.ToString().Trim();
If i remove this line,the printer prints to my default printer and print comes correctly
I tried various combinations of setting printer name with the below values,all print junk values
1)printerSettings.PrinterName= "Dyna_Offshore";
2)pSettings.PrinterSettings.PrinterName= "Dyna_Offshore";
3)System.Drawing.Printing.PrinterSettings.PrinterName = "\\\\My PC IP\\Dyna_Offshore";
I tried setting printer name on report document like this ,but the code ignores this setting and takes PrinterName from printerSettings
1)ObjDoc.PrintOptions.PrinterName= "Dyna_Offshore";
it was printer driver issue.In WPF VS2017 ,when we are printing what ever driver name is printed on the physical printer .The printer needs to be installed with the exact driver name .If there is even a slight mismatch in the driver name ,it was causing junk values to be printed when printing programmatically through VS2017.Normal printing will work if there is mismatch in drivers.Also this issue is not there in VS2010 with Webforms .I have tested this in 2 printers in different countries and i was able to print successfully.
In my project I came across this problem that I have been struggling for so much hours. Hope somebody could help me.
My client needs to print many tickets from the web (with one click) with some info from the database, let's say Name, Date and Price. All the tickets will be printed on a Rollpaper Printer, so after every ticket it should autocut each one.
Which would be an appropriate way to achieve this task?
I have a working code, that uses the PrintDocument Class (code below), the problem is that I need to have access to the printer to use it.
Scenario:
I'm using ASP.NET MVC3 on Visual Studio 2010.
The app is on a Shared Server.
Need to generate many tickets that will print all at once.
I have access to the Client PC, so I can install everything there and touch whatever is neccesary.
The app is used with Firefox and/or Chrome.
The printer is an Epson TMT82.
Thanks in advance.
public static bool PrintTicket(ref string Msg, string Impresora)
{
bool result = false;
try
{
System.Drawing.Printing.PrintDocument Pd = new System.Drawing.Printing.PrintDocument();
//If empty, Default
if(!String.IsNullOrEmpty(Impresora))
Pd.PrinterSettings.PrinterName = Impresora;
Margins margins = new Margins(10, 0, 0, 0);
Pd.DefaultPageSettings.Margins = margins;
Pd.PrintController = new System.Drawing.Printing.StandardPrintController();
Pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printTicket_PrintPage);
Pd.Print();
PrintServer ps = new PrintServer();
PrintQueue printerQueue = LocalPrintServer.GetDefaultPrintQueue();
SpotTroubleUsingProperties(ref Msg, printerQueue);
result = (Msg == String.Empty);
if (!result)
{
var jobs = printerQueue.GetPrintJobInfoCollection();
foreach (var job in jobs)
{
job.Cancel();
}
}
}
catch (Exception ex)
{
Msg = ex.Message;
}
return result;
}
I'm trying to get the total pages count from all the printers connected to a computer. To do that i try in different ways but nothing give me the expected result:
SNMP: Very useful but impossible use it on a local printer.
Win32_printer: No way to get the total page count of a network printer and more of the local printers not store the page count on it.
printui.dll: total page count not supported.
Now i'm trying a different approach: there is a way to programmatically print the device configuration page (Example: THAT) to a file? you can print it whitout connect the printer to a PC's so it shoud be stored somewhere in some digital format. the only thing i found on internet is the Bidi Communication but i can't found any documentation that can help me... I not need a particular programming language, but if possible i prefere c#,c++ or java.
#Soner Gönül: Ok, so i choose c# just because is the language that i use to write the snmp test, but examples in other languages are appreciated:
SNMP:
SNMP snmp = new SNMP();
// Aprire la connessione verso la stampante
try
{
snmp.Open(IPAddressOfPrinter, CommunityString, Retries, TimeoutInMS);
} catch {
MessageBox.Show("Unable to reach the printer");
}
//Sides Counter
lblSides.Text = snmp.Get(".1.3.6.1.2.1.43.10.2.1.4.1.1").ToString();
rtbLog.Text += "Printer Counter: " + lblSides.Text;
rtbLog.Text += " Sides.\n";
That code give me the number of sides printed by the printer, that is ok, but need that the printer is a network printer, on a USB printer i can't use SNMP.
Win32_Printer:
ConnectionOptions options = new ConnectionOptions();
ManagementScope scope = new ManagementScope(#"\\" + System.Environment.MachineName.ToString() + #"\root\cimv2"); //yeah... i know #"root\cimv2" is enought, i notice only now...
scope.Connect();
ObjectQuery PRNquery = new ObjectQuery("SELECT * FROM Win32_Printer");
ManagementObjectSearcher PRNsearcher = new ManagementObjectSearcher(scope, PRNquery);
ManagementObjectCollection PRNqueryCollection = PRNsearcher.Get();
foreach (ManagementObject m in PRNqueryCollection)
{
MessageBox.Show(m["JobCountSinceLastReset"].Tostring());
//But the result is Zero or random error the 90% of the times.
}
priuntui.dll:
If i launch
rundll32 printui.dll PrintUIEntry /something
or try to export the report with:
public static class PrintTest
{
[DllImport("printui.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern void PrintUIEntryW(IntPtr hwnd,
IntPtr hinst, string lpszCmdLine, int nCmdShow);
public static void Print(string printerName)
{
var printParams = string.Format(#"/f C:\test.dat /Xg /n{0}", printerName);
PrintUIEntryW(IntPtr.Zero, IntPtr.Zero, printParams, 0);
}
}
i not found a page count report, but only generic information.
I am creating pdf files in an asp.net project that is being stored on the server in a folder. When a user wants to print this file, I need the user to specify which printer among all the label printers on the network since it may contain numeral laser printers as well. I have tried creating a print process but this send the pdf file straight to the default printer. is there any way to display the print dialog so that users can select the required printer?
printjob.StartInfo.FileName = pdfFileName;<br/>
printjob.StartInfo.Verb = "Print";<br/>
printjob.StartInfo.CreateNoWindow = false;<br/>
printjob.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
PrinterSettings setting = new PrinterSettings();<br/>
printjob.Start();
This can be achieved by Spire.pdf.dll reference.
To install this Open package manager console and type Install-Package Spire.pdf. this will install spire.pdf. Now the following code will help you print the pdf files.
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("D:\\sample.pdf");
//Use the default printer to print all the pages
//doc.PrintDocument.Print();
//Set the printer and select the pages you want to print
PrintDialog dialogPrint = new PrintDialog();
dialogPrint.AllowPrintToFile = true;
dialogPrint.AllowSomePages = true;
dialogPrint.PrinterSettings.MinimumPage = 1;
dialogPrint.PrinterSettings.MaximumPage = doc.Pages.Count;
dialogPrint.PrinterSettings.FromPage = 1;
dialogPrint.PrinterSettings.ToPage = doc.Pages.Count;
if (dialogPrint.ShowDialog() == DialogResult.OK)
{
doc.PrintFromPage = dialogPrint.PrinterSettings.FromPage;
doc.PrintToPage = dialogPrint.PrinterSettings.ToPage;
doc.PrinterName = dialogPrint.PrinterSettings.PrinterName;
PrintDocument printDoc = doc.PrintDocument;
dialogPrint.Document = printDoc;
printDoc.Print();
}
I am trying to print PowerPoint docs through my windows application in C#. I am using Microsoft.Office.Interop.PowerPoint for this functionality. Following is the code which I have used. It sends the request to printer but nothing gets printed.
string filename = "C:\\test.ppt";
int copies = 1;
Microsoft.Office.Interop.PowerPoint.Presentation work = null;
Microsoft.Office.Interop.PowerPoint.Application app = new Microsoft.Office.Interop.PowerPoint.ApplicationClass();
Microsoft.Office.Interop.PowerPoint.Presentations presprint = app.Presentations;
work = presprint.Open(filename, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoCTrue, Microsoft.Office.Core.MsoTriState.msoFalse);
//app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
work.PrintOptions.PrintInBackground = Microsoft.Office.Core.MsoTriState.msoFalse;
//work.PrintOptions.PrintInBackground = Microsoft.Office.Core.MsoTriState.msoTrue;
//work.PrintOptions.ActivePrinter = "HP LaserJet 5000 Series PCL6";
work.PrintOptions.ActivePrinter = app.ActivePrinter;
work.PrintOut(1, work.Slides.Count, app.ActivePrinter, copies, Microsoft.Office.Core.MsoTriState.msoFalse);
work.Close();
app.Quit();`
When debugging, try halting after work.PrintOut and check your printer to see if the jobs arrives. I'm guessing you are closing PowerPoint too fast.