使用C#将ESC命令发送到打印机

Ewe*_*ton 6 c# printing command epson

我的应用程序需要打印发票,然后从数据库中获取发票,在大字符串中插入发票上的信息(告诉行,列等),之后我准备将字符串发送到打印机.

我的问题是:我需要在我的大字符串中放入一些ESC/P命令/字符

我试着这样做:

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

        MyBigString.Insert(10, formFeed);
Run Code Online (Sandbox Code Playgroud)

这样,第10行将执行FormFeed,但这不起作用

注意:我将MybigString一次性发送到打印机.

为了使我的代码有效,我需要逐行将数据发送到打印机?

谢谢您的帮助.

PS:对不起,对于我的英语,我是一名不会说英语的巴西开发人员.

Nic*_*cki 5

在我不得不自己做之后,我才开始写这篇文章.不要太大声地吹响我自己的号角,但我建议您阅读该条目,因为我在谈论打印机的复杂图像命令.如果你能理解,你可以打印任何东西!

(我谈到ESC/POS,用于零售收据打印机,但讨论的语义也适用于ESC/P,旧的点阵语言.)

简而言之,使用a BinaryWriter而不是a string或者你将无可救药地混淆(就像我一样),因为某些字符在前往打印机的路上被错误编码"烘焙".(相信我这个!StringBuilder当试图在ESC/POS中说话时不要使用.)

注意不要使用Write(string)过载,BinaryWriter因为它会将字符串的长度作为流中的一个字节前置,这不是你想要的.(在同一个项目上学习了很难的方法之后,我也写了博客.)

然后我使用一些代码通过P/Invoking 将byte数组BinaryWriter直接发送到打印机:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

祝好运!


Han*_*ant 5

绕过打印机驱动程序并使用其本机命令语言直接控制打印机是受支持的方案.P/Invoke在这篇知识库文章中得到了很好的解释.

你肯定要这样做吗?温和地说,通常只使用低成本销售点热销或矩阵打印机进行尝试是不常见的.如果你不喜欢PrintDocument.PrintPage的机制,没有人这样做,你可以考虑我在这个线程中的代码.请注意FormFeed方法.