Syncfusion WPF SFDatagrid打印预览/导出日期格式冗余问题
解决Syncfusion SfDataGrid日期格式在打印/导出时异常的问题
我之前也碰到过一模一样的问题!Syncfusion的SfDataGrid在显示层用DisplayBinding.StringFormat设置日期格式是没问题,但打印预览和导出时,它并不会直接沿用这个格式化规则,反而会带出原始格式或者奇怪的占位符。给你几个亲测有效的解决方案:
方案1:改用专门的GridDateTimeColumn(最推荐)
既然是日期类型的列,直接用Syncfusion官方提供的GridDateTimeColumn是最省心的,它会统一处理显示、打印和导出的格式逻辑,不需要额外折腾:
var columnName = ReportSourceDataTable.Columns[i].ToString(); if (ReportSourceDataTable.Columns[i].DataType == typeof(DateTime)) { var dateCol = new GridDateTimeColumn(); dateCol.HeaderText = columnName; dateCol.MappingName = columnName; dateCol.FormatMode = DateTimeFormatMode.Custom; dateCol.CustomFormat = "MM/dd/yyyy"; // 把列添加到DataGrid中 sfDataGrid.Columns.Add(dateCol); } else { // 你的CustomGridTextColumn原有逻辑 var textCol = new CustomGridTextColumn(); textCol.HeaderText = columnName; textCol.DisplayBinding = new Binding(columnName); sfDataGrid.Columns.Add(textCol); }
方案2:为打印/导出单独设置格式化规则
如果一定要保留CustomGridTextColumn,可以通过Syncfusion的打印管理器和导出事件来手动指定格式:
处理打印预览
订阅PrintManager的PrintCell事件,在打印渲染时替换日期文本:
// 初始化时绑定事件 sfDataGrid.PrintManager.PrintCell += PrintManager_PrintCell; private void PrintManager_PrintCell(object sender, PrintCellEventArgs e) { // 判断当前列是否是日期列 var columnDataType = ReportSourceDataTable.Columns[e.Column.MappingName]?.DataType; if (columnDataType == typeof(DateTime) && e.Record != null) { var dateValue = (DateTime)e.Record.GetType().GetProperty(e.Column.MappingName).GetValue(e.Record); // 替换成指定格式的文本 e.PrintText = dateValue.ToString("MM/dd/yyyy"); } }
处理数据导出(以Excel为例)
导出时直接给Excel列设置格式:
var excelEngine = new ExcelEngine(); IWorkbook workbook = excelEngine.Excel.Workbooks.Create(1); IWorksheet worksheet = workbook.Worksheets[0]; // 导入DataTable数据 worksheet.ImportDataTable(ReportSourceDataTable, true, 1, 1); // 找到日期列,设置Excel单元格格式 var dateColumnIndex = i + 1; // Excel列索引从1开始 worksheet.Columns[dateColumnIndex].NumberFormat = "MM/dd/yyyy"; // 保存文件 workbook.SaveAs("ExportedData.xlsx");
方案3:用ValueConverter统一处理格式
创建一个日期格式化转换器,让绑定的所有场景(显示、打印、导出)都使用转换后的值:
public class DateFormatConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is DateTime date) { return date.ToString("MM/dd/yyyy"); } return value ?? string.Empty; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // 如果不需要编辑功能,可以直接抛出异常或者返回默认值 throw new NotImplementedException(); } }
然后在绑定的时候使用这个转换器:
var columnName = ReportSourceDataTable.Columns[i].ToString(); var col = new CustomGridTextColumn(); col.HeaderText = columnName; var binding = new Binding(columnName); binding.Converter = new DateFormatConverter(); col.DisplayBinding = binding; sfDataGrid.Columns.Add(col);
为什么DisplayBinding.StringFormat不生效?
本质原因是Syncfusion的打印/导出模块在处理数据时,有时候会直接读取数据源的原始值,而不是经过DisplayBinding格式化后的UI显示文本,所以必须用它自身的列类型、事件或者转换器来统一处理格式逻辑。
内容的提问来源于stack exchange,提问作者ConfuseD
相关产品推荐
相关产品推荐

