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 src/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<ItemGroup>
<PackageReference Include="Zomp.SyncMethodGenerator" Version="[1.6.13]" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="Zomp.SyncMethodGenerator" Version="2.0.16" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
Expand Down
2 changes: 1 addition & 1 deletion src/MiniExcel.Core/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
global using MiniExcelLib.Core.Abstractions;
global using MiniExcelLib.Core.Helpers;
global using MiniExcelLib.Core.Reflection;
global using Zomp.SyncMethodGenerator;
global using Zomp.SyncMethodGenerator;
105 changes: 60 additions & 45 deletions src/MiniExcel.OpenXml/Constants/ExcelXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,65 @@

internal static class ExcelXml
{
static ExcelXml()
{
DefaultRels = XmlHelper.MinifyXml(DefaultRels);
DefaultWorkbookXml = XmlHelper.MinifyXml(DefaultWorkbookXml);
DefaultWorkbookXmlRels = XmlHelper.MinifyXml(DefaultWorkbookXmlRels);
DefaultSheetRelXml = XmlHelper.MinifyXml(DefaultSheetRelXml);
DefaultDrawing = XmlHelper.MinifyXml(DefaultDrawing);
}

internal const string EmptySheetXml = """<?xml version="1.0" encoding="utf-8"?><x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><x:dimension ref="A1"/><x:sheetData></x:sheetData></x:worksheet>""";
internal static readonly string EmptySheetXml = XmlHelper.MinifyXml("""
<?xml version="1.0" encoding="utf-8"?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:dimension ref="A1"/>
<x:sheetData></x:sheetData>
</x:worksheet>
""");

internal static readonly string DefaultRels =
"""
<?xml version="1.0" encoding="utf-8"?>
internal static readonly string DefaultRels = XmlHelper.MinifyXml("""
<?xml version="1.0" encoding="utf-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml" Id="Rfc2254092b6248a9" />
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml" Id="rId1" />
</Relationships>
""";
""");

internal static readonly string DefaultWorkbookXmlRels =
"""
internal static string DefaultWorkbookXmlRels(string sheets) => XmlHelper.MinifyXml(
$"""
<?xml version="1.0" encoding="utf-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
{{sheets}}
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="/xl/styles.xml" Id="R3db9602ace774fdb" />
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="/xl/sharedStrings.xml" Id="R3db9602ace778fdb" />
{sheets}
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="/xl/styles.xml" Id="rStylesId" />
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="/xl/sharedStrings.xml" Id="rSharedStringsId" />
</Relationships>
""";
""");

internal static readonly string DefaultWorkbookXml =
"""
internal static string DefaultWorkbookXml(string content) => XmlHelper.MinifyXml(
$"""
<?xml version="1.0" encoding="utf-8"?>
<x:workbook xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheets>
{{sheets}}
{content}
</x:sheets>
</x:workbook>
""";
""");

internal static readonly string DefaultSheetRelXml =
"""
internal static string DefaultSheetRelXml(string content) => XmlHelper.MinifyXml(
$"""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
{{format}}
{content}
</Relationships>
""";
""");

internal static readonly string DefaultDrawing =
"""
internal static string DefaultDrawing(string content) => XmlHelper.MinifyXml(
$"""
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xdr:wsDr xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
{{format}}
{content}
</xdr:wsDr>
""";
""");

internal const string DefaultDrawingXmlRels =
"""
internal static string DefaultDrawingXmlRels(string content) =>
$"""
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
{{format}}
{content}
</Relationships>
""";

Expand All @@ -88,18 +84,37 @@ internal static string SharedStrings(Dictionary<string, int> sharedStrings)
return sb.ToString();
}

internal const string StartTypes = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings" Extension="bin"/><Default ContentType="application/xml" Extension="xml"/><Default ContentType="image/jpeg" Extension="jpg"/><Default ContentType="image/png" Extension="png"/><Default ContentType="image/gif" Extension="gif"/><Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>""";
internal static string ContentType(string contentType, string partName) => $"<Override ContentType=\"{contentType}\" PartName=\"/{partName}\" />";
internal const string EndTypes = "</Types>";
internal static string ContentTypes(Dictionary<string, string> contentTypes)
{
var sb = new StringBuilder();
sb.AppendLine("""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings" Extension="bin"/>
<Default ContentType="application/xml" Extension="xml"/><Default ContentType="image/jpeg" Extension="jpg"/>
<Default ContentType="image/png" Extension="png"/>
<Default ContentType="image/gif" Extension="gif"/>
<Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
""");

foreach (var (name, type) in contentTypes.OrderBy(x => x.Key, StringComparer.OrdinalIgnoreCase))
sb.AppendLine($"""<Override ContentType="{type}" PartName="/{name}" />""");

sb.Append("</Types>");
return XmlHelper.MinifyXml(sb.ToString());
}

internal static string WorksheetRelationship(SheetDto sheetDto)
=> $"""<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="/{sheetDto.Path}" Id="{sheetDto.ID}" />""";
=> $"""<Relationship Id="{sheetDto.Id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="/{sheetDto.Path}" />""";

