从DatagridView创建一个Tiff位图文件

3
我想从DataGridView创建一个Tiff文件。我已经成功将DataGridView转换为Tiff文件,但是我只想要行和列,不需要其他内容。
不使用第三方工具能否实现这一点?
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    DataGridView1.Rows.Add(New String() {"Value1", "Value2", "Value3"})


    Dim height As Integer = DataGridView1.Height
    DataGridView1.Height = DataGridView1.RowCount * DataGridView1.RowTemplate.Height

    Dim bitmap As Bitmap = New Bitmap(Me.DataGridView1.Width - 1, Me.DataGridView1.Height - 1)
    DataGridView1.DrawToBitmap(bitmap, New Rectangle(0, 0, Me.DataGridView1.Width - 1, Me.DataGridView1.Height - 1))

    'Save the Bitmap to folder.
    bitmap.Save("C:Development\DataGridView.Tiff")

End Sub

我不想要被突出显示的部分

在这里输入图片描述


尝试在使用 .DrawToBitmap () 之前使用 DataGridView1.ClearSelection() - preciousbetine
尝试过这个,但没有成功,结果相同。 - CodeMonger
您可能想考虑从DataGridView动态创建RDLC报告和在不显示ReportViewer的情况下打印RDLC报告。 - Reza Aghaei
1个回答

3

需要考虑以下几个问题:

  1. 当控件呈现到位图上时,DataGridView的行和列必须可见,
  2. 可能存在滚动条,
  3. 每行的高度可能不同,所以我们必须累加所有行的高度,
  4. 每列也是一样,因为每列都有自己的宽度,
  5. 可能存在单元格格式设置,因此我们需要在绘制之前刷新DataGridView:未显示的行可能还没有进行格式化,
  6. 位图大小有限制(32,767)。

按照以下方式调用此方法,指定是否要包括行或列标题或排除两者,将True/False作为ColumnHeadersRowHeaders参数传递。
dgv参数当然是要绘制的DataGridView控件实例:

' Prints the DataGridView including the Columns' Headers only
Dim dgvBitmap = DataGridViewToBitmap(DataGridView1, True, False)
Dim imagePath = Path.Combine(AppContext.BaseDirectory, $"{NameOf(DataGridView1)}.tiff")
dgvBitmap.Save(imagePath, ImageFormat.Tiff)

' Dispose of the Bitmap or set it as the PictureBox.Image, dispose of it later.  
dgvBitmap.Dispose()

Private Function DataGridViewToBitmap(dgv As DataGridView, ColumnHeaders As Boolean, RowHeaders As Boolean) As Bitmap
    dgv.ClearSelection()
    Dim originalSize = dgv.Size
    dgv.Height = dgv.Rows.OfType(Of DataGridViewRow).Sum(Function(r) r.Height) + dgv.ColumnHeadersHeight
    dgv.Width = dgv.Columns.OfType(Of DataGridViewColumn).Sum(Function(c) c.Width) + dgv.RowHeadersWidth
    dgv.Refresh()

    Dim dgvPosition = New Point(If(RowHeaders, 0, dgv.RowHeadersWidth), If(ColumnHeaders, 0, dgv.ColumnHeadersHeight))
    Dim dgvSize = New Size(dgv.Width, dgv.Height)
    If dgvSize.Height > 32760 OrElse dgvSize.Width > 32760 Then Return Nothing

    Dim rect As Rectangle = New Rectangle(Point.Empty, dgvSize)
    Using bmp As Bitmap = New Bitmap(dgvSize.Width, dgvSize.Height)
        dgv.DrawToBitmap(bmp, rect)
        If (dgv.Width > originalSize.Width) AndAlso dgv.ScrollBars.HasFlag(ScrollBars.Vertical) Then
            dgvSize.Width -= SystemInformation.VerticalScrollBarWidth
        End If
        If (dgv.Height > originalSize.Height) AndAlso dgv.ScrollBars.HasFlag(ScrollBars.Horizontal) Then
            dgvSize.Height -= SystemInformation.HorizontalScrollBarHeight
        End If
        dgvSize = New Size(dgvSize.Width - dgvPosition.X, dgvSize.Height - dgvPosition.Y)

        dgv.Size = originalSize
        Return bmp.Clone(New Rectangle(dgvPosition, dgvSize), PixelFormat.Format32bppArgb)
    End Using
End Function

1
我做了一个小改动,添加了一个参数,允许指定是否应包括“行标题”和/或“列标题”(而不是包括或排除两者)。 - Jimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接