Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
681 views
in Technique[技术] by (71.8m points)

printing - Send ESC commands to a printer in C#

My application needs to print invoices, then a get the invoice from database, insert information on the invoice in a big string (telling the line, column, etc.) after this I have the string ready to be sent to a printer.

My problem is: I need to put some ESC/P commands/characters in my big string

I tried to do something like this:

        char formFeed = (char)12;
        Convert.ToChar(12);

        MyBigString.Insert(10, formFeed);

Whith this, the line 10 will do a FormFeed, but this doesn't work

NOTE: I send the MybigString all at once to the printer.

To make my code works, I need to send the data line by line to a printer?

Thanks for the help.

PS: Sorry, for my English, I'am a Brazilian developer which don't speak English (yet).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've blogged about this before after having to do it myself. Not to toot my own horn too loudly, but I recommend that you read that entry, as I talk about a complex image command with the printer. If you can understand that, you can print anything!

(I talk about ESC/POS, used in retail receipt printers, but the semantics of the discussion applies to ESC/P, the older dot-matrix language, as well.)

In short, use a BinaryWriter instead of a string or you'll get hopelessly confused (as I did) as certain characters get "baked" in the wrong encoding on their way to the printer. (Trust me on this one! Do not use a StringBuilder when trying to talk in ESC/POS.)

Be careful not to use the Write(string) overload of the BinaryWriter as it will prepend the length of the string as a byte in the stream, which is not what you want. (I also blogged about that after learning that the hard way, too, on the same project.)

Then I use some code to send the byte array, as obtained from the BinaryWriter, directly to the printer by P/Invoking:

private static void Print(string printerName, byte[] document)
{
    NativeMethods.DOC_INFO_1 documentInfo;
    IntPtr printerHandle;

    documentInfo = new NativeMethods.DOC_INFO_1();
    documentInfo.pDataType = "RAW";
    documentInfo.pDocName = "Bit Image Test";

    printerHandle = new IntPtr(0);

    if (NativeMethods.OpenPrinter(printerName.Normalize(), out printerHandle, IntPtr.Zero))
    {
        if (NativeMethods.StartDocPrinter(printerHandle, 1, documentInfo))
        {
            int bytesWritten;
            byte[] managedData;
            IntPtr unmanagedData;

            managedData = document;
            unmanagedData = Marshal.AllocCoTaskMem(managedData.Length);
            Marshal.Copy(managedData, 0, unmanagedData, managedData.Length);

            if (NativeMethods.StartPagePrinter(printerHandle))
            {
                NativeMethods.WritePrinter(
                    printerHandle,
                    unmanagedData,
                    managedData.Length,
                    out bytesWritten);
                NativeMethods.EndPagePrinter(printerHandle);
            }
            else
            {
                throw new Win32Exception();
            }

            Marshal.FreeCoTaskMem(unmanagedData);

            NativeMethods.EndDocPrinter(printerHandle);
        }
        else
        {
            throw new Win32Exception();
        }

        NativeMethods.ClosePrinter(printerHandle);
    }
    else
    {
        throw new Win32Exception();
    }
}

Good luck!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...