How to Print a Text File on Thermal Printer Using Printdocument

How to print a text file on thermal printer using PrintDocument?

If you send a plain string to your printPage(object sender, PrintEventArgs e) method, it will just print plain text in all the same font which looks 'messy' (as you named it)
If you want it to be printed well formatted with different fonts (bold, regular), you have to do it all manually:

List<string> itemList = new List<string>()
{
"201", //fill from somewhere in your code
"202"
};

private void printPage( object sender, PrintPageEventArgs e )
{
Graphics graphics = e.Graphics;

Font regular = new Font( FontFamily.GenericSansSerif, 10.0f, FontStyle.Regular );
Font bold = new Font( FontFamily.GenericSansSerif, 10.0f, FontStyle.Bold );

//print header
graphics.DrawString( "FERREIRA MATERIALS PARA CONSTRUCAO LTDA", bold, Brushes.Black, 20, 10 );
graphics.DrawString( "EST ENGENHEIRO MARCILAC, 116, SAO PAOLO - SP", regular, Brushes.Black, 30, 30 );
graphics.DrawString( "Telefone: (11)5921-3826", regular, Brushes.Black, 110, 50 );
graphics.DrawLine( Pens.Black, 80, 70, 320, 70 );
graphics.DrawString( "CUPOM NAO FISCAL", bold, Brushes.Black, 110, 80 );
graphics.DrawLine( Pens.Black, 80, 100, 320, 100 );

//print items
graphics.DrawString( "COD | DESCRICAO | QTY | X | Vir Unit | Vir Total |", bold, Brushes.Black, 10, 120 );
graphics.DrawLine( Pens.Black, 10, 140, 430, 140 );

for( int i = 0; i < itemList.Count; i++ )
{
graphics.DrawString( itemList[i].ToString(), regular, Brushes.Black, 20, 150 + i * 20 );
}

//print footer
//...

regular.Dispose();
bold.Dispose();

// Check to see if more pages are to be printed.
e.HasMorePages = ( itemList.Count > 20 );
}

Possible improvements on my example:

  • Centering the header strings could better be done using graphics.MeasureString().
  • List of items should better be a list of a business class insted of a plain string

Because this all is a lot of work, you should really consider using RDLC or some third party software to design your documents.

How to send cut command in Thermal Printer using PrintDocument in c#

I have tried a combination of below two code blocks

PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += PrintDocumentOnPrintPage;
printDocument.PrinterSettings.PrinterName = "TestPrinter";
printDocument.Print();
printDocument.Dispose();

and at the end, I am sending below commands it's working fine for me

        string GS = Convert.ToString((char)29);
string ESC = Convert.ToString((char)27);
string documentName ="x"

string COMMAND = this.textBox.T`ext;
COMMAND = ESC + "@";
COMMAND += GS + "V" + (char)1;
RawPrinterHelper.SendStringToPrinter(this.textBox1.Text, COMMAND,documentName);

Writing nice receipt in C# WPF for printing on thermal printer POS

In the past when doing this I split up the receipt into separate parts that used different fonts or alignments such as Header, Body, Footer.

I used the following class layout to encapsulate my printed text definition.
(where you get the Font from and how you manage its lifetime is up to you)

public class PrintText
{
public PrintText(string text, Font font) : this(text, font, new StringFormat()) {}

public PrintText(string text, Font font, StringFormat stringFormat)
{
Text = text;
Font = font;
StringFormat = stringFormat;
}

public string Text { get; set; }

public Font Font { get; set; }

/// <summary> Default is horizontal string formatting </summary>
public StringFormat StringFormat { get; set; }
}

When there are longer lists of texts using the same font & padding then using a stringbuilder to build up your text makes life easy so you get a visual of how it will look just from inspecting your code.

If you had static text you can fit it all together as so:

var sb = new StringBuilder();
sb.AppendLine("Start of receipt");
sb.AppendLine("================");
sb.AppendLine("Item 1");
sb.AppendLine("Item 2");
sb.AppendLine("================");

Or if the data is a bit dynamic pass in some object you can iterate over and append your formatted text:

private class ReceiptItem
{
public string Name { get; set; }

public decimal Cost { get; set; }

public int Amount { get; set; }

public int Discount { get; set; }

public decimal Total { get { return Cost * Amount; } }
}
const int FIRST_COL_PAD = 20;
const int SECOND_COL_PAD = 7;
const int THIRD_COL_PAD = 20;

var sb = new StringBuilder();
sb.AppendLine("Start of receipt");
sb.AppendLine("================");

foreach (var item in receiptItems)
{
sb.Append(item.Name.PadRight(FIRST_COL_PAD));

var breakDown = item.Amount > 0 ? item.Amount + "x" + item.Cost : string.Empty;
sb.Append(breakDown.PadRight(SECOND_COL_PAD));

sb.AppendLine(string.Format("{0:0.00} A", item.Total).PadLeft(THIRD_COL_PAD));

if (item.Discount > 0)
{
sb.Append(string.Format("DISCOUNT {0:D2}%", item.Discount).PadRight(FIRST_COL_PAD + SECOND_COL_PAD));
sb.Append(string.Format("{0:0.00} A", -(item.Total / 100 * item.Discount)).PadLeft(THIRD_COL_PAD));
sb.AppendLine();
}
}

sb.AppendLine("================");

The output will look like:

Start of receipt
================
Joes Food 1x10 10.00 A
DISCOUNT 10% -1.00 A
Fun Facts 1x20 20.00 A
DISCOUNT 15% -3.00 A
Bag of Sand 7x40 280.00 A
================

Using the PrintText class earlier we can store our nicely formatted string builder output

var printText = new PrintText(sb.ToString(), new Font("Monospace Please...", 8));

Then finally use that when attempting to draw the string

var layoutArea = new SizeF(AvailableWidth, 0);
SizeF stringSize = g.MeasureString(printText.Text, printText.Font, layoutArea, printText.StringFormat);

RectangleF rectf = new RectangleF(new PointF(), new SizeF(AvailableWidth, stringSize.Height));

g.DrawString(printText.Text, printText.Font, Brushes.Black, rectf, printText.StringFormat);

You can also play around with a few different graphical tweaks if the text doesn't print quite right such as:

g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;

Printing to receipt printer with PrintDocument does not print all content

Read this article on MSDN: How to: Print a Multi-Page Text File in Windows Forms.

Since your task is very similar to printing of a text file, I believe this should help.

How to print invoice in a particular format on a thermal printer

You have to manually check string length and do text wrapping.

Example:

string columnName = "...";
if(columnName.Length > 60)
{
graphic.DrawString(columnName_part1, new Font("Times New Roman", 10, FontStyle.Bold), new SolidBrush(Color.Black), startX, startY);
startY += 50;
graphic.DrawString(columnName_part2, new Font("Times New Roman", 10, FontStyle.Bold), new SolidBrush(Color.Black), startX, startY);
}

Print raw data to a thermal-printer using .NET

Okay, the reason for all that stuff is just the fact that I use an adapter because my computer does not has an old lpt port. I copied my application to an old computer running windows xp and everything works fine.

Now I have to hope that some other lpt2usb adaters I bought do their work correctly.

Edit 20.04.2010

With another lpt2usb adapter everything works fine now. If anyone is intersted in all the code I am using now, please contact me or comment here.



Related Topics



Leave a reply



Submit