Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
namespace MiniExcelLib.Core.Helpers;

#if NETSTANDARD2_0

/// <summary>
/// Provides .NET Standard 2.0 polyfills for utility methods found in later framework versions.
/// This enables a unified API surface across the codebase without the need for conditional compilation directives.
/// </summary>
public static class NetStandardExtensions
{
#if NETSTANDARD2_0
public static TValue? GetValueOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, TValue? defaultValue = default)
{
return dictionary.TryGetValue(key, out var value) ? value : defaultValue;
}
#endif
}
#endif
16 changes: 16 additions & 0 deletions src/MiniExcel.Core/Helpers/SynchronousHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.IO.Compression;

namespace MiniExcelLib.Core.Helpers;

/// <summary>
/// Supplements base classes with synchronous method counterparts, ensuring compatibility with the SyncMethodGenerator
/// by providing missing entry points without requiring manual preprocessor directives (#if SYNC_ONLY)
/// </summary>
public static class SynchronousHelper
{
extension(ZipArchive)
{
public static ZipArchive Create(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding? encoding = null)
=> new(stream, mode, leaveOpen, encoding);
}
}
11 changes: 6 additions & 5 deletions src/MiniExcel.OpenXml/Api/OpenXmlImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ public async Task<List<string>> GetSheetNamesAsync(Stream stream, OpenXmlConfigu
{
config ??= OpenXmlConfiguration.Default;

using var archive = new OpenXmlZip(stream, leaveOpen: true);

var archive = await OpenXmlZip.CreateAsync(stream, leaveOpen: true, cancellationToken: cancellationToken).ConfigureAwait(false);
await using var disposableArchive = archive.ConfigureAwait(false);
using var reader = await OpenXmlReader.CreateAsync(stream, config, cancellationToken: cancellationToken).ConfigureAwait(false);
var rels = await reader.GetWorkbookRelsAsync(archive.EntryCollection, cancellationToken).ConfigureAwait(false);

var rels = await reader.GetWorkbookRelsAsync(archive.EntryCollection, cancellationToken).ConfigureAwait(false);
return rels?.Select(s => s.Name).ToList() ?? [];
}

Expand All @@ -248,10 +248,11 @@ public async Task<List<SheetInfo>> GetSheetInformationsAsync(Stream stream, Open
{
config ??= OpenXmlConfiguration.Default;

using var archive = new OpenXmlZip(stream);
var archive = await OpenXmlZip.CreateAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
await using var disposableArchve = archive.ConfigureAwait(false);
using var reader = await OpenXmlReader.CreateAsync(stream, config, cancellationToken: cancellationToken).ConfigureAwait(false);
var rels = await reader.GetWorkbookRelsAsync(archive.EntryCollection, cancellationToken).ConfigureAwait(false);

var rels = await reader.GetWorkbookRelsAsync(archive.EntryCollection, cancellationToken).ConfigureAwait(false);
return rels?.Select((s, i) => s.ToSheetInfo((uint)i)).ToList() ?? [];
}

Expand Down
2 changes: 1 addition & 1 deletion src/MiniExcel.OpenXml/Constants/Schemas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

internal static class Schemas
{
public const string SpreadsheetmlXmlNs = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
public const string SpreadsheetmlXmlMain = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
public const string SpreadsheetmlXmlStrictNs = "http://purl.oclc.org/ooxml/spreadsheetml/main";

public const string OpenXmlPackageRelationships = "http://schemas.openxmlformats.org/package/2006/relationships";
Expand Down
14 changes: 8 additions & 6 deletions src/MiniExcel.OpenXml/OpenXmlReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace MiniExcelLib.OpenXml;

internal partial class OpenXmlReader : IMiniExcelReader
{
private static readonly string[] Ns = [Schemas.SpreadsheetmlXmlNs, Schemas.SpreadsheetmlXmlStrictNs];
private static readonly string[] Ns = [Schemas.SpreadsheetmlXmlMain, Schemas.SpreadsheetmlXmlStrictNs];
private static readonly string[] RelationshiopNs = [Schemas.SpreadsheetmlXmlRelationships, Schemas.SpreadsheetmlXmlStrictRelationships];
private readonly OpenXmlConfiguration _config;

Expand All @@ -21,18 +21,20 @@ internal partial class OpenXmlReader : IMiniExcelReader
internal readonly OpenXmlZip Archive;
internal IDictionary<int, string> SharedStrings = new Dictionary<int, string>();

private OpenXmlReader(Stream stream, IMiniExcelConfiguration? configuration)
private OpenXmlReader(OpenXmlZip openXmlZip, IMiniExcelConfiguration? configuration)
{
Archive = new OpenXmlZip(stream);
Archive = openXmlZip;
_config = (OpenXmlConfiguration?)configuration ?? OpenXmlConfiguration.Default;
}

[CreateSyncVersion]
internal static async Task<OpenXmlReader> CreateAsync(Stream stream, IMiniExcelConfiguration? configuration, CancellationToken cancellationToken = default)
{
ThrowHelper.ThrowIfInvalidOpenXml(stream);

var reader = new OpenXmlReader(stream, configuration);

var archive = await OpenXmlZip.CreateAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
var reader = new OpenXmlReader(archive, configuration);

await reader.SetSharedStringsAsync(cancellationToken).ConfigureAwait(false);
return reader;
}
Expand Down Expand Up @@ -1149,7 +1151,7 @@ internal async Task<CommentResultSet> ReadCommentsAsync(string? sheetName, Cance

XNamespace nsRel = Schemas.OpenXmlPackageRelationships;
XNamespace ns18Tc = Schemas.SpreadsheetmlXmlX18Tc;
XNamespace nsMain = Schemas.SpreadsheetmlXmlNs;
XNamespace nsMain = Schemas.SpreadsheetmlXmlMain;
XNamespace ns14R = Schemas.SpreadsheetmlXmlX14R;

SetWorkbookRels(Archive.EntryCollection);
Expand Down
4 changes: 2 additions & 2 deletions src/MiniExcel.OpenXml/OpenXmlWriter.DefaultOpenXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace MiniExcelLib.OpenXml;

internal partial class OpenXmlWriter : IMiniExcelWriter
internal partial class OpenXmlWriter
{
private readonly Dictionary<string, ZipPackageInfo> _zipDictionary = [];
private Dictionary<string, string> _cellXfIdMap;
private Dictionary<string, string> _cellXfIdMap = [];

private IEnumerable<Tuple<SheetDto, object?>> GetSheets()
{
Expand Down
30 changes: 18 additions & 12 deletions src/MiniExcel.OpenXml/OpenXmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,37 @@ internal partial class OpenXmlWriter : IMiniExcelWriter

private int _currentSheetIndex = 0;

private OpenXmlWriter(Stream stream, object? value, string? sheetName, IMiniExcelConfiguration? configuration, bool printHeader)
private OpenXmlWriter(Stream stream, ZipArchive archive, object? value, string? sheetName, OpenXmlConfiguration configuration, bool printHeader)
{
_stream = stream;

// A. Why ZipArchiveMode.Update and not ZipArchiveMode.Create?
// R. ZipArchiveEntry does not support seeking when Mode is Create.
_configuration = configuration as OpenXmlConfiguration ?? OpenXmlConfiguration.Default;
if (_configuration is { EnableAutoWidth: true, FastMode: false })
throw new InvalidOperationException("Auto width requires fast mode to be enabled");

var archiveMode = _configuration.FastMode ? ZipArchiveMode.Update : ZipArchiveMode.Create;
_archive = new ZipArchive(_stream, archiveMode, true, Utf8WithBom);
_configuration = configuration;
_archive = archive;

_value = value;
_printHeader = printHeader;
_defaultSheetName = sheetName;
}

[CreateSyncVersion]
internal static Task<OpenXmlWriter> CreateAsync(Stream stream, object? value, string? sheetName, bool printHeader, IMiniExcelConfiguration? configuration, CancellationToken cancellationToken = default)
internal static async ValueTask<OpenXmlWriter> CreateAsync(Stream stream, object? value, string? sheetName, bool printHeader, IMiniExcelConfiguration? configuration, CancellationToken cancellationToken = default)
{
ThrowHelper.ThrowIfInvalidSheetName(sheetName);

var writer = new OpenXmlWriter(stream, value, sheetName, configuration, printHeader);
return Task.FromResult(writer);
var conf = configuration as OpenXmlConfiguration ?? OpenXmlConfiguration.Default;
if (conf is { EnableAutoWidth: true, FastMode: false })
throw new InvalidOperationException("Auto width requires fast mode to be enabled");

// A. Why ZipArchiveMode.Update and not ZipArchiveMode.Create?
// R. ZipArchiveEntry does not support seeking when Mode is Create.
var archiveMode = conf.FastMode ? ZipArchiveMode.Update : ZipArchiveMode.Create;

#if NET10_0_OR_GREATER
var archive = await ZipArchive.CreateAsync(stream, archiveMode, true, Utf8WithBom, cancellationToken).ConfigureAwait(false);
#else
var archive = new ZipArchive(stream, archiveMode, true, Utf8WithBom);
#endif
return new OpenXmlWriter(stream, archive, value, sheetName, conf, printHeader);
}

[CreateSyncVersion]
Expand Down
10 changes: 6 additions & 4 deletions src/MiniExcel.OpenXml/Picture/OpenXmlPictureImplement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ private static XmlNamespaceManager GetRNamespaceManager(XmlDocument doc)
public static async Task AddPictureAsync(Stream excelStream, CancellationToken cancellationToken = default, params MiniExcelPicture[] images)
{
// get sheets
using var excelArchive = new OpenXmlZip(excelStream);
var excelArchive = await OpenXmlZip.CreateAsync(excelStream, cancellationToken: cancellationToken).ConfigureAwait(false);
await using var disposableExcelArchive = excelArchive.ConfigureAwait(false);

using var reader = await OpenXmlReader.CreateAsync(excelStream, null, cancellationToken).ConfigureAwait(false);

#if NET10_0_OR_GREATER
var archive = new ZipArchive(excelStream, ZipArchiveMode.Update, true);
await using var disposableArchive = archive.ConfigureAwait(false);
var archive = await ZipArchive.CreateAsync(excelStream, ZipArchiveMode.Update, true, null, cancellationToken).ConfigureAwait(false);
await using var disposableArchive = archive.ConfigureAwait(false);
#else
using var archive = new ZipArchive(excelStream, ZipArchiveMode.Update, true);
#endif
var rels = await reader.GetWorkbookRelsAsync(excelArchive.EntryCollection, cancellationToken).ConfigureAwait(false);
var rels = await reader.GetWorkbookRelsAsync(excelArchive.EntryCollection, cancellationToken).ConfigureAwait(false);
var sheetEntries = rels?.ToList() ?? [];

// Group images by sheet
Expand Down
2 changes: 1 addition & 1 deletion src/MiniExcel.OpenXml/Styles/OpenXmlStyles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace MiniExcelLib.OpenXml.Styles;

internal class OpenXmlStyles
{
private static readonly string[] Ns = [Schemas.SpreadsheetmlXmlNs, Schemas.SpreadsheetmlXmlStrictNs];
private static readonly string[] Ns = [Schemas.SpreadsheetmlXmlMain, Schemas.SpreadsheetmlXmlStrictNs];

private readonly Dictionary<int, StyleRecord> _cellXfs = new();
private readonly Dictionary<int, StyleRecord> _cellStyleXfs = new();
Expand Down
Loading
Loading