donnytian / Npoi.Mapper

Use this tool to import or export data with Excel file. The tool is a convention based mapper between strong typed object and Excel data via NPOI.
MIT License
601 stars 115 forks source link

ForHeader委托应该在填充完数据后执行,而不是填充数据前 #25

Closed VAllens closed 6 years ago

VAllens commented 6 years ago

ForHeader委托应该在填充完数据后执行,而不是填充数据前. 这是有原因的。 如果仅仅只是设置头部样式,你的写法毫无问题。 但如果调用者想要为单元格设置自适应列宽,那么这样写就肯定有问题的。 因为NPOI提供的Sheet.AutoSizeColumn自适应列宽方法,是基于当前列最宽的那一个单元格的宽度设置整列的宽度。 所以如果调用者在ForHeader委托里调用Sheet.AutoSizeColumn自适应列宽方法,是不会提作用的。 调用者只能在调用了你的Put方法之后,自己另外写for调用Sheet.AutoSizeColumn方法。 而如果你把ForHeader委托的执行放在填充数据之后,那么调用者无须另写for代码。

所以请考虑将以下代码段移到Put方法底部。

// Injects custom action for headers.
if (overwrite && HasHeader && _headerAction != null)
{
    firstRow?.Cells.ForEach(c => _headerAction(c));
}

移到这个填充数据的代码段之后

foreach (var o in objectArray)
{
    var row = sheet.GetRow(rowIndex);

    if (overwrite && row != null)
    {
        sheet.RemoveRow(row);
        row = sheet.CreateRow(rowIndex);
    }

    row = row ?? sheet.CreateRow(rowIndex);

    foreach (var column in columns)
    {
        var pi = column.Attribute.Property;
        var value = pi?.GetValue(o);
        var cell = row.GetCell(column.Attribute.Index, MissingCellPolicy.CREATE_NULL_AS_BLANK);

        column.CurrentValue = value;
        if (column.Attribute.TryPut == null || column.Attribute.TryPut(column, o))
        {
            SetCell(cell, column.CurrentValue, column, setStyle: overwrite);
        }
    }

    rowIndex++;
}

谢谢

VAllens commented 6 years ago

very good