Skip to content

Commit

Permalink
[Bug] Fixed SaveAsByTemplate when merge cells will cause collection r…
Browse files Browse the repository at this point in the history
…endering error [#207]
  • Loading branch information
shps951023 committed Apr 22, 2021
1 parent 490ddc8 commit 760bd5e
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 73 deletions.
5 changes: 3 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
---

### 0.13.3
- [New] Support open with read only mode, avoid error of The process cannot access the file because it is being used by another process [#87](https://github.com/shps951023/MiniExcel/issues/#87)
- [New] Support open with read only mode, avoid error of The process cannot access the file because it is being used by another process [#87](https://github.com/shps951023/MiniExcel/issues/87)
- [Breaking Change] Change CSV SaveAs datetime default format : "yyyy-MM-dd HH:mm:ss"
- [Bug] Fixed SaveAsByTemplate when merge cells will cause collection rendering error [#207](https://github.com/shps951023/MiniExcel/issues/207)

### 0.13.2
- [Bug] Fix Column more than 255 rows cannot be read error [#208](https://github.com/shps951023/MiniExcel/issues/#208)
- [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
Expand Down
5 changes: 3 additions & 2 deletions docs/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
---

### 0.13.3
- [New] 支持 Excel 单纯读取模式,避免同时改模版又运行 MiniExcel 出现错误 "The process cannot access the file because it is being used by another process" [#87](https://github.com/shps951023/MiniExcel/issues/#87)
- [New] 支持 Excel 单纯读取模式,避免同时改模版又运行 MiniExcel 出现错误 "The process cannot access the file because it is being used by another process" [#87](https://github.com/shps951023/MiniExcel/issues/87)
- [Breaking Change] CSV SaveAs datetime 预设格式改为 "yyyy-MM-dd HH:mm:ss"
- [Bug] 修正模版模式集合渲染遇到合并列会出现异常问题 [#207](https://github.com/shps951023/MiniExcel/issues/207)

### 0.13.2
- [Bug] 超过 255 列无法读取错误 [#208](https://github.com/shps951023/MiniExcel/issues/#208)
- [Bug] 超过 255 列无法读取错误 [#208](https://github.com/shps951023/MiniExcel/issues/208)

### 0.13.1
- [New] SaveAsByTemplate 支持读取模板 byte[],方便缓存跟支持多用户同时读取同一个模板 #189
Expand Down
5 changes: 3 additions & 2 deletions docs/README.zh-Hant.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
---

### 0.13.3
- [New] 支持 Excel 單純讀取模式,避免同時改模版又運行 MiniExcel 出現錯誤 "The process cannot access the file because it is being used by another process" [#87](https://github.com/shps951023/MiniExcel/issues/#87)
- [New] 支持 Excel 單純讀取模式,避免同時改模版又運行 MiniExcel 出現錯誤 "The process cannot access the file because it is being used by another process" [#87](https://github.com/shps951023/MiniExcel/issues/87)
- [Breaking Change] CSV SaveAs datetime 預設格式改為 "yyyy-MM-dd HH:mm:ss"
- [Bug] 修正模版模式集合渲染遇到合併列會出現異常問題 [#207](https://github.com/shps951023/MiniExcel/issues/207)

### 0.13.2
- [Bug] 超過 255 列無法讀取錯誤 [#208](https://github.com/shps951023/MiniExcel/issues/#208)
- [Bug] 超過 255 列無法讀取錯誤 [#208](https://github.com/shps951023/MiniExcel/issues/208)

### 0.13.1
- [New] SaveAsByTemplate 支持讀取模板 byte[],方便緩存跟支持多用戶同時讀取同一個模板 [#189](https://github.com/shps951023/MiniExcel/issues/189)
Expand Down
229 changes: 191 additions & 38 deletions src/MiniExcel/OpenXml/ExcelOpenXmlTemplate.Impl.cs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/MiniExcel/OpenXml/ExcelOpenXmlTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public void SaveAsByTemplateImpl(Stream templateStream, object value)
foreach (var sheet in sheets)
{
this.XRowInfos = new List<XRowInfo>(); //every time need to use new XRowInfos or it'll cause duplicate problem: https://user-images.githubusercontent.com/12729184/115003101-0fcab700-9ed8-11eb-9151-ca4d7b86d59e.png
this.XMergeCellInfos = new Dictionary<string, XMergeCell>();
this.NewXMergeCellInfos = new List<XMergeCell>();

var sheetStream = sheet.Open();
var fullName = sheet.FullName;

Expand Down
48 changes: 31 additions & 17 deletions src/MiniExcel/Utils/StringHelper.cs
Original file line number Diff line number Diff line change
@@ -1,61 +1,75 @@
/**
This Class Modified from ExcelDataReader : https://github.com/ExcelDataReader/ExcelDataReader
**/
namespace MiniExcelLibs.Utils
namespace MiniExcelLibs.Utils
{
using System;
using System.Linq;
using System.Text;
using System.Xml;

internal static class StringHelper
{

public static string GetLetter(string content)
{
//TODO:need to chekc
return new String(content.Where(Char.IsLetter).ToArray());
}

public static int GetNumber(string content)
{
return int.Parse(new String(content.Where(Char.IsNumber).ToArray()));
}

/// <summary>
/// Copy&Modify from ExcelDataReader : https://github.com/ExcelDataReader/ExcelDataReader
/// </summary>
public static string ReadStringItem(XmlReader reader)
{
string result = string.Empty;
var result = new StringBuilder();
if (!XmlReaderHelper.ReadFirstContent(reader))
{
return result;
}
return string.Empty;

while (!reader.EOF)
{
if (reader.IsStartElement("t", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
{
// There are multiple <t> in a <si>. Concatenate <t> within an <si>.
result += reader.ReadElementContentAsString();
result.Append(reader.ReadElementContentAsString());
}
else if (reader.IsStartElement("r", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
{
result += ReadRichTextRun(reader);
result.Append(ReadRichTextRun(reader));
}
else if (!XmlReaderHelper.SkipContent(reader))
{
break;
}
}

return result;
return result.ToString();
}

/// <summary>
/// Copy&Modify from ExcelDataReader : https://github.com/ExcelDataReader/ExcelDataReader
/// </summary>
private static string ReadRichTextRun(XmlReader reader)
{
string result = string.Empty;
var result = new StringBuilder();
if (!XmlReaderHelper.ReadFirstContent(reader))
{
return result;
}
return string.Empty;

while (!reader.EOF)
{
if (reader.IsStartElement("t", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"))
{
result += reader.ReadElementContentAsString();
result.Append(reader.ReadElementContentAsString());
}
else if (!XmlReaderHelper.SkipContent(reader))
{
break;
}
}

return result;
return result.ToString();
}
}

Expand Down
86 changes: 74 additions & 12 deletions tests/MiniExcelTests/MiniExcelIssueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,85 @@ public MiniExcelIssueTests(ITestOutputHelper output)
}

/// <summary>
/// Version <= v0.13.1 Template merge row list rendering has no merge
/// https://github.com/shps951023/MiniExcel/issues/207
/// </summary>
[Fact]
public void Issue207()
{
//var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
//var tempaltePath = @"../../../../../samples/xlsx/TestIssue207_Template_Merge_row_list_rendering_without_merge/template.xlsx";

//var value = new
//{
// project = new[] {
// new {name = "項目1",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
// new {name = "項目2",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
// }
//};

//MiniExcel.SaveAsByTemplate(path, tempaltePath, value);
{
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
var tempaltePath = @"../../../../../samples/xlsx/TestIssue207_2.xlsx";

var value = new
{
project = new[] {
new {name = "項目1",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目2",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目3",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目4",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
}
};

MiniExcel.SaveAsByTemplate(path, tempaltePath, value);

var rows = MiniExcel.Query(path).ToList();

Assert.Equal("項目1", rows[0].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[0].B);
Assert.Equal("項目2", rows[2].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[2].B);
Assert.Equal("項目3", rows[4].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[4].B);
Assert.Equal("項目4", rows[6].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[6].B);

Assert.Equal("Test1", rows[8].A);
Assert.Equal("Test2", rows[8].B);
Assert.Equal("Test3", rows[8].C);

Assert.Equal("項目1", rows[12].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[12].B);
Assert.Equal("項目2", rows[13].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[13].B);
Assert.Equal("項目3", rows[14].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[14].B);
Assert.Equal("項目4", rows[15].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[15].B);

var demension = Helpers.GetFirstSheetDimensionRefValue(path);
Assert.Equal("A1:C16", demension);
}

{
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
var tempaltePath = @"../../../../../samples/xlsx/TestIssue207_Template_Merge_row_list_rendering_without_merge/template.xlsx";

var value = new
{
project = new[] {
new {name = "項目1",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目2",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目3",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
new {name = "項目4",content="[]內容1,[]內容2,[]內容3,[]內容4,[]內容5"},
}
};

MiniExcel.SaveAsByTemplate(path, tempaltePath, value);

var rows = MiniExcel.Query(path).ToList();

Assert.Equal("項目1", rows[0].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[0].C);
Assert.Equal("項目2", rows[3].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[3].C);
Assert.Equal("項目3", rows[6].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[6].C);
Assert.Equal("項目4", rows[9].A);
Assert.Equal("[]內容1,[]內容2,[]內容3,[]內容4,[]內容5", rows[9].C);
var demension = Helpers.GetFirstSheetDimensionRefValue(path);
Assert.Equal("A1:E15", demension);
}
}

/// <summary>
Expand Down

0 comments on commit 760bd5e

Please sign in to comment.