How to save what i print as image

Viewed 36

i hope someone can help me with this problem.

so, i have a code that will print records in the data grid view and i hope to save that as image how do i make that happen, i search through the web but i dont see one that solve this problem. i even see one from stackoverflow but the approach is different.

this is the code:

        Dim addressFont As New Font(dgvWarehouse.Font.FontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel)
        Dim logoImage As Image = CType(My.Resources.ResourceManager.GetObject("logo1"), Image)
        e.Graphics.DrawImage(logoImage, CInt((e.PageBounds.Width - 800) / 2), 10, 300, 180)
        Dim companyname As String = "Sample"
        Dim address As String = "Sample"
        Dim number As String = "Sample"
        Dim email As String = "Sample"
        e.Graphics.DrawString(companyname, CompanyFont, Brushes.Black, CSng(e.PageBounds.Width - 1100 / 2), 60)
        e.Graphics.DrawString(address, addressFont, Brushes.Black, CSng(e.PageBounds.Width - 1100 / 2), 90)
        e.Graphics.DrawString(number, addressFont, Brushes.Black, CSng(e.PageBounds.Width - 1100 / 2), 105)
        e.Graphics.DrawString(email, addressFont, Brushes.Black, CSng(e.PageBounds.Width - 1100 / 2), 120)
        ''

        Dim headerFont As New Font(dgvWarehouse.Font.FontFamily, 15, FontStyle.Italic, GraphicsUnit.Pixel)
        Dim actualWidth As Integer = dgvWarehouse.Columns.Cast(Of DataGridViewColumn).Sum(Function(c) c.Width)
        Dim percentage As Decimal = CDec(((100 / actualWidth) * e.MarginBounds.Width) / 100)
        Dim header As String = "Warehouse Inventory"
        Dim footer As String
        Dim startX As Integer = e.MarginBounds.Left - 30
        Dim startY As Integer = e.MarginBounds.Top
        Dim r As Rectangle


        Dim szf As SizeF = e.Graphics.MeasureString(header, headerFont)
        e.Graphics.DrawString(header, headerFont, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - szf.Width) / 2, startY - (r.Height - 80))
        footer = "Page " & pageCounter.ToString
        szf = e.Graphics.MeasureString(footer, headerFont)
        e.Graphics.DrawString(footer, headerFont, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - szf.Width) / 2, e.MarginBounds.Bottom + 5)

        startY += 100

        ''this is the text alignment
        Dim sf As New StringFormat
        sf.Alignment = StringAlignment.Center
        sf.LineAlignment = StringAlignment.Center

        Dim gridFont As New Font(dgvWarehouse.Font.FontFamily, dgvWarehouse.Font.Size, FontStyle.Regular, GraphicsUnit.Pixel)

        '' this create the table header column
        'If startRow = 0 Then
        For x As Integer = 0 To dgvWarehouse.Columns.Count - 1
            r.X = startX
            r.Y = startY
            r.Width = CInt((dgvWarehouse.Columns(x).Width + 15) * percentage)
            r.Height = dgvWarehouse.Rows(0).Height
            dgvWarehouse.Columns(x).HeaderCell.Style.BackColor = Color.Gray
            e.Graphics.FillRectangle(New SolidBrush(dgvWarehouse.Columns(x).HeaderCell.Style.BackColor), r)
            e.Graphics.DrawRectangle(Pens.Black, r)
            e.Graphics.DrawString(dgvWarehouse.Columns(x).HeaderText, gridFont, Brushes.White, r, sf)
            startX += r.Width
        Next

        startY += r.Height
        'End If

        '' this create the table header row
        For y As Integer = startRow To dgvWarehouse.Rows.Count - 1
            If y = dgvWarehouse.NewRowIndex Then Continue For
            startX = e.MarginBounds.Left
            For x As Integer = 0 To dgvWarehouse.Columns.Count - 1
                r.X = startX - 30
                r.Y = startY
                r.Width = CInt((dgvWarehouse.Columns(x).Width + 15) * percentage)
                r.Height = dgvWarehouse.Rows(0).Height
                e.Graphics.DrawRectangle(Pens.Black, r)
                e.Graphics.DrawString(If(Not dgvWarehouse.Rows(y).Cells(x).Value Is Nothing, dgvWarehouse.Rows(y).Cells(x).Value.ToString, ""),
                                        gridFont, Brushes.Black, r, sf)

                startX += r.Width
            Next
            startY += r.Height
            If startY >= e.MarginBounds.Bottom - 10 Then
                If y < dgvWarehouse.Rows.Count - 1 Then
                    e.HasMorePages = True
                    pageCounter += 1
                    startRow = y + 1
                    Exit For
                End If
            End If
        Next

i can just save the datagridview as image but that is not what i want. i want to save the one in print preview where there is an icon and has stylish table.

1 Answers

Move your code to its own method and replace all instances of e.Graphics with a parameter of type Graphics. You can then call that method anywhere and pass it a Graphics object created any way you like. For instance, if you had this code:

Private Sub PrintDocument1_PrintPage(...) Handles PrintDocument1.PrintPage
    e.Graphics.DrawString(...)
End Sub

you could change it to this:

Private Sub DrawPage(g As Graphics)
    g.DrawString(...)
End Sub

Private Sub PrintDocument1_PrintPage(...) Handles PrintDocument1.PrintPage
    DrawPage(e.Graphics)
End Sub

to get the same result. You can then do this elsewhere:

Dim img As New Bitmap(...)
Dim g = Graphics.FromImage(img)

DrawPage(g)

to do the same drawing on your Bitmap as you printed. As your printing is fairly complex, there may be some other small adjustments that you need to make but the principle remains.

Related