Dynamic paper height with .NET PrintDocument
Asked Answered
D

1

11

I ran into a problem with sizing pages on a thermal printer. I have started from this answer: https://mcmap.net/q/598269/-pos-application-development-receipt-printing and now I have the code I pasted below.

This works nicely, however altough I calculate and set the size of the page, it seems to print a full A4 sized page each time. (I am testing on a Sam4s Ellix II and Microsoft PDF Printer) - It is a big problem, as it's needed to often print 5-6 line long text snippets.

I need to support multiple thermal printers and I only need the basic functions (so no need to receive signals such as paper jam, etc.) so I decided to go with the Windows printer driver, instead of the POS for .NET one.

I calculate the height of the text and size the paper accordingly, however it has no effect on the output paper size. Does anyone have a solution for this issue?

Thank you very much

public int Print(DatabaseConnector dc)
{
    try {

        // Set up PrintDocument
        PrintDocument recordDoc = new PrintDocument();
        recordDoc.DocumentName = "PrintTask ID "+id.ToString();
        recordDoc.PrintPage += new PrintPageEventHandler(PrintTask.PrintReceiptPage); // Filling in the stuff

        // Print Controller
        StandardPrintController spc = new StandardPrintController();
        recordDoc.PrintController = spc; // This hides popup

        // Printer Settings
        PrinterSettings ps = new PrinterSettings();
        ps.PrinterName = dc.ReadSetting("PrinterName"); 
        recordDoc.PrinterSettings = ps;
        recordDoc.Print();

        // Clean up
        recordDoc.Dispose();
    }
    catch (Exception exc)
    {
        ((MainForm)Application.OpenForms[0]).msg(exc.Message);
    }
    return 1; // ignore this 
}

private static void PrintReceiptPage(object sender, PrintPageEventArgs e)
{
    try {
        // Read settings
        DatabaseConnector db = new DatabaseConnector();
        PrintTask pt = db.ReadTask();
        float x = float.Parse(db.ReadSetting("PaperMarginFromLeft"));
        float y = float.Parse(db.ReadSetting("PaperMarginFromTop"));
        float width = float.Parse(db.ReadSetting("PaperWidth"));
        float height = 0F;
        string text;

        // Set up font
        Font drawFont1 = new Font(db.ReadSetting("PrintFont"), Int32.Parse(db.ReadSetting("PrintFontSize")), FontStyle.Regular);
        SolidBrush drawBrush = new SolidBrush(Color.Black);

        // Set format of string.
        StringFormat drawFormatLeft = new StringFormat();
        drawFormatLeft.Alignment = StringAlignment.Near;

        // Draw string to screen.
        text = pt.getData();
        e.Graphics.DrawString(text, drawFont1, drawBrush, new RectangleF(x, y, width, height), drawFormatLeft);

        // calculate text size
        SizeF textSize = e.Graphics.MeasureString(text, drawFont1);
        y += textSize.Height;

        // Set page size - has no effect
        e.HasMorePages = false;
        float inchHeight = PrintTask.PixelsToInchY(y, e.Graphics);
        PaperSize originalPaperSize  = e.PageSettings.PaperSize;
        PaperSize scaledSize = new PaperSize("Custom", originalPaperSize.Width, (int)Math.Ceiling(inchHeight * 100));
        e.PageSettings.PaperSize = scaledSize;
        e.PageSettings.PrinterSettings.DefaultPageSettings.PaperSize = scaledSize;

    }
    catch (Exception exc)
    {
        ((MainForm)Application.OpenForms[0]).msg(exc.Message);
    }
}

public static float PixelsToInchX(float n, Graphics graphics)
{
    return n * graphics.DpiX / 300;
}
public static float PixelsToInchY(float n, Graphics graphics)
{
    return n * graphics.DpiY / 300;
}
Delaware answered 14/2, 2016 at 14:8 Comment(1)
Thermal printers don't use pages, they have a continuous paper roll. Using the PrintDocument class is almost never correct. Not just because of size, it is also usually far too slow. POS is the correct approach.Brien
R
4

You don't have to calculate height when printing to POS printers, as driver handles paper height and cut at the end of the document. Go to POS printer settings and select 'Receipt' as paper size. Usually there are also settings to control how and when printer cuts paper (Full Cut, Partial Cur, Feed Only, ...)

Resound answered 25/2, 2016 at 9:22 Comment(2)
Wow thanks! I completely forgot to check the driver settings!Delaware
Might be worth mentioning, that I recently had a slip printer that did not have this "receipt" setting. It did, however, have a page size of 3.14 x 3200 (I guess this is their way of "unlimited page height"). The printer however still cuts the slip correctly after your last printed lines.Anthropomorphism

© 2022 - 2024 — McMap. All rights reserved.