mirror of
https://gitee.com/dotnetchina/MiniExcel.git
synced 2024-11-29 18:38:08 +08:00
0.13.2
- [Bug] Fix Column more than 255 rows cannot be read error [#208](https://github.com/shps951023/MiniExcel/issues/#208)
This commit is contained in:
parent
7c2a4dd337
commit
9b593cb474
@ -25,14 +25,16 @@ At present, most popular frameworks need to load all the data into the memory to
|
||||
### Get Started
|
||||
|
||||
- [Excel Query](#getstart1)
|
||||
|
||||
- [Create Excel](#getstart2)
|
||||
|
||||
- [Fill Data To Excel Template](#getstart3)
|
||||
|
||||
- [Excel Column Name/Index/Ignore Attribute](#getstart4)
|
||||
|
||||
- [Examples](#getstart5)
|
||||
|
||||
### Demo
|
||||
|
||||
- LINQPad : Download [Basic Demo.linq](drafts/【MiniExcel】Basic%20Demo.linq)
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
|
@ -39,9 +39,6 @@ MiniExcel简单、高效避免OOM的.NET处理Excel查、写、填充数据工
|
||||
|
||||
|
||||
|
||||
### Demo
|
||||
- LINQPad : Download [Basic Demo.linq](drafts/[MiniExcel]Basic%20Demo.linq)
|
||||
|
||||
### 安装
|
||||
|
||||
请查看 [from NuGet](https://www.nuget.org/packages/MiniExcel)
|
||||
|
@ -1,4 +1,4 @@
|
||||
[![NuGet](https://img.shields.io/nuget/v/MiniExcel.svg)](https://www.nuget.org/packages/MiniExcel) [![](https://img.shields.io/nuget/dt/MiniExcel.svg)](https://www.nuget.org/packages/MiniExcel) [![Build status](https://ci.appveyor.com/api/projects/status/b2vustrwsuqx45f4/branch/master?svg=true)](https://ci.appveyor.com/project/shps951023/miniexcel/branch/master) [![.NET Framework](https://img.shields.io/badge/.NET%20Framework-%3E%3D%204.5-red.svg)](#) [![.NET Standard](https://img.shields.io/badge/.NET%20Standard-%3E%3D%202.0-red.svg)](#) [![.NET](https://img.shields.io/badge/.NET%20-%3E%3D%205.0-red.svg)](#)
|
||||
[![NuGet](https://img.shields.io/nuget/v/MiniExcel.svg)](https://www.nuget.org/packages/MiniExcel) [![](https://img.shields.io/nuget/dt/MiniExcel.svg)](https://www.nuget.org/packages/MiniExcel) [![Build status](https://ci.appveyor.com/api/projects/status/b2vustrwsuqx45f4/branch/master?svg=true)](https://ci.appveyor.com/project/shps951023/miniexcel/branch/master) [![.NET Framework](https://img.shields.io/badge/.NET%20Framework-%3E%3D%204.5-red.svg)](#) [![.NET Standard](https://img.shields.io/badge/.NET%20Standard-%3E%3D%202.0-red.svg)](#) [![.NET](https://img.shields.io/badge/.NET%20-%3E%3D%205.0-red.svg)](#) [![](https://img.shields.io/badge/Facebook-1877F2?logo=facebook&logoColor=white)](https://www.facebook.com/MiniExcel)
|
||||
|
||||
---
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
|
||||
---
|
||||
|
||||
Facebook : https://www.facebook.com/miniexcel
|
||||
|
||||
---
|
||||
|
||||
### 簡介
|
||||
|
||||
MiniExcel 簡單、高效避免OOM的.NET處理Excel查、寫、填充工具。
|
||||
@ -39,10 +35,6 @@ MiniExcel 簡單、高效避免OOM的.NET處理Excel查、寫、填充工具。
|
||||
- [範例](#getstart5)
|
||||
|
||||
|
||||
|
||||
### Demo
|
||||
- LINQPad : Download [Basic Demo.linq](drafts/[MiniExcel]Basic%20Demo.linq)
|
||||
|
||||
### 安裝
|
||||
|
||||
請查看 [from NuGet](https://www.nuget.org/packages/MiniExcel)
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
---
|
||||
|
||||
### 0.13.2
|
||||
- [Bug] Fix Column more than 255 rows cannot be read error [#208](https://github.com/shps951023/MiniExcel/issues/#208)
|
||||
|
||||
### 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 or DataTable` parameters [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
---
|
||||
|
||||
### 0.13.2
|
||||
- [Bug] 列超过 255 行无法读取错误 [#208](https://github.com/shps951023/MiniExcel/issues/#208)
|
||||
|
||||
### 0.13.1
|
||||
- [New] SaveAsByTemplate 支持读取模板 byte[],方便缓存跟支持多用户同时读取同一个模板 #189
|
||||
- [New] SaveAsByTemplate 支持传入 `IEnmerable<IDicionary<string,object>> 或 DapperRows 或 DataTable` 参数 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
---
|
||||
|
||||
### 0.13.2
|
||||
- [Bug] 列超過 255 行無法讀取錯誤 [#208](https://github.com/shps951023/MiniExcel/issues/#208)
|
||||
|
||||
### 0.13.1
|
||||
- [New] SaveAsByTemplate 支持讀取模板 byte[],方便緩存跟支持多用戶同時讀取同一個模板 [#189](https://github.com/shps951023/MiniExcel/issues/189)
|
||||
- [New] SaveAsByTemplate 支持傳入 `IEnmerable<IDicionary<string,object>> 或 DapperRows 或 DataTable` 參數 [#201](https://github.com/shps951023/MiniExcel/issues/201)
|
||||
|
87
drafts/【Try】Issue208.linq
Normal file
87
drafts/【Try】Issue208.linq
Normal file
@ -0,0 +1,87 @@
|
||||
<Query Kind="Program">
|
||||
<NuGetReference>Dapper</NuGetReference>
|
||||
<NuGetReference>MiniExcel</NuGetReference>
|
||||
<NuGetReference>Newtonsoft.Json</NuGetReference>
|
||||
<NuGetReference>System.Data.SqlClient</NuGetReference>
|
||||
<Namespace>Dapper</Namespace>
|
||||
<Namespace>MiniExcelLibs</Namespace>
|
||||
<Namespace>Newtonsoft.Json</Namespace>
|
||||
<RemoveNamespace>System.Data</RemoveNamespace>
|
||||
<RemoveNamespace>System.Diagnostics</RemoveNamespace>
|
||||
<RemoveNamespace>System.Linq.Expressions</RemoveNamespace>
|
||||
<RemoveNamespace>System.Text</RemoveNamespace>
|
||||
<RemoveNamespace>System.Text.RegularExpressions</RemoveNamespace>
|
||||
<RemoveNamespace>System.Threading</RemoveNamespace>
|
||||
<RemoveNamespace>System.Transactions</RemoveNamespace>
|
||||
<RemoveNamespace>System.Xml</RemoveNamespace>
|
||||
<RemoveNamespace>System.Xml.Linq</RemoveNamespace>
|
||||
<RemoveNamespace>System.Xml.XPath</RemoveNamespace>
|
||||
</Query>
|
||||
|
||||
void Main()
|
||||
{
|
||||
Console.WriteLine(Helpers.GetAlphabetColumnName(255));
|
||||
Console.WriteLine(Helpers.GetAlphabetColumnName(256));
|
||||
Console.WriteLine(Helpers.GetAlphabetColumnName(257));
|
||||
Console.WriteLine(Helpers.GetAlphabetColumnName(258));
|
||||
Console.WriteLine(Helpers.GetAlphabetColumnName(16383));
|
||||
//Console.WriteLine(Helpers.GetAlphabetColumnName(16384));
|
||||
var _IntMappingAlphabet = Helpers._IntMappingAlphabet;
|
||||
var _AlphabetMappingInt = Helpers._AlphabetMappingInt;
|
||||
}
|
||||
|
||||
// You can define other methods, fields, classes and namespaces here
|
||||
internal static class Helpers
|
||||
{
|
||||
private const int GENERAL_COLUMN_INDEX = 255;
|
||||
private const int MAX_COLUMN_INDEX = 16383;
|
||||
|
||||
internal static Dictionary<int, string> _IntMappingAlphabet;
|
||||
internal static Dictionary<string, int> _AlphabetMappingInt;
|
||||
static Helpers()
|
||||
{
|
||||
if (_IntMappingAlphabet == null && _AlphabetMappingInt == null)
|
||||
{
|
||||
_IntMappingAlphabet = new Dictionary<int, string>();
|
||||
_AlphabetMappingInt = new Dictionary<string, int>();
|
||||
for (int i = 0; i <= GENERAL_COLUMN_INDEX; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetAlphabetColumnName(int columnIndex)
|
||||
{
|
||||
if (columnIndex >= _IntMappingAlphabet.Count)
|
||||
{
|
||||
if (columnIndex > MAX_COLUMN_INDEX)
|
||||
throw new InvalidDataException($"ColumnIndex {columnIndex} over excel vaild max index.");
|
||||
for (int i = _IntMappingAlphabet.Count; i <= columnIndex; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
return _IntMappingAlphabet[columnIndex];
|
||||
}
|
||||
public static int GetColumnIndex(string columnName)
|
||||
{
|
||||
var columnIndex = _AlphabetMappingInt[columnName];
|
||||
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
internal static string IntToLetters(int value)
|
||||
{
|
||||
value = value + 1;
|
||||
string result = string.Empty;
|
||||
while (--value >= 0)
|
||||
{
|
||||
result = (char)('A' + value % 26) + result;
|
||||
value /= 26;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
BIN
samples/xlsx/TestIssue208.xlsx
Normal file
BIN
samples/xlsx/TestIssue208.xlsx
Normal file
Binary file not shown.
@ -1,24 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net45;netstandard2.0;net5.0</TargetFrameworks>
|
||||
<Version>0.13.1</Version>
|
||||
<Version>0.13.2</Version>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyName>MiniExcel</AssemblyName>
|
||||
<Title>MiniExcel</Title>
|
||||
<Product>MiniExcel</Product>
|
||||
<PackageTags>excel;xlsx;micro-helper;mini;openxml;helper;</PackageTags>
|
||||
<Description>
|
||||
A high performance and easy Excel(xlsx,csv) Micro-Helper that avoids OOM and without third-party dependencies to create or dynamic/type POCO mapping query etc..
|
||||
* Support excel template report generation with which you can easily export any data from your .NET classes to Excel.
|
||||
<Description>A high performance and easy Excel(xlsx,csv) Micro-Helper that avoids OOM and without third-party dependencies to create or dynamic/type POCO mapping query etc..
|
||||
* Support excel template report generation with which you can easily export any data from your .NET classes to Excel.
|
||||
|
||||
Github : https://github.com/shps951023/MiniExcel
|
||||
China Gitee : https://gitee.com/dotnetchina/MiniExcel
|
||||
Issues : github https://github.com/shps951023/MiniExcel/issues or China Gitee https://gitee.com/dotnetchina/MiniExcel/issues
|
||||
Todo : https://github.com/shps951023/MiniExcel/projects/1?fullscreen=true
|
||||
Facebook : https://www.facebook.com/miniexcel
|
||||
China QQ : 813100564
|
||||
</Description>
|
||||
Github : https://github.com/shps951023/MiniExcel
|
||||
Gitee : https://gitee.com/dotnetchina/MiniExcel
|
||||
Issues : github https://github.com/shps951023/MiniExcel/issues or Gitee https://gitee.com/dotnetchina/MiniExcel/issues
|
||||
Todo : https://github.com/shps951023/MiniExcel/projects/1?fullscreen=true
|
||||
Facebook : https://www.facebook.com/miniexcel
|
||||
QQ : 813100564
|
||||
</Description>
|
||||
<Authors>ITWeiHan</Authors>
|
||||
<Copyright>©2021 WeiHan Lin</Copyright>
|
||||
<license>https://raw.githubusercontent.com/shps951023/MiniExcel/master/LICENSE.md</license>
|
||||
@ -26,11 +25,7 @@
|
||||
<PackageProjectUrl>https://github.com/shps951023/MiniExcel</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/shps951023/MiniExcel</RepositoryUrl>
|
||||
<PackageIconUrl>https://user-images.githubusercontent.com/12729184/115023335-39440c80-9ef1-11eb-8771-7260d1e50d5a.png</PackageIconUrl>
|
||||
<PackageReleaseNotes>
|
||||
Please Check [Release Notes](https://github.com/shps951023/MiniExcel/tree/master/docs)
|
||||
or
|
||||
[China Gitee Release Notes](https://gitee.com/dotnetchina/MiniExcel/blob/master/docs/README.zh-CN.md)
|
||||
</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>Please Check [Release Notes](https://github.com/shps951023/MiniExcel/tree/master/docs)</PackageReleaseNotes>
|
||||
<RepositoryType>Github</RepositoryType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461'">
|
||||
|
@ -44,7 +44,6 @@ namespace MiniExcelLibs.OpenXml
|
||||
|
||||
sheetZipEntry.Delete(); // ZipArchiveEntry can't update directly, so need to delete then create logic
|
||||
|
||||
var worksheet = doc.SelectSingleNode("/x:worksheet", _ns);
|
||||
var sheetData = doc.SelectSingleNode("/x:worksheet/x:sheetData", _ns);
|
||||
|
||||
var newSheetData = sheetData.Clone(); //avoid delete lost data
|
||||
@ -55,8 +54,11 @@ namespace MiniExcelLibs.OpenXml
|
||||
//Update dimension && Check if the column contains a collection and get type and properties infomations
|
||||
UpdateDimensionAndGetCollectionPropertiesInfos(inputMaps, ref doc, ref rows);
|
||||
|
||||
#region Render cell values
|
||||
RenderRowsAndCells(stream, doc, sheetData);
|
||||
}
|
||||
|
||||
private void RenderRowsAndCells(Stream stream, XmlDocument doc, XmlNode sheetData)
|
||||
{
|
||||
//Q.Why so complex?
|
||||
//A.Because try to use string stream avoid OOM when rendering rows
|
||||
sheetData.RemoveAll();
|
||||
@ -219,7 +221,6 @@ namespace MiniExcelLibs.OpenXml
|
||||
writer.Write($"</{prefix}sheetData>");
|
||||
writer.Write(contents[1]);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private static string CleanXml(string xml, string endPrefix)
|
||||
|
@ -61,7 +61,7 @@ namespace MiniExcelLibs.OpenXml
|
||||
values.Add(p.Name, p.GetValue(value));
|
||||
}
|
||||
}
|
||||
//TODO:DataTable & DapperRow
|
||||
|
||||
{
|
||||
templateStream.CopyTo(stream);
|
||||
|
||||
|
@ -4,24 +4,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
internal static partial class Helpers
|
||||
{
|
||||
private static Dictionary<int, string> _IntMappingAlphabet = new Dictionary<int, string>();
|
||||
private static Dictionary<string, int> _AlphabetMappingInt = new Dictionary<string, int>();
|
||||
private const int GENERAL_COLUMN_INDEX = 255;
|
||||
private const int MAX_COLUMN_INDEX = 16383;
|
||||
private static Dictionary<int, string> _IntMappingAlphabet;
|
||||
private static Dictionary<string, int> _AlphabetMappingInt;
|
||||
static Helpers()
|
||||
{
|
||||
for (int i = 0; i <= 255; i++)
|
||||
if (_IntMappingAlphabet == null && _AlphabetMappingInt == null)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
_IntMappingAlphabet = new Dictionary<int, string>();
|
||||
_AlphabetMappingInt = new Dictionary<string, int>();
|
||||
for (int i = 0; i <= GENERAL_COLUMN_INDEX; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetAlphabetColumnName(int ColumnIndex) => _IntMappingAlphabet[ColumnIndex];
|
||||
internal static int GetColumnIndex(string columnName) => _AlphabetMappingInt[columnName];
|
||||
public static string GetAlphabetColumnName(int columnIndex)
|
||||
{
|
||||
CheckAndSetMaxColumnIndex(columnIndex);
|
||||
return _IntMappingAlphabet[columnIndex];
|
||||
}
|
||||
|
||||
public static int GetColumnIndex(string columnName)
|
||||
{
|
||||
var columnIndex = _AlphabetMappingInt[columnName];
|
||||
CheckAndSetMaxColumnIndex(columnIndex);
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
private static void CheckAndSetMaxColumnIndex(int columnIndex)
|
||||
{
|
||||
if (columnIndex >= _IntMappingAlphabet.Count)
|
||||
{
|
||||
if (columnIndex > MAX_COLUMN_INDEX)
|
||||
throw new InvalidDataException($"ColumnIndex {columnIndex} over excel vaild max index.");
|
||||
for (int i = _IntMappingAlphabet.Count; i <= columnIndex; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static string IntToLetters(int value)
|
||||
{
|
||||
|
@ -23,6 +23,18 @@ namespace MiniExcelLibs.Tests
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/shps951023/MiniExcel/issues/208
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Issue208()
|
||||
{
|
||||
var path = @"..\..\..\..\..\samples\xlsx\TestIssue208.xlsx";
|
||||
var columns = MiniExcel.GetColumns(path).ToList();
|
||||
Assert.Equal(16384, columns.Count);
|
||||
Assert.Equal("XFD", columns[16383]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://github.com/shps951023/MiniExcel/issues/206
|
||||
/// </summary>
|
||||
|
@ -21,21 +21,52 @@ namespace MiniExcelLibs.Tests.Utils
|
||||
|
||||
internal static class Helpers
|
||||
{
|
||||
private static Dictionary<int, string> _IntMappingAlphabet = new Dictionary<int, string>();
|
||||
private static Dictionary<string, int> _AlphabetMappingInt = new Dictionary<string, int>();
|
||||
static Helpers()
|
||||
{
|
||||
for (int i = 0; i <= 255; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
private const int GENERAL_COLUMN_INDEX = 255;
|
||||
private const int MAX_COLUMN_INDEX = 16383;
|
||||
private static Dictionary<int, string> _IntMappingAlphabet;
|
||||
private static Dictionary<string, int> _AlphabetMappingInt;
|
||||
static Helpers()
|
||||
{
|
||||
if (_IntMappingAlphabet == null && _AlphabetMappingInt == null)
|
||||
{
|
||||
_IntMappingAlphabet = new Dictionary<int, string>();
|
||||
_AlphabetMappingInt = new Dictionary<string, int>();
|
||||
for (int i = 0; i <= GENERAL_COLUMN_INDEX; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetAlphabetColumnName(int ColumnIndex) => _IntMappingAlphabet[ColumnIndex];
|
||||
public static int GetColumnIndex(string columnName) => _AlphabetMappingInt[columnName];
|
||||
public static string GetAlphabetColumnName(int columnIndex)
|
||||
{
|
||||
CheckAndSetMaxColumnIndex(columnIndex);
|
||||
return _IntMappingAlphabet[columnIndex];
|
||||
}
|
||||
|
||||
internal static string IntToLetters(int value)
|
||||
public static int GetColumnIndex(string columnName)
|
||||
{
|
||||
var columnIndex = _AlphabetMappingInt[columnName];
|
||||
CheckAndSetMaxColumnIndex(columnIndex);
|
||||
return columnIndex;
|
||||
}
|
||||
|
||||
private static void CheckAndSetMaxColumnIndex(int columnIndex)
|
||||
{
|
||||
if (columnIndex >= _IntMappingAlphabet.Count)
|
||||
{
|
||||
if (columnIndex > MAX_COLUMN_INDEX)
|
||||
throw new InvalidDataException($"ColumnIndex {columnIndex} over excel vaild max index.");
|
||||
for (int i = _IntMappingAlphabet.Count; i <= columnIndex; i++)
|
||||
{
|
||||
_IntMappingAlphabet.Add(i, IntToLetters(i));
|
||||
_AlphabetMappingInt.Add(IntToLetters(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static string IntToLetters(int value)
|
||||
{
|
||||
value = value + 1;
|
||||
string result = string.Empty;
|
||||
|
Loading…
Reference in New Issue
Block a user