You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中如何手动将DataGridView列值转换为字符串?

问题:DataGridView格式化后KtReport打印预览格式失效

在VB.NET中使用KtReport做打印预览时,遇到以下问题:通过DataGridView的CellFormatting事件格式化Price列后,DataGridView显示正常,但打印预览里格式失效;而直接添加格式化后的字符串到DataGridView时,打印预览则正常。请问原代码是否存在错误?


问题代码

Public Function getData() As DataTable
    Dim dt As New DataTable()
    dt.Columns.Add("UserId", GetType(Int32))
    dt.Columns.Add("UserName", GetType(String))
    dt.Columns.Add("Education", GetType(String))
    dt.Columns.Add("Location", GetType(String))
    dt.Columns.Add("Price", GetType(Double))
    dt.Rows.Add(1, "Satinder Singh", "Bsc Com Sci", "Mumbai", 25000)
    dt.Rows.Add(2, "Amit Sarna", "Mstr Com Sci", "Mumbai", 21000)
    dt.Rows.Add(3, "Andrea Ely", "Bsc Bio-Chemistry", "Queensland", 35000)
    dt.Rows.Add(4, "Leslie Mac", "MSC", "Town-ville", 22000)
    dt.Rows.Add(5, "Vaibhav Adhyapak", "MBA", "New Delhi", 27000)
    Return dt
End Function

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    DataGridView1.DataSource = getData()
End Sub

Private Sub DataGridView1_CellFormatting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
    If (e.ColumnIndex = 4) Then
        e.Value = String.Format("{0:N2}", e.Value)
    End If
End Sub

Private Sub GenerateReport()
    KtReport1.Clear()
    KtReport1.AddString("<h2>Product List</h2>")
    KtReport1.AddHorizontalRule()
    ktReport1.AddDatagridView(DataGridView1)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    GenerateReport()
    KtReport1.ShowPrintPreviewDialog()
End Sub

效果对比

  • DataGridView中Price列显示:
    DataGridView中Price列正常显示
  • 打印预览中Price列效果(格式失效):
    打印预览中Price列格式失效

正常运行的示例代码

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim random As New Random()
    For i As Integer = 0 To 4
        Dim productName = "Product" & (i + 1)
        Dim productPrice = random.Next(5, 5000)
        DataGridView1.Rows.Add(New Object() {productName, productPrice.ToString("N2")})
    Next i
End Sub

Private Sub GenerateReport()
    KtReport1.Clear()
    KtReport1.AddString("<h2>Product List</h2>")
    KtReport1.AddHorizontalRule()
    ktReport1.AddDatagridView(DataGridView1)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    GenerateReport()
    KtReport1.ShowPrintPreviewDialog()
End Sub

效果对比

  • DataGridView中Price列显示:
    正常示例的DataGridView显示
  • 打印预览中Price列效果(格式正常):
    正常示例的打印预览显示

问题原因与修正方案

原因

CellFormatting事件仅修改DataGridView的显示内容,不会改变绑定数据源(DataTable)中的原始数值。而KtReport的AddDatagridView方法是直接读取数据源的原始值,而非DataGridView格式化后的显示值,因此打印时会显示未格式化的Double类型数据。

修正方案

方案1:修改数据源,直接存储格式化后的字符串

修改getData方法,将Price列改为存储格式化后的字符串:

Public Function getData() As DataTable
    Dim dt As New DataTable()
    dt.Columns.Add("UserId", GetType(Int32))
    dt.Columns.Add("UserName", GetType(String))
    dt.Columns.Add("Education", GetType(String))
    dt.Columns.Add("Location", GetType(String))
    dt.Columns.Add("Price", GetType(String)) '改为字符串类型存储格式化后的值
    dt.Rows.Add(1, "Satinder Singh", "Bsc Com Sci", "Mumbai", String.Format("{0:N2}", 25000))
    dt.Rows.Add(2, "Amit Sarna", "Mstr Com Sci", "Mumbai", String.Format("{0:N2}", 21000))
    dt.Rows.Add(3, "Andrea Ely", "Bsc Bio-Chemistry", "Queensland", String.Format("{0:N2}", 35000))
    dt.Rows.Add(4, "Leslie Mac", "MSC", "Town-ville", String.Format("{0:N2}", 22000))
    dt.Rows.Add(5, "Vaibhav Adhyapak", "MBA", "New Delhi", String.Format("{0:N2}", 27000))
    Return dt
End Function

方案2:手动构建KtReport表格,读取DataGridView的格式化值

不使用AddDatagridView,手动遍历DataGridView的行和列,读取每个单元格的FormattedValue来构建报表:

Private Sub GenerateReport()
    KtReport1.Clear()
    KtReport1.AddString("<h2>Product List</h2>")
    KtReport1.AddHorizontalRule()
    
    '手动创建表格
    KtReport1.AddStartTable()
    '添加表头
    KtReport1.AddStartTableRow()
    For Each col As DataGridViewColumn In DataGridView1.Columns
        KtReport1.AddTableHeaderCell(col.HeaderText)
    Next
    KtReport1.AddEndTableRow()
    
    '添加数据行
    For Each row As DataGridViewRow In DataGridView1.Rows
        If Not row.IsNewRow Then
            KtReport1.AddStartTableRow()
            For Each cell As DataGridViewCell In row.Cells
                KtReport1.AddTableCell(cell.FormattedValue.ToString())
            Next
            KtReport1.AddEndTableRow()
        End If
    Next
    KtReport1.AddEndTable()
End Sub

参考解答效果

  • DataGridView显示效果:
    参考解答的DataGridView效果
  • 打印预览效果:
    参考解答的打印预览效果
  • 对应的代码截图:
    参考解答的代码截图

内容的提问来源于stack exchange,提问作者roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:30:03