Skip to content

Commit 44b89cc

Browse files
committed
0.13.5
- [New] Support QueryAsDataTable method [#216](#216) - [New] SaveAs support IDataReader value parameter [#211](#211) - [Bug] Fix numeric format string will be cast to numeric type [#I3OSKV](https://gitee.com/dotnetchina/MiniExcel/issues/I3OSKV) - [Opt] Optimize SaveAs convert value type logic to improve performance
1 parent 8a45590 commit 44b89cc

File tree

10 files changed

+150
-104
lines changed

10 files changed

+150
-104
lines changed

README.md

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,22 @@ foreach(IDictionary<string,object> row in MiniExcel.Query(path))
227227

228228

229229

230+
#### 9. Query Query Excel return DataTable
231+
232+
Not recommended, because DataTable will load all data into memory and lose MiniExcel's low memory consumption feature.
233+
234+
```C#
235+
var table = MiniExcel.QueryAsDataTable(path, useHeaderRow: true);
236+
```
237+
238+
![image](https://user-images.githubusercontent.com/12729184/116673475-07917200-a9d6-11eb-947e-a6f68cce58df.png)
239+
240+
241+
242+
243+
244+
245+
230246
### Create Excel <a name="getstart2"></a>
231247

232248
1. Must be a non-abstract type with a public parameterless constructor .
@@ -302,6 +318,12 @@ using (var stream = File.Create(path))
302318
}
303319
```
304320

321+
#### 6. Support IDataReader value parameter
322+
323+
```csharp
324+
MiniExcel.SaveAs(path, reader);
325+
```
326+
305327

306328

307329
### Fill Data To Excel Template <a name="getstart3"></a>
@@ -760,38 +782,6 @@ public static IEnumerable<T> Page<T>(IEnumerable<T> en, int pageSize, int page)
760782

761783
### FAQ
762784

763-
#### Q: How to convert query results to DataTable
764-
765-
Reminder: Not recommended, because DataTable will load all data into memory and lose MiniExcel's low memory consumption function.
766-
767-
```csharp
768-
public static DataTable QueryAsDataTable(string path)
769-
{
770-
var rows = MiniExcel.Query(path, true);
771-
var dt = new DataTable();
772-
var first = true;
773-
foreach (IDictionary<string, object> row in rows)
774-
{
775-
if (first)
776-
{
777-
foreach (var key in row.Keys)
778-
{
779-
var type = row[key]?.GetType() ?? typeof(string);
780-
dt.Columns.Add(key, type);
781-
}
782-
783-
first = false;
784-
}
785-
dt.Rows.Add(row.Values.ToArray());
786-
}
787-
return dt;
788-
}
789-
```
790-
791-
![image](https://user-images.githubusercontent.com/12729184/115068722-3105c480-9f25-11eb-8f5a-994416754134.png)
792-
793-
794-
795785
#### Q: Excel header title not equal class property name, how to mapping?
796786

797787
A. Please use ExcelColumnName attribute

README.zh-CN.md

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,15 @@ foreach(IDictionary<string,object> row in MiniExcel.Query(path))
231231
}
232232
```
233233

234+
#### 9. Query 读 Excel 返回 DataTable
234235

236+
提醒 : 不建议使用,因为DataTable会将数据`全载入内存`,失去MiniExcel低内存消耗功能。
237+
238+
```C#
239+
var table = MiniExcel.QueryAsDataTable(path, useHeaderRow: true);
240+
```
241+
242+
![image](https://user-images.githubusercontent.com/12729184/116673475-07917200-a9d6-11eb-947e-a6f68cce58df.png)
235243

236244

237245

@@ -297,7 +305,7 @@ output :
297305
| MiniExcel | 1 |
298306
| Github | 2 |
299307

300-
#### 5. SaveAs 支援 Stream [[Try it]](https://dotnetfiddle.net/JOen0e)
308+
#### 5. SaveAs 支持 Stream [[Try it]](https://dotnetfiddle.net/JOen0e)
301309

302310
```csharp
303311
using (var stream = File.Create(path))
@@ -308,6 +316,14 @@ using (var stream = File.Create(path))
308316

309317

310318

319+
#### 6. 支持 IDataReader 参数
320+
321+
```csharp
322+
MiniExcel.SaveAs(path, reader);
323+
```
324+
325+
326+
311327

312328

313329
### 模板填充 Excel <a name="getstart3"></a>
@@ -769,36 +785,6 @@ public static IEnumerable<T> Page<T>(IEnumerable<T> en, int pageSize, int page)
769785

770786
### FAQ 常见问题
771787

772-
#### Q: 如何将查询结果转为 DataTable
773-
774-
提醒 : 不建议使用,因为DataTable会将数据`全载入内存`,失去MiniExcel低内存消耗功能。
775-
776-
```csharp
777-
public static DataTable QueryAsDataTable(string path)
778-
{
779-
var rows = MiniExcel.Query(path, true);
780-
var dt = new DataTable();
781-
var first = true;
782-
foreach (IDictionary<string, object> row in rows)
783-
{
784-
if (first)
785-
{
786-
foreach (var key in row.Keys)
787-
{
788-
var type = row[key]?.GetType() ?? typeof(string);
789-
dt.Columns.Add(key, type);
790-
}
791-
792-
first = false;
793-
}
794-
dt.Rows.Add(row.Values.ToArray());
795-
}
796-
return dt;
797-
}
798-
```
799-
800-
![image](https://user-images.githubusercontent.com/12729184/115068549-fac84500-9f24-11eb-9f12-884b19cf1489.png)
801-
802788
#### Q: Excel 表头标题名称跟 class 属性名称不一致,如何对应?
803789

804790
A. 请使用 ExcelColumnName 作 mapping

README.zh-Hant.md

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,21 @@ foreach(IDictionary<string,object> row in MiniExcel.Query(path))
229229
}
230230
```
231231

232+
![image](https://user-images.githubusercontent.com/12729184/116673475-07917200-a9d6-11eb-947e-a6f68cce58df.png)
232233

233234

234235

236+
#### 9. Query 讀 Excel 返回 DataTable
237+
238+
提醒 : 不建議使用,因為DataTable會將數據`全載入內存`,失去MiniExcel低記憶體消耗功能。
239+
240+
```C#
241+
var table = MiniExcel.QueryAsDataTable(path, useHeaderRow: true);
242+
```
243+
244+
![image](https://user-images.githubusercontent.com/12729184/116673475-07917200-a9d6-11eb-947e-a6f68cce58df.png)
245+
246+
235247

236248
### 寫 Excel <a name="getstart2"></a>
237249

@@ -304,7 +316,11 @@ using (var stream = File.Create(path))
304316
}
305317
```
306318

319+
#### 6. 支持 IDataReader 參數
307320

321+
```csharp
322+
MiniExcel.SaveAs(path, reader);
323+
```
308324

309325

310326

@@ -768,36 +784,6 @@ public static IEnumerable<T> Page<T>(IEnumerable<T> en, int pageSize, int page)
768784

769785
### FAQ 常見問題
770786

771-
#### Q: 如何將查詢結果轉為 DataTable
772-
773-
提醒 : 不建議使用,因為DataTable會將數據`全載入記憶體`,失去MiniExcel低記憶體消耗功能。
774-
775-
```csharp
776-
public static DataTable QueryAsDataTable(string path)
777-
{
778-
var rows = MiniExcel.Query(path, true);
779-
var dt = new DataTable();
780-
var first = true;
781-
foreach (IDictionary<string, object> row in rows)
782-
{
783-
if (first)
784-
{
785-
foreach (var key in row.Keys)
786-
{
787-
var type = row[key]?.GetType() ?? typeof(string);
788-
dt.Columns.Add(key, type);
789-
}
790-
791-
first = false;
792-
}
793-
dt.Rows.Add(row.Values.ToArray());
794-
}
795-
return dt;
796-
}
797-
```
798-
799-
![image](https://user-images.githubusercontent.com/12729184/115068722-3105c480-9f25-11eb-8f5a-994416754134.png)
800-
801787
#### Q: Excel 表頭標題名稱跟 class 屬性名稱不一致,如何對應?
802788

803789
A. 請使用 ExcelColumnName 作 mapping

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
### 0.13.5
1010
- [New] Support QueryAsDataTable method [#216](https://github.com/shps951023/MiniExcel/issues/216)
11+
- [New] SaveAs support IDataReader value parameter [#211](https://github.com/shps951023/MiniExcel/issues/211)
1112
- [Bug] Fix numeric format string will be cast to numeric type [#I3OSKV](https://gitee.com/dotnetchina/MiniExcel/issues/I3OSKV)
1213
- [Opt] Optimize SaveAs convert value type logic to improve performance
1314

docs/README.zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
### 0.13.5
1111
- [New] 新增 QueryAsDataTable 方法 [#216](https://github.com/shps951023/MiniExcel/issues/216)
12+
- [New] SaveAs 支持 IDataReader value 参数 [#211](https://github.com/shps951023/MiniExcel/issues/211)
1213
- [Bug] 修正数字格式的字串会被强制转换为decimal类型 [#I3OSKV](https://gitee.com/dotnetchina/MiniExcel/issues/I3OSKV)
1314
- [Opt] 优化 SaveAs 类别转换算法,避免效率浪费
1415

docs/README.zh-Hant.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
### 0.13.5
1111
- [New] 新增 QueryAsDataTable 方法 [#216](https://github.com/shps951023/MiniExcel/issues/216)
12+
- [New] SaveAs 支持 IDataReader value 參數 [#211](https://github.com/shps951023/MiniExcel/issues/211)
1213
- [Bug] 修正數字格式的字串會被強制轉換為decimal類型 [#I3OSKV](https://gitee.com/dotnetchina/MiniExcel/issues/I3OSKV)
1314
- [Opt] 優化 SaveAs 類別轉換算法,避免效率浪費
1415

src/MiniExcel/MiniExcel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public static void SaveAsByTemplate(this Stream stream, byte[] templateBytes, ob
106106
/// <summary>
107107
/// This method is not recommended, because it'll load all data into memory.
108108
/// </summary>
109-
public static DataTable QueryAsDataTable(string path, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null)
109+
public static DataTable QueryAsDataTable(string path, bool useHeaderRow = true, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null)
110110
{
111111
using (var stream = Helpers.OpenSharedRead(path))
112112
return QueryAsDataTable(stream, useHeaderRow, sheetName, GetExcelType(path, excelType), configuration);
@@ -115,7 +115,7 @@ public static DataTable QueryAsDataTable(string path, bool useHeaderRow = false,
115115
/// <summary>
116116
/// This method is not recommended, because it'll load all data into memory.
117117
/// </summary>
118-
public static DataTable QueryAsDataTable(this Stream stream, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null)
118+
public static DataTable QueryAsDataTable(this Stream stream, bool useHeaderRow = true, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null)
119119
{
120120
var dt = new DataTable();
121121
dt.TableName = sheetName;

src/MiniExcel/MiniExcelLibs.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net45;netstandard2.0;net5.0</TargetFrameworks>
4-
<Version>0.13.4</Version>
4+
<Version>0.13.5</Version>
55
</PropertyGroup>
66
<PropertyGroup>
77
<AssemblyName>MiniExcel</AssemblyName>

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,10 @@ public void SaveAs(object value, string sheetName, bool printHeader, IConfigurat
165165
{
166166
GenerateSheetByDataTable(writer, archive, value as DataTable, printHeader);
167167
}
168+
else if (value is IDataReader)
169+
{
170+
GenerateSheetByIDataReader(writer, archive, value as IDataReader, printHeader);
171+
}
168172
else
169173
{
170174
throw new NotImplementedException($"Type {type.Name} & genericType {genericType.Name} not Implemented. please issue for me.");
@@ -332,6 +336,55 @@ private void GenerateSheetByDataTable(StreamWriter writer, MiniExcelZipArchive a
332336
writer.Write("</x:sheetData></x:worksheet>");
333337
}
334338

339+
private void GenerateSheetByIDataReader(StreamWriter writer, MiniExcelZipArchive archive, IDataReader value, bool printHeader)
340+
{
341+
var xy = ExcelOpenXmlUtils.ConvertCellToXY("A1");
342+
343+
writer.Write($@"<?xml version=""1.0"" encoding=""utf-8""?><x:worksheet xmlns:x=""http://schemas.openxmlformats.org/spreadsheetml/2006/main"">");
344+
{
345+
var yIndex = xy.Item2;
346+
347+
// TODO: dimension
348+
//var maxRowIndex = value.Rows.Count + (printHeader && value.Rows.Count > 0 ? 1 : 0);
349+
//var maxColumnIndex = value.Columns.Count;
350+
//writer.Write($@"<x:dimension ref=""{GetDimensionRef(maxRowIndex, maxColumnIndex)}""/>");
351+
writer.Write("<x:sheetData>");
352+
int fieldCount = value.FieldCount;
353+
if (printHeader)
354+
{
355+
writer.Write($"<x:row r=\"{yIndex.ToString()}\">");
356+
var xIndex = xy.Item1;
357+
for (int i = 0; i < fieldCount; i++)
358+
{
359+
var r = ExcelOpenXmlUtils.ConvertXyToCell(xIndex, yIndex);
360+
writer.Write($"<x:c r=\"{r}\" t=\"str\">");
361+
writer.Write($"<x:v>{value.GetName(i)}");
362+
writer.Write($"</x:v>");
363+
writer.Write($"</x:c>");
364+
xIndex++;
365+
}
366+
writer.Write($"</x:row>");
367+
yIndex++;
368+
}
369+
370+
while (value.Read())
371+
{
372+
writer.Write($"<x:row r=\"{yIndex.ToString()}\">");
373+
var xIndex = xy.Item1;
374+
375+
for(int i = 0; i < fieldCount; i++)
376+
{
377+
var cellValue = value.GetValue(i);
378+
WriteCell(writer, yIndex, xIndex, cellValue);
379+
xIndex++;
380+
}
381+
writer.Write($"</x:row>");
382+
yIndex++;
383+
}
384+
}
385+
writer.Write("</x:sheetData></x:worksheet>");
386+
}
387+
335388
private void GenerateContentTypesXml(MiniExcelZipArchive archive, Dictionary<string, ZipPackageInfo> packages)
336389
{
337390
//[Content_Types].xml

0 commit comments

Comments
 (0)