2010-05-14 116 views
6

我的應用程序需要打印發票,然後從數據庫獲取發票,在發票上插入大字符串(告訴行,列等)的信息後,我有準備好將字符串發送到打印機。發送ESC命令到打印機的C#

我的問題是:我需要把一些ESC/P命令/在我的大字符串中的字符

我試圖做這樣的事情:

 char formFeed = (char)12; 
     Convert.ToChar(12); 

     MyBigString.Insert(10, formFeed); 

蒙山爲此,10號線將做一個FormFeed,但這不起作用

注:我一次發送MybigString到打印機。

爲了使我的代碼有效,我需要逐行將數據發送到打印機?

感謝您的幫助。

PS:對不起,對於我的英語,我是一位巴西開發者,他不會說英語(還)。

+0

打印機是EPSON FX-1170(點陣打印機) – Ewerton 2010-05-14 21:37:59

+2

什麼是MyBigString? – SLaks 2010-05-14 21:39:46

回答

5

繞過打印機驅動程序和直接控制打印機,使用其本地命令語言,是一個支持的方案。 P/Invoke在這個KB article中有很好的解釋。

確定要這麼做嗎?通常只用低成本的銷售點熱敏打印機或矩陣打印機進行試用,這種情況並不常見。如果你不喜歡PrintDocument.PrintPage的機制,沒有人做,你可以考慮在this thread我的代碼。請注意FormFeed方法。

+0

a閱讀並實施知識庫文章,它適用於我。謝謝 – Ewerton 2010-05-18 12:40:59

+0

知識庫文章以「'RAW'」模式打開打印機,這意味着您需要發佈打印機驅動程序可以接受的字節。嘗試將0xFF發送到XPS打印機將導致它無法執行任何操作。您必須將模式更改爲「'TEXT」(http://social.msdn.microsoft.com/forums/en-US/windowsxps/thread/6280ebb0-61ad-4c42-a870-7f022fcdfbfe/) – 2010-12-30 19:06:08

5

I've blogged about this before after having to do it myself.不嘟我自己的喇叭太大聲,但我建議您閱讀條目,如我談談打印機複雜的圖像命令。如果你能理解,你可以打印任何東西!

(我說說ESC/POS,零售收據打印機使用,但討論的語義適用於ESC/P,舊的點陣的語言,也是如此。)

總之,使用BinaryWriter而不是string,否則你會變得很無奈(正如我所做的那樣),因爲某些字符在打印機的途中以錯誤的編碼「烘焙」。 (相信我在這一個!試圖在ESC/POS交談時,不要使用StringBuilder。)

要小心,不要使用Write(string)超載BinaryWriter的,因爲它會在前面加上字符串的長度爲一個字節流,這不是你想要的。 (I also blogged about that後得知硬盤的方式,也對同一個項目。)

然後我使用一些代碼來發送byte陣列,由P /調用從BinaryWriter獲得直接輸出到打印機:

private static void Print(string printerName, byte[] document) 
{ 
    NativeMethods.DOC_INFO_1 documentInfo; 
    IntPtr printerHandle; 

    documentInfo = new NativeMethods.DOC_INFO_1(); 
    documentInfo.pDataType = "RAW"; 
    documentInfo.pDocName = "Bit Image Test"; 

    printerHandle = new IntPtr(0); 

    if (NativeMethods.OpenPrinter(printerName.Normalize(), out printerHandle, IntPtr.Zero)) 
    { 
     if (NativeMethods.StartDocPrinter(printerHandle, 1, documentInfo)) 
     { 
      int bytesWritten; 
      byte[] managedData; 
      IntPtr unmanagedData; 

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

      if (NativeMethods.StartPagePrinter(printerHandle)) 
      { 
       NativeMethods.WritePrinter(
        printerHandle, 
        unmanagedData, 
        managedData.Length, 
        out bytesWritten); 
       NativeMethods.EndPagePrinter(printerHandle); 
      } 
      else 
      { 
       throw new Win32Exception(); 
      } 

      Marshal.FreeCoTaskMem(unmanagedData); 

      NativeMethods.EndDocPrinter(printerHandle); 
     } 
     else 
     { 
      throw new Win32Exception(); 
     } 

     NativeMethods.ClosePrinter(printerHandle); 
    } 
    else 
    { 
     throw new Win32Exception(); 
    } 
}

祝你好運!

+0

謝謝尼古拉斯,你的代碼似乎對我來說很先進,但我試圖理解它。 :D – Ewerton 2010-05-17 12:03:46

+0

@Nicholas你的博客不再工作了。無論如何,我可以看看這些代碼嗎? – 2015-12-26 10:47:54

0

「...... OpenPrinter(printerName.Normalize(),出printerHandle,IntPtr.Zero)......」

力量來IntPtr.Zero設置爲原料太需要。打印機特別是點陣打印機,它可以直接使用DOS,CMD方法,這對打印來說非常簡單和快速,也可以使用基本的ESC/0x1b命令代碼來控制打印機。 。等等。

作爲windowos /圖形,它可以是圖形和原始設置openprinter(,, printer_defaults)printer_defaults和doc-inf,請參閱win32 sdk引用。

對於任何原始打印,它可以使用ESC命令(請參閱打印機手冊的詳細信息)打印任何圖形,作爲驅動程序所執行的任何圖形。

作爲打印原料,它只是追加任何第一20個ASCII,如oxoc(換頁)0x0doa(0X0A,0X0D,\ n或換行) 每個打印機已輕微ESC命令差異,但使用主ESC命令是對大多數Dot矩陣罰款相似。

爲原料模式例如如下, 換頁,\ n & \ r

炭cFormfeed = 0x0c; //或\ f

char cStr [] =「1 = text,...... @ \ n2 = text ..... \ r \ f3 = text .......」; // use \ f not using cFormfeed you can work it out

cStr> lpt1; //輸出到打印機的dos或cmd方法,原因必須讓lpt1可用。

打印輸出將是

第一頁

1 =文本,...... @

2 =文本.....

在第二頁是

3 =文字.......

希望這可以幫助,祝你好運。