Link to home
Start Free TrialLog in
Avatar of Paybit
Paybit

asked on

Printing in non standard page format from VB.net

Hi,

I'm trying to print  a report (from MS reporting service) on a continous piece of paper.
I have a printer that can print continous paper an cut's the paper when he's done(at end of page).

So I'm using reporting services to generate my report (which is variable in length)
When I print from reporting services I get 2 A4 sized papers (test report is 1.5 A4 pages long)
When I export to excel I get an excel file. When I set my printers print length to 1.5A4 (+-45cm) (in the printer properties) I can print the excel on 1 page that is 45cm long.

So the goal is to print the report from vb.net code.

From code I can export the report to excel (using the reporting webservice)
And I can print the excel to the printer, bu I can't change the print length while printing the excel.

I can however change the print length using the printdocument from vb.net (see attached code)

But I can't combine the 2. So I'm unable to print the excel using printdocument.

And I can't manualy create the report using graphics in the printdocument.printpage event because the report contains barcodes and those are hard to draw (+ this is to much coding)

I've been searching to print the xls to an image and print the image in the printdocument.printpage event, but the xls to image (from code) is still a problem...

So any ideas? tia

m_PrintDocument.PrinterSettings = printerSetting
Dim pk as New PaperSize("cstm",670,1850)
Dim intIdx As Integer
 
For intIdx = 0 To m_PrintDocument.PrinterSettings.PaperSizes.Count - 1 Step 1
    If m_PrintDocument.PrinterSettings.PaperSizes(intIdx).Kind = Printing.PaperKind.Custom Then
        pk.RawKind = m_PrintDocument.PrinterSettings.PaperSizes(intIdx).RawKind
        m_PrintDocument.DefaultPageSettings.PaperSize = pk
    End If
Next
m_PrintDocument.Print()

Open in new window

Avatar of Howard Cantrell
Howard Cantrell
Flag of United States of America image

I am not sure what you are looking for.
1. a report to print to excel
2. a barcade print

Here is a simple barcode sample.
One FORM CLASS
one CLASS
you will need to download the free TTF barcode files from the internet.
'FORM 1
Imports System.Drawing.Printing
Public Class Form1
    Inherits System.Windows.Forms.Form
    Private WithEvents BarcodeDoc As BarcodingParts.TextPrint
 
#Region " Windows Form Designer generated code "
 
    Public Sub New()
        MyBase.New()
 
        'This call is required by the Windows Form Designer.
        InitializeComponent()
 
        'Add any initialization after the InitializeComponent() call
 
    End Sub
 
    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
 
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
 
    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents PrintDocument1 As System.Drawing.Printing.PrintDocument
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents PrintPreviewDialog1 As System.Windows.Forms.PrintPreviewDialog
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(Form1))
        Me.PrintDocument1 = New System.Drawing.Printing.PrintDocument
        Me.Button1 = New System.Windows.Forms.Button
        Me.PrintPreviewDialog1 = New System.Windows.Forms.PrintPreviewDialog
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(196, 224)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        '
        'PrintPreviewDialog1
        '
        Me.PrintPreviewDialog1.AutoScrollMargin = New System.Drawing.Size(0, 0)
        Me.PrintPreviewDialog1.AutoScrollMinSize = New System.Drawing.Size(0, 0)
        Me.PrintPreviewDialog1.ClientSize = New System.Drawing.Size(400, 300)
        Me.PrintPreviewDialog1.Enabled = True
        Me.PrintPreviewDialog1.Icon = CType(resources.GetObject("PrintPreviewDialog1.Icon"), System.Drawing.Icon)
        Me.PrintPreviewDialog1.Location = New System.Drawing.Point(132, 132)
        Me.PrintPreviewDialog1.MinimumSize = New System.Drawing.Size(375, 250)
        Me.PrintPreviewDialog1.Name = "PrintPreviewDialog1"
        Me.PrintPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty
        Me.PrintPreviewDialog1.Visible = False
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
 
    End Sub
 
