diff --git a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs index c72b271add3e4f0e064ac5d68b2f00df6a857814..fac7bdff3d036f80e8f96a2ba7b5a695ef45648c 100644 --- a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs +++ b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs @@ -25,6 +25,7 @@ internal class FileDto public int RowIndex { get; set; } public int CellIndex { get; set; } public bool IsImage { get; set; } = false; + public int SheetId { get; set; } } internal class SheetDto { @@ -47,6 +48,8 @@ internal partial class ExcelOpenXmlSheetWriter : IExcelWriter private readonly object _value; private readonly List _sheets = new List(); private readonly List _files = new List(); + private int currentSheetIndex = 0; + public ExcelOpenXmlSheetWriter(Stream stream, object value, string sheetName, IConfiguration configuration, bool printHeader) { this._stream = stream; @@ -71,6 +74,9 @@ public void SaveAs() sheetId++; var s = new SheetDto { Name = sheet.Key, SheetIdx = sheetId }; _sheets.Add(s); //TODO:remove + + currentSheetIndex = sheetId; + CreateSheetXml(sheet.Value, s.Path); } } @@ -85,11 +91,17 @@ public void SaveAs() var s = new SheetDto { Name = dt.TableName, SheetIdx = sheetId }; _sheets.Add(s); //TODO:remove var sheetPath = s.Path; + + currentSheetIndex = sheetId; + CreateSheetXml(dt, sheetPath); } } else { + //Single sheet export. + currentSheetIndex++; + CreateSheetXml(_value, _sheets[0].Path); } } @@ -262,7 +274,7 @@ private void CreateSheetXml(object value, string sheetPath) writer.Write(""); if (_configuration.AutoFilter) writer.Write($""); - writer.Write(""); + writer.Write(""); } else if (value is DataTable) { @@ -444,7 +456,8 @@ private void WriteCell(StreamWriter writer, int rowIndex, int cellIndex, object { Byte = bytes, RowIndex = rowIndex, - CellIndex = cellIndex + CellIndex = cellIndex, + SheetId = currentSheetIndex }; if (format != ImageFormat.unknown) { @@ -628,25 +641,30 @@ private void GenerateEndXml() // drawing rel { - var drawing = new StringBuilder(); - foreach (var i in _files.Where(w=>w.IsImage)) + for (int j = 0; j < _sheets.Count; j++) { - drawing.AppendLine($@""); + var drawing = new StringBuilder(); + foreach (var i in _files.Where(w => w.IsImage && w.SheetId == j + 1)) + { + drawing.AppendLine($@""); + } + CreateZipEntry($"xl/drawings/_rels/drawing{j + 1}.xml.rels", "", + _defaultDrawingXmlRels.Replace("{{format}}", drawing.ToString())); } - CreateZipEntry($"xl/drawings/_rels/drawing1.xml.rels", "", - _defaultDrawingXmlRels.Replace("{{format}}", drawing.ToString())); } // drawing { - var drawing = new StringBuilder(); - foreach (var i in _files.Where(w => w.IsImage)) + for (int j = 0; j < _sheets.Count; j++) { - drawing.Append($@" + var drawing = new StringBuilder(); + foreach (var i in _files.Where(w => w.IsImage && w.SheetId == j + 1)) + { + drawing.Append($@" - {i.CellIndex- 1/* why -1 : https://user-images.githubusercontent.com/12729184/150460189-f08ed939-44d4-44e1-be6e-9c533ece6be8.png*/} + {i.CellIndex - 1/* why -1 : https://user-images.githubusercontent.com/12729184/150460189-f08ed939-44d4-44e1-be6e-9c533ece6be8.png*/} 0 - {i.RowIndex-1} + {i.RowIndex - 1} 0 @@ -675,9 +693,10 @@ private void GenerateEndXml() "); + } + CreateZipEntry($"xl/drawings/drawing{j + 1}.xml", "application/vnd.openxmlformats-officedocument.drawing+xml", + _defaultDrawing.Replace("{{format}}", drawing.ToString())); } - CreateZipEntry($"xl/drawings/drawing1.xml", "application/vnd.openxmlformats-officedocument.drawing+xml", - _defaultDrawing.Replace("{{format}}", drawing.ToString())); } // workbook.xml 、 workbookRelsXml @@ -694,7 +713,7 @@ private void GenerateEndXml() //TODO: support multiple drawing //TODO: ../drawings/drawing1.xml or /xl/drawings/drawing1.xml - var sheetRelsXml = $@""; + var sheetRelsXml = $@""; CreateZipEntry($"xl/worksheets/_rels/sheet{s.SheetIdx}.xml.rels", "", _defaultSheetRelXml.Replace("{{format}}", sheetRelsXml)); } diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs index 12f24060010a1da018a72b73fcd9428c635f8a4a..23acab2d2d537bc3bc291c0230f32c9131d70db6 100644 --- a/tests/MiniExcelTests/MiniExcelIssueTests.cs +++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs @@ -635,7 +635,7 @@ public void TestIssue325() }; MiniExcel.SaveAs(path, value); var xml = Helpers.GetZipFileContent(path, "xl/worksheets/_rels/sheet2.xml.rels"); - var cnt = Regex.Matches(xml, "Id=\"drawing1\"").Count; + var cnt = Regex.Matches(xml, "Id=\"drawing2\"").Count; Assert.True(cnt == 1); } @@ -2952,5 +2952,50 @@ public class Issue138ExcelRow public double? 波段 { get; set; } public double? 當沖 { get; set; } } + + /// + /// https://gitee.com/dotnetchina/MiniExcel/issues/I50VD5 + /// + [Fact] + public void IssueI50VD5() + { + var path = PathHelper.GetTempFilePath(); + + var list1 = new List() + { + new { Name="github",Image=File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png"))}, + new { Name="google",Image=File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png"))}, + new { Name="microsoft",Image=File.ReadAllBytes(PathHelper.GetFile("images/microsoft_logo.png"))}, + new { Name="reddit",Image=File.ReadAllBytes(PathHelper.GetFile("images/reddit_logo.png"))}, + new { Name="statck_overflow",Image=File.ReadAllBytes(PathHelper.GetFile("images/statck_overflow_logo.png"))}, + }; + + var list2 = new List() + { + new { Id = 1, Name="github",Image=File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png"))}, + new { Id = 2, Name="google",Image=File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png"))}, + }; + + var sheets = new Dictionary + { + ["A"] = list1, + ["B"] = list2, + }; + MiniExcel.SaveAs(path, sheets); + + { + Assert.Contains("/xl/media/", Helpers.GetZipFileContent(path, "xl/drawings/_rels/drawing1.xml.rels")); + Assert.Contains("ext cx=\"609600\" cy=\"190500\"", Helpers.GetZipFileContent(path, "xl/drawings/drawing1.xml")); + Assert.Contains("/xl/drawings/drawing1.xml", Helpers.GetZipFileContent(path, "[Content_Types].xml")); + Assert.Contains("drawing r:id=\"drawing1\"", Helpers.GetZipFileContent(path, "xl/worksheets/sheet1.xml")); + Assert.Contains("../drawings/drawing1.xml", Helpers.GetZipFileContent(path, "xl/worksheets/_rels/sheet1.xml.rels")); + + Assert.Contains("/xl/media/", Helpers.GetZipFileContent(path, "xl/drawings/_rels/drawing2.xml.rels")); + Assert.Contains("ext cx=\"609600\" cy=\"190500\"", Helpers.GetZipFileContent(path, "xl/drawings/drawing2.xml")); + Assert.Contains("/xl/drawings/drawing1.xml", Helpers.GetZipFileContent(path, "[Content_Types].xml")); + Assert.Contains("drawing r:id=\"drawing2\"", Helpers.GetZipFileContent(path, "xl/worksheets/sheet2.xml")); + Assert.Contains("../drawings/drawing2.xml", Helpers.GetZipFileContent(path, "xl/worksheets/_rels/sheet2.xml.rels")); + } + } } } \ No newline at end of file