NPOI DataFormat

我正在使用NPOI v1.2.3导出网格,并且无法使单元格格式化工作。

我有一个类将对象列表导出到XLS文件。 为每个对象创建一行,并为每个已配置的属性添加一个单元格。 可以在每个属性级别上设置单元格数据格式。

我已经读过你不应该为每个单元格创建一个新的样式 。 我无法对我的样式进行硬编码,因为我的导出器需要支持任何类。 相反,我编写了一个小缓存系统,只有在尚未为当前单元格格式创建的情况下才创建新的CellStyle。

不幸的是,这仍然没有解决问题。 格式未在最终的XLS文件中正确应用。 在我的测试用例中,XLS中的大多数单元格都使用“日期”格式,即使只有几列是日期。 但是,第一列正确使用自定义格式。 没有单元格设置为文本,即使它应该是大多数单元格。

我究竟做错了什么?

下面的“AddRecords”方法用于添加数据行(页眉和页脚行分别添加)。 最后一点代码是延迟加载CellStyles的方法。

private void AddRecords( Sheet sheet, IList records ) { foreach( var record in records ) { // append row var row = sheet.CreateRow ( sheet.LastRowNum + 1 ); // iterate through all configured columns foreach ( var column in GetColumns() ) { // append cell Cell cell = row.CreateCell ( row.LastCellNum == -1 ? 0 : row.LastCellNum ); // get the property value of the column from the record object value = GetCellValue ( column, record ); // extension method that takes an object value and calls the appropriate type-specific SetCellValue overload cell.SetCellValue ( value ); // get format from the column definition ("m/d", "##.###", etc.), or use the default string dataFormat = column.DataFormat ?? GetDefaultDataFormat ( value ); // find/create cell style cell.CellStyle = GetCellStyleForFormat( sheet.Workbook, dataFormat ); } } } ///  /// Returns a default format string based on the object type of value. /// /// http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/BuiltinFormats.html ///  ///  ///  private string GetDefaultDataFormat( object value ) { if( value == null ) { return "General"; } if( value is DateTime ) { return "m/d"; } if( value is bool ) { return "[=0]\"Yes\";[=1]\"No\""; } if( value is byte || value is ushort || value is short || value is uint || value is int || value is ulong || value is long ) { return "0"; } if( value is float || value is double ) { return "0.00"; } // strings and anything else should be text return "text"; } private readonly Dictionary _cellStyleCache = new Dictionary  (); private CellStyle GetCellStyleForFormat( Workbook workbook, string dataFormat ) { if( !_cellStyleCache.ContainsKey ( dataFormat ) ) { var newDataFormat = workbook.CreateDataFormat (); var style = workbook.CreateCellStyle (); style.DataFormat = newDataFormat.GetFormat ( dataFormat ); _cellStyleCache[dataFormat] = style; } return _cellStyleCache[dataFormat]; } 

看起来这个问题与创建与内置格式匹配的新格式有关。 我改变了我的延迟加载方法以使用内置格式(如果可用),并且我最终XLS中的单元格格式现在都是正确的。

 if( !_cellStyleCache.ContainsKey ( dataFormat ) ) { var style = workbook.CreateCellStyle (); // check if this is a built-in format var builtinFormatId = HSSFDataFormat.GetBuiltinFormat ( dataFormat ); if( builtinFormatId != - 1) { style.DataFormat = builtinFormatId; } else { // not a built-in format, so create a new one var newDataFormat = workbook.CreateDataFormat (); style.DataFormat = newDataFormat.GetFormat ( dataFormat ); } _cellStyleCache[dataFormat] = style; }