How to print HTML without WebBrowser control and Acrobat window? - vb.net

I know my question is not focused on a precise problem but Google ran out of results. I'm trying to make a little app in Visual Basic .Net and have a HTML string which needs to be printed to a specific printer, and the problem is that i've tried to:
write out to a HTML file then print it with a WebBrowser: the problem is that i can't print to a specific printer, only to the default one.
convert it to a PDF with htmlToPdf package but: (1) it needs Acrobat Reader AND file association in Windows, (2) it opens the Acrobat Reader which is not quite professional.
EDIT
Thanks to a solution provided by the first commenter, i've made it partially. The problem is that the first document is printed perfectly, but the next ones are printed to the first specified printer (in Devices and Printers the default printer changes but the target printer remains the first one) Here is the code:
Public Sub PrintHTML(ByVal text As String, ByVal printer As String)
Try
LogData("Changing default printer to " & printer)
Dim wtype = Type.GetTypeFromProgID("WScript.Network")
Dim instance = Activator.CreateInstance(wtype)
wtype.InvokeMember("SetDefaultPrinter", System.Reflection.BindingFlags.InvokeMethod, Nothing, instance, New Object() {printer})
Catch ex As Exception
LogData("Changing failed...")
LogData(ex.ToString)
Finally
LogData("PrintHTML Init with " & printer)
Me.wbForPrint.Navigate("about:blank")
If Not WebBrowserReadyState.Interactive = WebBrowserReadyState.Complete Then
Me.wbForPrint.Stop()
End If
Me.wbForPrint.DocumentText = text
AddHandler (Me.wbForPrint.DocumentCompleted), AddressOf HTMLDocumentCompleted
End Try
End Sub

