Skip to content

Commit

Permalink
Upgrade to .NET 8.0 and refactor input value extraction (#681)
Browse files Browse the repository at this point in the history
* Upgrade to .NET 8.0

* Add tests
  • Loading branch information
ramioh authored Nov 2, 2024
1 parent f0fe803 commit a0797a5
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 164 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
env:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ FodyWeavers.xsd
*.msp

# JetBrains Rider
.idea/
*.sln.iml

/BenchmarkDotNet.Artifacts
Expand Down
4 changes: 3 additions & 1 deletion src/MiniExcel/ExcelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using MiniExcelLibs.Csv;
using MiniExcelLibs.OpenXml;
using MiniExcelLibs.OpenXml.SaveByTemplate;
using System;
using System.IO;

Expand Down Expand Up @@ -49,7 +50,8 @@ internal static IExcelTemplateAsync GetProvider(Stream stream, IConfiguration co
switch (excelType)
{
case ExcelType.XLSX:
return new ExcelOpenXmlTemplate(stream, configuration);
var valueExtractor = new InputValueExtractor();
return new ExcelOpenXmlTemplate(stream, configuration, valueExtractor);
default:
throw new NotSupportedException($"Please Issue for me");
}
Expand Down
2 changes: 1 addition & 1 deletion src/MiniExcel/MiniExcelLibs.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0;net6.0;</TargetFrameworks>
<TargetFrameworks>net45;netstandard2.0;net8.0;</TargetFrameworks>
<Version>1.34.2</Version>
</PropertyGroup>
<PropertyGroup>
Expand Down
154 changes: 0 additions & 154 deletions src/MiniExcel/OpenXml/ExcelOpenXmlTemplate.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using System.Text.RegularExpressions;
using System.Xml;

namespace MiniExcelLibs.OpenXml
namespace MiniExcelLibs.OpenXml.SaveByTemplate
{
internal partial class ExcelOpenXmlTemplate
{
Expand Down Expand Up @@ -113,7 +113,7 @@ public string ToXmlString(string prefix)
public List<XMergeCell> NewXMergeCellInfos { get; private set; }

private void GenerateSheetXmlImpl(ZipArchiveEntry sheetZipEntry, Stream stream, Stream sheetStream,
Dictionary<string, object> inputMaps, IDictionary<int, string> sharedStrings,
IDictionary<string, object> inputMaps, IDictionary<int, string> sharedStrings,
bool mergeCells = false)
{
var doc = new XmlDocument();
Expand Down Expand Up @@ -911,7 +911,7 @@ private void ReplaceSharedStringsToStr(IDictionary<int, string> sharedStrings, r
}
}

private void UpdateDimensionAndGetRowsInfo(Dictionary<string, object> inputMaps, ref XmlDocument doc, ref XmlNodeList rows, bool changeRowIndex = true)
private void UpdateDimensionAndGetRowsInfo(IDictionary<string, object> inputMaps, ref XmlDocument doc, ref XmlNodeList rows, bool changeRowIndex = true)
{
// note : dimension need to put on the top ![image](https://user-images.githubusercontent.com/12729184/114507911-5dd88400-9c66-11eb-94c6-82ed7bdb5aab.png)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace MiniExcelLibs.OpenXml
namespace MiniExcelLibs.OpenXml.SaveByTemplate
{
internal partial class ExcelOpenXmlTemplate
{
Expand Down
126 changes: 126 additions & 0 deletions src/MiniExcel/SaveByTemplate/ExcelOpenXmlTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
namespace MiniExcelLibs.OpenXml.SaveByTemplate
{
using MiniExcelLibs.Utils;
using MiniExcelLibs.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

internal partial class ExcelOpenXmlTemplate : IExcelTemplate, IExcelTemplateAsync
{
private static readonly XmlNamespaceManager _ns;
private static readonly Regex _isExpressionRegex;

static ExcelOpenXmlTemplate()
{
_isExpressionRegex = new Regex("(?<={{).*?(?=}})");
_ns = new XmlNamespaceManager(new NameTable());
_ns.AddNamespace("x", Config.SpreadsheetmlXmlns);
_ns.AddNamespace("x14ac", Config.SpreadsheetmlXml_x14ac);
}

private readonly Stream _stream;
private readonly OpenXmlConfiguration _configuration;
private readonly IInputValueExtractor _inputValueExtractor;
private readonly StringBuilder _calcChainContent = new StringBuilder();

public ExcelOpenXmlTemplate(Stream stream, IConfiguration configuration, InputValueExtractor inputValueExtractor)
{
_stream = stream;
_configuration = (OpenXmlConfiguration)configuration ?? OpenXmlConfiguration.DefaultConfig;
_inputValueExtractor = inputValueExtractor;
}

public void SaveAsByTemplate(string templatePath, object value)
{
using (var stream = FileHelper.OpenSharedRead(templatePath))
SaveAsByTemplateImpl(stream, value);
}

public void SaveAsByTemplate(byte[] templateBtyes, object value)
{
using (Stream stream = new MemoryStream(templateBtyes))
SaveAsByTemplateImpl(stream, value);
}

public void SaveAsByTemplateImpl(Stream templateStream, object value)
{
//only support xlsx
templateStream.CopyTo(_stream);

var reader = new ExcelOpenXmlSheetReader(_stream, null);
var _archive = new ExcelOpenXmlZip(_stream, mode: ZipArchiveMode.Update, true, Encoding.UTF8);
{
//read sharedString
var sharedStrings = reader._sharedStrings;
StringBuilder calcSheetContent = new StringBuilder();

//read all xlsx sheets
var sheets = _archive.zipFile.Entries.Where(w =>
w.FullName.StartsWith("xl/worksheets/sheet", StringComparison.OrdinalIgnoreCase)
|| w.FullName.StartsWith("/xl/worksheets/sheet", StringComparison.OrdinalIgnoreCase)
).ToList();

int sheetIdx = 0;
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;

var inputValues = _inputValueExtractor.ToValueDictionary(value);
ZipArchiveEntry entry = _archive.zipFile.CreateEntry(fullName);
using (var zipStream = entry.Open())
{
GenerateSheetXmlImpl(sheet, zipStream, sheetStream, inputValues, sharedStrings, false);
//doc.Save(zipStream); //don't do it because : ![image](https://user-images.githubusercontent.com/12729184/114361127-61a5d100-9ba8-11eb-9bb9-34f076ee28a2.png)
}

// disposing writer disposes streams as well. reopen the entry to read and parse calc functions
using (var filledStream = entry.Open())
{
sheetIdx++;
_calcChainContent.Append(CalcChainHelper.GetCalcChainContent(CalcChainCellRefs, sheetIdx));
}
}

var calcChain = _archive.zipFile.Entries.FirstOrDefault(e => e.FullName.Contains("xl/calcChain.xml"));
if (calcChain != null)
{
string calcChainPathname = calcChain.FullName;
calcChain.Delete();
var calcChainEntry = _archive.zipFile.CreateEntry(calcChainPathname);
using (var calcChainStream = calcChainEntry.Open())
{
CalcChainHelper.GenerateCalcChainSheet(calcChainStream, _calcChainContent.ToString());
}
}
}

_archive.zipFile.Dispose();
}

public Task SaveAsByTemplateAsync(string templatePath, object value,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.Run(() => SaveAsByTemplate(templatePath, value), cancellationToken);
}

public Task SaveAsByTemplateAsync(byte[] templateBtyes, object value,
CancellationToken cancellationToken = default(CancellationToken))
{
return Task.Run(() => SaveAsByTemplate(templateBtyes, value), cancellationToken);
}
}
}
9 changes: 9 additions & 0 deletions src/MiniExcel/SaveByTemplate/IInputValueExtractor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace MiniExcelLibs.OpenXml.SaveByTemplate
{
public interface IInputValueExtractor
{
IDictionary<string, object> ToValueDictionary(object valueObject);
}
}
Loading

0 comments on commit a0797a5

Please sign in to comment.