#End Region
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        BarcodeDoc = New BarcodingParts.TextPrint("*00417955*", "Here is Second line")
        BarcodeDoc.Font = New Font("FREE 3 OF 9", 30) '<---- Free Font on the internet or add your own
        'For Pre-veiw Printing
        PrintPreviewDialog1.Document = BarcodeDoc
        PrintPreviewDialog1.ShowDialog()
 
        'For Direct Printing
        Dim PrintDialog1 As New PrintDialog
        'PrintDialog1.Document = BarcodeDoc
        'PrintDocument1.Print()
    End Sub
    Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        BarcodeDoc.PrinterSettings.PrinterName = InitializeDefaultPrinter() '"Zebra"
        BarcodeDoc.DefaultPageSettings.Margins.Left = 10
        BarcodeDoc.DefaultPageSettings.Margins.Right = 10
        BarcodeDoc.DefaultPageSettings.Margins.Top = 40
    End Sub
#Region " Initialize Default Printer "
    Public Function InitializeDefaultPrinter()
        ' Set the specified printer to the default printer for this program. Return
        ' true if the printer was found.
 
        Dim objprinter As PageSettings = New PageSettings
        Dim strname = objprinter.PrinterSettings.PrinterName
 
        InitializeDefaultPrinter = strname
    End Function
#End Region
End Class
 
