[New] Support GetReader method #328 #290

This commit is contained in:
Wei 2022-02-14 16:22:59 +08:00
parent d016c2c524
commit c46a03dfc7
10 changed files with 316 additions and 1 deletions

View File

@ -910,6 +910,25 @@ MiniExcel.SaveAs(path, value,excelType:ExcelType.CSV, configuration: config);
### DataReader
#### 1. GetReader
Since 1.23.0, you can GetDataReader
```csharp
using (var reader = MiniExcel.GetReader(path,true))
{
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var value = reader.GetValue(i);
}
}
}
```
### Async
@ -993,6 +1012,8 @@ MiniExcel.Query(path, configuration: config);
### Examples:
#### 1. SQLite & Dapper `Large Size File` SQL Insert Avoid OOM

View File

@ -914,6 +914,29 @@ MiniExcel.SaveAs(path, value,excelType:ExcelType.CSV, configuration: config);
### DataReader
#### 1. GetReader
从 1.23.0 版本开始能获取 DataReader
```csharp
using (var reader = MiniExcel.GetReader(path,true))
{
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var value = reader.GetValue(i);
}
}
}
```
### 异步 Async
从 v0.17.0 版本开始支持异步 (感谢[isdaniel ( SHIH,BING-SIOU)](https://github.com/isdaniel))

View File

@ -922,6 +922,26 @@ MiniExcel.SaveAs(path, value,excelType:ExcelType.CSV, configuration: config);
```
### DataReader
#### 1. GetReader
从 1.23.0 版本开始能获取 DataReader
```csharp
using (var reader = MiniExcel.GetReader(path,true))
{
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var value = reader.GetValue(i);
}
}
}
```
### 異步 Async

View File

@ -16,7 +16,13 @@
---
### 1.23.0
- [New] Support `GetReader` method #328 #290 (Thanks [杨福来 Yang](https://github.com/yfl8910) )
### 1.22.0
- [New] SaveAs support to custom CultureInfo #316
- [New] Query support to custom CultureInfo #316
- [New] New efficiency byte array Converter #327

View File

@ -24,6 +24,9 @@
---
### 1.23.0
- [New] 新增 `GetReader` 方法 #328 #290 (感谢 [杨福来 Yang](https://github.com/yfl8910) )
### 1.22.0
- [New] SaveAs 支持自定义 CultureInfo #316
- [New] Query 支持自定义 CultureInfo #316

View File

@ -17,7 +17,13 @@
---
### 1.23.0
- [New] 新增 `GetReader` 方法 #328 #290 (感謝 [楊福來 Yang](https://github.com/yfl8910) )
### 1.22.0
- [New] SaveAs 支持自定義 CultureInfo #316
- [New] Query 支持自定義 CultureInfo #316
- [New] 新 byte array 轉換器 #327

View File

@ -12,6 +12,17 @@
public static partial class MiniExcel
{
public static MiniExcelDataReader GetReader(string path, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null)
{
var stream = FileHelper.OpenSharedRead(path);
return new MiniExcelDataReader(stream, useHeaderRow, sheetName, excelType, startCell, configuration);
}
public static MiniExcelDataReader GetDataReader(this Stream stream, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null)
{
return new MiniExcelDataReader(stream, useHeaderRow, sheetName, excelType, startCell, configuration);
}
public static void SaveAs(string path, object value, bool printHeader = true, string sheetName = "Sheet1", ExcelType excelType = ExcelType.UNKNOWN, IConfiguration configuration = null)
{
if (Path.GetExtension(path).ToLowerInvariant() == ".xlsm")

View File

@ -0,0 +1,186 @@
namespace MiniExcelLibs
{
using MiniExcelLibs.Utils;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
public class MiniExcelDataReader : IDataReader
{
private readonly IEnumerator<IDictionary<string, object>> _source;
private readonly int _fieldCount;
private readonly List<string> _keys;
private readonly Stream _stream;
private bool _isFirst = true;
internal MiniExcelDataReader(Stream stream, bool useHeaderRow = false, string sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration configuration = null)
{
_stream = stream;
_source = MiniExcel.Query(_stream, useHeaderRow, sheetName, excelType, startCell, configuration).Cast<IDictionary<string, object>>().GetEnumerator();
var isNext = _source.MoveNext();
if (isNext)
{
_keys = _source.Current.Keys.ToList();
_fieldCount = _keys.Count;
}
}
public void Dispose()
{
_stream.Dispose();
}
public object GetValue(int i)
{
return _source.Current[_keys[i]];
}
public int FieldCount
{
get { return _fieldCount; }
}
public bool Read()
{
if (_isFirst)
{
_isFirst = false;
return true;
}
return _source.MoveNext();
}
public string GetName(int i)
{
return _keys[i];
}
public int GetOrdinal(string name)
{
var i = _keys.IndexOf(name);
return _keys.IndexOf(name);
}
public void Close()
{
throw new NotImplementedException();
}
public int Depth => throw new NotImplementedException();
public bool IsClosed => throw new NotImplementedException();
public int RecordsAffected => throw new NotImplementedException();
public object this[string name] => throw new NotImplementedException();
public object this[int i] => throw new NotImplementedException();
public DataTable GetSchemaTable()
{
throw new NotImplementedException();
}
public bool NextResult()
{
throw new NotImplementedException();
}
public bool GetBoolean(int i)
{
throw new NotImplementedException();
}
public byte GetByte(int i)
{
throw new NotImplementedException();
}
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public char GetChar(int i)
{
throw new NotImplementedException();
}
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}
public IDataReader GetData(int i)
{
throw new NotImplementedException();
}
public string GetDataTypeName(int i)
{
throw new NotImplementedException();
}
public DateTime GetDateTime(int i)
{
throw new NotImplementedException();
}
public decimal GetDecimal(int i)
{
throw new NotImplementedException();
}
public double GetDouble(int i)
{
throw new NotImplementedException();
}
public Type GetFieldType(int i)
{
throw new NotImplementedException();
}
public float GetFloat(int i)
{
throw new NotImplementedException();
}
public Guid GetGuid(int i)
{
throw new NotImplementedException();
}
public short GetInt16(int i)
{
throw new NotImplementedException();
}
public int GetInt32(int i)
{
throw new NotImplementedException();
}
public long GetInt64(int i)
{
throw new NotImplementedException();
}
public string GetString(int i)
{
throw new NotImplementedException();
}
public int GetValues(object[] values)
{
throw new NotImplementedException();
}
public bool IsDBNull(int i)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0;net5.0</TargetFrameworks>
<Version>1.22.0</Version>
<Version>1.23.0</Version>
</PropertyGroup>
<PropertyGroup>
<AssemblyName>MiniExcel</AssemblyName>

View File

@ -31,6 +31,45 @@ namespace MiniExcelLibs.Tests
this.output = output;
}
[Fact]
public void TestIssue328()
{
var path = PathHelper.GetTempFilePath();
var value = new[] {
new { id=1,name="Jack",indate=new DateTime(2022,5,13), file = File.ReadAllBytes(PathHelper.GetFile("images/TestIssue327.png")) },
new { id=2,name="Henry",indate=new DateTime(2022,4,10), file = File.ReadAllBytes(PathHelper.GetFile("other/TestIssue327.txt")) },
};
MiniExcel.SaveAs(path, value);
var rowIndx = 0;
using (var reader = MiniExcel.GetReader(path,true))
{
Assert.Equal("id", reader.GetName(0));
Assert.Equal("name", reader.GetName(1));
Assert.Equal("indate", reader.GetName(2));
Assert.Equal("file", reader.GetName(3));
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
var v = reader.GetValue(i);
if (rowIndx==0 && i==0) Assert.Equal((double)1,v);
if (rowIndx == 0 && i == 1) Assert.Equal("Jack", v);
if (rowIndx == 0 && i == 2) Assert.Equal(new DateTime(2022, 5, 13), v);
if (rowIndx == 0 && i == 3) Assert.Equal(File.ReadAllBytes(PathHelper.GetFile("images/TestIssue327.png")), v);
if (rowIndx == 1 && i == 0) Assert.Equal((double)2, v);
if (rowIndx == 1 && i == 1) Assert.Equal("Henry", v);
if (rowIndx == 1 && i == 2) Assert.Equal(new DateTime(2022, 4, 10), v);
if (rowIndx == 1 && i == 3) Assert.Equal(File.ReadAllBytes(PathHelper.GetFile("other/TestIssue327.txt")), v);
}
rowIndx++;
}
}
//TODO:How to resolve empty body sheet?
}
[Fact]
public void TestIssue327()
{