ShippingLabels.vb
'''' This code is part of Document Solutions for Imaging demos.'' Copyright (c) MESCIUS inc. All rights reserved.''Imports SystemImports System.IOImports System.Collections.GenericImports System.DrawingImports System.GlobalizationImports GrapeCity.Documents.ImagingImports GrapeCity.Documents.TextImports GrapeCity.Documents.DrawingImports GrapeCity.Documents.BarcodeImports GCTEXT = GrapeCity.Documents.TextImports GCDRAW = GrapeCity.Documents.Drawing
'' This sample prints a set of shipping labels that also include barcodes.'' Note also the use of tab stops to vertically align data.Public Class ShippingLabels
'' Client info. This sample prints one shipping label for each client. Class Client Public Name As String Public Addr As String Public City As String Public Country As String
Public Sub New(name As String, addr As String, city As String, country As String) Me.Name = name Me.Addr = addr Me.City = city Me.Country = country End Sub End Class
'' The clients base. Shared ReadOnly s_clients As New List(Of Client) From { New Client("Simons bistro", "Vinbæltet 34", "København", "Denmark"), New Client("Richter Supermarkt", "Starenweg 5", "Genève", "Switzerland"), New Client("Bon app'", "12, rue des Bouchers", "Marseille", "France"), New Client("Rattlesnake Canyon Grocery", "2817 Milton Dr.", "Albuquerque", "USA"), New Client("Lehmanns Marktstand", "Magazinweg 7", "Frankfurt a.M.", "Germany"), New Client("LILA-Supermercado", "Carrera 52 con Ave. Bolívar #65-98 Llano Largo", "Barquisimeto", "Venezuela"), New Client("Ernst Handel", "Kirchgasse 6", "Graz", "Austria"), New Client("Pericles Comidas clásicas", "Calle Dr. Jorge Cash 321", "México D.F.", "Mexico"), New Client("Drachenblut Delikatessen", "Walserweg 21", "Aachen", "Germany"), New Client("Queen Cozinha", "Alameda dos Canàrios, 891", "São Paulo", "Brazil"), New Client("Tortuga Restaurante", "Avda. Azteca 123", "México D.F.", "Mexico"), New Client("Save-a-lot Markets", "187 Suffolk Ln.", "Boise", "USA"), New Client("Franchi S.p.A.", "Via Monte Bianco 34", "Torino", "Italy") }
'' The main sample driver. Public Function GenerateImageStream(targetMime As String, pixelSize As Size, dpi As Single, opaque As Boolean, Optional sampleParams As String() = Nothing) As Stream Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi) Dim g = bmp.CreateGraphics(Color.White) Dim ms = New MemoryStream() Dim tw As GcTiffWriter = Nothing If targetMime = Util.MimeTypes.TIFF Then tw = New GcTiffWriter(ms) End If
Init(pixelSize)
'' Loop over clients, print up to 4 labels per page: Dim i As Integer = 0 For pg = 0 To (s_clients.Count + 3) \ 4 - 1 PrintLabel(s_clients(i), g, New RectangleF(hmargin, vmargin, _labelWidth, _labelHeight)) : i += 1 If i < s_clients.Count Then PrintLabel(s_clients(i), g, New RectangleF(hmargin + _labelWidth, vmargin, _labelWidth, _labelHeight)) : i += 1 End If If i < s_clients.Count Then PrintLabel(s_clients(i), g, New RectangleF(hmargin, vmargin + _labelHeight, _labelWidth, _labelHeight)) : i += 1 End If If i < s_clients.Count Then PrintLabel(s_clients(i), g, New RectangleF(hmargin + _labelWidth, vmargin + _labelHeight, _labelWidth, _labelHeight)) : i += 1 End If
'' For formats other than TIFF print just one page: If tw Is Nothing Then Exit For If i < s_clients.Count Then tw.AppendFrame(bmp) bmp.Clear(Color.White) End If Next
Select Case targetMime Case Util.MimeTypes.TIFF tw.AppendFrame(bmp) tw.Dispose() Case Util.MimeTypes.JPEG bmp.SaveAsJpeg(ms) Case Util.MimeTypes.PNG bmp.SaveAsPng(ms) Case Util.MimeTypes.BMP bmp.SaveAsBmp(ms) Case Util.MimeTypes.GIF bmp.SaveAsGif(ms) Case Util.MimeTypes.WEBP bmp.SaveAsWebp(ms) Case Util.MimeTypes.ICO bmp.SaveAsIco(ms, Nothing, IcoFrameEncoding.Png) Case Else Throw New Exception($"Encoding {targetMime} is not supported.") End Select
bmp.Dispose() g.Dispose() Term() Return ms End Function
'' Consts and vars used to render the labels: Const hmargin As Single = 24, vmargin As Single = 36 Dim _labelWidth As Single, _labelHeight As Single Dim _pBold As GCDRAW.Pen, _pNorm As GCDRAW.Pen Dim _fontReg As GCTEXT.Font, _fontBold As GCTEXT.Font Dim _tfSmall As TextFormat, _tfSmallB As TextFormat, _tfLarge As TextFormat Dim _tsHeader As List(Of TabStop), _tsFrom As List(Of TabStop), _tsCodes As List(Of TabStop) Dim _logo As GCDRAW.Image Dim _ia As ImageAlign Dim bcTop As GcBarcode, bcBottom As GcBarcode
'' Init variables used to render labels: Sub Init(pixelSize As Size) _labelWidth = (pixelSize.Width - hmargin * 2) / 2 _labelHeight = _labelWidth _pBold = New GCDRAW.Pen(Color.Black, 2) _pNorm = New GCDRAW.Pen(Color.Black, 0.5F) _logo = GCDRAW.Image.FromFile(Path.Combine("Resources", "ImagesBis", "AcmeLogo-vertical-250px.png")) _fontReg = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf")) _fontBold = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Bold.ttf")) _tfSmall = New TextFormat() With {.Font = _fontReg, .FontSize = 9} _tfSmallB = New TextFormat() With {.Font = _fontBold, .FontSize = 10} _tfLarge = New TextFormat() With {.Font = _fontBold, .FontSize = 17}
_ia = New ImageAlign(ImageAlignHorz.Right, ImageAlignVert.Center, True, True, True, False, False) _tsHeader = New List(Of TabStop) From {New TabStop(24, TabStopAlignment.Leading), New TabStop(108, TabStopAlignment.Leading)} _tsFrom = New List(Of TabStop) From {New TabStop(12, TabStopAlignment.Leading), New TabStop(72, TabStopAlignment.Leading)} _tsCodes = New List(Of TabStop) From {New TabStop(_labelWidth / 8, TabStopAlignment.Center)}
bcTop = New GcBarcode() With { .TextFormat = _tfSmall, .CodeType = CodeType.Code_128_B, .HorizontalAlignment = ImageAlignHorz.Center, .VerticalAlignment = ImageAlignVert.Center, .ScaleFactor = 2 } bcTop.Options.CaptionPosition = BarCodeCaptionPosition.Below
bcBottom = New GcBarcode() With { .TextFormat = _tfSmall, .CodeType = CodeType.Code_128auto, .HorizontalAlignment = ImageAlignHorz.Center, .VerticalAlignment = ImageAlignVert.Center, .ScaleFactor = 2 } bcBottom.Options.CaptionPosition = BarCodeCaptionPosition.Below End Sub
Sub Term() If _logo IsNot Nothing Then _logo.Dispose() _logo = Nothing End Sub
Sub PrintLabel(client As Client, g As GcGraphics, bounds As RectangleF) '' Used to randomize some sample data: Dim rnd = Util.NewRandom()
'' Sample shipper/sender data: Dim shipper = If(rnd.Next(2) = 0, "United Package", "Speedy Express") Dim sender = (name:="ACME Inc.", addr:="1 Main Street", city:="Metropolis", country:="USA", zip:="34567") Dim shuttle = rnd.Next(10000, 15000).ToString() Dim area = rnd.Next(1, 12).ToString() Dim tour = rnd.Next(0, 20).ToString()
Dim tl = g.CreateTextLayout() tl.DefaultFormat.Font = _tfSmall.Font tl.DefaultFormat.FontSize = _tfSmall.FontSize tl.LineSpacingScaleFactor = 0.75F tl.ParagraphAlignment = ParagraphAlignment.Center
'' Header Dim hHeader = bounds.Height / 2 / 5 Dim rHeader = New RectangleF(bounds.X, bounds.Y, bounds.Width, hHeader) tl.TabStops = _tsHeader tl.Append(vbTab & shipper) tl.Append(vbTab & "CMR", _tfSmallB) tl.Append(vbLf & vbTab & vbTab & Util.TimeNow().ToString("dd-MMM-yy", CultureInfo.InvariantCulture)) tl.MaxHeight = rHeader.Height tl.MaxWidth = rHeader.Width tl.PerformLayout(True) g.DrawTextLayout(tl, rHeader.Location)
Dim rLogo = rHeader rLogo.Inflate(-5, -5) g.DrawImage(_logo, rLogo, Nothing, _ia)
'' From Dim hFrom = hHeader Dim rFrom = New RectangleF(bounds.X, rHeader.Bottom, bounds.Width, hFrom) tl.Clear() tl.TabStops = _tsFrom tl.Append(vbTab & "From:" & vbTab & sender.name & vbLf & vbTab & vbTab & sender.addr & vbLf & vbTab & vbTab & $"{sender.city}, {sender.country} {sender.zip}") tl.MaxHeight = rFrom.Height tl.MaxWidth = rFrom.Width tl.PerformLayout(True) g.DrawTextLayout(tl, rFrom.Location)
'' To Dim hTo = bounds.Height / 2 / 3 Dim rTo = New RectangleF(bounds.X, rFrom.Bottom, bounds.Width, hTo) tl.Clear() tl.TabStops = _tsFrom tl.Append(vbTab & "To:" & vbTab & client.Name & vbLf & vbTab & vbTab & client.Addr & vbLf & vbTab & vbTab & client.City & vbLf & vbTab & vbTab & client.Country) tl.MaxHeight = rTo.Height tl.MaxWidth = rTo.Width tl.PerformLayout(True) g.DrawTextLayout(tl, rTo.Location)
'' Codes Dim hCodes = bounds.Height / 2 / (15.0F / 4.0F) Dim rCodes = New RectangleF(bounds.X, rTo.Bottom, bounds.Width, hCodes) tl.TabStops = _tsCodes
tl.Clear() tl.AppendLine(vbTab & "Shuttle") tl.Append(vbTab & shuttle, _tfLarge) tl.MaxHeight = rCodes.Height tl.MaxWidth = rCodes.Width / 4.0F tl.PerformLayout(True) g.DrawTextLayout(tl, rCodes.Location)
tl.Clear() tl.AppendLine(vbTab & "Area") tl.Append(vbTab & area, _tfLarge) tl.PerformLayout(True) g.DrawTextLayout(tl, New PointF(rCodes.X + rCodes.Width / 4.0F, rCodes.Y))
tl.Clear() tl.AppendLine(vbTab & "Exception") tl.Append(vbTab & " ", _tfLarge) tl.PerformLayout(True) g.DrawTextLayout(tl, New PointF(rCodes.X + rCodes.Width / 4.0F * 2.0F, rCodes.Y))
tl.Clear() tl.AppendLine(vbTab & "Tour") tl.Append(vbTab & tour, _tfLarge) tl.PerformLayout(True) g.DrawTextLayout(tl, New PointF(rCodes.X + rCodes.Width / 4.0F * 3.0F, rCodes.Y))
'' Barcodes Dim hBarcodes = bounds.Height / 2.0F Dim rBcTop = New RectangleF(bounds.X, rCodes.Bottom, bounds.Width, hBarcodes / 2.0F) Dim rBcBottom = New RectangleF(bounds.X, rBcTop.Bottom, bounds.Width, hBarcodes / 2.0F)
bcTop.Text = client.Country g.DrawBarcode(bcTop, rBcTop)
'' Make up a longish "code": Dim code = $"{Char.ToUpper(client.Name(0))}{Char.ToUpper(client.Addr(0))}{Char.ToUpper(client.City(0))}{Char.ToUpper(client.Country(0))}" bcBottom.Text = $"{code}{client.GetHashCode().ToString("X12")}" g.DrawBarcode(bcBottom, rBcBottom)
'' Lines: g.DrawLine(rHeader.Left, rHeader.Bottom, rHeader.Right, rHeader.Bottom, _pNorm) g.DrawLine(rFrom.Left, rFrom.Bottom, rFrom.Right, rFrom.Bottom, _pNorm) g.DrawLine(rTo.Left, rTo.Bottom, rTo.Right, rTo.Bottom, _pNorm) g.DrawLine(rCodes.Left, rCodes.Bottom, rCodes.Right, rCodes.Bottom, _pNorm)
g.DrawLine(rCodes.Left + rCodes.Width / 4.0F, rCodes.Top, rCodes.Left + rCodes.Width / 4.0F, rCodes.Bottom, _pNorm) g.DrawLine(rCodes.Left + rCodes.Width / 4.0F * 2.0F, rCodes.Top, rCodes.Left + rCodes.Width / 4.0F * 2.0F, rCodes.Bottom, _pNorm) g.DrawLine(rCodes.Left + rCodes.Width / 4.0F * 3.0F, rCodes.Top, rCodes.Left + rCodes.Width / 4.0F * 3.0F, rCodes.Bottom, _pNorm)
g.DrawRectangle(bounds, _pBold) End SubEnd Class