ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 75|ตอบกลับ: 0

[VB.NET] โค้ดการพิมพ์สลิปใบเสร็จรับเงินขนาดหน้ากว้าง 3 นิ้ว ด้วย PrintDocument

[คัดลอกลิงก์]

332

กระทู้

528

โพสต์

7335

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
7335
โพสต์ เมื่อวาน 15:07 | ดูโพสต์ทั้งหมด |โหมดอ่าน


หน้าจอการแสดงผลรายการ ก่อนทำการ Preview ...


หน้าจอการใช้งาน Print Preview Dialog ...

PrintDocument เป็นคลาสใน .NET Framework (ภายใต้ System.Drawing.Printing) ที่ใช้สำหรับกำหนดเนื้อหาที่จะพิมพ์ลงบนกระดาษ โดยไม่ได้ควบคุมเครื่องพิมพ์โดยตรง แต่ส่งคำสั่งผ่านระบบ Windows Printer Spooler

หลักการทำงาน:
- สร้างออบเจ็กต์ PrintDocument
- กำหนด Event Handler สำหรับเหตุการณ์ PrintPage (ชื่อเหตุการณ์ PrintPageHandler)
- ใน PrintPageHandler ใช้ e.Graphics กับทุกสิ่งที่เราวาด เช่น ข้อความ (DrawString), เส้น (DrawLine), รูปภาพ (DrawImage) หรือ QR Code ก็จะถูกส่งไปยังเครื่องพิมพ์
- เรียก PrintDocument.Print() เพื่อส่งงานพิมพ์จริง หรือ PrintPreviewDialog เพื่อแสดงตัวอย่างก่อนพิมพ์

เพิ่มเติม: แอดมินเพิ่มเติมการแสดงผลใน Print Preview Dialog เพื่อให้ทำการขยายหน้าจอการแสดงผลของกระดาษให้เป็นแบบอัตโนมัติ ตามขนาดหน้าจอของฟอร์ม

ข้อมูลเพิ่มเติมเกี่ยวกับเครื่องพิมพ์สลิป
การตัดกระดาษจะขึ้นอยู่กับการตั้งค่าใน Properties ที่เครื่องพิมพ์สลิปใน Windows ได้ด้วย หากข้อมูลหมดเครื่องพิมพ์จะตัดกระดาษให้อัตโนมัติเองครับ

สูตรคำนวณหาความกว้างของหน้ากระดาษ: (เราต้องใช้หน่วย Pixel)
ขนาดความกว้างของกระดาษมีหน่วย Pixel = Inch × DPI (DPI มีค่าประมาณ 100 = 1 Inch = 100 Pixel)
ดังนั้นหากต้องการขนาดหน้ากว้าง (Width) = 3 นิ้ว (Inch)
Pixel = 3 x 100 = 300 Pixel

