iT邦幫忙

0

C# 出單機 列印時要如何分頁(切紙)?

現在要做的功能有 3 個

  1. 列印發票
  2. 列印明細(長度不固定)
  3. 列印取餐單(長度及張數都不固定)

個別的列印功能沒有問題,想請教的問題如下

Q1.

透過設置 PrintPageEventArgs.HasMorePage = true 在預覽列印視窗可以看的出來是有分頁的,但實際上印表機在切紙的時候是以列印佇列中的一個佇列為單位來切紙。所以現在如果要列印發票與明細在不同張,就要分別建立 printDocument。那如果我在一筆交易中要印出多張分切的取餐單,就一樣要建立多筆 printDocument。

有什麼辦法可以在一個 printDocument 就達到分切的效果嗎?或者是有其他的方法可以實現在指定位置分切單據的功能?

Q2.

現在用的出單機(EP-380CK)在列印完成時會多印一段空白(約 3 公分),修改過PrintDocument.DefaultPageSettings的相關參數(例如MarginsPageSize)都試過了但幾乎沒有改善,這個有什麼辦法可以解決嗎?

範例程式碼:

string printType;
List<string> proofData;

// 建立 列印發票 用的 PrintDocument 及綁定事件
public void printInvoice(){
    PrintDocument printDoc = new PrintDocument();
    printDoc.BeginPrint += new PrintEventHandler(BeginPrint);
    printDoc.PrintPage += new PrintPageEventHandler(printPageHandler);
    printDoc.EndPrint += new PrintEventHandler(EndPrint);
    printDoc.print();
}
// 列印發票
public void printInvoiceHandler(object sender, PrintPageEventArgs e){
    if (printType = "全版發票") // 發票 與 明細 在同一張
    {
      drawInvoice(e); // 繪製發票
      drawDetail(e); // 繪製明細
    }else if (printType = "發票+明細") // 發票 與 明細 在不同張
    {
      drawInvoice(e); // 繪製發票
      // 這裡該做什麼才能分成不同張?
      drawDetail(e); // 繪製明細
    }
}

// 建立 列印取餐單 用的 PrintDocument 及綁定事件
public void printProof(){
    PrintDocument printDoc = new PrintDocument();
    printDoc.BeginPrint += new PrintEventHandler(BeginPrint);
    printDoc.PrintPage += new PrintPageEventHandler(printProofHandler);
    printDoc.EndPrint += new PrintEventHandler(EndPrint);
    printDoc.print();
}

// 將 proofData 中每筆字串列印不同張取餐單
int currentProofPage = 0; //當前取餐單頁數暫存
public void printProofHandler(object sender, PrintPageEventArgs e){     
      drawProof(e); // 繪製取餐單
      currentProofPage++; // 暫存變數累加
      
      if (currentProofPage <= proofData.count){ // 還沒印完
        e.HasMorePage = true; // 重新呼叫 printProofHandler ?
      }else{ // 已經印完
        e.HasMorePage = false;
        currentProofPage = 0; // 重置暫存變數
      }
}

// 繪製發票內容
public void drawInvoice(PrintPageEventArgs e){ ... }
// 繪製明細內容
public void drawDetail(PrintPageEventArgs e){ ... }
// 依 currentProofPage 繪製指定的取餐單內容
public void drawProof(PrintPageEventArgs e){ 
    e.Graphics.DrawString(proofData[currentProofPage]); 
}

2 個回答

3
japhenchen
iT邦大師 1 級 ‧ 2020-07-15 15:25:53
最佳解答

這樣寫會不會太辛苦了?還要自己畫線、字、表格.........
我用Visual studio C#的RDLC做自定義報表,不只小張到1x2.5㎝,2.5x6.5㎝的連續標籤,中一刀的點陣式連續報表發票,大到25x36.5㎝的大信封,都可以列印

且不用程式drawline、text、rectangle............跟excel一樣填格子塞欄位(不一定要套資料庫,可以自定義資料來源,或List<T>)設數值format,置左置中置右字體大小...所見即所得,格式可以自定義寬高,長寬一到自動換頁,點陣式的也會以輸出紙張長度自動歸位..https://ithelp.ithome.com.tw/upload/images/20200715/20117954pbRaihizJx.jpg

看更多先前的回應...收起先前的回應...

不能混搭圖片?可以
這個QRCODE是自己跑語法產生出來的BITMAP點陣圖,照搭
https://ithelp.ithome.com.tw/upload/images/20200715/20117954apZj2zce1B.jpg

我忘了有做自定義圖片的功能了...
https://ithelp.ithome.com.tw/upload/images/20200715/20117954VN5lxvClv8.jpg

因為接手前人的專案,之前也沒印單經驗,只知道笨方法 QQ
感謝您的回答讓我認識新東西~ 我也研究看看RDLC
/images/emoticon/emoticon41.gif

感謝大神分享, 以前做報表是拿先刻好的Word/Excel範本改要替換的參數, 現在看到VS有RDLC這設計工具, 豁然開朗XD

1
eric19740521
iT邦新手 3 級 ‧ 2020-07-19 03:39:55

EP-380CK
你確定要 用Visual studio C#的RDLC 去折磨人嗎??
我沒用過RDLC,但我稍微看一下,應該是driver方式列印..
這不就. 列印時,慢吞吞的~~~~

何不直接下達 escpos command 給 出單機
列印明細的時候,line mode (不固定長度)
列印9cm 雙Qrcode的時候,page mode (固定長度)
跟廠商要開發檔案,裡面有說明

不是DRIVER哦,只是純綷把輸出給印表機的資料用結構化文本(XML)生成,但跟設計者無關,設計者只需要套表,選擇印表機的事,就交給軟體使用者,而不是由程式鎖定並列埠,要是遇到主機板沒有並列埠的,不就...

用ESC/P2只適合相容的點陣式印表機,且直接輸出到LPT,網上的參考資料都缺漏已久,不易找到正確的資料,還要考慮每頁可印字元數,遇到UNICODE還得求點陣印表機是不是有內建UNICODE字庫....你真的確定ESC/P2真的適用於各種環境嗎?

1.請搜尋
https://www.google.com/search?q=escpos&rlz=1C1CHZL_zh-TWTW710TW710&oq=escpos&aqs=chrome..69i57j69i59j69i60l3&sourceid=chrome&ie=UTF-8

並非 ESC/P2

2.出單機.用你的方式做.也OK...快與慢,取決你

3.出單機本身有一套指令集.ESC/POS指令集
若搭配指令集 可檢查 機器本身的狀況..(此為很重要)

0.設計要求時間短.用報表套表.....

感謝兩位都提供了方向~因為時間有限已經用硬幹的方式勉強弄到可以接受的結果,之後有機會就來嘗試這兩位提供的方式。

我要發表回答

立即登入回答