Coder Social home page Coder Social logo

donnytian / npoi.mapper Goto Github PK

View Code? Open in Web Editor NEW
577.0 32.0 111.0 373 KB

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.

License: MIT License

C# 100.00%
npoi mapper excel orm xls xlsx export import

npoi.mapper's People

Contributors

donnytian avatar john0king avatar pczajkowski-ptw avatar poferro avatar workgroupengineering avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

npoi.mapper's Issues

请问怎么对 target.Items 深层的嵌套?


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npoi.Mapper;
using Npoi.Mapper.Attributes;

namespace WS.NPOI
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = @"F:\test.xlsx";
            var list = new Helper().ToMapper(path);
        }
    }
    public class Helper
    {
        public List ToMapper(string filePath)
        {
            Mapper mapper = new Mapper(filePath);
            mapper.HeaderRowIndex = 0;
            mapper.HasHeader = true;
            var item = new BClass();
            mapper = mapper.Map(
                  col => { return true; },
                 (col, target) =>
                 {
                     // 请问怎么对 target.Items 深层的嵌套?
                     ((AClass)target).Items.Add(item);
                     return true;
                 });

            var list = mapper.Take< AClass >(0).Select(s => s.Value).ToList();
            return list;
        }
    }
    public class AClass
    {
        public AClass()
        {
            Items = new List();
        }
        [Column("columnName1")]
        public int MyColumnName { get; set; }

        public List< BClass > Items { get; set; }
    }
    public class BClass
    {
        [Column("columnName21")]
        public string MyColumnName1 { get; set; }
        [Column("columnName22")]
        public string MyColumnName2 { get; set; }
    }
}


Style problem

Hello, does the library support the table style? Such as background color or font color or font type and so on

How to apply trim before checking rows

Before using the mapper, I apply a .trim() to the headers to remove empty spaces. But the problem comes when trying to match with the rows that don't have the column name with the .trim() method used on them. Do you know if there is a method or a place where I can apply the trim to the column names of the rows?

Try to set HeaderRowIndex but dosen't work

Hi,

My demo excel has two headers, the first header for Chinese Name and the second one is the actual column name of the table.

I have tried to set HeaderRowIndex to 1 or 2, but the mapping result is not expected, which the value of the properties is the default value. But if I just keep single hearer, it works fine.

Below are my code and excel:
`

            var mapper = new Mapper(fullPath);
            mapper.HeaderRowIndex = 1;
            var objs = mapper.Take<ProductDTO>().ToList();

`
image

Cannot apply TryTake if there is error when parsing Enum

Get attribute value as friendly display name if property has DisplayName attribute.

Or you design a custom attribute enhancement class that provides a custom friendly display name, column display order, and so on.

Or does Npoi.Mapper already have a similar function? Do you have a better idea?

Sample data model code:

public class CatalogCareViewModel
{
	/// <summary>
	/// ISO/国际标准
	/// </summary>
	public virtual string ISO { get; set; }

	/// <summary>
	/// German/德语
	/// </summary>
	[DisplayName("German")]
	public virtual string DE { get; set; }

	/// <summary>
	/// English/英语
	/// </summary>
	[DisplayName("English")]
	public virtual string EN { get; set; }

	/// <summary>
	/// French/法语
	/// </summary>
	[DisplayName("French")]
	public virtual string FR { get; set; }

	/// <summary>
	/// Russion/俄语
	/// </summary>
	[DisplayName("Russion")]
	public virtual string RU { get; set; }

	/// <summary>
	/// Italian/意大利语
	/// </summary>
	[DisplayName("Italian")]
	public virtual string IT { get; set; }

	/// <summary>
	/// Dutch/荷兰语
	/// </summary>
	[DisplayName("Dutch")]
	public virtual string NL { get; set; }

	/// <summary>
	/// Norwegian/挪威
	/// </summary>
	[DisplayName("Norwegian")]
	public virtual string NO { get; set; }
}

Sample excel sheet table

ISO German English French Russion Italian Dutch Norwegian
value1 value2 value3 value4 value5 value6 value7 value8
value1 value2 value3 value4 value5 value6 value7 value8
value1 value2 value3 value4 value5 value6 value7 value8

Problems importing sheet with date as double

