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列显示:

- 打印预览中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列显示:

- 打印预览中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显示效果:

- 打印预览效果:

- 对应的代码截图:

内容的提问来源于stack exchange,提问作者roy
相关产品推荐
相关产品推荐

