2014-01-09 136 views
3

我正在使用VB.NET,并且出现了一些与我刚刚连接的POS打印机(Epson TM-T88V)有关的问题。我最近从YouTube上发现的一个示例代码中,使用了Epson TM-88II,这是V的一个老版本。如果我能打开串口,这个代码就可以工作得很好!发生什么事是打印机在端口USB-001(虚拟打印机端口)上,您不能将其设置为VB中的COM端口来写入它。我从Epson下载了.NET的Microsoft POS和OPOSN。我到目前为止唯一的问题是我从哪里开始?任何人都可以帮助我用VB连接到打印机,然后可能会发送一个基本的“Hello World”到打印机,然后是autocut?使用Epson打印机在VB.NET中进行POS打印

+0

你有没有试过使用Crystal Reports设计报表?我在一台POS系统的Epson U220上做这件事,它适用于我。您甚至不必为串行通信编写代码。 –

回答

4

这很难,因为它不容易找到好的文章。如果你寻找信息,你会注意到爱普生分享他们的知识并不是很开心。 BOT这里有一些文章,帮助我这样的:

  • 这篇文章是非常好的,如果你要打印的图像Images
  • 这一个是爱普生Epson

** **更新

这是什么使魔:

Public Class EscPOS 

    Private Shared PrintNam As String = "POS" 

    Public Shared Property PrinterName 
     Set(value) 
      PrintNam = value 
     End Set 
     Get 
      Return PrintNam 
     End Get 
    End Property 

    ' Structure and API declarions: 
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _ 
    Structure DOCINFOW 
     <MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String 
     <MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String 
     <MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String 
    End Structure 

    <DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter As IntPtr, ByVal pd As Long) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean 
    End Function 
    <DllImport("winspool.Drv", EntryPoint:="WritePrinter", _ 
     SetLastError:=True, CharSet:=CharSet.Unicode, _ 
     ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As Boolean 
    End Function 

    Public Shared Function PrintImage(BM As Bitmap) As Boolean 

     Dim b As Byte() = ConvertImagetoBytes(BM) 
     Dim bSuccess As Boolean 
     Dim pUnmanagedBytes As IntPtr 

     ' Allocate some unmanaged memory for those bytes. 
     pUnmanagedBytes = Marshal.AllocCoTaskMem(b.Count) 
     ' Copy the managed byte array into the unmanaged array. 
     Marshal.Copy(b, 0, pUnmanagedBytes, b.Count) 
     ' Send the unmanaged bytes to the printer. 
     bSuccess = EscPOS.PrintBytes(b) 

     Return bSuccess 
    End Function 
    Public Shared Function PrintBytes(Document As Byte()) As Boolean 
     Dim hPrinter As IntPtr  ' The printer handle. 
     Dim dwError As Int32  ' Last error - in case there was trouble. 
     Dim di As DOCINFOW  ' Describes your document (name, port, data type). 
     Dim dwWritten As Int32  ' The number of bytes written by WritePrinter(). 
     Dim bSuccess As Boolean  ' Your success code. 

     ' Set up the DOCINFO structure. 

     di = New DOCINFOW 
     di.pDocName = "RAW LOGO" 
     di.pDataType = "RAW" 

     hPrinter = New IntPtr(0) 

     bSuccess = False 
     If OpenPrinter(PrinterName.Normalize(), hPrinter, 0) Then 
      If StartDocPrinter(hPrinter, 1, di) Then 
       Dim managedData As Byte() 
       Dim unmanagedData As IntPtr 

       managedData = Document 
       unmanagedData = Marshal.AllocCoTaskMem(managedData.Length) 
       Marshal.Copy(managedData, 0, unmanagedData, managedData.Length) 

       If StartPagePrinter(hPrinter) Then 
        bSuccess = WritePrinter(hPrinter, unmanagedData, managedData.Length, dwWritten) 
        EndPagePrinter(hPrinter) 
       End If 
       Marshal.FreeCoTaskMem(unmanagedData) 
       EndDocPrinter(hPrinter) 
      End If 
      ClosePrinter(hPrinter) 
     End If 
     If bSuccess = False Then 
      dwError = Marshal.GetLastWin32Error() 
     End If 
     Return bSuccess 
    End Function 
    Public Shared Function ConvertImagetoBytes(BM As Bitmap) As Byte() 
     Dim Data As BitMapData = GetBitmapData(BM) 
     Dim Op As New MemoryStream 
     Dim bw As New BinaryWriter(Op) 

     bw.Write(Chr(Keys.Escape)) 
     bw.Write("@"c) 

     ' So we have our bitmap data sitting in a bit array called "dots." 
     ' This is one long array of 1s (black) and 0s (white) pixels arranged 
     ' as if we had scanned the bitmap from top to bottom, left to right. 
     ' The printer wants to see these arranged in bytes stacked three high. 
     ' So, essentially, we need to read 24 bits for x = 0, generate those 
     ' bytes, and send them to the printer, then keep increasing x. If our 
     ' image is more than 24 dots high, we have to send a second bit image 
     ' command to draw the next slice of 24 dots in the image. 

     ' Set the line spacing to 24 dots, the height of each "stripe" of the 
     ' image that we're drawing. If we don't do this, and we need to 
     ' draw the bitmap in multiple passes, then we'll end up with some 
     ' whitespace between slices of the image since the default line 
     ' height--how much the printer moves on a newline--is 30 dots. 
     bw.Write(Chr(Keys.Escape)) 
     bw.Write("3"c) 
     ' '3' just means 'change line height command' 
     bw.Write(CByte(24)) 

     ' OK. So, starting from x = 0, read 24 bits down and send that data 
     ' to the printer. The offset variable keeps track of our global 'y' 
     ' position in the image. For example, if we were drawing a bitmap 
     ' that is 48 pixels high, then this while loop will execute twice, 
     ' once for each pass of 24 dots. On the first pass, the offset is 
     ' 0, and on the second pass, the offset is 24. We keep making 
     ' these 24-dot stripes until we've run past the height of the 
     ' bitmap. 
     Dim offset As Integer = 0 
     Dim width As Byte() 

     While offset < Data.Height 
      ' The third and fourth parameters to the bit image command are 
      ' 'nL' and 'nH'. The 'L' and the 'H' refer to 'low' and 'high', respectively. 
      ' All 'n' really is is the width of the image that we're about to draw. 
      ' Since the width can be greater than 255 dots, the parameter has to 
      ' be split across two bytes, which is why the documentation says the 
      ' width is 'nL' + ('nH' * 256). 
      bw.Write(Chr(Keys.Escape)) 
      bw.Write("*"c) 
      ' bit-image mode 
      bw.Write(CByte(33)) 
      ' 24-dot double-density 
      width = BitConverter.GetBytes(Data.Width) 
      bw.Write(width(0)) 
      ' width low byte 
      bw.Write(width(1)) 
      ' width high byte 
      For x As Integer = 0 To Data.Width - 1 
       ' Remember, 24 dots = 24 bits = 3 bytes. 
       ' The 'k' variable keeps track of which of those 
       ' three bytes that we're currently scribbling into. 
       For k As Integer = 0 To 2 
        Dim slice As Byte = 0 
        ' A byte is 8 bits. The 'b' variable keeps track 
        ' of which bit in the byte we're recording. 
        For b As Integer = 0 To 7 
         ' Calculate the y position that we're currently 
         ' trying to draw. We take our offset, divide it 
         ' by 8 so we're talking about the y offset in 
         ' terms of bytes, add our current 'k' byte 
         ' offset to that, multiple by 8 to get it in terms 
         ' of bits again, and add our bit offset to it. 
         Dim y As Integer = (((offset \ 8) + k) * 8) + b 
         ' Calculate the location of the pixel we want in the bit array. 
         ' It'll be at (y * width) + x. 
         Dim i As Integer = (y * Data.Width) + x 
         ' If the image (or this stripe of the image) 
         ' is shorter than 24 dots, pad with zero. 
         Dim v As Boolean = False 
         If i < Data.Dots.Length Then 
          v = Data.Dots(i) 
         End If 
         ' Finally, store our bit in the byte that we're currently 
         ' scribbling to. Our current 'b' is actually the exact 
         ' opposite of where we want it to be in the byte, so 
         ' subtract it from 7, shift our bit into place in a temp 
         ' byte, and OR it with the target byte to get it into there. 
         slice = slice Or CByte((If(v, 1, 0)) << (7 - b)) 
        Next 
        ' Phew! Write the damn byte to the buffer 
        bw.Write(slice) 
       Next 
      Next 
      ' We're done with this 24-dot high pass. Render a newline 
      ' to bump the print head down to the next line 
      ' and keep on trucking. 
      offset = offset + 24 
      bw.Write(vbCrLf.ToCharArray) 
     End While 

     ' Restore the line spacing to the default of 30 dots. 
     bw.Write(Chr(Keys.Escape)) 
     bw.Write("3"c) 
     bw.Write(CByte(30)) 

     bw.Flush() 

     Return Op.ToArray 
    End Function 
    Private Shared Function GetBitmapData(BM As Bitmap) As BitMapData 
     Dim threshold = 127 
     Dim index As Integer = 0 
     Dim dimensions As Integer = BM.Width * BM.Height 
     Dim dots As BitArray = New BitArray(dimensions) 
     Dim res As New BitMapData 
     Dim a As Integer 

     For y = 0 To BM.Height - 1 
      For x = 0 To BM.Width - 1 
       Dim col As Color = BM.GetPixel(x, y) 
       Dim luminance = CInt(col.R * 0.3 + col.G * 0.59 + col.B * 0.11) 
       If (luminance < threshold) = True Then 
        a = 1 
       End If 
       dots(index) = (luminance < threshold) 
       index = index + 1 
      Next 
     Next 
     res.Dots = dots : res.Height = BM.Height : res.Width = BM.Width 
     Return res 
    End Function 
    Private Class BitMapData 
     Public Dots As BitArray 
     Public Height As Int16 
     Public Width As Int16 
    End Class 

    ' When the function is given a printer name and an unmanaged array of 
    ' bytes, the function sends those bytes to the print queue. 
    ' Returns True on success or False on failure. 
    Private Shared Function PrintEsto(ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean 
     Dim hPrinter As IntPtr  ' The printer handle. 
     Dim dwError As Int32  ' Last error - in case there was trouble. 
     Dim di As DOCINFOW = Nothing   ' Describes your document (name, port, data type). 
     Dim dwWritten As Int32  ' The number of bytes written by WritePrinter(). 
     Dim bSuccess As Boolean  ' Your success code. 

     ' Set up the DOCINFO structure. 
     With di 
      .pDocName = "RAW Document" 
      .pDataType = "RAW" 
     End With 
     ' Assume failure unless you specifically succeed. 
     bSuccess = False 
     If OpenPrinter(PrinterName, hPrinter, 0) Then 
      If StartDocPrinter(hPrinter, 1, di) Then 
       If StartPagePrinter(hPrinter) Then 
        ' Write your printer-specific bytes to the printer. 
        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten) 
        EndPagePrinter(hPrinter) 
       End If 
       EndDocPrinter(hPrinter) 
      End If 
      ClosePrinter(hPrinter) 
     End If 
     ' If you did not succeed, GetLastError may give more information 
     ' about why not. 
     If bSuccess = False Then 
      dwError = Marshal.GetLastWin32Error() 
     End If 
     Return bSuccess 
    End Function 

    ' SendFileToPrinter() 
    ' When the function is given a file name and a printer name, 
    ' the function reads the contents of the file and sends the 
    ' contents to the printer. 
    ' Presumes that the file contains printer-ready data. 
    ' Shows how to use the SendBytesToPrinter function. 
    ' Returns True on success or False on failure. 
    Public Shared Function PrintFile(ByVal szFileName As String) As Boolean 
     ' Open the file. 
     Try 
      Dim fs As New FileStream(szFileName, FileMode.Open) 
      ' Create a BinaryReader on the file. 
      Dim br As New BinaryReader(fs) 
      ' Dim an array of bytes large enough to hold the file's contents. 
      Dim bytes(fs.Length) As Byte 
      Dim bSuccess As Boolean 
      ' Your unmanaged pointer. 
      Dim pUnmanagedBytes As IntPtr 

      ' Read the contents of the file into the array. 
      bytes = br.ReadBytes(fs.Length) 
      ' Allocate some unmanaged memory for those bytes. 
      pUnmanagedBytes = Marshal.AllocCoTaskMem(fs.Length) 
      ' Copy the managed byte array into the unmanaged array. 
      Marshal.Copy(bytes, 0, pUnmanagedBytes, fs.Length) 
      ' Send the unmanaged bytes to the printer. 
      bSuccess = PrintEsto(pUnmanagedBytes, fs.Length) 
      ' Free the unmanaged memory that you allocated earlier. 
      Marshal.FreeCoTaskMem(pUnmanagedBytes) 
      fs.Close() 
      Return bSuccess 
     Catch ex As Exception 
      MsgBox(ex.Message) 
      Return False 
     End Try 
    End Function 

    ' When the function is given a string and a printer name, 
    ' the function sends the string to the printer as raw bytes. 
    Public Shared Function PrintString(ByVal szString As String) 
     Dim pBytes As IntPtr 
     Dim dwCount As Int32 
     Dim Res As Boolean 
     ' How many characters are in the string? 
     dwCount = szString.Length() 
     ' Assume that the printer is expecting ANSI text, and then convert 
     ' the string to ANSI text. 
     pBytes = Marshal.StringToCoTaskMemAnsi(szString) 
     ' Send the converted ANSI string to the printer. 
     Res = PrintEsto(pBytes, dwCount) 
     Marshal.FreeCoTaskMem(pBytes) 
     Return Res 
    End Function 

End Class 

这就是我所说的白色类:

If EsImpresionTermica Then 
      If File.Exists(My.Application.Info.DirectoryPath & "\Settings.{2559a1f2-21d7-11d4-bdaf-00c04f60b9f0}\Logo.conf") Then _ 
       RawPrinting.EscPOS.PrintBytes(File.ReadAllBytes(My.Application.Info.DirectoryPath & "\Settings.{2559a1f2-21d7-11d4-bdaf-00c04f60b9f0}\Logo.conf")) 
     Else 
      Dim MSe As New MemoryStream 
      Dim BWe As New BinaryWriter(MSe) 
      BWe.Write(Chr(&H1B)) 
      BWe.Write("@"c) 'Inicia Imresora 
      BWe.Write(Chr(&H1B)) 
      BWe.Write(CByte(3)) 
      BWe.Write(Chr(18)) 'Establece interlineado 
      BWe.Write(Chr(&H1B)) 
      BWe.Write("U"c) 
      BWe.Write(Chr(1)) 'Impresión unidireccional 
      BWe.Write(Chr(&H1B)) 
      BWe.Write("a"c) 
      BWe.Write(Chr(1)) 'Centra Impresión 
      BWe.Write(Chr(&H1B)) 
      BWe.Write(vbCrLf.ToCharArray) 
      BWe.Write(Encoding.ASCII.GetBytes(Encabezado)) 
      BWe.Write(Chr(10)) 
      BWe.Write(Chr(10)) 
      BWe.Flush() 
      BWe.Close() 
      RawPrinting.EscPOS.PrintBytes(MSe.ToArray) 
     End If 
    End Sub 
相关问题