none
(Sumber: milist DOTNET) Cetak struk menggunakan Driver Bawaan Manufacture RRS feed

  • Pertanyaan

  • Salam,

    mau nanya bagaimana cetak hasil cetakan struk ke mini printer(printer kasir) dengan menggunakan Driver bawaan dari produsen printer nya ya?
    jadi tanpa menggunakan OPOS Driver.. soalnya kalo menggunakan opos driver manakala ganti device merek lain kadang tidak berfungsi syntax OPOS Driver nya dari merek pertama..


    Agnes Sannie [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Selasa, 25 Oktober 2011 06.46
    Moderator

Jawaban

  • Ok, kalau mau print text dengan dot matrix/thermal/lainnya (semua merek dan model kecuali non device/generic printer seperti PDF atau Fax) bisa dengan mengirim data langsung ke printer controller.

     

    using System.Runtime.InteropServices;

    public class Printer

    {

       const string winspool = "winspool.Drv";

     

       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

       public class DOCINFOA

       {

           [MarshalAs(UnmanagedType.LPStr)]public string DocName;

           [MarshalAs(UnmanagedType.LPStr)]public string OutputFile;

           [MarshalAs(UnmanagedType.LPStr)]public string PrintJobDataType;

       }

     

       [DllImport(winspool, 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, EntryPoint = "ClosePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool ClosePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, 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, EntryPoint = "EndDocPrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndDocPrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "StartPagePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool StartPagePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "EndPagePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndPagePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "WritePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes,

       Int32 dwCount, out Int32 dwWritten);

     

       static bool SendDataToPrinter(string docName, string PrinterName, IntPtr pBytes, int length)

       {

           bool Success = false;

     

           int errorPrint = 0;

           int dataWritten = 0;

           IntPtr printerHandler = new IntPtr(0);

     

           DOCINFOA docinfo = new DOCINFOA { DocName = docName, PrintJobDataType = "RAW" };

     

           if(OpenPrinter(PrinterName.Normalize(), out printerHandler, IntPtr.Zero))

           {

               if(StartDocPrinter(printerHandler, 1, docinfo))

               {

                   if(StartPagePrinter(printerHandler))

                   {

                       Success = WritePrinter(printerHandler, pBytes, length, out dataWritten);

                       EndPagePrinter(printerHandler);

                   }

                   EndDocPrinter(printerHandler);

               }

               ClosePrinter(printerHandler);

           }

     

           if(!Success) errorPrint = Marshal.GetLastWin32Error();

     

           // proses errorPrint disini (bisa dengan events, write log dan sebagainya)

     

           return Success;

       }

     

       public static bool PrintString(string docName, string PrinterName, string text)

       {

           int textLength = text.Length;

           IntPtr  pBytes = Marshal.StringToCoTaskMemAnsi(text);

           bool success = SendDataToPrinter(docName, PrinterName, pBytes, textLength);

           Marshal.FreeCoTaskMem(pBytes);

     

           return success;

       }

    }

     

    Implementasinya,

     

    string printerName = "EPSON LX-300+";

     

    // Buat dulu seluruh bagian text yang mau si cetak

    StringBuilder sb = new StringBuilder();

    sb.Append("===================\n");

    sb.Append("|   CETAK  STRUK  |\n");

    sb.Append("===================");

    string myText = sb.ToString();

     

    bool printOk = Printer.PrintString("Struk", printerName, myText);

     

    Printer name bisa diambil dari Devices and Printers setting di Control Panel. Perlu diingat juga bahwa penulisan namanya harus sama dengan yang di Control Panel device printer yang terpasang atau bisa diambil dari PrinterSetting.PrinterName. Tetapi saya lebih suka ceknya pakai System.Management seperti contoh,

     

    using System.Management;

    foreach (ManagementObject printer in new ManagementObjectSearcher("SELECT * from Win32_Printer").Get())

    {

        foreach (PropertyData property in printer.Properties)

        {

            if (property.Name.Equals("Name") || property.Name.Equals("PortName") || property.Name.Equals("PrintJobDataType"))

                Console.WriteLine(string.Format("{0}= {1}", property.Name, property.Value));

        }

    }

     

    Kalau mau pakai grafis bisa dengan cara biasa yaitu dengan System.Drawing.Printing. Kalau grafis dan pake Thermal Printer masih lumayan cepat dan tidak bising, tapi kalau pake Dot Matrix agak lama dan bisa bangunin tetangga tidur.

     

    Mudah2an bisa membantu.

     

    Dijawab oleh: Riza Marhaban


    Agnes Sannie [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Selasa, 25 Oktober 2011 06.49
    Moderator

Semua Balasan

  • Printer nya Dot Matrix apa Thermal? Tipe/Model? Mau cetak output nya plain text apa grafis?

     

    Dijawab oleh: Riza Marhaban


    Agnes Sannie [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Selasa, 25 Oktober 2011 06.47
    Moderator
  • @Mas Riza,

    untuk sekarang ini sih pakai dot matrix. tapi ini kemungkinan mau buat ke thermal juga,
    cetakannya nya lebih dominan text.. grafis hanya buat logo perusahaan saja..

    Agnes Sannie [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Selasa, 25 Oktober 2011 06.47
    Moderator
  • Ok, kalau mau print text dengan dot matrix/thermal/lainnya (semua merek dan model kecuali non device/generic printer seperti PDF atau Fax) bisa dengan mengirim data langsung ke printer controller.

     

    using System.Runtime.InteropServices;

    public class Printer

    {

       const string winspool = "winspool.Drv";

     

       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

       public class DOCINFOA

       {

           [MarshalAs(UnmanagedType.LPStr)]public string DocName;

           [MarshalAs(UnmanagedType.LPStr)]public string OutputFile;

           [MarshalAs(UnmanagedType.LPStr)]public string PrintJobDataType;

       }

     

       [DllImport(winspool, 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, EntryPoint = "ClosePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool ClosePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, 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, EntryPoint = "EndDocPrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndDocPrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "StartPagePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool StartPagePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "EndPagePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool EndPagePrinter(IntPtr hPrinter);

     

       [DllImport(winspool, EntryPoint = "WritePrinter", SetLastError = true,

       ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

       public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes,

       Int32 dwCount, out Int32 dwWritten);

     

       static bool SendDataToPrinter(string docName, string PrinterName, IntPtr pBytes, int length)

       {

           bool Success = false;

     

           int errorPrint = 0;

           int dataWritten = 0;

           IntPtr printerHandler = new IntPtr(0);

     

           DOCINFOA docinfo = new DOCINFOA { DocName = docName, PrintJobDataType = "RAW" };

     

           if(OpenPrinter(PrinterName.Normalize(), out printerHandler, IntPtr.Zero))

           {

               if(StartDocPrinter(printerHandler, 1, docinfo))

               {

                   if(StartPagePrinter(printerHandler))

                   {

                       Success = WritePrinter(printerHandler, pBytes, length, out dataWritten);

                       EndPagePrinter(printerHandler);

                   }

                   EndDocPrinter(printerHandler);

               }

               ClosePrinter(printerHandler);

           }

     

           if(!Success) errorPrint = Marshal.GetLastWin32Error();

     

           // proses errorPrint disini (bisa dengan events, write log dan sebagainya)

     

           return Success;

       }

     

       public static bool PrintString(string docName, string PrinterName, string text)

       {

           int textLength = text.Length;

           IntPtr  pBytes = Marshal.StringToCoTaskMemAnsi(text);

           bool success = SendDataToPrinter(docName, PrinterName, pBytes, textLength);

           Marshal.FreeCoTaskMem(pBytes);

     

           return success;

       }

    }

     

    Implementasinya,

     

    string printerName = "EPSON LX-300+";

     

    // Buat dulu seluruh bagian text yang mau si cetak

    StringBuilder sb = new StringBuilder();

    sb.Append("===================\n");

    sb.Append("|   CETAK  STRUK  |\n");

    sb.Append("===================");

    string myText = sb.ToString();

     

    bool printOk = Printer.PrintString("Struk", printerName, myText);

     

    Printer name bisa diambil dari Devices and Printers setting di Control Panel. Perlu diingat juga bahwa penulisan namanya harus sama dengan yang di Control Panel device printer yang terpasang atau bisa diambil dari PrinterSetting.PrinterName. Tetapi saya lebih suka ceknya pakai System.Management seperti contoh,

     

    using System.Management;

    foreach (ManagementObject printer in new ManagementObjectSearcher("SELECT * from Win32_Printer").Get())

    {

        foreach (PropertyData property in printer.Properties)

        {

            if (property.Name.Equals("Name") || property.Name.Equals("PortName") || property.Name.Equals("PrintJobDataType"))

                Console.WriteLine(string.Format("{0}= {1}", property.Name, property.Value));

        }

    }

     

    Kalau mau pakai grafis bisa dengan cara biasa yaitu dengan System.Drawing.Printing. Kalau grafis dan pake Thermal Printer masih lumayan cepat dan tidak bising, tapi kalau pake Dot Matrix agak lama dan bisa bangunin tetangga tidur.

     

    Mudah2an bisa membantu.

     

    Dijawab oleh: Riza Marhaban


    Agnes Sannie [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Selasa, 25 Oktober 2011 06.49
    Moderator