diff --git a/README.md b/README.md index 1ad8a9d..81f4d64 100644 --- a/README.md +++ b/README.md @@ -469,6 +469,27 @@ MiniExcel.SaveAs(path, value, configuration: new OpenXmlConfiguration() { AutoFi +#### 10. Create Image + +```csharp +var value = new[] { + 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"))}, +}; +MiniExcel.SaveAs(path, value); +``` + +![image](https://user-images.githubusercontent.com/12729184/150462383-ad9931b3-ed8d-4221-a1d6-66f799743433.png) + + + + + + + ### Fill Data To Excel Template diff --git a/README.zh-CN.md b/README.zh-CN.md index be81dc7..481d399 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -473,6 +473,29 @@ MiniExcel.SaveAs(path, value, configuration: new OpenXmlConfiguration() { AutoFi +#### 10. 图片生成 + +```csharp +var value = new[] { + 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"))}, +}; +MiniExcel.SaveAs(path, value); +``` + +![image](https://user-images.githubusercontent.com/12729184/150462383-ad9931b3-ed8d-4221-a1d6-66f799743433.png) + + + + + + + + + ### 模板填充 Excel diff --git a/README.zh-Hant.md b/README.zh-Hant.md index 472485a..6f22cd1 100644 --- a/README.zh-Hant.md +++ b/README.zh-Hant.md @@ -479,6 +479,27 @@ MiniExcel.SaveAs(path, value, configuration: new OpenXmlConfiguration() { AutoFi +#### 10. 圖片生成 + +```csharp +var value = new[] { + 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"))}, +}; +MiniExcel.SaveAs(path, value); +``` + +![image](https://user-images.githubusercontent.com/12729184/150462383-ad9931b3-ed8d-4221-a1d6-66f799743433.png) + + + + + + + diff --git a/docs/README.md b/docs/README.md index 5c08197..0e84198 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,9 @@ --- +### 0.20.0 +- [New] SaveAs support image #304 + ### 0.19.3-beta - [Fix] Excelnumberformat 1.1.0 valid date expired (Valid from: 2018-04-10 08:00:00 to 2021-04-14 20:00:00) [link](https://github.com/andersnm/ExcelNumberFormat/issues/34) diff --git a/docs/README.zh-CN.md b/docs/README.zh-CN.md index 9ec929f..465a88d 100644 --- a/docs/README.zh-CN.md +++ b/docs/README.zh-CN.md @@ -23,6 +23,9 @@ --- +### 0.20.0 +- [New] SaveAs 支持图片生成 #304 + ### 0.19.3-beta - [Fix] Excelnumberformat 1.1.0 凭证过期 (Valid from: 2018-04-10 08:00:00 to 2021-04-14 20:00:00) [link](https://github.com/andersnm/ExcelNumberFormat/issues/34) diff --git a/docs/README.zh-Hant.md b/docs/README.zh-Hant.md index 5c805f8..1a5e5f2 100644 --- a/docs/README.zh-Hant.md +++ b/docs/README.zh-Hant.md @@ -17,6 +17,8 @@ --- +### 0.20.0 +- [New] SaveAs 支持圖片生成 #304 ### 0.19.3-beta - [Fix] Excelnumberformat 1.1.0 憑證過期 (Valid from: 2018-04-10 08:00:00 to 2021-04-14 20:00:00) [link](https://github.com/andersnm/ExcelNumberFormat/issues/34) diff --git a/samples/images/google_logo.png b/samples/images/google_logo.png new file mode 100644 index 0000000..8efaf81 Binary files /dev/null and b/samples/images/google_logo.png differ diff --git a/samples/images/microsoft_logo.png b/samples/images/microsoft_logo.png new file mode 100644 index 0000000..1973db7 Binary files /dev/null and b/samples/images/microsoft_logo.png differ diff --git a/samples/images/reddit_logo.png b/samples/images/reddit_logo.png new file mode 100644 index 0000000..f3bbaa0 Binary files /dev/null and b/samples/images/reddit_logo.png differ diff --git a/samples/images/statck_overflow_logo.png b/samples/images/statck_overflow_logo.png new file mode 100644 index 0000000..ecfa23f Binary files /dev/null and b/samples/images/statck_overflow_logo.png differ diff --git a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs index 807233f..2e3ebfb 100644 --- a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs +++ b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs @@ -15,18 +15,20 @@ namespace MiniExcelLibs.OpenXml { internal class ImageDto { - public string ID { get; set; } = $"R{Guid.NewGuid().ToString("N")}".Substring(0,5); + public string ID { get; set; } = $"R{Guid.NewGuid().ToString("N")}"; public string Extension { get; set; } - public string Path { get { return $"xl/media/image{ID}.{Extension}"; }} + public string Path { get { return $"xl/media/image{ID}.{Extension}"; } } public string Path2 { get { return $"/xl/media/image{ID}.{Extension}"; } } public Byte[] Byte { get; set; } + public int RowIndex { get; set; } + public int CellIndex { get; set; } } internal class SheetDto { public string ID { get; set; } = $"R{Guid.NewGuid().ToString("N")}"; public string Name { get; set; } public int SheetIdx { get; set; } - public string Path { get { return $"xl/worksheets/sheet{SheetIdx}.xml"; } } + public string Path { get { return $"xl/worksheets/sheet{SheetIdx}.xml"; } } } internal class DrawingDto { @@ -49,7 +51,7 @@ namespace MiniExcelLibs.OpenXml this._configuration = configuration as OpenXmlConfiguration ?? OpenXmlConfiguration.DefaultConfig; this._printHeader = printHeader; this._value = value; - _sheets.Add(new SheetDto{ Name =sheetName, SheetIdx =1}); //TODO:remove + _sheets.Add(new SheetDto { Name = sheetName, SheetIdx = 1 }); //TODO:remove } public void SaveAs() @@ -344,7 +346,7 @@ namespace MiniExcelLibs.OpenXml } } - private void WriteCell(StreamWriter writer, int yIndex, int cellIndex, object value, ExcelCustomPropertyInfo p) + private void WriteCell(StreamWriter writer, int rowIndex, int cellIndex, object value, ExcelCustomPropertyInfo p) { var v = string.Empty; var t = "str"; @@ -400,11 +402,14 @@ namespace MiniExcelLibs.OpenXml { //it can't insert to zip first to avoid cache image to memory //because sheet xml is opening.. https://github.com/shps951023/MiniExcel/issues/304#issuecomment-1017031691 + //int rowIndex, int cellIndex _images.Add(new ImageDto() { Extension = format.ToString(), Byte = bytes, - }); + RowIndex = rowIndex, + CellIndex = cellIndex + }); } } } @@ -428,7 +433,7 @@ namespace MiniExcelLibs.OpenXml } } - var columname = ExcelOpenXmlUtils.ConvertXyToCell(cellIndex, yIndex); + var columname = ExcelOpenXmlUtils.ConvertXyToCell(cellIndex, rowIndex); if (v != null && (v.StartsWith(" ") || v.EndsWith(" "))) /*Prefix and suffix blank space will lost after SaveAs #294*/ writer.Write($"{v}"); else @@ -582,15 +587,15 @@ namespace MiniExcelLibs.OpenXml { drawing.Append($@" - 0 + {i.CellIndex- 1/* why -1 : https://user-images.githubusercontent.com/12729184/150460189-f08ed939-44d4-44e1-be6e-9c533ece6be8.png*/} 0 - 0 + {i.RowIndex-1} 0 - + @@ -641,7 +646,7 @@ namespace MiniExcelLibs.OpenXml CreateZipEntry(@"xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", _defaultWorkbookXml.Replace("{{sheets}}", workbookXml.ToString())); CreateZipEntry(@"xl/_rels/workbook.xml.rels", "", - _defaultWorkbookXmlRels.Replace("{{sheets}}", workbookRelsXml.ToString())); + _defaultWorkbookXmlRels.Replace("{{sheets}}", workbookRelsXml.ToString())); } //[Content_Types].xml diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs index 2335178..82342a3 100644 --- a/tests/MiniExcelTests/MiniExcelIssueTests.cs +++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs @@ -34,15 +34,23 @@ namespace MiniExcelLibs.Tests [Fact] public void TestIssue304() { - var imagePath = PathHelper.GetFile("images/github_logo.png"); - var image = File.ReadAllBytes(imagePath); - var value = Enumerable.Range(1, 5).Select(s => new { image }); - var path = PathHelper.GetRandomPath(); + var path = PathHelper.GetTempFilePath(); + var value = new[] { + 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"))}, + }; MiniExcel.SaveAs(path, value); - - //TODO: Read from base 64 not work - //var image = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAAEElEQVR4nGJgAQAAAP//AwAABgAFV7+r1AAAAABJRU5ErkJggg=="); + { + Assert.Contains("/xl/media/image", 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=", Helpers.GetZipFileContent(path, "xl/worksheets/sheet1.xml")); + Assert.Contains("../drawings/drawing1.xml", Helpers.GetZipFileContent(path, "xl/worksheets/_rels/sheet1.xml.rels")); + } } /// diff --git a/tests/MiniExcelTests/Utils/PathHelper.cs b/tests/MiniExcelTests/Utils/PathHelper.cs index a3f9153..059f687 100644 --- a/tests/MiniExcelTests/Utils/PathHelper.cs +++ b/tests/MiniExcelTests/Utils/PathHelper.cs @@ -20,7 +20,7 @@ return path; } - public static string GetRandomPath(string extension = "xlsx") + public static string GetTempFilePath(string extension = "xlsx") { return Path.GetTempPath() + Guid.NewGuid().ToString() + "." + extension; }