If the printing needs to be automatic with any user input then you could use this code to change the default printer, and then restore the default printer back to what it was once you have done the printing (source: http://codesnippets.fesslersoft.de/how-to-set-the-default-printer-in-c-and-vb-net/)
Public Shared Sub SetDefaultPrinter(ByVal printername As String)
Dim type As var = Type.GetTypeFromProgID("WScript.Network")
Dim instance As var = Activator.CreateInstance(type)
type.InvokeMember("SetDefaultPrinter", System.Reflection.BindingFlags.InvokeMethod, Nothing, instance, New Object() {printername})
End Sub
Or if you want the user to choose which printer to send to, you could try:
WebBrowser1.ShowPrintPreviewDialog()
or
WebBrowser1.ShowPrintDialog()

Related

Select Printer to Print PDF file in vb.net

I have to select a printer and print a PDF file.
here i used, this code prints ONLY in the default printer.. i tired for searching and didn't find a solution.
Dim PrintPDF As New ProcessStartInfo
PrintPDF.UseShellExecute = True
PrintPDF.Verb = "print"
PrintPDF.WindowStyle = ProcessWindowStyle.Hidden
PrintPDF.FileName = "temp.pdf" 'fileName is a string parameter
Process.Start(PrintPDF)
i had done another part to find the printers in dropdown list
this code to find printer
Dim pkInstalledPrinters As String
For Each pkInstalledPrinters In PrinterSettings.InstalledPrinters
ComboBox1.Items.Add(pkInstalledPrinters)
Next pkInstalledPrinters
ComboBox1.SelectedIndex = ComboBox1.Items.Count - 1
Is there any Suggestions?
Thanks.
Try this,
I have added a web browser control in form.
add file file name of your pdf filename as follows:
WebBrowser1.naviagte(YourFileName)
Try
WebBrowser1.Print()
Catch ex As Exception
MsgBox(ex.Message)
End Try
While Doing this your app show print dialog with inbuilt option with which printer to you need to print.

How do I load the same Crystal Report twice?

For some reason I can't load this report twice in one program session. I can print it the first time without a problem. The second time I get the error:
CrystalDecisions.Shared.CrystalReportsException: Load report failed.
Here is my code for this segment.
Private Sub Print_Report()
Using CrystalReport As New ReportDocument
CrystalReport.Load("Reports\PrintMe.rpt")
CrystalReport.SetParameterValue("Code", txtCode.Text)
CrystalReport.SetParameterValue("Control", txtControl.Text)
CrystalReport.PrintOptions.PrinterName = DefaultPrinterName()
CrystalReport.PrintToPrinter(1, True, 0, 0)
End Using
End Sub
Private Function DefaultPrinterName() As String
Dim psDefault As New System.Drawing.Printing.PrinterSettings
Try
DefaultPrinterName = psDefault.PrinterName
Catch ex As System.Exception
DefaultPrinterName = ""
Finally
psDefault = Nothing
End Try
End Function
All I can think is that the file isn't being let go at the end of the first print. Am I over looking something simple?
The issues was caused by using Foxit Reader's PDF Printer. I switched to using Adobe Acrobat and the issue is now gone. I'm only using the PDF Printer for printer tests to save paper. I will be using the Export to Disk for anything PDF related.

Manipulating FedEx label in vb.net API

I am writing a FedEx API in vb.net to work with our universe database. So far everything is about done but i'm stuck on the printing label part. The code FedEx gave me saves the label image as a pdf and prints from acrobat. Problem is you can't really do anything with a pdf image, or so i'm sure of at least, meaning i can't line the image up correctly on a 4 x 6 thermal label. How would i do this or is there a good way to just use the image and assign x and y coordinates without messing up the FedEx label? here is the code from where it saves the label down to print:
Sub ShowShipmentLabels(ByRef CompletedShipmentDetail As CompletedShipmentDetail, ByRef packageDetail As CompletedPackageDetail, ByVal isCodShipment As Boolean)
If (packageDetail.Label.Parts(0).Image IsNot Nothing) Then
' Save outbound shipping label
Dim FileName As String = getProperty("labelpath") + packageDetail.TrackingIds(0).TrackingNumber + ".pdf"
SaveLabel(FileName, packageDetail.Label.Parts(0).Image)
Mylabel.Print()
' Save COD Return label
If (isCodShipment) Then
FileName = getProperty("labelpath") + CompletedShipmentDetail.CompletedPackageDetails(0).TrackingIds(0).TrackingNumber + "CR.pdf"
SaveLabel(FileName, CompletedShipmentDetail.CompletedPackageDetails(0).CodReturnDetail.Label.Parts(0).Image)
End If
End If
End Sub
Sub SaveLabel(ByRef labelFileName As String, ByRef labelBuffer() As Byte)
' Save label buffer to file
Dim LabelFile As FileStream = New FileStream(labelFileName, FileMode.Create)
LabelFile.Write(labelBuffer, 0, labelBuffer.Length)
LabelFile.Close()
' Display label in Acrobat
DisplayLabel(labelFileName)
End Sub
Sub DisplayLabel(ByRef labelFileName As String)
Dim info As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo(labelFileName)
info.UseShellExecute = True
info.CreateNoWindow = True
info.WindowStyle = ProcessWindowStyle.Hidden
info.Verb = "Print"
System.Diagnostics.Process.Start(info)
End Sub
If it looks fine on the screen, but is not aligning correctly on the printer then you should probably look to the printer settings either on the device itself or in the driver. I would with the driver, you probably need to specificy the media and maybe adjust the margins.
Chris, if this hasn't been solved yet, check out this FAQ from our database at Shippo: http://support.goshippo.com/hc/en-us/articles/203804319-My-labels-are-not-printing-correctly-How-can-I-fix-this-
Printing 4x6 can be a bit of a headache at first. If it's not yet working for you, feel free to comment with more details what printer you use and your printer settings. This would help to debug further.
You have the option to save the image in ZPLII format. Do it and save it as tracking_id.zpl.
Share the Zebra printer as FedexThermal.
Then create a print.cmd script on he fly from vb to execute...
COPY /B tracking_id.zpl \\localhost\FedexThermal
Then in vb create a process to run that script,
Works for me.

Print rdlc report without viewing print dialogue box

I have am writing a POS application, which requires to print invoice very often.
I need to send it directly to printer instead of viewing the print dialogue. Using Reportviewer_renderingcomplete, I can avoid seeing the report but I do not know how to avoid seeing the print dialogue box and print report without user intervention?
Thanks a lot.
Here is how you can do it:
Dim m_currentPageIndex As Integer
Private m_streams As IList(Of Stream)
Dim report As New LocalReport()
report.DataSources.Add(New ReportDataSource("testData", reportData.Tables(0)))
report.ReportEmbeddedResource = "ReportsLibrary.rptTestData.rdlc"
Dim deviceInfo As String = "<DeviceInfo><OutputFormat>EMF</OutputFormat><PageWidth>8.5in</PageWidth><PageHeight>11in</PageHeight><MarginTop>0.25in</MarginTop><MarginLeft>0.25in</MarginLeft><MarginRight>0.25in</MarginRight><MarginBottom>0.25in</MarginBottom></DeviceInfo>"
Dim warnings As Warning()
m_streams = New List(Of Stream)()
report.Render("Image", deviceInfo, CreateStream, warnings)
For Each stream As Stream In m_streams
stream.Position = 0
Next
Dim printDoc As New PrintDocument()
printDoc.PrinterSettings.PrinterName = "<your default printer name>"
Dim ps As New PrinterSettings()
ps.PrinterName = printDoc.PrinterSettings.PrinterName
printDoc.PrinterSettings = ps
printDoc.PrintPage += New PrintPageEventHandler(PrintPage)
m_currentPageIndex = 0
printDoc.Print()
Where PrintPage defined as follows:
' Handler for PrintPageEvents
Private Sub PrintPage(sender As Object, ev As PrintPageEventArgs)
Dim pageImage As New Metafile(m_streams(m_currentPageIndex))
' Adjust rectangular area with printer margins.
Dim adjustedRect As New Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX), ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY), ev.PageBounds.Width, ev.PageBounds.Height)
' Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect)
' Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect)
' Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex += 1
ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
End Sub
This is an interesting walkthrough by Microsoft: Printing a Local Report without Preview.
It's a different approach from yours because it prints directly a report without using ReportViewer and RenderingComplete event.
In order to not display PrintDialog box you must set printDoc.PrinterSettings.PrinterName with your default printer name.
Maybe you can store this value in a user configuration file.
It is actually far more simple than you would have imagined.
Within your form, include a "PrintDocument" component from the Toolbox.
Within your code behind, you will want to call the following method on your newly added component.
PrintDoc.Print()
The documentations state that the Print() "Starts the document's printing process". It will automatically begin printing the default set printer.
As tezzo mentioned, to set the Printer manually you can use the following snippet:
PrintDoc.PrinterSettings.PrinterName = "YourPrinterNameHere"
PrintDoc.PrinterSettings.PrinterName "gets or sets the name of the printer to use" as according to documentation. And if you need any further help, check out this video.
Please note however that video does not mention how to print "silently". It is just a good reference for beginners to see how the Print Components work together.

