mirror of
https://gitee.com/dotnetchina/MiniExcel.git
synced 2024-12-02 03:47:41 +08:00
SaveAsByTemplate support input IEnmerable<IDicionary<string,object>> or DapperRows or DataTable
parameters
This commit is contained in:
parent
fbfca6354e
commit
ff746cf928
@ -8,7 +8,7 @@
|
||||
|
||||
### 0.13.1
|
||||
- [New] SaveAsByTemplate by template bytes, convenient to cache and support multiple users to read the same template at the same time #189
|
||||
- [New] SaveAsByTemplate support input `IEnmerable<IDicionary<string,object>> or DapperRows` parameters [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [New] SaveAsByTemplate support input `IEnmerable<IDicionary<string,object>> or DapperRows or DataTable` parameters [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [Bug] Fix after stream SaveAs/SaveAsByTemplate, miniexcel will close stream [#200](https://github.com/shps951023/MiniExcel/issues/200)
|
||||
|
||||
### 0.13.0
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
### 0.13.1
|
||||
- [New] SaveAsByTemplate 支持读取模板 byte[],方便缓存跟支持多用户同时读取同一个模板 #189
|
||||
- [New] SaveAsByTemplate 支持传入 `IEnmerable<IDicionary<string,object>> 或 DapperRows` 参数 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [New] SaveAsByTemplate 支持传入 `IEnmerable<IDicionary<string,object>> 或 DapperRows 或 DataTable` 参数 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [Bug] 修正使用 stream SaveAs/SaveAsByTemplate 系统会自动关闭流 stream [#200](https://github.com/shps951023/MiniExcel/issues/200)
|
||||
|
||||
### 0.13.0
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
### 0.13.1
|
||||
- [New] SaveAsByTemplate 支持讀取模板 byte[],方便緩存跟支持多用戶同時讀取同一個模板 [#189](https://github.com/shps951023/MiniExcel/issues/189)
|
||||
- [New] SaveAsByTemplate 支持傳入 `IEnmerable<IDicionary<string,object>> 或 DapperRows` 參數 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [New] SaveAsByTemplate 支持傳入 `IEnmerable<IDicionary<string,object>> 或 DapperRows 或 DataTable` 參數 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
- [Bug] 修正使用 stream SaveAs/SaveAsByTemplate 系統會自動關閉流 stream [#200](https://github.com/shps951023/MiniExcel/issues/200)
|
||||
|
||||
### 0.13.0
|
||||
|
@ -3,6 +3,7 @@ using MiniExcelLibs.Zip;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
@ -21,8 +22,9 @@ namespace MiniExcelLibs.OpenXml
|
||||
public string IEnumerablePropName { get; set; }
|
||||
public XmlElement Row { get; set; }
|
||||
public Type IEnumerableGenricType { get; set; }
|
||||
public IDictionary<string, PropInfo > PropsMap { get; set; }
|
||||
public IDictionary<string, PropInfo> PropsMap { get; set; }
|
||||
public bool IsDictionary { get; set; }
|
||||
public bool IsDataTable { get; set; }
|
||||
public IEnumerable CellIEnumerableValues { get; set; }
|
||||
}
|
||||
|
||||
@ -75,12 +77,11 @@ namespace MiniExcelLibs.OpenXml
|
||||
//TODO: some xlsx without r
|
||||
originRowIndex = int.Parse(row.GetAttribute("r"));
|
||||
var newRowIndex = originRowIndex + rowIndexDiff;
|
||||
|
||||
if (xInfo.CellIEnumerableValues != null)
|
||||
{
|
||||
var first = true;
|
||||
|
||||
|
||||
|
||||
foreach (var item in xInfo.CellIEnumerableValues)
|
||||
{
|
||||
var newRow = row.Clone() as XmlElement;
|
||||
@ -107,6 +108,42 @@ namespace MiniExcelLibs.OpenXml
|
||||
}
|
||||
|
||||
|
||||
var cellValueStr = ExcelOpenXmlUtils.EncodeXML(cellValue);
|
||||
var type = propInfo.Value.UnderlyingTypePropType;
|
||||
if (type == typeof(bool))
|
||||
{
|
||||
cellValueStr = (bool)cellValue ? "1" : "0";
|
||||
}
|
||||
else if (type == typeof(DateTime))
|
||||
{
|
||||
//c.SetAttribute("t", "d");
|
||||
cellValueStr = ((DateTime)cellValue).ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
//TODO: ![image](https://user-images.githubusercontent.com/12729184/114848248-17735880-9e11-11eb-8258-63266bda0a1a.png)
|
||||
newRow.InnerXml = newRow.InnerXml.Replace(key, cellValueStr);
|
||||
}
|
||||
}
|
||||
else if (xInfo.IsDataTable)
|
||||
{
|
||||
var datarow = item as DataRow;
|
||||
foreach (var propInfo in xInfo.PropsMap)
|
||||
{
|
||||
var key = $"{{{{{xInfo.IEnumerablePropName}.{propInfo.Key}}}}}";
|
||||
if (item == null) //![image](https://user-images.githubusercontent.com/12729184/114728510-bc3e5900-9d71-11eb-9721-8a414dca21a0.png)
|
||||
{
|
||||
newRow.InnerXml = newRow.InnerXml.Replace(key, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
var cellValue = datarow[propInfo.Key];
|
||||
if (cellValue == null)
|
||||
{
|
||||
newRow.InnerXml = newRow.InnerXml.Replace(key, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var cellValueStr = ExcelOpenXmlUtils.EncodeXML(cellValue);
|
||||
var type = propInfo.Value.UnderlyingTypePropType;
|
||||
if (type == typeof(bool))
|
||||
@ -279,9 +316,9 @@ namespace MiniExcelLibs.OpenXml
|
||||
{
|
||||
xRowInfo.IsDictionary = true;
|
||||
var dic = element as IDictionary<string, object>;
|
||||
xRowInfo.PropsMap = dic.Keys.ToDictionary(key => key, key => dic[key] != null
|
||||
? new PropInfo { UnderlyingTypePropType= Nullable.GetUnderlyingType(dic[key].GetType()) ?? dic[key].GetType() }
|
||||
: new PropInfo { UnderlyingTypePropType = typeof(object) } ) ;
|
||||
xRowInfo.PropsMap = dic.Keys.ToDictionary(key => key, key => dic[key] != null
|
||||
? new PropInfo { UnderlyingTypePropType = Nullable.GetUnderlyingType(dic[key].GetType()) ?? dic[key].GetType() }
|
||||
: new PropInfo { UnderlyingTypePropType = typeof(object) });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -296,14 +333,13 @@ namespace MiniExcelLibs.OpenXml
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: check if not contain 1 index
|
||||
//only check first one match IEnumerable, so only render one collection at same row
|
||||
|
||||
// auto check type https://github.com/shps951023/MiniExcel/issues/177
|
||||
var prop = xRowInfo.PropsMap[propNames[1]];
|
||||
var type = prop.UnderlyingTypePropType; //avoid nullable
|
||||
//
|
||||
//
|
||||
if (!xRowInfo.PropsMap.ContainsKey(propNames[1]))
|
||||
throw new InvalidDataException($"{propNames[0]} doesn't have {propNames[1]} property");
|
||||
|
||||
@ -326,6 +362,43 @@ namespace MiniExcelLibs.OpenXml
|
||||
|
||||
break;
|
||||
}
|
||||
else if (cellValue is DataTable)
|
||||
{
|
||||
var dt = cellValue as DataTable;
|
||||
if (xRowInfo.CellIEnumerableValues == null)
|
||||
{
|
||||
xRowInfo.IEnumerablePropName = propNames[0];
|
||||
xRowInfo.IEnumerableGenricType = typeof(DataRow);
|
||||
xRowInfo.IsDataTable = true;
|
||||
xRowInfo.CellIEnumerableValues = dt.Rows.Cast<DataRow>(); //TODO: need to optimize performance
|
||||
maxRowIndexDiff = dt.Rows.Count <= 1 ? 0 : dt.Rows.Count;
|
||||
xRowInfo.PropsMap = dt.Columns.Cast<DataColumn>().ToDictionary(col => col.ColumnName, col =>
|
||||
new PropInfo { UnderlyingTypePropType = Nullable.GetUnderlyingType(col.DataType) }
|
||||
);
|
||||
}
|
||||
|
||||
var column = dt.Columns[propNames[1]];
|
||||
var type = Nullable.GetUnderlyingType(column.DataType) ?? column.DataType; //avoid nullable
|
||||
if (!xRowInfo.PropsMap.ContainsKey(propNames[1]))
|
||||
throw new InvalidDataException($"{propNames[0]} doesn't have {propNames[1]} property");
|
||||
|
||||
if (isMultiMatch)
|
||||
{
|
||||
c.SetAttribute("t", "str");
|
||||
}
|
||||
else if (Helpers.IsNumericType(type))
|
||||
{
|
||||
c.SetAttribute("t", "n");
|
||||
}
|
||||
else if (Type.GetTypeCode(type) == TypeCode.Boolean)
|
||||
{
|
||||
c.SetAttribute("t", "b");
|
||||
}
|
||||
else if (Type.GetTypeCode(type) == TypeCode.DateTime)
|
||||
{
|
||||
c.SetAttribute("t", "str");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var cellValueStr = ExcelOpenXmlUtils.EncodeXML(cellValue);
|
||||
|
@ -3,6 +3,7 @@ using MiniExcelLibs;
|
||||
using MiniExcelLibs.Tests.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
@ -11,6 +12,147 @@ namespace MiniExcelTests
|
||||
{
|
||||
public class MiniExcelTemplateTests
|
||||
{
|
||||
[Fact]
|
||||
public void DatatableTemptyRowTest()
|
||||
{
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
var templatePath = @"..\..\..\..\..\samples\xlsx\TestTemplateComplex.xlsx";
|
||||
var managers = new DataTable();
|
||||
{
|
||||
managers.Columns.Add("name");
|
||||
managers.Columns.Add("department");
|
||||
}
|
||||
var employees = new DataTable();
|
||||
{
|
||||
employees.Columns.Add("name");
|
||||
employees.Columns.Add("department");
|
||||
}
|
||||
var value = new Dictionary<string, object>()
|
||||
{
|
||||
["title"] = "FooCompany",
|
||||
["managers"] = managers,
|
||||
["employees"] = employees
|
||||
};
|
||||
MiniExcel.SaveAsByTemplate(path, templatePath, value);
|
||||
{
|
||||
var rows = MiniExcel.Query(path).ToList();
|
||||
|
||||
var demension = Helpers.GetFirstSheetDimensionRefValue(path);
|
||||
Assert.Equal("A1:C5", demension);
|
||||
}
|
||||
}
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
var templatePath = @"..\..\..\..\..\samples\xlsx\TestTemplateComplex.xlsx";
|
||||
var managers = new DataTable();
|
||||
{
|
||||
managers.Columns.Add("name");
|
||||
managers.Columns.Add("department");
|
||||
managers.Rows.Add("Jack", "HR");
|
||||
}
|
||||
var employees = new DataTable();
|
||||
{
|
||||
employees.Columns.Add("name");
|
||||
employees.Columns.Add("department");
|
||||
employees.Rows.Add("Wade", "HR");
|
||||
}
|
||||
var value = new Dictionary<string, object>()
|
||||
{
|
||||
["title"] = "FooCompany",
|
||||
["managers"] = managers,
|
||||
["employees"] = employees
|
||||
};
|
||||
MiniExcel.SaveAsByTemplate(path, templatePath, value);
|
||||
{
|
||||
var rows = MiniExcel.Query(path).ToList();
|
||||
|
||||
var demension = Helpers.GetFirstSheetDimensionRefValue(path);
|
||||
Assert.Equal("A1:C5", demension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatatableTest()
|
||||
{
|
||||
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
|
||||
var templatePath = @"..\..\..\..\..\samples\xlsx\TestTemplateComplex.xlsx";
|
||||
var managers = new DataTable();
|
||||
{
|
||||
managers.Columns.Add("name");
|
||||
managers.Columns.Add("department");
|
||||
managers.Rows.Add("Jack", "HR");
|
||||
managers.Rows.Add("Loan", "IT");
|
||||
}
|
||||
var employees = new DataTable();
|
||||
{
|
||||
employees.Columns.Add("name");
|
||||
employees.Columns.Add("department");
|
||||
employees.Rows.Add("Wade", "HR");
|
||||
employees.Rows.Add("Felix", "HR");
|
||||
employees.Rows.Add("Eric", "IT");
|
||||
employees.Rows.Add("Keaton", "IT");
|
||||
}
|
||||
var value = new Dictionary<string, object>()
|
||||
{
|
||||
["title"] = "FooCompany",
|
||||
["managers"] = managers,
|
||||
["employees"] = employees
|
||||
};
|
||||
MiniExcel.SaveAsByTemplate(path, templatePath, value);
|
||||
{
|
||||
var rows = MiniExcel.Query(path).ToList();
|
||||
|
||||
var demension = Helpers.GetFirstSheetDimensionRefValue(path);
|
||||
Assert.Equal("A1:C9", demension);
|
||||
|
||||
Assert.Equal(9, rows.Count);
|
||||
|
||||
Assert.Equal("FooCompany", rows[0].A);
|
||||
Assert.Equal("Jack", rows[2].B);
|
||||
Assert.Equal("HR", rows[2].C);
|
||||
Assert.Equal("Loan", rows[3].B);
|
||||
Assert.Equal("IT", rows[3].C);
|
||||
|
||||
Assert.Equal("Wade", rows[5].B);
|
||||
Assert.Equal("HR", rows[5].C);
|
||||
Assert.Equal("Felix", rows[6].B);
|
||||
Assert.Equal("HR", rows[6].C);
|
||||
|
||||
Assert.Equal("Eric", rows[7].B);
|
||||
Assert.Equal("IT", rows[7].C);
|
||||
Assert.Equal("Keaton", rows[8].B);
|
||||
Assert.Equal("IT", rows[8].C);
|
||||
}
|
||||
|
||||
{
|
||||
var rows = MiniExcel.Query(path, sheetName: "Sheet2").ToList();
|
||||
|
||||
Assert.Equal(9, rows.Count);
|
||||
|
||||
Assert.Equal("FooCompany", rows[0].A);
|
||||
Assert.Equal("Jack", rows[2].B);
|
||||
Assert.Equal("HR", rows[2].C);
|
||||
Assert.Equal("Loan", rows[3].B);
|
||||
Assert.Equal("IT", rows[3].C);
|
||||
|
||||
Assert.Equal("Wade", rows[5].B);
|
||||
Assert.Equal("HR", rows[5].C);
|
||||
Assert.Equal("Felix", rows[6].B);
|
||||
Assert.Equal("HR", rows[6].C);
|
||||
|
||||
Assert.Equal("Eric", rows[7].B);
|
||||
Assert.Equal("IT", rows[7].C);
|
||||
Assert.Equal("Keaton", rows[8].B);
|
||||
Assert.Equal("IT", rows[8].C);
|
||||
|
||||
var demension = Helpers.GetFirstSheetDimensionRefValue(path);
|
||||
Assert.Equal("A1:C9", demension);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void DapperTemplateTest()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user