'CLASS
Imports System.Drawing.Graphics
Public Class TextPrint
    ' Inherits all the functionality of a PrintDocument
    Inherits Printing.PrintDocument
    ' Private variables to hold default font and text
    Private fntPrintFont As Font
    Private strText As String
    Private strText2 As String
    Private PrintBarCodeText As String
    Public Sub New(ByVal Text As String, ByVal Text2 As String)
        ' Sets the file stream
        MyBase.New()
        strText = Text
        strText2 = Text2
    End Sub
    Public Property Text() As String
        Get
            Return strText
        End Get
        Set(ByVal Value As String)
            strText = Value
        End Set
    End Property
    Public Property Text2() As String
        Get
            Return Trim(strText2)
        End Get
        Set(ByVal Value As String)
            strText2 = Trim(Value)
        End Set
    End Property
    Public Property CodeText() As String
        Get
            PrintBarCodeText = Trim(Replace(strText, "*", " "))
            Return PrintBarCodeText
        End Get
        Set(ByVal Value As String)
            If PrintBarCodeText = "" Then
                PrintBarCodeText = Trim(Replace(Value, "*", " "))
            End If
            PrintBarCodeText = Value
        End Set
    End Property
    Protected Overrides Sub OnBeginPrint(ByVal ev As Printing.PrintEventArgs)
        ' Run base code
        MyBase.OnBeginPrint(ev)
        ' Sets the default font
        If fntPrintFont Is Nothing Then
            fntPrintFont = New Font("Times New Roman", 12)
        End If
    End Sub
    Public Property Font() As Font
        ' Allows the user to override the default font
        Get
            Return fntPrintFont
        End Get
        Set(ByVal Value As Font)
            fntPrintFont = Value
        End Set
    End Property
    Protected Overrides Sub OnPrintPage(ByVal ev As Printing.PrintPageEventArgs)
        ' Provides the print logic for our document
 
        ' Run base code
        MyBase.OnPrintPage(ev)
        ' Variables
        Static intCurrentChar As Integer
        Dim intPrintAreaHeight, intPrintAreaWidth, intMarginLeft, intMarginTop As Integer
        ' Set printing area boundaries and margin coordinates
        With MyBase.DefaultPageSettings
            intPrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
            intPrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
            intMarginLeft = .Margins.Left 'X
            intMarginTop = .Margins.Top   'Y
        End With
        ' If Landscape set, swap printing height/width
        If MyBase.DefaultPageSettings.Landscape Then
            Dim intTemp As Integer
            intTemp = intPrintAreaHeight
            intPrintAreaHeight = intPrintAreaWidth
            intPrintAreaWidth = intTemp
        End If
        ' Calculate total number of lines
        Dim intLineCount As Int32 = CInt(intPrintAreaHeight / Font.Height)
        ' Initialise rectangle printing area
        Dim rectPrintingArea As New RectangleF(intMarginLeft, intMarginTop, intPrintAreaWidth, intPrintAreaHeight)
        ' Initialise StringFormat class, for text layout
        Dim objSF As New StringFormat(StringFormatFlags.LineLimit)
        ' Figure out how many lines will fit into rectangle
        Dim intLinesFilled, intCharsFitted As Int32
        Dim stringSize As New SizeF
        stringSize = ev.Graphics.MeasureString(Mid(strText, _
                    UpgradeZeros(intCurrentChar)), Font, New SizeF(intPrintAreaWidth, _
                    intPrintAreaHeight), objSF, intCharsFitted, intLinesFilled)
        ' Print the text to the page
        ev.Graphics.DrawString(Mid(strText, _
            UpgradeZeros(intCurrentChar)), Font, Brushes.Black, rectPrintingArea, objSF)
 
        ' Initialise rectangle printing area for the Barcode Text
        Dim stringFont As New Font("Arial", 12, FontStyle.Bold)
        Dim size As SizeF = ev.Graphics.MeasureString(CodeText, stringFont)
        Dim size2 As SizeF = ev.Graphics.MeasureString(strText2, stringFont)
        Dim BCPrintingArea As New RectangleF(stringSize.Width - size.Width / 2, intMarginTop + stringSize.Height, intPrintAreaWidth, intPrintAreaHeight)
 
        'Move Second line to center
        Dim moveStr As Integer
        moveStr = stringSize.Width - size2.Width / 2
        moveStr = intMarginLeft + (moveStr / intMarginLeft)
        Dim BCPrintingArea2 As New RectangleF(moveStr, intMarginTop + stringSize.Height + size2.Height, intPrintAreaWidth, intPrintAreaHeight)
 
        'ADD text Bottom of Barcode
        ev.Graphics.DrawString(CodeText, stringFont, Brushes.Black, BCPrintingArea)
        ev.Graphics.DrawString(strText2, stringFont, Brushes.Black, BCPrintingArea2)
 
        ' Increase current char count
        intCurrentChar += intCharsFitted
        ' Check whether we need to print more
        If intCurrentChar < strText.Length Then
            ev.HasMorePages = True
        Else
            ev.HasMorePages = False
            intCurrentChar = 0
        End If
    End Sub
    Public Function UpgradeZeros(ByVal Input As Integer) As Integer
        ' Upgrades all zeros to ones
        ' - used as opposed to defunct IIF or messy If statements
        If Input = 0 Then
            Return 1
        Else
            Return Input
        End If
    End Function
 
End Class

Open in new window

Avatar of Paybit
Paybit

ASKER

I can export from Windows Reporting Services to Excel.

Im looking for:
Either a way to print the generated excel using the .net printdocument class (I need this class to set print length)
Or another way to get the report to the printer that enables me to set the print length.

I could manually draw the report (using graphics.drawstring) in the prindocument.printpage class, but this would be a lot of work, and hard to maintain the report, and it would be a thing that has to be done for all reports that go onto that printer...
I have this code you can try....
'FORM 1
Public Class Form1
    Inherits System.Windows.Forms.Form
 
#Region " Windows Form Designer generated code "
 
    Public Sub New()
        MyBase.New()
 
        'This call is required by the Windows Form Designer.
        InitializeComponent()
 
        'Add any initialization after the InitializeComponent() call
 
    End Sub
 
    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
 
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
 
    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(104, 12)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(72, 24)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Read Excel"
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(196, 12)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(72, 24)
        Me.Button2.TabIndex = 1
        Me.Button2.Text = "Exit"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(284, 264)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)
 
    End Sub
 
