Я экспортирую сетку с помощью NPOI v1.2.3, и у меня возникают проблемы с форматированием ячеек.
У меня есть класс, который экспортирует список объектов в файл XLS. Для каждого объекта создается строка, а для каждого настроенного свойства добавляется ячейка. Формат данных ячейки может быть установлен на уровне каждого свойства.
Я читал, что вам не следует не создавать новый стиль для каждой ячейки. Я не могу жестко закодировать свои стили, так как мой экспортер должен поддерживать любой класс. Вместо этого я написал небольшую систему кэширования, которая создает новый CellStyle только в том случае, если он еще не создан для текущего формата ячейки.
К сожалению, это до сих пор не решило проблему. Форматирование неправильно применяется в окончательном файле XLS. В моем тестовом примере большинство ячеек в XLS используют формат «Дата», хотя только несколько столбцов являются датами. Однако первый столбец правильно использует пользовательский формат. Ни одна ячейка не настроена на текст, хотя это должно быть большинство из них.
Что я делаю неправильно?
Код
Приведенный ниже метод AddRecords используется для добавления строк данных (строки верхнего и нижнего колонтитула добавляются отдельно). Последний фрагмент кода — это метод ленивой загрузки CellStyles.
private void AddRecords( Sheet sheet, IList<T> 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 );
}
}
}
/// <summary>
/// Returns a default format string based on the object type of value.
///
/// http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/BuiltinFormats.html
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
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<string, CellStyle> _cellStyleCache = new Dictionary < string, CellStyle > ();
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];
}