NPOI DataFormat

Ich exportiere ein Raster mit NPOI v1.2.3 und habe Probleme, die Zellformatierung zum Laufen zu bringen.

Ich habe eine Klasse, die eine Liste von Objekten in eine XLS-Datei exportiert. Für jedes Objekt wird eine Zeile erstellt und für jede konfigurierte Eigenschaft eine Zelle hinzugefügt. Das Zellendatenformat kann pro Eigenschaft festgelegt werden.

Ich habe gelesen, dassSie sollten nicht für jede Zelle einen neuen Stil erstellen. Ich kann meine Styles nicht hart codieren, da mein Exporter jede Klasse unterstützen muss. Stattdessen habe ich ein kleines Cache-System geschrieben, das nur dann einen neuen CellStyle erstellt, wenn noch keiner für das Format der aktuellen Zelle erstellt wurde.

Leider hat dies das Problem noch nicht gelöst. Die Formatierung wird in der endgültigen XLS-Datei nicht korrekt angewendet. In meinem Testfall verwenden die meisten Zellen in der XLS das Format "Datum", obwohl nur wenige Spalten Datumsangaben sind. Die erste Spalte verwendet jedoch ein benutzerdefiniertes Format. Es werden keine Zellen auf Text gesetzt, obwohl dies die meisten von ihnen sein sollten.

Was mache ich falsch

Cod

Die folgende Methode "AddRecords" wird zum Hinzufügen der Datenzeilen verwendet (Kopf- und Fußzeilen werden separat hinzugefügt). Das letzte Codebit ist die Methode, mit der CellStyles faul geladen werden kann.

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];
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage