Issue
I tried printing from HTML and CSS on a printer with the program language vb.net.
Please Guide Me
one more I want to add QR in footer section
This My code :
Public Class Form1
Private Function ToHtml() As String
Dim Pathimageheader As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logo.png")
Dim Pathimagefooter As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Qr.png")
Dim html =
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Receipt example</title>
<link rel="stylesheet" href="style.css"/>
</head>
<style>
{
font-size: 12px;
font-family: 'Times New Roman';
}
td,
th,
tr,
table {
border-top: 1px solid black;
border-collapse: collapse;
}
td.description,
th.description {
width: 75px;
max-width: 75px;
}
td.quantity,
th.quantity {
width: 40px;
max-width: 40px;
word-break: break-all;
}
td.price,
th.price {
width: 40px;
max-width: 40px;
word-break: break-all;
}
.centered {
text-align: center;
align-content: center;
}
.ticket {
width: 155px;
max-width: 155px;
}
img {
max-width: inherit;
width: inherit;
}
</style>
<body>
<div class="ticket">
<img src=<%= Pathimageheader %> alt="logo"></img>
<p class="centered">RECEIPT EXAMPLE
<br>Address line 1
</br><br>Address line2</br></p>
<table>
<thead>
<tr>
<th class="quantity">Q.</th>
<th class="description">Description</th>
<th class="price">$$</th>
</tr>
</thead>
<tbody>
<tr>
<td class="quantity">1.00</td>
<td class="description">ARDUINO UNO R3</td>
<td class="price">$25.00</td>
</tr>
<tr>
<td class="quantity">2.00</td>
<td class="description">JAVASCRIPT BOOK</td>
<td class="price">$10.00</td>
</tr>
<tr>
<td class="quantity">1.00</td>
<td class="description">STICKER PACK</td>
<td class="price">$10.00</td>
</tr>
<tr>
<td class="quantity"></td>
<td class="description">TOTAL</td>
<td class="price">$55.00</td>
</tr>
</tbody>
</table>
<p class="centered">Thanks for your purchase!
<br>parzibyte.me/blog</br></p>
<img src=<%= Pathimagefooter %> alt="logo"></img>
</div>
</body>
</html>
Return html.ToString()
End Function
Private Sub BtnPrint_Click(sender As Object, e As EventArgs) Handles BtnPrint.Click
myWebBrowser.DocumentText = ToHtml()
End Sub
Private Sub myWebBrowser_DocumentCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs) Handles myWebBrowser.DocumentCompleted
myWebBrowser.Parent = Me
myWebBrowser.Visible = False
myWebBrowser.ShowPrintPreviewDialog()
End Sub
Desired result (without botton)
sorry I can't post the original html and css code because of an error at the time of posting but below is the link of the html and css code
result after update code
RESULT AFTER UPDATE CODE LATEST
print screen dialog
Solution
The WebBrowser control is quite old and may not support some of the newer styling. You may consider using the WebView2 control instead. Also, it appears that you've included style information twice - once as a link to a Style Sheet, and a second time in the HTML.
The following shows how to use JavaScript, CSS, and HTML to create a receipt in VB.NET. It's an implementation of the code referenced in the OP - Print receipt in thermal printer using JavaScript, CSS & HTML. The code below uses NuGet package WebView2 to display the receipt. See the comments throughout the code for more information.
VS 2022:
Create a new Windows Forms App (.NET Framework) project
Open Solution Explorer
- In VS menu, click View
- Select Solution Explorer
Download/install NuGet package: Microsoft.Web.WebView2
- In Solution Explorer, right-click <project name> and select Manage NuGet Packages...
- Click Browse tab
- Search for Microsoft.Web.WebView2
- Click Install
Create Templates folder
- In Solution Explorer, right-click <project name>
- Select Add
- Select New Folder...
- Rename folder: Templates
Open Properties Window
- In VS menu, click View
- Select Properties Window
Add logo image to Templates folder: (name: logo.png)
- In Solution Explorer, right-click Templates
- Select Add
- Select Existing Item...
- In the drop-down (lower-right) change the filter to Image Files(...) and select your logo image (ex: logo.png)
- In Solution Explorer, under the Templates folder, select the logo image (ex: logo.png)
- In the Properties Window, set Build Action: Content and Copy to Output Directory: Copy Always
Add QR code image to Templates folder: (name: qrCode.jpg)
- In Solution Explorer, right-click Templates
- Select Add
- Select Existing Item...
- In the drop-down (lower-right) change the filter to Image Files(...) and select your logo image (ex: qrCode.jpg)
- In Solution Explorer, under the Templates folder, select the QR code image (ex: qrCode.jpg)
- In the Properties Window, set Build Action: Content and Copy to Output Directory: Copy Always
Note: If you'd like to generate a QR code programmatically, see this post.
Add Style Sheet to Templates folder: (name: style.css)
- In Solution Explorer, right-click Templates
- Select Add
- Select New Item...
- On left side expand Common Items. Then click Web.
- Select Style Sheet (name: style.css)
- In the Properties Window, set Build Action: Content and Copy to Output Directory: Copy Always
style.css:
* {
font-size: 12px;
font-family: 'Times New Roman';
}
td,
th,
tr,
table {
border-top: 1px solid black;
border-collapse: collapse;
}
td.description,
th.description {
width: 75px;
max-width: 75px;
}
td.quantity,
th.quantity {
width: 40px;
max-width: 40px;
word-break: break-all;
}
td.price,
th.price {
width: 40px;
max-width: 40px;
word-break: break-all;
}
.centered {
text-align: center;
align-content: center;
}
.ticket {
width: 155px;
max-width: 155px;
}
img {
max-width: inherit;
width: inherit;
}
@media print {
.hidden-print,
.hidden-print * {
display: none !important;
}
}
Add JavaScript file to Templates folder: (name: printReceipt.js)
- In Solution Explorer, right-click Templates
- Select Add
- Select New Item...
- On left side expand Common Items. Then click Web.
- Select JavaScript File (name: printReceipt.js)
- In the Properties Window, set Build Action: Content and Copy to Output Directory: Copy Always
printReceipt.js:
const $btnPrint = document.querySelector("#btnPrint");
$btnPrint.addEventListener("click", () => {
window.print();
});
Add receipt.html to Templates folder:
- In Solution Explorer, right-click Templates
- Select Add
- Select New Item...
- On left side expand Common Items. Then click Web.
- Select HTML Page (name: receipt.html)
- In the Properties Window, set Build Action: Content and Copy to Output Directory: Copy Always
Note: In the HTML, I've removed the table data, and replaced it with a placeholder ("rowsPlaceHolder"). In VB.NET, we'll generate the HTML that goes here, and replace "rowsPlaceHolder" with the HTML. The paths for the style sheet and JavaScript file are relative to this HTML file, so either change the paths as necessary, or ensure that the HTML file is in the same folder as the style sheet (.css) and JavaScript file (.js).
receipt.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Receipt example</title>
</head>
<body>
<div class="ticket">
<img src="./logo.png" alt="Logo">
<p class="centered">
RECEIPT EXAMPLE
<br>Address line 1
<br>Address line 2
</p>
<table>
<thead>
<tr>
<th class="quantity">Q.</th>
<th class="description">Description</th>
<th class="price">$$</th>
</tr>
</thead>
<tbody>
rowsPlaceHolder
</tbody>
</table>
<p class="centered">
Thanks for your purchase!
<br />
<img src="qrCode.jpg" alt="QRCode" />
</p>
</div>
<button id="btnPrint" class="hidden-print">Print</button>
<script src="printReceipt.js"></script>
</body>
</html>
In Solution Explorer, you should see the following:
Add a Form to the project (name: FrmReceipt.vb)
Note: This form will host the WebView2 browser control which will display the receipt.
- In Solution Explorer, right-click <project name>
- Select Add
- Select New Item...
- On left side click Common Items.
- Select Form (Windows Form) (name: FrmReceipt.vb)
- Double-click the form to add the Load event handler
- Resize the form as desired
Open the Toolbox
- In VS menu, select View
- Select Toolbox
Add WebView2 to FrmReceipt (name: webView21)
- In Solution Explorer, right-click FrmReceipt.vb and select View Designer.
- In the Toolbox, scroll to the top and expand WebView2 Windows Forms Control
- Drag WebView2 control onto FrmReceipt
- On the form, click the WebView2 control to select it
- In the Properties Window, set Dock: Fill
FrmReceipt.vb:
Note: In the code below, you'll notice that the async keyword has been added to the Load event handler.
Imports Microsoft.Web.WebView2.WinForms
Public Class FrmReceipt
Private appTempFolder As String = String.Empty
Private receiptFilename As String = String.Empty
Public Sub New(receiptFilename As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.receiptFilename = receiptFilename
'set value
appTempFolder = System.IO.Path.GetDirectoryName(receiptFilename)
Debug.WriteLine($"FrmReceipt appTempFolder: {appTempFolder}")
End Sub
Private Async Sub FrmReceipt_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.WriteLine($"WebView2 version: {GetWebView2Version()}")
'set UserDataFolder
WebView21.CreationProperties = New CoreWebView2CreationProperties() With {.UserDataFolder = appTempFolder}
'explicitly initialize CoreWebView2
Await WebView21.EnsureCoreWebView2Async()
'display receipt
WebView21.Source = New Uri($"file:///{receiptFilename}")
End Sub
Public Function GetWebView2Version() As String
Dim webView2Assembly As System.Reflection.Assembly = GetType(WebView2).Assembly
Return FileVersionInfo.GetVersionInfo(webView2Assembly.Location).ProductVersion
End Function
End Class
One can use the following to generate the receipt:
Note: The code below will go in the main form (ex: Form1.vb). If desired one can rename Form1.vb to something such as FrmMain.vb.
Private appTempFolder As String = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetExecutingAssembly().Location))
Private templatesFolder As String = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Templates")
Private addressLine1 As String = "123 Walnut Street"
Private addressLine2 As String = "Some City, ABC 12345"
Private Sub CreateReceipt()
'for testing, we'll create a folder in the user's temp folder
If Not System.IO.Directory.Exists(appTempFolder) Then
System.IO.Directory.CreateDirectory(appTempFolder)
End If
'copy the following files so that they exist in the same folder as the .html file
System.IO.File.Copy(System.IO.Path.Combine(templatesFolder, "logo.png"), System.IO.Path.Combine(appTempFolder, "logo.png"), True)
System.IO.File.Copy(System.IO.Path.Combine(templatesFolder, "printReceipt.js"), System.IO.Path.Combine(appTempFolder, "printReceipt.js"), True)
System.IO.File.Copy(System.IO.Path.Combine(templatesFolder, "qrCode.jpg"), System.IO.Path.Combine(appTempFolder, "qrCode.jpg"), True)
System.IO.File.Copy(System.IO.Path.Combine(templatesFolder, "style.css"), System.IO.Path.Combine(appTempFolder, "style.css"), True)
'get data
'here a method is used to generate test data
'but one could get data from a database instead
Dim dt As DataTable = CreateTestData()
'HTML filename
Dim receiptFilename As String = System.IO.Path.Combine(appTempFolder, "receipt.html")
'generate HTML and save to file
GenerateHtml(dt, receiptFilename)
'display receipt
Dim receipt As FrmReceipt = New FrmReceipt(receiptFilename)
receipt.Show()
End Sub
Private Function CreateTestData() As DataTable
'create new instance
Dim dt As DataTable = New DataTable("Items")
'Add column: Qty
Dim quantity As DataColumn = New DataColumn() With {.ColumnName = "Qty", .DataType = GetType(Double)}
dt.Columns.Add(quantity)
'Add column: Description
Dim description As DataColumn = New DataColumn() With {.ColumnName = "Description", .DataType = GetType(String)}
dt.Columns.Add(description)
'Add column: Price
Dim price As DataColumn = New DataColumn() With {.ColumnName = "Price", .DataType = GetType(Decimal)}
dt.Columns.Add(price)
Dim row As DataRow = Nothing
row = dt.NewRow() 'create new row
row("Qty") = 1
row("Description") = "ARDUINO UNO R3"
row("Price") = 25
dt.Rows.Add(row) 'add to DataTable
row = dt.NewRow() 'create new row
row("Qty") = 2
row("Description") = "JAVASCRIPT BOOK"
row("Price") = 10
dt.Rows.Add(row) 'add to DataTable
row = dt.NewRow() 'create new row
row("Qty") = 2
row("Description") = "JAVASCRIPT BOOK"
row("Price") = 10
dt.Rows.Add(row) 'add to DataTable
row = dt.NewRow() 'create new row
row("Qty") = 1
row("Description") = "STICKER PACK"
row("Price") = 10
dt.Rows.Add(row) 'add to DataTable
Return dt
End Function
Private Sub GenerateHtml(dt As DataTable, outputFilename As String)
'get HTML from template
Dim html As String = File.ReadAllText(System.IO.Path.Combine(templatesFolder, "receipt.html"))
Dim itemsHtml As StringBuilder = New StringBuilder()
Dim total As Decimal = 0
'create HTML for each item
For i As Integer = 0 To dt.Rows.Count - 1
'create HTML for each row
itemsHtml.AppendFormat($"{Space(16)}<tr>{System.Environment.NewLine}")
'convert to double
Dim quantity As Double = 0
Double.TryParse(dt(i)("Qty").ToString(), quantity)
'convert to decimal
Dim price As Decimal = 0
Decimal.TryParse(dt(i)("Price").ToString(), price)
'add data to table column
itemsHtml.AppendFormat($"{Space(20)}<td class = ""quantity"">{quantity.ToString("N2")}</td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(20)}<td class = ""description"">{dt(i)("Description")}</td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(20)}<td class = ""price"">{price.ToString("N2")}</td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(16)}</tr>{System.Environment.NewLine}")
'add
total += price
Next
'add HTML for Total
itemsHtml.AppendFormat($"{Space(16)}<tr>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(20)}<td class = ""quantity""></td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(20)}<td class = ""description"">TOTAL</td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(20)}<td class = ""price"">${total.ToString("N2")}</td>{System.Environment.NewLine}")
itemsHtml.AppendFormat($"{Space(16)}</tr>{System.Environment.NewLine}")
'replace address
html = html.Replace("Address line 1", addressLine1)
html = html.Replace("Address line 2", addressLine2)
'replace place holder with HTML for items
html = html.Replace("rowsPlaceHolder", itemsHtml.ToString())
'save
System.IO.File.WriteAllText(outputFilename, html)
End Sub
Private Function Space(numSpaces As Integer) As String
Return New String(" ", numSpaces)
End Function
Usage:
CreateReceipt()
Update:
If one needs to adjust the size of an image, one can use MS Paint to resize the image prior to adding it to the Templates folder or one can use the width and height properties of the img tag in the HTML to specify the desired size. When setting these properties in the HTML, the width and height should be less than or equal to the width and height of the image.
<img src="qrCode.jpg" alt="QRCode" width="75" height="75" />
Answered By - user246821
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.