2014-01-09 172 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 
相關問題