Print to XPS without a Save As dialog

How can I save an xps file by printing to a virtual printer without using the Save File As dialog? When I call the print method, a dialog automatically pops up asking the user to specify the file name and path. This only works when creating brand new files; it throws an error 'you do not have permission to write to that file...' if I attempt to overwrite an existing file. Anyways, I want the user to be able to specify the file name in my own dialog, not the one that is autamatically called by the printDocument's Print method.
Public Event PrintPage As System.Drawing.Printing.PrintPageEventHandler
Private WithEvents Doc As New Printing.PrintDocument
Public Sub SaveXPSFile()
Doc.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"
Doc.PrinterSettings.PrintFileName = "C:\Users\POConnell\Documents\t.xps"
Doc.Print()
Doc.Dispose()
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Doc.PrintPage
'drawing commands go here
End sub
It's a couple of months late, but here we go.
2 questions, two answers.
Question 1:
How can I save an xps file by printing to a virtual printer without using the Save File As dialog?
Answer 1: You were close. I think you're looking for
Doc.DefaultPageSettings.PrinterSettings.PrintToFile = True
Doc.DefaultPageSettings.PrinterSettings.PrintFileName = "C:\Users\POConnell\Documents\t.xps"
Here is my implementation:
(Legal paper size, landscape mode)
Using prn As New PrintDocument
With prn
.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"
AddHandler .PrintPage, _
AddressOf Me.PrintPageHandler
.DefaultPageSettings.Landscape = landscape
.DefaultPageSettings.PaperSize = New PaperSize("Legal", 850, 1400)
If My.Computer.FileSystem.FileExists("C:\temp\Log.oxps") Then My.Computer.FileSystem.DeleteFile("C:\temp\Log.oxps")
.DefaultPageSettings.PrinterSettings.PrintToFile = True
.DefaultPageSettings.PrinterSettings.PrintFileName = "C:\temp\Log.oxps"
.Print()
RemoveHandler .PrintPage, _
AddressOf Me.PrintPageHandler
End With
End Using
As you can see, I use the oxps file format, but it should still work just the same for you.
Question 2: it throws an error 'you do not have permission to write to that file...' if I attempt to overwrite an existing file.
Answer 2: Check if the file already exists prior to printing the file, and delete it if it does. Of course it will fail attempting to create a file that already exists.
For some reason using My.Computer.FileSystem.DeleteFile is faster than the traditional Kill() and System.IO.File.Delete, which both require the thread to sleep for ~1-200ms prior to recreating the file, or else a different access denied error will occur.
Hopefully this helps someone in the future!