如何将DataGridView打印预览内容保存为图片
将打印预览内容保存为图片的解决方案
你的需求是复用现有打印逻辑(包含Logo、样式化表格)生成图片,而非直接导出DataGridView控件本身。以下是实现方案:
核心思路
把原本绘制到打印页面的逻辑,改为绘制到内存中的Bitmap对象,最终将Bitmap保存为图片文件。这样能保证生成的图片和打印预览内容完全一致。
实现步骤
- 提取绘制逻辑为独立方法:将原有打印事件中的绘制代码抽离,接收
Graphics对象作为参数,同时兼容打印和图片生成场景。 - 创建Bitmap模拟打印页面:根据打印页面的尺寸(如A4)创建对应大小的
Bitmap,获取其Graphics上下文。 - 调用绘制方法生成内容:把
Bitmap的Graphics传入提取的方法,完成内容绘制。 - 保存Bitmap为图片:将生成的
Bitmap保存为PNG/JPG等格式文件。
完整代码实现
第一步:提取通用绘制方法
Private Sub DrawPrintContent(g As Graphics, pageBounds As Rectangle, marginBounds As Rectangle, ByRef startRow As Integer, ByRef pageCounter As Integer) Dim addressFont As New Font(dgvWarehouse.Font.FontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel) Dim logoImage As Image = CType(My.Resources.ResourceManager.GetObject("logo1"), Image) g.DrawImage(logoImage, CInt((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" ' 注意:确保CompanyFont已在代码中定义,若未定义需补充声明 g.DrawString(companyname, CompanyFont, Brushes.Black, CSng(pageBounds.Width - 1100 / 2), 60) g.DrawString(address, addressFont, Brushes.Black, CSng(pageBounds.Width - 1100 / 2), 90) g.DrawString(number, addressFont, Brushes.Black, CSng(pageBounds.Width - 1100 / 2), 105) g.DrawString(email, addressFont, Brushes.Black, CSng(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) * marginBounds.Width) / 100) Dim header As String = "Warehouse Inventory" Dim footer As String Dim startX As Integer = marginBounds.Left - 30 Dim startY As Integer = marginBounds.Top Dim r As Rectangle Dim szf As SizeF = g.MeasureString(header, headerFont) g.DrawString(header, headerFont, Brushes.Black, marginBounds.Left + (marginBounds.Width - szf.Width) / 2, startY - (r.Height - 80)) footer = "Page " & pageCounter.ToString szf = g.MeasureString(footer, headerFont) g.DrawString(footer, headerFont, Brushes.Black, marginBounds.Left + (marginBounds.Width - szf.Width) / 2, marginBounds.Bottom + 5) startY += 100 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) ' 绘制表格表头 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 g.FillRectangle(New SolidBrush(dgvWarehouse.Columns(x).HeaderCell.Style.BackColor), r) g.DrawRectangle(Pens.Black, r) g.DrawString(dgvWarehouse.Columns(x).HeaderText, gridFont, Brushes.White, r, sf) startX += r.Width Next startY += r.Height ' 绘制表格内容行 For y As Integer = startRow To dgvWarehouse.Rows.Count - 1 If y = dgvWarehouse.NewRowIndex Then Continue For startX = 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 g.DrawRectangle(Pens.Black, r) g.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 >= marginBounds.Bottom - 10 Then If y < dgvWarehouse.Rows.Count - 1 Then startRow = y + 1 pageCounter += 1 Exit For End If End If Next ' 释放资源,避免内存泄漏 addressFont.Dispose() headerFont.Dispose() gridFont.Dispose() sf.Dispose() logoImage.Dispose() End Sub
第二步:添加生成并保存图片的方法
Private Sub SavePrintContentAsImage() ' 模拟A4纸尺寸(96 DPI),可根据实际打印设置调整 Dim pageWidth As Integer = CInt(8.5 * 96) Dim pageHeight As Integer = CInt(11 * 96) Dim pageBounds As New Rectangle(0, 0, pageWidth, pageHeight) ' 模拟打印边距,与打印设置保持一致 Dim marginBounds As New Rectangle(50, 50, pageWidth - 100, pageHeight - 100) ' 创建Bitmap对象 Using bmp As New Bitmap(pageWidth, pageHeight) Using g As Graphics = Graphics.FromImage(bmp) ' 设置绘图质量,匹配打印效果 g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit g.Clear(Color.White) ' 设置背景为白色 Dim startRow As Integer = 0 Dim pageCounter As Integer = 1 ' 调用绘制方法生成内容 DrawPrintContent(g, pageBounds, marginBounds, startRow, pageCounter) ' 处理多页:若内容有多页,可循环调用DrawPrintContent,更新startRow和pageCounter,保存为不同文件 ' 示例仅生成第一页,多页场景可自行扩展循环逻辑 ' 保存图片到指定路径 bmp.Save("C:\Temp\WarehouseInventory_Page1.png", Imaging.ImageFormat.Png) MessageBox.Show("图片已成功保存!") End Using End Using End Sub
关键注意事项
- 资源释放:所有实现
IDisposable的对象(如Font、Image、StringFormat)需调用Dispose()或用Using语句包裹,避免内存泄漏。 - 多页处理:如果打印内容超过一页,可通过循环调用
DrawPrintContent,每次更新startRow和pageCounter,并将每页保存为单独的图片文件。 - 尺寸匹配:确保
Bitmap的尺寸和打印页面尺寸一致,这样生成的图片比例才会和预览完全相同。
内容的提问来源于stack exchange,提问作者Karl
相关产品推荐
相关产品推荐

