Отправить команды ESC на принтер в C # - PullRequest
6 голосов
/ 15 мая 2010

Моему приложению необходимо распечатать счета, затем получить счет из базы данных, вставить информацию о счете в большую строку (указав строку, столбец и т. Д.), После этого у меня есть строка, готовая для отправки на принтер .

Моя проблема: мне нужно поместить несколько команд / символов ESC / P в мою большую строку

Я пытался сделать что-то вроде этого:

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

        MyBigString.Insert(10, formFeed);

При этом строка 10 будет выполнять FormFeed, но это не работает

ПРИМЕЧАНИЕ. Я сразу отправляю MybigString на принтер.

Чтобы мой код работал, мне нужно построчно отправлять данные на принтер?

Спасибо за помощь.

PS: Извините, за мой английский, я бразильский разработчик, который еще не говорит по-английски.

Ответы [ 3 ]

5 голосов
/ 15 мая 2010

Обход драйвера принтера и непосредственное управление принтером с использованием его собственного языка команд - поддерживаемый сценарий. P / Invoke хорошо объясняется в этой статье KB .

Конечно, ты хочешь это сделать? Мягко говоря, это нечасто, обычно это делается только при использовании недорогих термопринтеров или матричных принтеров в точках продаж. Если вам не нравится механизм PrintDocument.PrintPage, никто не любит, вы можете рассмотреть мой код в этой теме . Обратите внимание на метод FormFeed.

5 голосов
/ 15 мая 2010

Я уже писал об этом раньше, после того, как сделал это сам. Не слишком громко мой собственный рог, но я рекомендую вам прочитать эту запись, так как я говорю о сложной команде изображения с принтер. Если вы можете это понять, вы можете напечатать что угодно!

(я говорю об ESC / POS, используемом в розничных принтерах чеков, но семантика обсуждения применима и к ESC / P, более старому языку точечных матриц).

Короче говоря, используйте BinaryWriter вместо string, иначе вы безнадежно запутаетесь (как я), поскольку некоторые символы «запекаются» в неправильной кодировке на пути к принтеру. (Поверьте мне в этом! Не используйте StringBuilder при попытке говорить в ESC / POS.)

Будьте осторожны, чтобы не использовать перегрузку Write(string) для BinaryWriter, так как она будет предшествовать длине строки как байта в потоке, а это не то, что вам нужно. ( Я также писал об этом после того, как узнал, что трудный путь тоже в том же проекте.)

Затем я использую некоторый код для отправки массива byte, полученного из BinaryWriter, непосредственно на принтер с помощью 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();
    }
}

Удачи!

0 голосов
/ 19 апреля 2013

".... OpenPrinter (printerName.Normalize (), out printerHandle, IntPtr.Zero) ..."

может потребоваться также установить для IntPtr.Zero значение raw.

Принтеры, особенно матричные, могут быть прямыми, используя DOS, метод CMD, который намного проще и быстрее для печати, также может использовать базовые коды команд ESC / 0x1b для управления принтером. , и т.д.

как windowos / graphic, он может быть графическим и необработанным, установив openprinter (,, printer_defaults) printer_defaults и doc-inf, pls ссылаются на ссылки win32 sdk.

для любой необработанной печати он может использовать команду ESC (см. Подробности в руководстве к принтеру), чтобы напечатать любой графический объект в виде окон водитель сделал.

в качестве печатного файла, он просто добавляет любую из первых 20 ascii, таких как oxoc (formfeed) 0x0doa (0x0a, 0x0d, \ n или перевод строки) у каждого принтера есть небольшие различия команд ESC, но использование основной команды ESC оштрафовано для большинства подобных точек матрицы.

как пример необработанного режима, FormFeed, \ n & \ r

char cFormfeed = 0x0c; // или \ f

char cStr [] = "1 = текст, ...... @ \ n2 = текст ..... \ r \ f3 = текст ......."; // использовать \ f без cFormfeed, вы можете решить это

cStr> lpt1; // вывод на принтер dos или cmd, причины должны получить доступный lpt1.

распечатка будет

первая страница

1 = текст, ...... @

2 = текст .....

на 2-й странице -

= 3 текст .......

надеюсь, это поможет, удачи.

...