internal static string ImageRelationship(FileDto image)
=> $"""<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="{image.Path2}" Id="{image.ID}" />""";
=> $"""<Relationship Id="{image.Id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="/{image.Path}" />""";

internal static string DrawingRelationship(int sheetIndex)
=> $"""<Relationship Id="rDrawing{sheetIndex}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing{sheetIndex}.xml" />""";

internal static string DrawingRelationship(int sheetId)
=> $"""<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing{sheetId}.xml" Id="drawing{sheetId}" />""";
internal static string TableRelationship(int sheetIndex)
=> $"""<Relationship Id="rTable{sheetIndex}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/table" Target="../tables/table{sheetIndex}.xml"/>""";

internal static string DrawingXml(FileDto file, int fileIndex)
=> $"""
Expand All @@ -119,7 +134,7 @@ internal static string DrawingXml(FileDto file, int fileIndex)
</xdr:cNvPicPr>
</xdr:nvPicPr>
<xdr:blipFill>
<a:blip r:embed="{file.ID}" cstate="print" />
<a:blip r:embed="{file.Id}" cstate="print" />
<a:stretch>
<a:fillRect />
</a:stretch>
Expand All @@ -139,5 +154,5 @@ internal static string DrawingXml(FileDto file, int fileIndex)
""";

internal static string Sheet(SheetDto sheetDto, int sheetId)
=> $"""<x:sheet name="{XmlHelper.EncodeXml(sheetDto.Name)}" sheetId="{sheetId}"{(string.IsNullOrWhiteSpace(sheetDto.State) ? string.Empty : $" state=\"{sheetDto.State}\"")} r:id="{sheetDto.ID}" />""";
=> $"""<x:sheet name="{XmlHelper.EncodeXml(sheetDto.Name)}" sheetId="{sheetId}"{(string.IsNullOrWhiteSpace(sheetDto.State) ? string.Empty : $" state=\"{sheetDto.State}\"")} r:id="{sheetDto.Id}" />""";
}
11 changes: 5 additions & 6 deletions src/MiniExcel.OpenXml/Models/FileDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

internal class FileDto
{
internal string ID { get; set; } = $"R{Guid.NewGuid():N}";
internal string Extension { get; set; }
internal string Path => $"xl/media/{ID}.{Extension}";
internal string Path2 => $"/xl/media/{ID}.{Extension}";
internal byte[] Contents { get; set; }
internal int SheetIndex { get; set; }
internal int RowIndex { get; set; }
internal int CellIndex { get; set; }
internal string Id => $"rFileId_{SheetIndex}_{RowIndex + 1}_{CellIndex + 1}";
internal string Path => $"xl/media/{Id}.{Extension}";
internal bool IsImage { get; set; }
internal int SheetId { get; set; }
internal string Extension { get; set; }
internal byte[] Contents { get; set; }
}
5 changes: 2 additions & 3 deletions src/MiniExcel.OpenXml/Models/SheetDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

