среда, 5 октября 2011 г.

Работа в C# c POS принтером Posiflex PP-7000ii

Вводная: Есть чековый принтер Posiflex PP-7000ii, необходимо из своей программы печатать на нём.

Возможные методы решения:
  1. Посылать напрямую в COM-порт. Плюсы - простая реализация. Минусы - очень сложная работа с изображениями, форматированием, дальнейшей переносимостью программы и поиском документации на принтер
  2. Использовать драйвера АТОЛ (и некоторые другие). Плюсы - готовый драйвер, очень простая установка (по сути просто копирование dll), есть документация. Минусы - не очень большой выбор оборудования (порядка 15 моделей принтеров), платность драйвера, нет сообщества и примеров кода для C# (хотя может не нашел просто).
  3. Использовать как Windows-принтер. Плюсы - простая реализация, можно печатать что угодно (ограничиваясь разрешением принтера). Минус - очень медленная печать (до 1-2 минут на чек, что неприемлемо)
  4. Использовать библиотеку Microsoft POS for .NET. Плюсы - простая реализация, достаточно документации в англоязычном интернете (в русском не так много), отличная поддержка оборудования (всё оборудование поддерживающее стандарт UPOS, а такого большая часть), бесплатность библиотеки, быстрая скорость. Минусы - в моём случае не существенны и не были замечены, буду рад дополнениям.
В этой статье я хочу рассмотреть работу с библиотекой Microsoft POS for .NET для печати на POS-принтерах.

Для начала необходимо установить саму библиотеку. Взять её можно по адресу http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5355

Затем нам надо настроить наш драйвер принтера -


Пройдёмся по пунктам
  1. Выбираем тип COM объекта - для POS for .Net должна быть выбран именно этот вариант
  2. Выбираем кодировку - тут думаю понятно, что если выбрать любую другую, то не будет русских символов. Если у вас верное форматирование и латинские символы печатаются нормально, значит не верно выбрана кодировка.
  3. Выбираем какой именно у нас принтер и даём ему имя.
  4. Настраиваем тип подключения и настройку скорости порта. ВНИМАНИЕ если у вас печатается "абракадабра", то вполне возможно не верна выставленная скорость подключения.
  5. Тут просто проверяем подключение - должно распечататься слово "Test"
  6. Нажимаем "Update Device" - на самом деле само устройство не обновляется, как можно подумать, обновляется только информация о нём в системе :)
Теперь необходимо рассказать нашей библиотеке о том, что у нас есть такой принтер это делается в консоли командой.

 "C:\Program Files\Microsoft Point Of Service\POSDM" ADDNAME pp7000 /TYPE:PosPrinter /SONAME:"pp7000"

Проверить, что принтер добавлен можно с помощью команды -
"C:\Program Files\Microsoft Point Of Service\POSDM" LISTNAMES


Именно по значению в поле Name мы и будем вызывать в программе наш принтер. Теперь можно переходить собственно к программированию.

Создаём проект. Добавляем в наше приложение ссылку на библиотеку c:\Program Files\Microsoft Point Of Service\SDK\Microsoft.PointOfService.dll и добавляем

using Microsoft.PointOfService;
И тут нас поджидает первая сложность - библиотека рассчитана на .Net Framework 2.0. И у нас есть два выхода либо использовать его (что сразу лишает нас очень многих возможностей более новых версий), либо добавить к проекту "Файл конфигурации приложения" и привести его к такому виду -

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <!--Следующая строка позволит работать библиотеке POS for .Net -->
    <NetFx40_LegacySecurityPolicy enabled="true"/>
  </runtime>
</configuration>
Далее добавляем две функции - 
        //Так как наш принтер настроен на 866 кодовую страницу
        //то необходимо преобразовывать строку перед печатью из 1251 в 866
        public string MyDecoder(string str)
        {
            byte[] b = Encoding.GetEncoding(866).GetBytes(str);            
            return Encoding.GetEncoding(1251).GetString(b);
        }
 
        //str - строка которую надо печатать. printerName - имя принтера для печати
        private bool POSprintString(string str, string printerName)
        {
            try
            {
                //подключаемся к принтеру
                PosExplorer explorer = new PosExplorer(this);
 
                DeviceInfo ObjDevicesInfo = explorer.GetDevice(DeviceType.PosPrinter, printerName);
                PosPrinter myPrinter = (PosPrinter)explorer.CreateInstance(ObjDevicesInfo);
                myPrinter.Open();
 
                myPrinter.Claim(1000);
 
                myPrinter.AsyncMode = false//Без этой строки у меня не работало
                myPrinter.DeviceEnabled = true;
                //Сама печать
                myPrinter.PrintNormal(PrinterStation.Receipt, (MyDecoder(str + Environment.NewLine)));
                //Функция отрезки чека (если в принтере нет отрезчика, то может быть ошибка)                               
                myPrinter.CutPaper(90);
                //закрываем подключение к принтеру
                myPrinter.DeviceEnabled = false;
                myPrinter.Release();
                myPrinter.Close();
 
                return true;
            }
            catch
            {
                return false;
            }
        }
 
Которые и печатают то, что нам надо.
В простейшем случае, нам надо просто вызвать -
if (!POSprintString("Тестовая строка""pp7000")) MessageBox.Show("Ошибка печати! Проверьте принтер!");
Что распечатает нам чек с надписью "Тестовая строка".
Для более красивого форматирования можно использовать, так называемые ESC-коды. Для примера, распечатаем жирным текстом -
string test = Convert.ToChar(27).ToString() + "|bC" + "Тестовая строка";
if (!POSprintString(test, "pp7000")) MessageBox.Show("Ошибка печати! Проверьте принтер!"); 
Таких кодов достаточно много для того, чтобы делать форматирование чека - посмотреть на список с описание можно по адресу http://msdn.microsoft.com/en-us/library/dd125967(v=winembedded.10).aspx

Если функций по форматированию не достаточно можно распечатать BMP изображение с помощью метода PrintBitmap.

Также рекомендую посетить следующие ресурсы в сети интернет -
http://www.techdays.ru/videos/1142.html - доклад "Введение в разработку с использованием POS for .NET"
http://social.msdn.microsoft.com/Forums/en-US/posfordotnet/thread/e20d927e-b666-4f26-9c5b-b9d6c0ab5c58/ - раздел на social.MSDN посвященный POS for .NET. На котором можно найти ответы на очень многие возникшие вопросы.

Комментариев нет:

Отправить комментарий