I'm trying to import a Excel sheet which contains several columns which can have date values as double. Here is my approach:

var mapper = new Mapper(filePath);
mapper.TrackObjects = false;
mapper.Map<Model>(0, o => o.Property1);
mapper.Map<Model>(1, o => o.Property2);
...
mapper.Map(column =>
{
    if (column.Attribute.Index == 10 && column.CurrentValue is double value)
    {
        column.CurrentValue = DateTime.FromOADate(value);
    }
    
    return true;
});

var result = mapper.Take<Model>().ToList();

When debugging, the debugger dont even stop in the mapper.Map(column => ...) method.

All I got as a result is a list of errors for the specific columns:
"Object reference not set to an instance of an object."

How do I have configure the mapper to convert the double to date?
Any help is welcomed!

Is there a way to set the format for all DateTime types?

Without setting a format on DateTime properties, excel seems to format them as integers. For example,
10/26/2016 prints as 42669.

I see that I can easily format a DateTime property if I know it in advance, like this:
mapper.Format<MyObject>("yyyy-MM-dd", x => x.MyDateField)

I tried to make it generic, so I don't need a custom method for every one of my types:

foreach (var property in typeof(T).GetProperties())
{
    if (property.PropertyType == typeof(DateTime) ||
        property.PropertyType == typeof(DateTime?))
    {
        mapper.Format<T>("yyyy-MM-dd", x => property.GetValue(x));
    }
}

But this fails with "Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpressionN' to type 'System.Linq.Expressions.UnaryExpression'."

Would you help me figure this out, or consider building in a default format for DateTime that isn't an integer?

No error reported for nullable value type columns during import

When import from file for nullable value types like DateTime? and int?, if the value from Excel file cannot be converted to the target type, no error reported, just set null to the object.

The expected result is to report errors or use setting to control whether or not report error for specific column/ property.

导入时,实体类与Excel列名不匹配,能否抛出例外,而不是赋空值。

用户故意上传了个文件格式合法,但列格式不合法的文件。
此时,我希望给用户一个友好的提示(列格式有误),而不是让用户顺利上传成功。
例如:

public class MyEntity
{
    public string Name { get; set; }
    public string Address { get; set; }
}

Excel

Comany|State|City

通过你的类库,能上传成功,但获取的实体类列表都是空值。
我希望有列名校验之类的功能。不知道你的Mapper.Map扩展方法能否做到。
或者你有更好的建议??

FR: Map to Enum by Enums Description or/and Display attribute

FEATURE REQUEST

Is there a support to map string to enum values, based on the defined DescriptionAttribute or DisplayAttribute (would choose probably this) on then enum values?

Common scenario is to use abbreviations with enums as well. Also the enum's property is used inside the code (like gold/silver/bronze client) and in excel we might consider to use some abbreviations (G/S/B) which when importing from excel should be converted to the proper enum value.

`DateTimeOffset?` cause whole row be null

base on my test

  1. the whole row will be null if your .Task<Import> , the Import contains DateTimeOffset?
  2. DateTime? is Ok

I think the DateTimeOffset should be support base on Current TimeZone of the thread

TryPutCell does not seem to work when using a custom column resolver.