มาดูโค้ดฉบับเต็มกันเถอะ ...
  1. Public Class frmPrintDoc3Inch
  2.     '// สูตรคำนวณ:
  3.     '// ขนาดความกว้างของกระดาษมีหน่วย Pixel = Inch × DPI (DPI มีค่าประมาณ 100 = 1 Inch = 100 Pixel)
  4.     '// MaxWidth = 3 (นิ้ว) x 100 DPI (Dot Per Inch) = 300 Pixel
  5.     '// กำหนดความกว้างของกระดาษ: กว้าง 295 Pixel (ลดค่าลงมาเล็กน้อย)
  6.     Private Const MaxWidth = 295
  7.     '// กำหนดระยะห่างระหว่างบรรทัด (หน่วยเป็นพิกเซลหรือจุดในการวาดบนกระดาษ)
  8.     Private Const LineSpacing = 14

  9.     Private Sub frmPrintDoc3Inch_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
  10.         Select Case e.KeyCode
  11.             Case Keys.F8
  12.                 Call btnPrintPreview_Click(sender, e)
  13.             Case Keys.F10
  14.                 Call btnExit_Click(sender, e)
  15.         End Select
  16.     End Sub

  17.     Private Sub PrintDoc3Inch_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  18.         Me.KeyPreview = True  '// สามารถกดปุ่มฟังค์ชั่นลงบนฟอร์มได้
  19.         '// กำหนดข้อมูลในส่วนหัวบิล
  20.         txtShopName.Text = "ทองก้อนมินิมาร์ท"
  21.         txtAddress1.Text = "142 ม.11 หมู่บ้านฉัตรทอง ถ.กลางเมือง"
  22.         txtAddress2.Text = "ต.เมืองเก่า อ.เมืองขอนแก่น จ.ขอนแก่น 40000"
  23.         txtTaxID.Text = "1234567890XXX"
  24.         txtHeaderBill.Text = "ใบเสร็จรับเงิน/ใบกำกับภาษีอย่างย่อ"
  25.         txtInvoiceID.Text = "CASH-" & RandomInvoiceID()
  26.         dtpInvoiceDate.Value = Now()

  27.         '// สร้างข้อมูลตัวอย่าง 10 รายการ
  28.         Call LoadSampleData()
  29.         '// ตั้งค่าเริ่มต้นให้กับ DataGridView
  30.         Call SetupDataGridView(dgvData)
  31.     End Sub

  32.     '// ข้อมูลตัวอย่าง
  33.     Private Sub LoadSampleData()
  34.         Dim DT As DataTable = New DataTable()
  35.         With DT.Columns
  36.             .Add("รายการ", GetType(String))
  37.             .Add("ราคา/หน่วย", GetType(Double))
  38.             .Add("จำนวน", GetType(Integer))
  39.             .Add("รวม", GetType(Double))
  40.         End With
  41.         Dim Items As String() = {
  42.             "กาแฟเย็น", "ชาเขียว", "เบเกอรี่", "ขนมปัง", "มันทอดกรอบหอมสดๆใหม่ๆ",
  43.             "น้ำอัดลม", "น้ำผลไม้", "ไข่เจียว", "ข้าวผัด", "ผักสด"
  44.         }
  45.         Dim Prices As Double() = {40, 35, 50, 30, 45, 20, 30, 40, 60, 20}
  46.         Dim Qty As Integer() = {1, 2, 1, 1, 1, 1, 1, 1, 1, 2}

  47.         For i As Integer = 0 To 9
  48.             Dim SubTotal As Double = Prices(i) * Qty(i)
  49.             DT.Rows.Add(Items(i), Prices(i), Qty(i), SubTotal)
  50.         Next
  51.         dgvData.DataSource = DT
  52.     End Sub

  53.     '// สุ่มเลขที่ใบเสร็จให้อยู่ในรูปแบบปี พ.ศ. 2 หลักสุดท้าย + จำนวนตัวเลข 5 หลัก
  54.     Function RandomInvoiceID() As String
  55.         '// ปกติ DateTime.Now.Year ที่ได้มาจาก .NET เป็นปี ค.ศ. (AD) อยู่แล้ว (แต่อยากเอาแบบให้ชัวร์ๆล่ะกัน)
  56.         '// อ่านปีปัจจุบัน (เป็น ค.ศ.)
  57.         Dim YearAD As Integer = DateTime.Now.Year
  58.         '// เช็คปีก่อนให้แน่ใจ
  59.         Dim YearBE As Integer
  60.         If YearAD < 2500 Then
  61.             '// กรณีเป็น ค.ศ. (เช่น 2025) → บวก 543
  62.             YearBE = YearAD + 543
  63.         Else
  64.             '// กรณีเป็น พ.ศ. อยู่แล้ว
  65.             YearBE = YearAD
  66.         End If
  67.         '// เอา 2 หลักท้าย
  68.         Dim YearTwoDigit As String = (YearBE Mod 100).ToString("00")
  69.         '// สุ่มเลข 5 หลัก
  70.         Dim rnd As New Random()
  71.         Dim RandomDigits As String = rnd.Next(0, 100000).ToString("D5")
  72.         '// รวมกัน
  73.         Return YearTwoDigit & RandomDigits
  74.     End Function

  75.     '// ------------------------------------------------------------------------------------------------------------------------------------
  76.     '// ตั้งค่าขนาดกระดาษก่อนทำการ Preview
  77.     '// ------------------------------------------------------------------------------------------------------------------------------------
  78.     Private Sub btnPrintPreview_Click(sender As Object, e As EventArgs) Handles btnPrintPreview.Click
  79.         '// ประกาศใช้งานแบบ Run Time ทำให้ไม่ต้องไปลาก Control มาวางไว้บนฟอร์มตอน Design Time
  80.         Dim PrintDoc As New PrintDocument()
  81.         Dim PrintPreview As PrintPreviewDialog

  82.         '// คำนวณจำนวนแถวจริงใน DataGridView (ไม่นับแถวว่างสุดท้าย)
  83.         Dim ItemCount As Integer = dgvData.Rows.Cast(Of DataGridViewRow)().Count(Function(r) Not r.IsNewRow)
  84.         Dim BaseHeight As Integer = 60 '// ความสูงพื้นฐานที่ใช้แน่นอนเสมอ (ส่วนหัวบิลมีชื่อร้าน วันที่ และอื่นๆ)
  85.         Dim ContentHeight As Integer = (ItemCount + 6) * LineSpacing    '// ความสูงที่ใช้เฉพาะ ส่วนเนื้อหา (รายการสินค้า + ส่วนท้าย)
  86.         Dim TotalHeight As Integer = BaseHeight + ContentHeight '// รวมส่วนหัว (BaseHeight) และเนื้อหา (ContentHeight)

  87.         '// กำหนดขนาดกระดาษ: กว้าง 295 Pixel (MaxWidth คือค่าคงที่ ที่ประกาศอยู่ด้านบน), สูงตามคำนวณ
  88.         Dim PaperSize As New PaperSize("Custom3Inch", MaxWidth, TotalHeight)
  89.         PrintDoc.DefaultPageSettings.PaperSize = PaperSize
  90.         PrintDoc.DefaultPageSettings.Margins = New Margins(10, 10, 10, 10)

  91.         '// Add Event Handler เพื่อกำหนดการพิมพ์ค่าต่างๆลงไปในกระดาษทั้งหมด
  92.         AddHandler PrintDoc.PrintPage, AddressOf PrintPageHandler

  93.         '// -------------------------- PrintPreviewDialog --------------------------
  94.         PrintPreview = New PrintPreviewDialog() '// PrintPreviewDialog เป็น Form สำเร็จรูปของ .NET ที่ใช้แสดงตัวอย่างเอกสารที่จะถูกพิมพ์
  95.         PrintPreview.Document = PrintDoc    '// กำหนดว่าเอกสารที่จะพรีวิว คือ PrintDoc

  96.         '// ให้กระดาษ Fit กับหน้าจอฟอร์มพอดี (ปรับซูมอัตโนมัติ)
  97.         Dim ppControl As PrintPreviewControl = TryCast(PrintPreview.Controls(1), PrintPreviewControl)
  98.         If ppControl IsNot Nothing Then ppControl.AutoZoom = True

  99.         '// ---------------- ปรับขนาดฟอร์มที่ Preview = ค่า % ของขนาดหน้าจอ ----------------
  100.         Dim ScreenBounds As Rectangle = Screen.PrimaryScreen.Bounds
  101.         Dim PreviewWidth As Integer = CInt(ScreenBounds.Width * 0.7)    '// กว้าง 70%
  102.         Dim PreviewHeight As Integer = CInt(ScreenBounds.Height * 0.9)  '// สูง 90%

  103.         '// --------------------------  กำหนดตำแหน่งให้อยู่กึ่งกลาง --------------------------
  104.         Dim x As Integer = (ScreenBounds.Width - PreviewWidth) \ 2
  105.         Dim y As Integer = (ScreenBounds.Height - PreviewHeight) \ 2

  106.         PrintPreview.StartPosition = FormStartPosition.Manual
  107.         PrintPreview.Location = New Point(x, y) '// ระบุพิกัดตำแหน่งมุมซ้ายบนของฟอร์มบนหน้าจอ
  108.         PrintPreview.Size = New Size(PreviewWidth, PreviewHeight)   '// กำหนดขนาดของ PrintPreviewDialog

  109.         '// กำหนดเครื่องพิมพ์ล่วงหน้า เมื่อเวลาไปกดไอคอนเครื่องพิมพ์ของ Print Preview Dialog
  110.         '// เพราะหากไม่กำหนดเอาไว้ มันจะส่งไปออกเครื่องพิมพ์ที่เป็น Default Printer แทน
  111.         '// *************** อย่าลืมแก้ไข PrinterName ด้วย ***************
  112.         PrintDoc.PrinterSettings.PrinterName = "POS-80"
  113.         If Not PrintDoc.PrinterSettings.IsValid Then
  114.             MessageBox.Show("ไม่พบเครื่องพิมพ์ชื่อ POS-80", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
  115.             Exit Sub
  116.         End If

  117.         '// เปิดหน้าจอฟอร์มแสดงผล
  118.         PrintPreview.ShowDialog()
  119.     End Sub

  120.     '// ------------------------------------------------------------------------------------------------------------------------------------
  121.     '// ส่วนของการนำข้อมูลมาพิมพ์
  122.     '// ------------------------------------------------------------------------------------------------------------------------------------
  123.     Private Sub PrintPageHandler(sender As Object, e As PrintPageEventArgs)
  124.         '// กำหนดขนาดของฟอนต์ของแต่ละส่วนที่จะนำมาพิมพ์
  125.         Dim FontHeader As Font = New Font("Tahoma", 9, FontStyle.Bold)
  126.         Dim FontNormal As Font = New Font("Tahoma", 8)
  127.         Dim FontTotal As Font = New Font("Tahoma", 9, FontStyle.Bold)
  128.         Dim Brush As Brush = Brushes.Black
  129.         '// Initialize Position
  130.         Dim StartX As Integer = 10
  131.         Dim StartY As Integer = 10

  132.         '// -------------------------- จัดข้อความให้อยู่กึ่งกลาง --------------------------
  133.         Dim CenterFormat As New StringFormat()
  134.         CenterFormat.Alignment = StringAlignment.Center
  135.         '// MaxWidth คือค่าคงที่ = 295 (ขนาดของกระดาษหน้ากว้าง 3 นิ้ว)
  136.         Dim CenterX As Single = MaxWidth / 2

  137.         '// การพิมพ์ส่วนหัวบิล
  138.         '// สังเกตค่า (LineSpacing * เลขจำนวนเต็ม) ... ตัวเลขจำนวนเต็มที่เพิ่มขึ้นไปทีละ 1 นั่นคือการเลื่อนบรรทัดขึ้นไปเรื่อยๆ
  139.         e.Graphics.DrawString(txtShopName.Text, FontHeader, Brush, CenterX, StartY, CenterFormat)
  140.         e.Graphics.DrawString(txtAddress1.Text, FontNormal, Brush, CenterX, StartY + LineSpacing, CenterFormat)
  141.         e.Graphics.DrawString(txtAddress2.Text, FontNormal, Brush, CenterX, StartY + LineSpacing * 2, CenterFormat)
  142.         e.Graphics.DrawString("เลขประจำตัวผู้เสียภาษี " & txtTaxID.Text, FontNormal, Brush, CenterX, StartY + LineSpacing * 3, CenterFormat)
  143.         e.Graphics.DrawString(txtHeaderBill.Text, FontNormal, Brush, CenterX, StartY + LineSpacing * 4, CenterFormat)
  144.         e.Graphics.DrawString("เลขที่ใบเสร็จ: " & txtInvoiceID.Text, FontNormal, Brush, CenterX, StartY + LineSpacing * 5, CenterFormat)
  145.         '// จัดรูปแบบวันที่:
  146.         Dim InvDateTime As DateTime = dtpInvoiceDate.Value
  147.         Dim ThaiDate As String = InvDateTime.ToString("dd MMMM yyyy HH:mm", New CultureInfo("th-TH"))
  148.         e.Graphics.DrawString("วันที่: " & ThaiDate, FontNormal, Brush, CenterX, StartY + LineSpacing * 6, CenterFormat)

  149.         '// วาดเส้นแบ่ง
  150.         DrawLine(e.Graphics, StartX, StartY + LineSpacing * 7, 280, StartY + LineSpacing * 7)

  151.         '// หัวตาราง
  152.         e.Graphics.DrawString("รายการ", FontNormal, Brush, StartX, StartY + LineSpacing * 7)
  153.         e.Graphics.DrawString("ราคา", FontNormal, Brush, 120, StartY + LineSpacing * 7)
  154.         e.Graphics.DrawString("จำนวน", FontNormal, Brush, 190, StartY + LineSpacing * 7, CenterFormat) '// การจัดข้อความกึ่งกลาง
  155.         e.Graphics.DrawString("รวม", FontNormal, Brush, 220, StartY + LineSpacing * 7)

  156.         '// วาดเส้นใต้หัวตาราง
  157.         DrawLine(e.Graphics, StartX, StartY + LineSpacing * 8, 280, StartY + LineSpacing * 8)

  158.         '// พิมพ์รายการสินค้า ราคา จำนวน และผลรวมราคา แสดงผลลงไปในแต่ละแถว
  159.         Dim yPosition As Integer = StartY + LineSpacing * 8
  160.         Dim TotalAmount As Double = 0
  161.         For Each row As DataGridViewRow In dgvData.Rows
  162.             If Not row.IsNewRow Then
  163.                 Dim ItemName As String = row.Cells(0).Value.ToString()
  164.                 Dim price As Double = Convert.ToDouble(row.Cells(1).Value)
  165.                 Dim qty As Integer = Convert.ToInt32(row.Cells(2).Value)
  166.                 Dim SubTotal As Double = price * qty
  167.                 '// หากชื่อสินค้าเกิน 15 ตัวอักษร ให้ตัดคำที่เกินออกไป
  168.                 Dim name As String = If(ItemName.Length > 15, ItemName.Substring(0, 15), ItemName)
  169.                 '//
  170.                 e.Graphics.DrawString(name, FontNormal, Brush, StartX, yPosition)
  171.                 e.Graphics.DrawString(price.ToString("N2"), FontNormal, Brush, 120, yPosition)
  172.                 e.Graphics.DrawString(qty.ToString("N0"), FontNormal, Brush, 190, yPosition, CenterFormat) '// การจัดข้อความกึ่งกลาง
  173.                 e.Graphics.DrawString(SubTotal.ToString("N2"), FontNormal, Brush, 220, yPosition)
  174.                 '//
  175.                 TotalAmount += SubTotal
  176.                 yPosition += LineSpacing
  177.             End If
  178.         Next

  179.         '// วาดเส้นแยก
  180.         DrawLine(e.Graphics, StartX, yPosition, 280, yPosition)

  181.         '// รวมยอด (ชิดกับเส้นเลย)
  182.         e.Graphics.DrawString("รวมจำนวนเงิน: ", FontNormal, Brush, StartX, yPosition + 2)
  183.         e.Graphics.DrawString(TotalAmount.ToString("N2"), FontTotal, Brush, 220, yPosition + 2)
  184.         '// สิ้นสุด
  185.         e.HasMorePages = False
  186.     End Sub

  187.     '/ ------------------------------------------------------------------------------------------------------------------------------------
  188.     '/ วาดเส้นแยก
  189.     Private Sub DrawLine(g As Graphics, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)
  190.         Using pen As New Pen(Color.Black, 0.5)
  191.             g.DrawLine(pen, x1, y1, x2, y2)
  192.         End Using
  193.     End Sub

  194.     Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
  195.         Me.Close()
  196.     End Sub

  197.     Private Sub frmPrintDoc3Inch_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
  198.         Me.Dispose()
  199.         GC.SuppressFinalize(Me)
  200.         Application.Exit()
  201.     End Sub

  202. #Region "SETUP DATAGRIDVIEW"
  203.     Sub SetupDataGridView(DGV As DataGridView)
  204.         '// จัดการรูปแบบและควบคุม DataGridView
  205.         With DGV
  206.             .RowHeadersVisible = False
  207.             .AllowUserToAddRows = False
  208.             .AllowUserToDeleteRows = False
  209.             .AllowUserToResizeRows = False
  210.             .MultiSelect = False
  211.             .SelectionMode = DataGridViewSelectionMode.FullRowSelect
  212.             .ReadOnly = True
  213.             '// Data rows
  214.             .Font = New Font("Tahoma", 10)
  215.             .RowTemplate.MinimumHeight = 27
  216.             .RowTemplate.Height = 27
  217.             '// Autosize Column
  218.             .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
  219.             '// Header
  220.             With .ColumnHeadersDefaultCellStyle
  221.                 .BackColor = Color.RoyalBlue
  222.                 .ForeColor = Color.White
  223.                 .Font = New Font(.Font, FontStyle.Bold)
  224.             End With
  225.             .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
  226.             .ColumnHeadersHeight = 36
  227.             '/ Accept changes to the header's background color.
  228.             .EnableHeadersVisualStyles = False
  229.             '// Even-Odd Color of Rows.
  230.             .AlternatingRowsDefaultCellStyle.BackColor = Color.Beige
  231.             '// Even-Odd Color of Columns.
  232.             For iCol As Integer = 0 To .Columns.Count - 1
  233.                 '// If any integer Mod by 2 and gets the answer is 0 so even number, 1 is an odd number.
  234.                 If iCol Mod 2 = 1 Then
  235.                     .Columns(iCol).HeaderCell.Style.BackColor = Color.DarkBlue
  236.                 Else
  237.                     .Columns(iCol).HeaderCell.Style.BackColor = Color.SeaGreen
  238.                 End If
  239.             Next
  240.         End With
  241.     End Sub
  242. #End Region

  243. End Class
คัดลอกไปที่คลิปบอร์ด

ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...


ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2025-9-23 13:18 , Processed in 0.170374 second(s), 5 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้