Solved

Printing in non standard page format from VB.net

Posted on 2008-06-11
7
1,720 Views
Last Modified: 2008-07-24
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

0
Comment
Question by:Paybit
  • 3
  • 2
7 Comments
 
LVL 27

Expert Comment

by:planocz
ID: 21770453
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

0
 

Author Comment

by:Paybit
ID: 21776479
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...
0
 
LVL 27

Expert Comment

by:planocz
ID: 21778178
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

0
 

Author Comment

by:Paybit
ID: 21800713
That just prints xls's in a directory.
It doesn't change the printer settings...
0
 
LVL 27

Accepted Solution

by:
planocz earned 500 total points
ID: 21802930
Add this to a button_click for pageset
  Private WithEvents mDoc As New PrintDocument()

 Dim dlg As New PageSetupDialog()
        dlg.Document = mDoc
        dlg.AllowMargins = True
        dlg.AllowOrientation = True
        dlg.AllowPaper = True
        dlg.AllowPrinter = True
        dlg.ShowDialog()
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now