Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.NET 6.0 (LTS) end date is Nov 12, 2024, we will follow the date to upgrade next month.

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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the new class is called: InputValueExtractor.ToValueDictionary()

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
Loading