#End Region
 
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        PrintReports()
    End Sub
    Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        Me.Close()
    End Sub
End Class
 
'MODULE
Imports System.IO
Imports Microsoft.Win32
Imports System.Drawing.Printing
 
Module modPrintExcel
    Public Declare Unicode Function GetTickCount32 Lib "Kernel32" Alias "GetTickCount" () As Integer
    Public sReader = "C:\Program Files\Microsoft Office\Office\Excel.exe"          '<----change to your Excel Directory
 
    Public Function InitializeDefaultPrinter()
        ' Set the specified printer to the default printer for this program. Return
        ' true if the printer was found.
 
        Dim objprinter As PageSettings = New PageSettings
        Dim strname = objprinter.PrinterSettings.PrinterName
 
        InitializeDefaultPrinter = strname
    End Function
    Public Sub PrintReports()
        Cursor.Current = Cursors.WaitCursor
 
        Dim regKey As RegistryKey
        Dim sPrinterDriver As String
        Dim sPrinterPort As String
        Dim myProcess As New Process
        Dim sDefaultPrinter As String
        Dim keyValue As String
 
        'To get the Printer driver...
        sDefaultPrinter = InitializeDefaultPrinter()
        'If sDefaultPrinter.StartsWith("\") Then
        '    sDefaultPrinter = sDefaultPrinter.Substring(2)
        'End If
        keyValue = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers\\" & sDefaultPrinter
        regKey = Registry.LocalMachine.OpenSubKey(keyValue, False)
        sPrinterDriver = regKey.GetValue("Printer Driver", 0)
        sPrinterPort = regKey.GetValue("Port", 0)
        regKey.Close()
 
        Try
            'THIS WILL PRINT ALL EXCELS IN DIRECTORY
            Dim di As New DirectoryInfo("C:\OLD D DIR\Visual Studio Projects\SerProjects\Abajo\AW_Sheets\")  '<----change to your Directory
            Dim fi As FileInfo() = di.GetFiles()
            Dim fiTemp As FileInfo
            Dim i As Short
            Dim j As Short = 20
            'Run this EXE to print files sReader = "C:\Program Files\Microsoft Office\Office\Excel.exe" 
            Dim startInfo As New ProcessStartInfo(sReader)
            startInfo.WindowStyle = ProcessWindowStyle.Hidden
            startInfo.CreateNoWindow = True
            startInfo.Verb = "Print"
 
            'CHANGE IF YOU WANT TO PRINT ALL EXCEL FILES
 
            For Each fiTemp In fi
                If fiTemp.Name = "31199049.XLS" Then   '<----- TEST FILE
                    startInfo.UseShellExecute = False
                    'startInfo.Arguments = "/t """ & fiTemp.FullName & """ """ & sDefaultPrinter & """ """ & sPrinterDriver & """ """ & sPrinterPort & """"
                    startInfo.Arguments = "/t """ & fiTemp.FullName & """"
                    myProcess.Start(startInfo)
                End If
                '
                'Use delay to wait for printer to print files in 20 file units
                'i += 1
                'Select Case i
                '    Case j
                '        delay(2000)  '2 mins.
                '        j += 30
                'End Select
            Next fiTemp
        Catch Exp As Exception
            MsgBox(Exp.Message & "   in Print Report Procedure", MsgBoxStyle.Critical, "General Error")
        End Try
        Cursor.Current = Cursors.Default
    End Sub
    Public Sub delay(ByVal msecs As Integer)
        Dim StartTime As Integer
        StartTime = GetTickCount32()
        While GetTickCount32() < StartTime + msecs
            ' do nothing
        End While
    End Sub
End Module

Open in new window

Avatar of Paybit

ASKER

That just prints xls's in a directory.
It doesn't change the printer settings...
ASKER CERTIFIED SOLUTION
Avatar of Howard Cantrell
Howard Cantrell
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial