C # ESC / POS Печать вьетнамский - PullRequest
       90

C # ESC / POS Печать вьетнамский

0 голосов
/ 09 октября 2018

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

Однако, когда я попытался напечатать вьетнамский, некоторые символы заменяются на «?».

Вот мой код:

public static readonly string ESC = "\u001B";
...
...
...
Encoding enc = Encoding.GetEncoding(1258); //vietnamese code page
string content = "Cơm chiên với các loại gia vị truyền thống làm cho lưỡi của bạn";
string toPrint = ESC + "t" + char.ConvertFromUtf32(94) + "\n" + Encoding.GetEncoding("Latin1").GetString(enc.GetBytes(str));  //code page 94 is for vietnamese (WPC1258). It is get from printer

В распечатке некоторые символы были заменены на "?"(см. прикрепленное изображение).Есть идеи?

Print Out

ОБНОВЛЕНИЕ

Основано на комментарии Панагиотиса Канавоса, я пробовал следующее:

Encoding enc = Encoding.GetEncoding(1258); //vietnamese code page
string content = "Cơm chiên với các loại gia vị truyền thống làm cho lưỡi của bạn";
string newStr = Encoding.GetEncoding("Latin1").GetString(enc.GetBytes(content));
string origStr = enc.GetString(Encoding.GetEncoding("Latin1").GetBytes(newStr));

origStr содержит ?.Я подтверждаю, что на китайском и тайском языках origStr будет равен содержанию.Но НЕ для вьетнамцев.Есть идеи?

ОБНОВЛЕНИЕ 2

Я решил использовать Panagiotis Kanavos с кодом bytesToPrint = enc.GetBytes("\x1Bt\x5E\n" + content);, но он дал мне точно такой же результат, который содержит ? вместо реальных символов.

Так я отправлял содержимое (строку или байты) на принтер.

[DllImport("Winspool.drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);

[DllImport("Winspool.drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);

[DllImport("Winspool.drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);

[DllImport("Winspool.drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

[DllImport("Winspool.drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

[DllImport("Winspool.drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);

[DllImport("Winspool.drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

public static bool SendBytesToPrinter(string printerName, IntPtr pBytes, int dwCount, string docName = null, string dataType = "RAW")
{
    DOCINFOA di = new DOCINFOA();
    di.pDocName = string.IsNullOrWhiteSpace(docName) ? string.Empty : docName;
    di.pDataType = string.IsNullOrWhiteSpace(dataType) ? "RAW" : dataType;

    IntPtr hPrinter = new IntPtr(0); int dwError = 0, dwWritten = 0; bool bSuccess = false;
    if (OpenPrinter(printerName.Normalize(), out hPrinter, IntPtr.Zero))
    {
        if (StartDocPrinter(hPrinter, 1, di))
        {
            if (StartPagePrinter(hPrinter))
            {
                bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                EndPagePrinter(hPrinter);
            }
            EndDocPrinter(hPrinter);
        }
        ClosePrinter(hPrinter);
    }

    if (bSuccess == false)
        dwError = Marshal.GetLastWin32Error();
    return bSuccess;
}

public static bool SendBytesToPrinter(string printerName, byte[] bytes, string docName)
{
    int dwCount = bytes.Length;
    IntPtr ptrBytes = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(byte)) * bytes.Length);
    try
    {
        Marshal.Copy(bytes, 0, ptrBytes, bytes.Length);
        SendBytesToPrinter(printerName, ptrBytes, dwCount, docName);
    }
    finally { Marshal.FreeCoTaskMem(ptrBytes); }
    return true;
}

public static bool SendStringToPrinter(string printerName, string str, string docName)
{
    int dwCount = str.Length;
    IntPtr ptrBytes = Marshal.StringToCoTaskMemAnsi(str);
    try { SendBytesToPrinter(printerName, ptrBytes, dwCount, docName); }
    finally { Marshal.FreeCoTaskMem(ptrBytes); }
    return true;
}

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Я нашел ответ!Это не мой код, а ограничение CodePage 1258 (см. Преобразование текста в латинское кодирование и проблема декодирования для вьетнамцев ).

Вопрос все еще остается, какпечатать на вьетнамском?

Есть имя парня HICURIN, которому удалось решить проблему (см. Печать символов Unicode на POS-принтере ).Надеюсь, он будет рад поделиться с нами своим кодом.

Приветствия, Сэм

0 голосов
/ 29 октября 2018

Это все, что вам нужно, чтобы иметь возможность правильно печатать вьетнамские символы на ваших распечатках, используя C #

, отредактируйте код для этого

public static readonly string ESC = "\u001B";
...
...
...
//Encoding enc = Encoding.GetEncoding(1258); //vietnamese code page
string content = "Cơm chiên với các loại gia vị truyền thống làm cho lưỡi của bạn";
string toPrint = ESC + "t" + char.ConvertFromUtf32(94) + "\n"; 
// First you need to convert the vietnamese string to utf-8 bytes.
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(content); 
// Convert utf-8 bytes to a string.
toPrint += System.Text.Encoding.UTF8.GetString(utf8Bytes);

Попробуйте приведенный выше код и дайте мне знатьесли вы все еще получаете забавные персонажи ...

...