Appears to be an issue in Mapper.cs -> Put( ...

SetCell not always called if using resolver.

From this:-

                if (column.Resolver != null)
                {
                    column.Resolver.TryPutCell(column, out value, o);
                }
                else
                {
                    SetCell(cell, value, column, setStyle: overwrite);
                }

To this:-

                if (column.Resolver != null)
                {
                    column.Resolver.TryPutCell(column, out value, o);
                }

                SetCell(cell, value, column, setStyle: overwrite);

Regards,

Gary

Possibility to get detected headers

Haven't found the possibility to get a list of all column headers.
Is there any way to get them using the NPOI Workbook maybe?

image

Best regards

导出的Excel(xlsx格式)在Microsoft Office中打不开,WPS中打开正常

使用Npoi IWorkbook的方式导出的excel在两者中打开都正常,使用3.3.0版本的Npoi.Mapper导出,在Microsoft Office中打开会提示如图
image无论点击是或者否都不能正常打开。
` //var stream = new MemoryStream();
//var mapper = new Mapper();
//mapper.Format("yyyy-MM-dd", ps=> ps.DeliverPeriod)
// .Format("yyyy-MM-dd", ps=>ps.ApplyTime)
// // 将各个属性映射为中文列名
// .Map("序号", o=>o.SeqNO)
// .Map("合同编号", o=>o.ContractNO)
// .Map("产品编号", o=>o.ProductNO)
// .Map("客户", o=>o.CustomerName)
// .Map("营销代表", o=>o.MarketerName)
// .Map("交货日期", o=>o.DeliverPeriod)
// .Map("物料代码", o=>o.Code)
// .Map("产品型号", o=>o.ProductModelName)
// .Map("规格参数", o=>o.Spec)
// .Map("数量", o=>o.Qty)
// .Map("创建时间", o=>o.ApplyTime)
// .Map("备注", o=>o.Remarks)
// .Map("是否禁用", o=>o.Disabled);

        //// 将数据保存到stream中
        //mapper.Save(stream, objs, "生产计划评审");
        //// 获取stream的buffer
        //var buffer = stream.GetBuffer();
        //stream.Dispose();
        //return buffer;`

其中objs为List的数据

能否将"列标题映射的默认命名约定"作用于Excel导出

能否在没有自定义映射规则的情况下,将"列标题映射的默认命名约定"作用于Excel导出。

举例:
我没有调用Map<TModel>(parameters...),但我希望导出后,
DisplayNameProperty属性在Excel表格中显示的列名是Display Name,而不是DisplayNameProperty

ColumnNameAttributeProperty属性在Excel表格中的列名是正确显示的——By Name
换句话说,在导出功能中,ColumnAttribute起作用了,但DisplayAttribute没起作用。

实体类SampleClass

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npoi.Mapper.Attributes;

namespace Sample
{
    public class SampleClass
    {
        public string StringProperty { get; set; }

        [Column("By Name")]
        public string ColumnNameAttributeProperty { get; set; }

        [Column(11)]
        public string ColumnIndexAttributeProperty { get; set; }

        [Ignore]
        public string IgnoredAttributeProperty { get; set; }

        [Display(Name = "Display Name")]
        public string DisplayNameProperty { get; set; }

        [Column(CustomFormat = "0%")]
        public double CustomFormatProperty { get; set; }
    }
}

能否根据Mapper.Attributes集合的顺序来导出Excel?

你好,很高兴你使用CI持续发布NuGet包。
现在有个问题:
image
你现在的Excel导出是根据类属性顺序导出的,而且是先输出派生类属性列,后输出基类属性列。
能否根据Mapper.Attributes集合的顺序来导出Excel?

Ignore base classes

Hi there!
Is there a way to ignore the base classes? I have already tried:
mapper.Ignore and mapper.Ignore but it is still saving it to the excel file.

Any clues on how to overcome this?

Nested Property Mapping: MapHelper.GetPropertyInfoByExpression[T](Expression`1 propertySelector) throws an error

Not sure what I'm doing wrong... trying to set up a mapping to my Customer class which has some nested properties to BillingAddress, ServiceAddress, BillingContact, etc. - my excel file is 17,000 lines, with some whitespace rows in certain regions.

System.IndexOutOfRangeException: Index was outside the bounds of the array.

StackTrace:

at Npoi.Mapper.MapHelper.GetPropertyInfoByExpression[T](Expression`1 propertySelector)
at Npoi.Mapper.MapExtensions.Map[T](Mapper mapper, String columnName, Expression`1 propertySelector, Func`3 tryTake, Func`3 tryPut)

The above error is thrown, seemingly, when I try to use the mapper .. here's my code:

    Npoi.Mapper.Mapper m_mapper = new Npoi.Mapper.Mapper("exportContacts.xlsx");

    m_mapper.Map<Customer>("_kftAccountID", o => o.CustomerId)
        .Map<Customer>("accountType", o => o.AccountType)
        .Map<Customer>("addrBilling", o => o.BillingAddress.AddressLine1)
        .Map<Customer>("addrBillingCity", o => o.BillingAddress.City)
        .Map<Customer>("addrBillingCounty", o => o.BillingAddress.County)
        .Map<Customer>("addrBillingState", o => o.BillingAddress.State)
        .Map<Customer>("addrBillingZip", o => o.BillingAddress.ZipCode)
        .Map<Customer>("addrService", o => o.ServiceAddress.AddressLine1)
        .Map<Customer>("addrServiceCity", o => o.ServiceAddress.City)
        .Map<Customer>("addrServiceCounty", o => o.ServiceAddress.County)
        .Map<Customer>("addrServiceState", o => o.ServiceAddress.State)
        .Map<Customer>("addrServiceZip", o => o.ServiceAddress.ZipCode)
        .Map<Customer>("addrServiceAreaSubdivision", o => o.ServiceAreaSubdivision)
        .Map<Customer>("contactBillingCompName", o => o.BillingContact.CompanyName)
        .Map<Customer>("contactBillingEmail", o => o.BillingContact.Email)
        .Map<Customer>("contactBillingNameFirst", o => o.BillingContact.FirstName)
        .Map<Customer>("contactBillingNameLast", o => o.BillingContact.LastName)
        .Map<Customer>("contactBillingNamePrefix", o => o.BillingContact.Prefix)
        .Map<Customer>("contactBillingPhoneFax", o => o.BillingContact.FaxNumber)
        .Map<Customer>("contactBillingPhoneHome", o => o.BillingContact.PhoneHome)
        .Map<Customer>("contactBillingPhoneMobile", o => o.BillingContact.PhoneMobile)
        .Map<Customer>("contactBillingProfessionalTitle", o => o.BillingContact.ProfessionalTitle)
        .Map<Customer>("contactBillingSecondaryName", o => o.BillingContact.SecondaryName)
        .Map<Customer>("contactBillingSecondaryType", o => o.BillingContact.SecondaryType)
        .Map<Customer>("contactBillingWebSite", o => o.BillingContact.WebSite)
        .Map<Customer>("contactServiceName", o => o.ServiceContact.CompanyName)
        .Map<Customer>("contactServiceEmail", o => o.ServiceContact.Email)
        .Map<Customer>("contactServiceNameFirst", o => o.ServiceContact.FirstName)
        .Map<Customer>("contactServiceNamePrefix", o => o.ServiceContact.Prefix)
        .Map<Customer>("contactServicePhoneFax", o => o.ServiceContact.FaxNumber)
        .Map<Customer>("contactServicePhoneHome", o => o.ServiceContact.PhoneHome)
        .Map<Customer>("contactServicePhoneMobile", o => o.ServiceContact.PhoneMobile)
        .Map<Customer>("contactServicePropertyManager", o => o.ServiceContact.PropertyManager)
        .Map<Customer>("contactServiceType", o => o.ServiceContact.Type)
        .Map<Customer>("contactServiceWebSite", o => o.ServiceContact.WebSite);

Doesn't work with NPOI 2.2.1

Hi,
there is a message about missing method if you try to export to XLS/S with NPOI version 2.2.1 (newest) installed.
Workaround: use NPOI version 2.1.3.1.

Regards

Mapper.Put<T> overload method has bug

throw System.ArgumentException: Sheet index (0) is out of range (no sheets).

/// <summary>
/// Put objects in the sheet with specified zero-based index.
/// </summary>
/// <typeparam name="T">Target object type</typeparam>
/// <param name="objects">The objects to save.</param>
/// <param name="sheetIndex">The sheet index, default is 0.</param>
/// <param name="overwrite"><c>true</c> to overwrite existing rows; otherwise append.</param>
public void Put<T>(IEnumerable<T> objects, int sheetIndex = 0, bool overwrite = true)
{
	if (Workbook == null) Workbook = new XSSFWorkbook();
	var sheet = Workbook.GetSheetAt(sheetIndex);
	Put(sheet, objects, overwrite);
}

The second line in the method needs to judge the NumberOfSheets property first.
When it‘s value is greater than 0, the GetSheetAt method is called, otherwise, the CreateSheet method is called.

Requesting Type Format support for nullable types when data in first row is null.

You mentioned in Issue #4 the new mapper.UseFormat() method. It works great on non-nullable types and on nullable types if the data in the first row after the header is not null. I tested with DateTime and DateTime?.

However, it does not apply the format if the data in the first row is null. In the case of DateTime? this results in integers being used in Excel instead of dates. Would support for this be feasible?

Also, thank you for implementing my previously-requested feature so quickly and I feel bad asking for more!

Support for System.Guid .NET property type

I think having to create a custom mapper to parse System.Guid values from a spreadsheet is something the mapper should have built in

If this is not going to be supported, can an example be added to the README .. as I had a hard time making a custom mapper for doing this

.NET sample object:

    public class MySampleTupleObject
    {
        public string Id { get; set; }

        public System.Guid ProcessId { get; set; }
    }

Separate BindingFlags seem to be needed.

When producing the object from a sheet only settable properties are used and, in particular, Readonly properties should be ignored. Presently, the mere presence of such properties causing a crash. Conversely, when writing a sheet Writeonly properties should be ignored. Consequently, two distinct BindingFlag seems necessary.

Invoke the Mapper.Workbook to throw exception

Please look at the code:

The original code, but ForHeader method does not work.

Mapper mapper = new Mapper();
mapper.Ignore<TModel>(t => t.Id).Put(list);

var headerCellStyle = mapper.Workbook.CreateCellStyle();
//Ignore style detail setting code...
mapper.ForHeader(cell =>
{
	cell.Sheet.AutoSizeColumn(cell.ColumnIndex);
	cell.CellStyle = headerCellStyle;
});

Modified Code, it throw NullReferenceException at the mapper.Workbook.CreateCellStyle() line

Mapper mapper = new Mapper();
mapper.Ignore<TModel>(t => t.Id);

var headerCellStyle = mapper.Workbook.CreateCellStyle();
//Ignore style detail setting code...
mapper.ForHeader(cell =>
{
	cell.Sheet.AutoSizeColumn(cell.ColumnIndex);
	cell.CellStyle = headerCellStyle;
});

mapper.Put(list);

Re-modified Code

IWorkbook workbook = new HSSFWorkbook();

Mapper mapper = new Mapper(workbook);
mapper.Ignore<TModel>(t => t.Id);

var headerCellStyle = mapper.Workbook.GetDefaultHeaderCellStyle();
//Ignore style detail setting code...
mapper.ForHeader(cell =>
{
	cell.Sheet.AutoSizeColumn(cell.ColumnIndex);
	cell.CellStyle = headerCellStyle;
});

mapper.Put(list);

I have to create an object for the Workbook property to work properly, but this is not what I want.
I looked at the code of the Mapper class, I think a IWorkbook object should be created inside the default constructor.

As follows:

/// <summary>
/// Initialize a new instance of <see cref="Mapper"/> class.
/// </summary>
public Mapper()
{
	Workbook = new HSSFWorkbook();
}

After that, the Workbook attribute non-null judgment code in your other methods can be deleted.
If you agree to do this, pay attention to your Save method

Mapper.Map重载需求

     Mapper Map<T>(string columnName, string toName)

     如果有这样的重载方法可能会更加方便 ,此方法参数lambda表达式最后的返回值是propInfo,那么 通过 T 和 toName 也是一样可以取到的。谢谢!

Ignore Columns By Property Name (or Names)

First off, awesome tool! As an enhancement, would it be possible to overload the Ignore method to pass properties by property name (as a string), or list of names. Passing in property selector is handy, but it'd be nice to pass in strings.

Would like support for DateTimeOffset

I know this isn't a code writing service, but, would you mind showing a sample custom resolver that converts a DateTime excel column and maps it into a SampleObj.MyDateTimeOffsetProperty - where the property is of type DateTimeOffset?

IgnoredNameChars not working with dynamic

There´s a column named "N.I.F.".
I set the mapper like:

_mapper = new Mapper(filePath) { IgnoredNameChars = new[] { '.' } };

The column is totally ignored when:

_mapper.Take<dynamic>()

Though it works if I change the column name to "NIF"

Questions

  1. Is there any property to set to skip certain number of lines from beginning?
  2. Does the column attribute mapping support chinese?

Thanks

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

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

谢谢

关于 mapper.Take<object>取到的列类型转换失败问题

看了下源码,数据类型是根据列头以外的第一行数据取,假如第一行是字符串,则这一列的所有数据都会转字符串,假如是数值,这一列就全是double。
但是有一种情况是,这一列既第一行是数值,其他行有字符串,然后字符串转数值会转换失败(比如中文不能转换成数字)。
代码在类 MapHelper.InferColumnDataType
请问能不能 mapper.Take 的时候,所有列设置为字符串类型

Mapper.Save Closes stream

Calling Mapper.Save and passing in a stream seems to close the stream. For files this is ok but if this is content we want to stream from a web server this causes errors when trying to write the data to the response. Would it be possible to create an overload which takes a "closeStream" boolean parameter? This would allow the existing stream to be seeked to zero and sent over the wire from asp.net core.

Mapper.Put<T> overload method have bug, ForHeader method will never execute !!!

The firstRow variable does not get the object returned by the PopulateFirstRow method

private void Put<T>(ISheet sheet, IEnumerable<T> objects, bool overwrite)
{
	var sheetName = sheet.SheetName;
	var firstRow = sheet.GetRow(sheet.FirstRowNum);
	var objectArray = objects as T[] ?? objects.ToArray();
	var type = MapHelper.GetConcreteType(objectArray);

	var columns = GetTrackedColumns(sheetName, type) ??
				   GetColumns(firstRow ?? PopulateFirstRow(sheet, null, type), type);

	if (firstRow == null)
	{
		PopulateFirstRow(sheet, columns, type);
	}

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

	var rowIndex = overwrite
		? HasHeader ? sheet.FirstRowNum + 1 : sheet.FirstRowNum
		: sheet.GetRow(sheet.LastRowNum) != null ? sheet.LastRowNum + 1 : sheet.LastRowNum;

	MapHelper.EnsureDefaultFormats(columns, TypeFormats);

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

	// Remove not used rows if any.
	while (overwrite && rowIndex <= sheet.LastRowNum)
	{
		var row = sheet.GetRow(rowIndex);
		if (row != null) sheet.RemoveRow(row);
		rowIndex++;
	}
}

error:

if (firstRow == null)
{
	PopulateFirstRow(sheet, columns, type);
}

right:

if (firstRow == null)
{
	firstRow = PopulateFirstRow(sheet, columns, type);
}

Remove `NetStandard.Library` from .csproj file

  <NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>

this line should be remove because it add unnecessary/obsolete dependancy (current netstandard.library version is 1.6.1 ) , it should be remove even you target netstandard

  <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
  <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
  <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>

those line should be remove too, the default value is true, and Properties/AssemblyInfo.cs will be automatic generate ( in obj folder ) , (it will be compile if you remove Properties/AssemblyInfo.cs )

Problem with read file

When I save the file everything work well, but when i want to read it I see:

System.MissingMethodException : No parameterless constructor defined for this object.
Stack Trace:
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
   at Npoi.Mapper.Mapper.Take[T](ISheet sheet, Int32 maxErrorRows, Func`1 objectInitializer)+MoveNext()
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
var mapper = SummaryMapping.Mapper(PathHelper.directory + "/statement.xlsx");                                                                                                                                                                                  
var test = mapper.Take<SummaryExelPersistence>("sheet0").Count();

What can cause the issue?

FR: Proposed changes to .Map

Proposed changes to .Map

Although the set-up is a bit different, I think some ideas from AutoMapper could be borrowed...

Currently the .Map function is a bit confusing to use.

First of all it will only be executed for properties where map via annotation failed (somehow feels as if it'd be conflicting with those annotations). And second: the given interface is hard to use (needs a lot of extra code).

Would consider (at least excel to object) following changes:

No1
have a ShouldMap function to replace the current .Map - first callback function (should map column)

  • should provide original excel column
  • should provide mapped destination property (if a match via attributes was found) - along with some match details

should return

  • null (if no mapping should occure)
  • or the destination property with a transformation function (optional)

No2
the Map function should change as follows (to work similarly as in case of AutoMapper):

  • should be aware of the original excel column
  • as of the destination column

...and should allow to do any kind of data manipulation from the excel value, before assigning it to the destination property (even value type changes by parsing and so)

Currently we need to match column names as find property names before we can do any extra changes... This would be maybe the first thing i'd consider to change (to pass the matched propertyname to the call)!

No3
AfterMap / BeforeMap could also help to do extra manipulation

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.