I searched for a lot in google and did not find what i actually wanted. I got following code, which will print the variable name. I got a Epson Dot Matrix Printer and Roll Paper (Endless continuous paper).
My problem is that, after printing name paper feeds up to size of A4. I don`t want the paper feed. This application is intended to do print receipts which will have unlimited data which need to be printed flawless ( with out page break).
Can you, the smart folk out there to point me in the correct direction with these codes?
edited this code and changed scenario .. please move down further
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Font Heading2 = new Font("Times New Roman", 13);
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Near;
sf.Alignment = StringAlignment.Center;
//e.HasMorePages = false;
PaperSize pkCustomSize1 = new PaperSize("First custom size", 100, 200);
pd.DefaultPageSettings.PaperSize = pkCustomSize1;
e.Graphics.DrawString(name.ToString(), Heading1, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width / 2), e.MarginBounds.Top, sf);
}
Edit 1:- #Adriano Repetti suggested this is a duplicate with Form feed in c# printing. What i learned from the above question is that he want to add the form feed. But i want to remove the form feed.
Edit 2:- I got an another hint by googling that setting the page Height equal to line height will make stop feeding which sounds promising. I am trying to figure that out too.
Edit 3:- #Adriano Repetti suggested me with Raw Printing (Directly printing binary data) with KB link. I googled around about it, and found out its c# better equivalent paste bin or pastie.org (provided because it is a handy one) . At first it sounded good and it worked nicely stopping form feeding. But eventually i struck some ice berg.
On my code i had to align some printing quotes to center or align to left`. for which i got only option of using space and tabs. But there will be no guaranty that it will be well formatted as we can not certain about built in fonts with printer.( Refer:SO Question by #syncis )
And secondly, i will have to move my application to unicode(local language support) capable one, at least with in a month or so. In that scenario, raw printing wont help and i will have to go through theses faces again. SO, For avoiding that its better for me to stay with Graphics DrawString. And for this i changed my code as.
//---------
// start button click
//---------
PrintDocument pdoc = new PrintDocument();
pdoc.DefaultPageSettings.PaperSize.Height = 300;
pdoc.Print();
//---------
// end button click
//---------
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Font Heading2 = new Font("Times New Roman", 13);
// changed following statement to met with new **unicode** criteria
//e.Graphics.DrawString(name.ToString(), Heading1, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width / 2), e.MarginBounds.Top, sf);
TextRenderer.DrawText(e.Graphics, "My name in local language is വിനീത്", Heading2, new Point(0, 0), Color.Black);
}
With current problems, i am redefining the Question extending tag to unicode as.
How can print with TextRenderer.DrawText with unicode support without form feeding ? I think setting paper height to line height will solve my problem. If so how or suggest me a better way to stop paper feeding. It really eats a lot of my valuable time...
EDIT 4: Today I found out a very interesting thing about my printer. I cant even set custom paper size manually (Not by coding.. I mean control panel->printers and faxes ->Epson LX-300+ ->properties -> printing preference-> paper/quality -> advanced -> paper size -> BOOOOOM not showing my custom paper size). I am using Epson LX-300+ printer. Do guys think it wont support custom paper sizes? is that causing me problems?
I found the solution by my self ( sorry for my english ) As Hans Passant says ( PrintDocument is page based. end of story ) You must use ( e.HasMorePages = true; )
float cordenadaX;
float cordenadaY;
int totalPages;
int paginaAtual;
int indiceItem;
List<string> items;
public void ImprimeDanfeNFCe()
{
totalPages = 1;
paginaAtual = 1;
indiceItem = 0;
cordenadaX = 0;
cordenadaY = 0;
items = new List<string>();
items.Add("Item1");
items.Add("Item2");
items.Add("Item3");
(............)
PrintDocument recordDoc = new PrintDocument();
recordDoc.DocumentName = "xMarket danfe";
recordDoc.PrintPage += new PrintPageEventHandler(imprimeDanfeReceipt);
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = "My printer";
recordDoc.PrinterSettings = ps;
recordDoc.Print();
recordDoc.Dispose();
}
void imprimeDanfeReceipt(PrintPageEventArgs e)
{
float pageHeight = e.MarginBounds.Height;
string text = "";
if (paginaAtual == 1)
{
text = "Cupom header";
e.Graphics.DrawString(text, drawFontDanfeTitulo, drawBrush, new
RectangleF(cordenadaX, cordenadaY, width, height),
drawFormatCenter);
cordenadaY += e.Graphics.MeasureString(text, drawFontDanfeTitulo).Height;
}
for (int i = indiceItem; i < items.Count; i++)
{
int indice = i + 1;
//items[i] Is very important to not print same items again while print next page
e.Graphics.DrawString(items[i], drawFontDanfeItems, drawBrush,
new RectangleF(cordenadaX, cordenadaY, width, height), drawFormatLeft);
cordenadaY += e.Graphics.MeasureString(text, drawFontDanfeTitulo).Height;
indiceItem++;
//cordenadaY+100 is for the size of the footer
if (cordenadaY+100 >= pageHeight)
{
paginaAtual++;
e.HasMorePages = true;
return;
}
}
e.Graphics.DrawString("page footer", drawFontDanfeItems, drawBrush,
new RectangleF(cordenadaX, cordenadaY, width, height), drawFormatLeft);
cordenadaY += e.Graphics.MeasureString(text, drawFontDanfeTitulo).Height;
}
Related
I'm trying to print userdata to a smartcard using a smartcard printer but the result is that i'm getting blank cards out of the printer. I've been stuck on this problem for a day now and there is no(findable) answer on the internet.
With printing to the printer (it's an Datacard SP35 Plus) using no custom papersize and no printdialog. the result is an empty card.
using (PrintDocument pd = new PrintDocument())
{
pd.PrintPage += (object sender, PrintPageEventArgs e) =>
{
Image i = Image.FromFile("E:\\tmp.png");
e.Graphics.DrawImage(i, e.MarginBounds);
};
pd.Print();
}
The image is present and visible and plenty of size.
Furthermore, I came across a post that said that the size of the printdocument has to be set
PaperSize papersize = new PaperSize("Custom", Convert.ToInt32(widthInInch * 100), Convert.ToInt32(heightInInch * 100));
pd.DefaultPageSettings.PaperSize = papersize;
pd.PrinterSettings.DefaultPageSettings.PaperSize = papersize;
But didnt result in a visible print.
I've also tried
e.Graphics.DrawImage(i, 0, 0);
instead of
e.Graphics.DrawImage(i, e.MarginBounds);
but didn't result in a visible print.
The widthInInch is 3.38 and the heightInInch is 2.13(The default size of an CR80 card). This also resulted in an empty card.
When I print to PDF the result is visible and correct(I do not know the whitespace, of course).
Does somebody see the problem or has worked out something similar?
I "fixed" it by rewriting my application to UWP. This uses the new print function and made it work as intended.
I'm doing some printing work in c# and got a small problem. I'm working with a thermal receipt printer. I want to set the height of the page according to the content of it. Which means, when I have fewer items, the page should be smaller and when I have long list of items, the page should grow accordingly.
I tried to set it with PrintPageEventArgs but this didn't result in satisfied result. How can this be done?
Thanks
Just take care of the width. Printer will cut the paper after the last printed element on the last page.
Just for the record. I had the same issue.
At the end what i had done is:
Int Line= starting position (in pixels)
For each line I want to print -> g.DrawString("text",font,xx,margin,line);
and then just before print
ps.Height = Line;
pd.Print();
pd is -> PrintDocument pd = new PrintDocument();
ps is -> PaperSize ps = new PaperSize("",my_width,1));
`enter code here` pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
pd.PrintController = new StandardPrintController();
pd.DefaultPageSettings.Margins.Left = 0;
pd.DefaultPageSettings.Margins.Right = 0;
pd.DefaultPageSettings.Margins.Top = 0;
pd.DefaultPageSettings.Margins.Bottom = 0;
pd.DefaultPageSettings.PaperSize = ps;
I have a Winform application that creates signs. Everything works and looks fine except when I print. I have an image with textboxes placed on top of them. They are visible on my computer, but not when I print. I am assuming that somehow when I print the image is getting "Brought-to-front."
Below is my Print Function:
private void btnPrint_Click(object sender, EventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintImage);
pd.Print();
}
void PrintImage(object o, PrintPageEventArgs e)
{
int x = SystemInformation.WorkingArea.X;
int y = SystemInformation.WorkingArea.Y;
int width = this.Width;
int height = this.Height;
Rectangle bounds = new Rectangle(x, y, width, height);
Bitmap img = new Bitmap(width, height);
this.DrawToBitmap(img, bounds);
Point p = new Point(100, 100);
e.Graphics.DrawImage(img, p);
}
I don't know for sure that anything in the print function is a cause, but I can't think of anything else.
I don't know the answer to the question of why the TextBox contents are not being rendered, but I can tell you that you are doing it "wrong".
What you should be doing is rendering the text in your paint handler and using a single, "in-place" TextBox for allowing the user to edit text at some location on the form which is moved into position and made visible just-in-time for editing.
It requires that your "document" consist of lists of objects (like "text blocks") which you can render and which you can detect the bounds of for when the user tries to manipulate them. This is very similar to how a "paint" program works.
This is going to be a complete departure from what you are doing now. It's always a lot more work to do things "correctly". I don't want to tell you to redo your application. If this is a learning experience and not a commercial product, it's OK to hack your way through it, using what you're familiar with. But maybe next time you might try another approach.
Using System.Drawing.Printing, I want to print a set of lines on print document.
But the problem is it prints every line on the very first page, what ever the coordinates are, also if I draw an image, It prints that on a single page no matter how big it is.
Following is what I have done for printing text on multiple pages:
protected void ThePrintDocument_PrintPage (object sender, System.Drawing.Printing.PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPosition = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;
Font printFont = this.richTextBox1.Font;
SolidBrush myBrush = new SolidBrush(Color.Black);
// Work out the number of lines per page, using the MarginBounds.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
// Iterate over the string using the StringReader, printing each line.
while(count < linesPerPage && ((line=myReader.ReadLine()) != null))
{
// calculate the next line position based on
// the height of the font according to the printing device
yPosition = topMargin + (count * printFont.GetHeight(ev.Graphics));
// draw the next line in the rich edit control
ev.Graphics.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());
count++;
}
// If there are more lines, print another page.
if(line != null)
ev.HasMorePages = true;
else
ev.HasMorePages = false;
myBrush.Dispose();
}
What I should do in order to print line on multiple pages, i.e the following code should print on two pages as the length of the line is 1400 and print doc length is 1100, so remaining 300 of the line should be printed on the next page
protected void ThePrintDocument_PrintPage (object sender, System.Drawing.Printing.PrintPageEventArgs ev)
{
Pen P1 = new Pen(Brushes.Violet, 5);
ev.Graphics.DrawLine(P1, new Point(0,0), new Point(500,1400));
}
This is not how printing works in .NET. It does not create a new page just because you print outside the coordinates of the current page. There are events and event arguments which .NET uses to ask from you how many pages your document will contain. It will then invoke the event for printing a page for every page.
See here for an example.
EDIT
Ok, replying to your comment, I can think of two possible solutions: The first solution would involve clipping: intersect your graphic objects with the page's rectangle and print only what's common to both of them. If there were parts outside the clipping region, take that part as the new graphic objects and clip again to print on new page. Repeat this until the remaining graphics fit the page rectangle. However, I can't think of a way of doing that easily.
My second idea is as follows:
Calculate how many pages you would need to print all graphic objects by dividing the bounding rectangle of the graphic objects by the height of the "visual rectangle" of one page (increase number of pages by one if there's a remainder in this division).
Loop the following until reaching the last page
Print all graphic objects to the current page
Decrease all y-coordinates by the "visual height" of a page (effectively moving the graphic objects upwards outside the "bounds of the paper")
While the overhead of printing the entire list of graphic objects for every page may be high, you're leaving the clipping part to the printer driver/the printer itself.
I have some code that prints a string, but if the string is say: "Blah blah blah"... and there are no line breaks, the text occupies a single line. I would like to be able to shape the string so it word wraps to the dimensions of the paper.
private void PrintIt(){
PrintDocument document = new PrintDocument();
document.PrintPage += (sender, e) => Document_PrintText(e, inputString);
document.Print();
}
static private void Document_PrintText(PrintPageEventArgs e, string inputString) {
e.Graphics.DrawString(inputString, new Font("Courier New", 12), Brushes.Black, 0, 0);
}
I suppose I could figure out the length of a character, and wrap the text manually, but if there is a built in way to do this, I'd rather do that. Thanks!
Yes there is the DrawString has ability to word wrap the Text automatically. You can use MeasureString method to check wheather the Specified string can completely Drawn on the Page or Not and how much space will be required.
There is also a TextRenderer Class specially for this purpose.
Here is an Example:
Graphics gf = e.Graphics;
SizeF sf = gf.MeasureString("shdadj asdhkj shad adas dash asdl asasdassa",
new Font(new FontFamily("Arial"), 10F), 60);
gf.DrawString("shdadj asdhkj shad adas dash asdl asasdassa",
new Font(new FontFamily("Arial"), 10F), Brushes.Black,
new RectangleF(new PointF(4.0F,4.0F),sf),
StringFormat.GenericTypographic);
Here i have specified maximum of 60 Pixels as width then measure string will give me Size that will be required to Draw this string. Now if you already have a Size then you can compare with returned Size to see if it will be Drawn properly or Truncated
I found this : How to: Print a Multi-Page Text File in Windows Forms
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of characters
// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);
// Draws the string within the bounds of the page
e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);
// Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage);
// Check to see if more pages are to be printed.
e.HasMorePages = (stringToPrint.Length > 0);
}
Dude im suffering with printing in HTML, total nightmare. I would say that in my opinion you should try use something else to print out the text etc pass parameters to reporting services and popup a PDF which the user can print off.
Or potentially you might need to count out the number of characters and explicitly specify a line break!