Search code examples
vb.netdatagridviewreportprintdocument

How to print collection of ID cards in one print like Microsoft Office Publisher?


In my application I have a form which is used to create a staff id card. All is good but I am facing a problem on printing it by adding all selected id cards to a page(s). Like it is very easy to print approximately 4 landscape cards in 1 page, which can be done using both print document method as well as rdlc report. Where I used printdocument's PrintPage event to do the job and rdlc report's parameter. But both are limited to 4 cards per print. But what I want is lets say there are twenty new employees/ staffs whose ID cards are required and I want to print them all at once.

What I tried?

PrintDocument Method

Add all the ID cards to a DataGridView and then use this code on the PrintPage Event of the PrintDocument

Dim i as integer = 25
For j as Integer = 0 To dgv.rowcount - 1
   e.Graphics.DrawImage(dgv.rows(j).Cells(0).Value, 25, i, 375, 236)
   i += 241
Next
i = 25

But this can only print up to 4 cards per print. I tried to use e.HasMorePages = True but couldn't make it work to get what I want.

RDLC Report Mothod

Creating a DataSet, DS1, and adding a tables with same column name as my datagridview column name and then create a rdlc report with DataSet, DS1, and adding a table in it with only the image column to be visible.

But unfortunately this was the biggest fail in this case as it cannot even show a single picture. So I had an option to create pictures on the report and use the Parameter method to get the values from the form which again restricts me from printing more than 4 cards per print.


Solution

  • Here's an example of printing a list of items over multiple pages. In this case, it's done four to a page.

    Const ITEMS_PER_PAGE As Integer = 4
    
    Private items As List(Of Object)
    Private itemIndex As Integer
    
    Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) Handles PrintDocument1.BeginPrint
        'Start from the beginning of the list.
        itemIndex = 0
    End Sub
    
    Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        For i = 1 To ITEMS_PER_PAGE
            If itemIndex = items.Count Then
                'We're done.
                Exit For
            End If
    
            Dim item = items(itemIndex)
    
            'Print item here.
    
            itemIndex += 1
        Next
    
        'Print another page if and only if we are not at the end of the list.
        e.HasMorePages = itemIndex < items.Count
    End Sub
    

    Note that itemIndex maintains its value between invocations of the PrintPage event handler.