internal class SheetDto
{
internal string ID { get; set; } = $"R{Guid.NewGuid():N}";
internal string? Name { get; set; }
internal int SheetIdx { get; set; }
internal string Id => $"rSheetId{SheetIdx}";
internal string? Name { get; set; }
internal string Path => ExcelFileNames.Worksheet(SheetIdx);

internal string State { get; set; }
}
15 changes: 7 additions & 8 deletions src/MiniExcel.OpenXml/Writer/OpenXmlWriter.CopyInsert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ public async Task<int> CopyAndInsertAsync(bool overwriteSheet = false, IProgress
await _sheetStyleBuilderContext.DisposeAsync().ConfigureAwait(false);
_sheetStyleBuilderContext = sheetStylesBuilderUtils.SheetStyleBuilderContext;

var sharedStringsEntry = _oldArchive.GetEntry(ExcelFileNames.SharedStrings);
if (sharedStringsEntry is not null)
if (_oldArchive.GetEntry(ExcelFileNames.SharedStrings) is not null)
{
foreach (var (key, value) in reader.SharedStrings)
{
Expand Down Expand Up @@ -126,26 +125,26 @@ public async Task<int> CopyAndInsertAsync(bool overwriteSheet = false, IProgress

await AddFilesToZipAsync(cancellationToken).ConfigureAwait(false);
await GenerateSharedStringsAsync(cancellationToken).ConfigureAwait(false);
await GenerateDrawingRelXmlAsync(_currentSheetIndex, cancellationToken).ConfigureAwait(false);
await GenerateDrawingRelAsync(_currentSheetIndex, cancellationToken).ConfigureAwait(false);
await GenerateDrawingXmlAsync(_currentSheetIndex, cancellationToken).ConfigureAwait(false);

await CreateZipEntryAsync(
ExcelFileNames.SheetRels(_currentSheetIndex),
null,
ExcelXml.DefaultSheetRelXml.Replace("{{format}}", ExcelXml.DrawingRelationship(_currentSheetIndex)),
ExcelXml.DefaultSheetRelXml(ExcelXml.DrawingRelationship(_currentSheetIndex)),
cancellationToken).ConfigureAwait(false);

var (workbookXml, workbookRelsXml, _) = GenerateWorkbookXmls();
var (workbookXml, workbookRelsXml, _) = GenerateWorkbookItems();
await CreateZipEntryAsync(
ExcelFileNames.Workbook,
ExcelContentTypes.Workbook,
ExcelXml.DefaultWorkbookXml.Replace("{{sheets}}", workbookXml),
ExcelXml.DefaultWorkbookXml(workbookXml),
cancellationToken).ConfigureAwait(false);

await CreateZipEntryAsync(
ExcelFileNames.WorkbookRels,
null,
ExcelXml.DefaultWorkbookXmlRels.Replace("{{sheets}}", workbookRelsXml),
ExcelXml.DefaultWorkbookXmlRels(workbookRelsXml),
cancellationToken).ConfigureAwait(false);

await CopyAndUpdateContentTypesAsync(cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -228,7 +227,7 @@ private async Task CopyAndUpdateContentTypesAsync(CancellationToken cancellation
var contentTypesZipEntry = _oldArchive!.Entries.SingleOrDefault(s => s.FullName == ExcelFileNames.ContentTypes);
if (contentTypesZipEntry is null)
{
await GenerateContentTypesXmlAsync(cancellationToken).ConfigureAwait(false);
await GenerateContentTypesAsync(cancellationToken).ConfigureAwait(false);
return;
}

Expand Down
37 changes: 12 additions & 25 deletions src/MiniExcel.OpenXml/Writer/OpenXmlWriter.XmlGeneration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ private string GetFileValue(int rowIndex, int cellIndex, object value)
Contents = bytes,
RowIndex = rowIndex,
CellIndex = cellIndex,
SheetId = _currentSheetIndex
SheetIndex = _currentSheetIndex
};

if (format != ImageFormat.Unknown)
Expand Down Expand Up @@ -380,7 +380,7 @@ private static string GetDimensionRef(int maxRowIndex, int maxColumnIndex)
private string GetDrawingRelationshipXml(int sheetIndex)
{
var drawing = new StringBuilder();
foreach (var image in _files.Where(w => w.IsImage && w.SheetId == sheetIndex))
foreach (var image in _files.Where(w => w.IsImage && w.SheetIndex == sheetIndex))
{
drawing.AppendLine(ExcelXml.ImageRelationship(image));
}
Expand All @@ -395,7 +395,7 @@ private string GetDrawingXml(int sheetIndex)
for (int fileIndex = 0; fileIndex < _files.Count; fileIndex++)
{
var file = _files[fileIndex];
if (file.IsImage && file.SheetId == sheetIndex)
if (file.IsImage && file.SheetIndex == sheetIndex)
{
drawing.Append(ExcelXml.DrawingXml(file, fileIndex));
}
Expand All @@ -404,37 +404,24 @@ private string GetDrawingXml(int sheetIndex)
return drawing.ToString();
}

private (string WorkbookXml, string WorkbookRelsXml, Dictionary<int, string> SheetRelsXml) GenerateWorkbookXmls()
private (string WorkbookContents, string WorkbookRelsContents, Dictionary<int, string> SheetRelsContents) GenerateWorkbookItems()
{
var workbookXml = new StringBuilder();
var workbookRelsXml = new StringBuilder();
var sheetsRelsXml = new Dictionary<int, string>();
var workbookContents = new StringBuilder();
var workbookRelsContents = new StringBuilder();
var sheetsRelsDict = new Dictionary<int, string>();

var sheetId = 0;
foreach (var sheetDto in _sheets)
{
sheetId++;

workbookXml.AppendLine(ExcelXml.Sheet(sheetDto, sheetId));
workbookRelsXml.AppendLine(ExcelXml.WorksheetRelationship(sheetDto));

workbookContents.AppendLine(ExcelXml.Sheet(sheetDto, sheetId));
workbookRelsContents.AppendLine(ExcelXml.WorksheetRelationship(sheetDto));
//TODO: support multiple drawing
//TODO: ../drawings/drawing1.xml or /xl/drawings/drawing1.xml
sheetsRelsXml.Add(sheetDto.SheetIdx, ExcelXml.DrawingRelationship(sheetId));
sheetsRelsDict.Add(sheetDto.SheetIdx, ExcelXml.DrawingRelationship(sheetId));
}

return (workbookXml.ToString(), workbookRelsXml.ToString(), sheetsRelsXml);
}

private string GetContentTypesXml()
{
var sb = new StringBuilder(ExcelXml.StartTypes);
foreach (var p in _zipContentsMap)
{
sb.Append(ExcelXml.ContentType(p.Value, p.Key));
}

sb.Append(ExcelXml.EndTypes);
return sb.ToString();
return (workbookContents.ToString(), workbookRelsContents.ToString(), sheetsRelsDict);
}
}
Loading
Loading