diff --git a/README.md b/README.md
index b02bd0a6..3328916f 100644
--- a/README.md
+++ b/README.md
@@ -1457,6 +1457,8 @@ MiniExcel.SaveAs(path, reader,configuration:config);
#### 6. Batch Add Image (MiniExcel.AddPicture)
+Please add pictures before batch generate rows data, or system will load large memory usage when calling AddPicture.
+
```csharp
var images = new[]
{
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 1a938305..e55b6a1a 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1634,6 +1634,8 @@ public class Order
#### 6. 批量添加/插入图片 (MiniExcel.AddPicture)
+请在批量生成行数据之前添加图片,否则在调用 AddPicture 时系统会占用大量内存。
+
```csharp
var images = new[]
{
diff --git a/README.zh-Hant.md b/README.zh-Hant.md
index ff1562b3..13b3c64d 100644
--- a/README.zh-Hant.md
+++ b/README.zh-Hant.md
@@ -1368,6 +1368,8 @@ MiniExcel.SaveAs(path, reader,configuration:config);
#### 6. 批量添加/插入圖片 (MiniExcel.AddPicture)
+請在批量生成行資料之前新增圖片,否則在呼叫 AddPicture 時系統將會佔用大量記憶體。
+
```csharp
var images = new[]
{
diff --git a/docs/README.md b/docs/README.md
index cf28a705..42248b87 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -23,6 +23,14 @@
---
+### 1.41.3
+- [New] Adding QuoteWhitespaces option to CsvConfiguration for adding double quotes to string containing whitespaces #790 (via @michelebastione )
+- [Bug] Fixed bug that made the DynamicExcelColumn property "Ignore" not work when generating using an IDataReader as source #584 (via @michelebastione )
+- [Bug] v1.41.2 AddPicture not working #814 (via @shps951023)
+- [Bug] v1.41.1 AddPicture image max column and row are 2 cells #815 (via @shps951023)
+- [Bug] AddPicture get error same export file and second time. #816 (via @shps951023)
+
+
### 1.41.2
- [New] Fixes enum behaviour and adds support for DescriptionAttribute when saving by template (via @michelebastione )
- [Bug] SaveAsByTemplate - Excel Dimension Xml is null #459 (via @michelebastione )
diff --git a/docs/README.zh-CN.md b/docs/README.zh-CN.md
index b1df9803..844cd3a7 100644
--- a/docs/README.zh-CN.md
+++ b/docs/README.zh-CN.md
@@ -27,6 +27,17 @@
+### 1.41.3
+
+* 【新增】在 `CsvConfiguration` 中新增 `QuoteWhitespaces` 選項,用於對包含空白字元的字串加上雙引號 #790(貢獻者:@michelebastione)
+* 【錯誤修正】修正使用 `IDataReader` 作為來源產生資料時,`DynamicExcelColumn` 的 `Ignore` 屬性無效的問題 #584(貢獻者:@michelebastione)
+* 【錯誤修正】v1.41.2 中 `AddPicture` 功能無法使用的問題 #814(貢獻者:@shps951023)
+* 【錯誤修正】v1.41.1 中 `AddPicture` 插入的圖片最大列與欄僅限於 2 個儲存格的問題 #815(貢獻者:@shps951023)
+* 【錯誤修正】`AddPicture` 在匯出檔案後再次執行時出現錯誤的問題 #816(貢獻者:@shps951023)
+
+
+
+
### 1.41.2
- [New] 增加 enum behaviour and adds support for DescriptionAttribute when saving by template (via @michelebastione )
- [Bug] SaveAsByTemplate - Excel Dimension Xml is null #459 (via @michelebastione )
diff --git a/docs/README.zh-Hant.md b/docs/README.zh-Hant.md
index 2dfbbd81..a09e23c6 100644
--- a/docs/README.zh-Hant.md
+++ b/docs/README.zh-Hant.md
@@ -25,6 +25,16 @@
---
+
+### 1.41.3
+
+* 【新增】在 CsvConfiguration 中新增 `QuoteWhitespaces` 選項,讓包含空白字元的字串自動加上雙引號 #790(由 @michelebastione 提供)
+* 【修正】修正當使用 IDataReader 作為資料來源時,DynamicExcelColumn 的 `Ignore` 屬性無效的問題 #584(由 @michelebastione 提供)
+* 【修正】v1.41.2 中 `AddPicture` 功能無法使用的問題 #814(由 @shps951023 提供)
+* 【修正】v1.41.1 中 `AddPicture` 插入的圖片最大列與欄僅為兩格儲存格的問題 #815(由 @shps951023 提供)
+* 【修正】當再次使用相同匯出檔案時,`AddPicture` 發生錯誤的問題 #816(由 @shps951023 提供)
+
+
### 1.41.2
- [New] 增加 enum behaviour and adds support for DescriptionAttribute when saving by template (via @michelebastione )
- [Bug] SaveAsByTemplate - Excel Dimension Xml is null #459 (via @michelebastione )
diff --git a/samples/xlsx/TestIssue815_1.xlsx b/samples/xlsx/TestIssue815_1.xlsx
new file mode 100644
index 00000000..a2e266e8
Binary files /dev/null and b/samples/xlsx/TestIssue815_1.xlsx differ
diff --git a/samples/xlsx/TestIssue815_1/[Content_Types].xml b/samples/xlsx/TestIssue815_1/[Content_Types].xml
new file mode 100644
index 00000000..431bc4e5
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/[Content_Types].xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/_rels/.rels b/samples/xlsx/TestIssue815_1/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/docProps/app.xml b/samples/xlsx/TestIssue815_1/docProps/app.xml
new file mode 100644
index 00000000..2e1cee69
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Sheet1falsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/docProps/core.xml b/samples/xlsx/TestIssue815_1/docProps/core.xml
new file mode 100644
index 00000000..5ff2c2da
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/docProps/core.xml
@@ -0,0 +1,2 @@
+
+WeiWei Lin2025-06-20T17:24:16Z2025-06-20T17:24:16Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue815_1/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..84cb2b36
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/drawings/_rels/drawing1.xml.rels b/samples/xlsx/TestIssue815_1/xl/drawings/_rels/drawing1.xml.rels
new file mode 100644
index 00000000..0d3c6177
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/drawings/_rels/drawing1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/drawings/drawing1.xml b/samples/xlsx/TestIssue815_1/xl/drawings/drawing1.xml
new file mode 100644
index 00000000..621e88ba
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/drawings/drawing1.xml
@@ -0,0 +1,86 @@
+
+
+
+
+ 2
+ 0
+ 4
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12
+ 0
+ 6
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/media/image1.Png b/samples/xlsx/TestIssue815_1/xl/media/image1.Png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue815_1/xl/media/image1.Png differ
diff --git a/samples/xlsx/TestIssue815_1/xl/styles.xml b/samples/xlsx/TestIssue815_1/xl/styles.xml
new file mode 100644
index 00000000..606c7134
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/theme/theme1.xml b/samples/xlsx/TestIssue815_1/xl/theme/theme1.xml
new file mode 100644
index 00000000..4a95cff0
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/workbook.xml b/samples/xlsx/TestIssue815_1/xl/workbook.xml
new file mode 100644
index 00000000..75d5a5ad
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue815_1/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..205832e9
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_1/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue815_1/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..cf3c093e
--- /dev/null
+++ b/samples/xlsx/TestIssue815_1/xl/worksheets/sheet1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2.xlsx b/samples/xlsx/TestIssue815_2.xlsx
new file mode 100644
index 00000000..d64d0771
Binary files /dev/null and b/samples/xlsx/TestIssue815_2.xlsx differ
diff --git a/samples/xlsx/TestIssue815_2/[Content_Types].xml b/samples/xlsx/TestIssue815_2/[Content_Types].xml
new file mode 100644
index 00000000..431bc4e5
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/[Content_Types].xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/_rels/.rels b/samples/xlsx/TestIssue815_2/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/docProps/app.xml b/samples/xlsx/TestIssue815_2/docProps/app.xml
new file mode 100644
index 00000000..2e1cee69
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Sheet1falsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/docProps/core.xml b/samples/xlsx/TestIssue815_2/docProps/core.xml
new file mode 100644
index 00000000..879b1b76
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/docProps/core.xml
@@ -0,0 +1,2 @@
+
+WeiWei Lin2025-06-20T17:25:32Z2025-06-20T17:25:32Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue815_2/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..84cb2b36
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/drawings/_rels/drawing1.xml.rels b/samples/xlsx/TestIssue815_2/xl/drawings/_rels/drawing1.xml.rels
new file mode 100644
index 00000000..0d3c6177
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/drawings/_rels/drawing1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/drawings/drawing1.xml b/samples/xlsx/TestIssue815_2/xl/drawings/drawing1.xml
new file mode 100644
index 00000000..a7a0b29c
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/drawings/drawing1.xml
@@ -0,0 +1,86 @@
+
+
+
+
+ 2
+ 0
+ 4
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12
+ 0
+ 6
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/media/image1.Png b/samples/xlsx/TestIssue815_2/xl/media/image1.Png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue815_2/xl/media/image1.Png differ
diff --git a/samples/xlsx/TestIssue815_2/xl/styles.xml b/samples/xlsx/TestIssue815_2/xl/styles.xml
new file mode 100644
index 00000000..606c7134
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/theme/theme1.xml b/samples/xlsx/TestIssue815_2/xl/theme/theme1.xml
new file mode 100644
index 00000000..4a95cff0
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/workbook.xml b/samples/xlsx/TestIssue815_2/xl/workbook.xml
new file mode 100644
index 00000000..5f963b6a
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue815_2/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..205832e9
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue815_2/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue815_2/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..3893564e
--- /dev/null
+++ b/samples/xlsx/TestIssue815_2/xl/worksheets/sheet1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1.xlsx b/samples/xlsx/TestIssue816_1.xlsx
new file mode 100644
index 00000000..9cbb6ef6
Binary files /dev/null and b/samples/xlsx/TestIssue816_1.xlsx differ
diff --git a/samples/xlsx/TestIssue816_1/[Content_Types].xml b/samples/xlsx/TestIssue816_1/[Content_Types].xml
new file mode 100644
index 00000000..51b87737
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/[Content_Types].xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/_rels/.rels b/samples/xlsx/TestIssue816_1/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/docProps/app.xml b/samples/xlsx/TestIssue816_1/docProps/app.xml
new file mode 100644
index 00000000..3db85d1a
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Demofalsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/docProps/core.xml b/samples/xlsx/TestIssue816_1/docProps/core.xml
new file mode 100644
index 00000000..84719d57
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/docProps/core.xml
@@ -0,0 +1,2 @@
+
+WeiWei Lin2015-06-05T18:17:20Z2025-04-20T14:24:59Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue816_1/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..65485f71
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/drawings/_rels/drawing8155941d47d148b990d1736b0f18eb14.xml.rels b/samples/xlsx/TestIssue816_1/xl/drawings/_rels/drawing8155941d47d148b990d1736b0f18eb14.xml.rels
new file mode 100644
index 00000000..f54325b6
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/drawings/_rels/drawing8155941d47d148b990d1736b0f18eb14.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/drawings/drawing8155941d47d148b990d1736b0f18eb14.xml b/samples/xlsx/TestIssue816_1/xl/drawings/drawing8155941d47d148b990d1736b0f18eb14.xml
new file mode 100644
index 00000000..4b79ac58
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/drawings/drawing8155941d47d148b990d1736b0f18eb14.xml
@@ -0,0 +1,119 @@
+
+
+
+ 2
+ 0
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/media/image6ef1fcd090e14c71a7feddd858da8770.png b/samples/xlsx/TestIssue816_1/xl/media/image6ef1fcd090e14c71a7feddd858da8770.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_1/xl/media/image6ef1fcd090e14c71a7feddd858da8770.png differ
diff --git a/samples/xlsx/TestIssue816_1/xl/media/imagef63d9dc50eff42f7964d4d5830991165.png b/samples/xlsx/TestIssue816_1/xl/media/imagef63d9dc50eff42f7964d4d5830991165.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue816_1/xl/media/imagef63d9dc50eff42f7964d4d5830991165.png differ
diff --git a/samples/xlsx/TestIssue816_1/xl/media/imagefb0519c58a7b412ba445a8775ba5a5cf.png b/samples/xlsx/TestIssue816_1/xl/media/imagefb0519c58a7b412ba445a8775ba5a5cf.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_1/xl/media/imagefb0519c58a7b412ba445a8775ba5a5cf.png differ
diff --git a/samples/xlsx/TestIssue816_1/xl/sharedStrings.xml b/samples/xlsx/TestIssue816_1/xl/sharedStrings.xml
new file mode 100644
index 00000000..a74a5953
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/sharedStrings.xml
@@ -0,0 +1,2 @@
+
+Image1:Image2:
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/styles.xml b/samples/xlsx/TestIssue816_1/xl/styles.xml
new file mode 100644
index 00000000..04695051
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/theme/theme1.xml b/samples/xlsx/TestIssue816_1/xl/theme/theme1.xml
new file mode 100644
index 00000000..f82d9ebb
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/workbook.xml b/samples/xlsx/TestIssue816_1/xl/workbook.xml
new file mode 100644
index 00000000..2a833c3d
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue816_1/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..45203544
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_1/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue816_1/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..12cc2053
--- /dev/null
+++ b/samples/xlsx/TestIssue816_1/xl/worksheets/sheet1.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 1
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2.xlsx b/samples/xlsx/TestIssue816_2.xlsx
new file mode 100644
index 00000000..bf718ad2
Binary files /dev/null and b/samples/xlsx/TestIssue816_2.xlsx differ
diff --git a/samples/xlsx/TestIssue816_2/[Content_Types].xml b/samples/xlsx/TestIssue816_2/[Content_Types].xml
new file mode 100644
index 00000000..3077b7d2
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/[Content_Types].xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/_rels/.rels b/samples/xlsx/TestIssue816_2/_rels/.rels
new file mode 100644
index 00000000..c50b69e8
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/_rels/.rels
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/docProps/app.xml b/samples/xlsx/TestIssue816_2/docProps/app.xml
new file mode 100644
index 00000000..ebd9f193
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/docProps/app.xml
@@ -0,0 +1,27 @@
+
+
+ Microsoft Excel
+ 0
+ false
+
+
+
+ Worksheets
+
+
+ 1
+
+
+
+
+
+ Demo
+
+
+
+ false
+ false
+ false
+ 16.0300
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/docProps/core.xml b/samples/xlsx/TestIssue816_2/docProps/core.xml
new file mode 100644
index 00000000..09f6e3aa
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/docProps/core.xml
@@ -0,0 +1,11 @@
+
+
+ Wei
+ Wei Lin
+ 2015-06-05T18:17:20Z
+ 2025-04-20T14:24:59Z
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue816_2/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..aafbae06
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/_rels/workbook.xml.rels
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml.rels b/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml.rels
new file mode 100644
index 00000000..f9d9ae72
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawingcea5e87afab34a1b886841980881e6a6.xml.rels b/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawingcea5e87afab34a1b886841980881e6a6.xml.rels
new file mode 100644
index 00000000..ea055178
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/drawings/_rels/drawingcea5e87afab34a1b886841980881e6a6.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/drawings/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml b/samples/xlsx/TestIssue816_2/xl/drawings/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml
new file mode 100644
index 00000000..9b1e2419
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/drawings/drawinga13dc3bfd6be4e238ad8f91fcc6c646d.xml
@@ -0,0 +1,119 @@
+
+
+
+ 3
+ 0
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/drawings/drawingcea5e87afab34a1b886841980881e6a6.xml b/samples/xlsx/TestIssue816_2/xl/drawings/drawingcea5e87afab34a1b886841980881e6a6.xml
new file mode 100644
index 00000000..0bebe2c5
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/drawings/drawingcea5e87afab34a1b886841980881e6a6.xml
@@ -0,0 +1,119 @@
+
+
+
+ 2
+ 0
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 0
+ 8
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/media/image037f9747190c43eca595e57604de932c.png b/samples/xlsx/TestIssue816_2/xl/media/image037f9747190c43eca595e57604de932c.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/image037f9747190c43eca595e57604de932c.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/media/image3f83eec97c6c49569a75f076c2d4045a.png b/samples/xlsx/TestIssue816_2/xl/media/image3f83eec97c6c49569a75f076c2d4045a.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/image3f83eec97c6c49569a75f076c2d4045a.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/media/image804ac538d3674fa2abc309543b617971.png b/samples/xlsx/TestIssue816_2/xl/media/image804ac538d3674fa2abc309543b617971.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/image804ac538d3674fa2abc309543b617971.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/media/image8d00375faa1f4b41aa5109c3e419c964.png b/samples/xlsx/TestIssue816_2/xl/media/image8d00375faa1f4b41aa5109c3e419c964.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/image8d00375faa1f4b41aa5109c3e419c964.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/media/imagec4303bb6725242df941fea79b5e1296f.png b/samples/xlsx/TestIssue816_2/xl/media/imagec4303bb6725242df941fea79b5e1296f.png
new file mode 100644
index 00000000..8efaf819
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/imagec4303bb6725242df941fea79b5e1296f.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/media/imagee87f98b0db1a48898a63678d92b3660a.png b/samples/xlsx/TestIssue816_2/xl/media/imagee87f98b0db1a48898a63678d92b3660a.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue816_2/xl/media/imagee87f98b0db1a48898a63678d92b3660a.png differ
diff --git a/samples/xlsx/TestIssue816_2/xl/sharedStrings.xml b/samples/xlsx/TestIssue816_2/xl/sharedStrings.xml
new file mode 100644
index 00000000..a74a5953
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/sharedStrings.xml
@@ -0,0 +1,2 @@
+
+Image1:Image2:
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/styles.xml b/samples/xlsx/TestIssue816_2/xl/styles.xml
new file mode 100644
index 00000000..04695051
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/theme/theme1.xml b/samples/xlsx/TestIssue816_2/xl/theme/theme1.xml
new file mode 100644
index 00000000..2c75da85
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/theme/theme1.xml
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/workbook.xml b/samples/xlsx/TestIssue816_2/xl/workbook.xml
new file mode 100644
index 00000000..2462c3ec
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/workbook.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue816_2/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..9fc078e3
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_2/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue816_2/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..f986fca9
--- /dev/null
+++ b/samples/xlsx/TestIssue816_2/xl/worksheets/sheet1.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 1
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3.xlsx b/samples/xlsx/TestIssue816_3.xlsx
new file mode 100644
index 00000000..52e750d1
Binary files /dev/null and b/samples/xlsx/TestIssue816_3.xlsx differ
diff --git a/samples/xlsx/TestIssue816_3/[Content_Types].xml b/samples/xlsx/TestIssue816_3/[Content_Types].xml
new file mode 100644
index 00000000..8ee982ab
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/[Content_Types].xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/_rels/.rels b/samples/xlsx/TestIssue816_3/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/docProps/app.xml b/samples/xlsx/TestIssue816_3/docProps/app.xml
new file mode 100644
index 00000000..d5e92215
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Sheet1falsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/docProps/core.xml b/samples/xlsx/TestIssue816_3/docProps/core.xml
new file mode 100644
index 00000000..50439f08
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/docProps/core.xml
@@ -0,0 +1,2 @@
+
+Wei LinWei Lin2025-06-21T14:00:28Z2025-06-21T14:01:05Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue816_3/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..65485f71
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/drawings/_rels/drawing1.xml.rels b/samples/xlsx/TestIssue816_3/xl/drawings/_rels/drawing1.xml.rels
new file mode 100644
index 00000000..9db7c50e
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/drawings/_rels/drawing1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/drawings/drawing1.xml b/samples/xlsx/TestIssue816_3/xl/drawings/drawing1.xml
new file mode 100644
index 00000000..e68275f7
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/drawings/drawing1.xml
@@ -0,0 +1,2 @@
+
+4013016370514382800615040281132952528096
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/media/image1.png b/samples/xlsx/TestIssue816_3/xl/media/image1.png
new file mode 100644
index 00000000..e52f6c8a
Binary files /dev/null and b/samples/xlsx/TestIssue816_3/xl/media/image1.png differ
diff --git a/samples/xlsx/TestIssue816_3/xl/media/image2.png b/samples/xlsx/TestIssue816_3/xl/media/image2.png
new file mode 100644
index 00000000..66283404
Binary files /dev/null and b/samples/xlsx/TestIssue816_3/xl/media/image2.png differ
diff --git a/samples/xlsx/TestIssue816_3/xl/sharedStrings.xml b/samples/xlsx/TestIssue816_3/xl/sharedStrings.xml
new file mode 100644
index 00000000..d36ba8f0
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/sharedStrings.xml
@@ -0,0 +1,2 @@
+
+f
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/styles.xml b/samples/xlsx/TestIssue816_3/xl/styles.xml
new file mode 100644
index 00000000..659107a0
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/theme/theme1.xml b/samples/xlsx/TestIssue816_3/xl/theme/theme1.xml
new file mode 100644
index 00000000..4a95cff0
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/workbook.xml b/samples/xlsx/TestIssue816_3/xl/workbook.xml
new file mode 100644
index 00000000..6182b7c8
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue816_3/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..205832e9
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_3/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue816_3/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..cb9d4e7c
--- /dev/null
+++ b/samples/xlsx/TestIssue816_3/xl/worksheets/sheet1.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4.xlsx b/samples/xlsx/TestIssue816_4.xlsx
new file mode 100644
index 00000000..1d9aedfe
Binary files /dev/null and b/samples/xlsx/TestIssue816_4.xlsx differ
diff --git a/samples/xlsx/TestIssue816_4/[Content_Types].xml b/samples/xlsx/TestIssue816_4/[Content_Types].xml
new file mode 100644
index 00000000..ce9f84a0
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/[Content_Types].xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/_rels/.rels b/samples/xlsx/TestIssue816_4/_rels/.rels
new file mode 100644
index 00000000..22c9382f
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/_rels/.rels
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/docProps/app.xml b/samples/xlsx/TestIssue816_4/docProps/app.xml
new file mode 100644
index 00000000..d5e92215
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Sheet1falsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/docProps/core.xml b/samples/xlsx/TestIssue816_4/docProps/core.xml
new file mode 100644
index 00000000..50439f08
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/docProps/core.xml
@@ -0,0 +1,2 @@
+
+Wei LinWei Lin2025-06-21T14:00:28Z2025-06-21T14:01:05Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssue816_4/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..e7fe8ebe
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/_rels/workbook.xml.rels
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/drawings/_rels/drawing1.xml.rels b/samples/xlsx/TestIssue816_4/xl/drawings/_rels/drawing1.xml.rels
new file mode 100644
index 00000000..fad44dfe
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/drawings/_rels/drawing1.xml.rels
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/drawings/drawing1.xml b/samples/xlsx/TestIssue816_4/xl/drawings/drawing1.xml
new file mode 100644
index 00000000..bf5f98f9
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/drawings/drawing1.xml
@@ -0,0 +1,2 @@
+
+401301636195038280051504028104775252809520140 120160
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/media/image1.png b/samples/xlsx/TestIssue816_4/xl/media/image1.png
new file mode 100644
index 00000000..e52f6c8a
Binary files /dev/null and b/samples/xlsx/TestIssue816_4/xl/media/image1.png differ
diff --git a/samples/xlsx/TestIssue816_4/xl/media/image2.png b/samples/xlsx/TestIssue816_4/xl/media/image2.png
new file mode 100644
index 00000000..66283404
Binary files /dev/null and b/samples/xlsx/TestIssue816_4/xl/media/image2.png differ
diff --git a/samples/xlsx/TestIssue816_4/xl/media/image3.Png b/samples/xlsx/TestIssue816_4/xl/media/image3.Png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssue816_4/xl/media/image3.Png differ
diff --git a/samples/xlsx/TestIssue816_4/xl/sharedStrings.xml b/samples/xlsx/TestIssue816_4/xl/sharedStrings.xml
new file mode 100644
index 00000000..33295552
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/sharedStrings.xml
@@ -0,0 +1 @@
+f
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/styles.xml b/samples/xlsx/TestIssue816_4/xl/styles.xml
new file mode 100644
index 00000000..e431b21a
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/styles.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/theme/theme1.xml b/samples/xlsx/TestIssue816_4/xl/theme/theme1.xml
new file mode 100644
index 00000000..e57b14ae
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/theme/theme1.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/workbook.xml b/samples/xlsx/TestIssue816_4/xl/workbook.xml
new file mode 100644
index 00000000..61bb5488
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/workbook.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssue816_4/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..5f1e29b8
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssue816_4/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssue816_4/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..95d494b1
--- /dev/null
+++ b/samples/xlsx/TestIssue816_4/xl/worksheets/sheet1.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1.xlsx b/samples/xlsx/TestIssueICFV1I_1_41_1.xlsx
new file mode 100644
index 00000000..9c86969c
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_1.xlsx differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/[Content_Types].xml b/samples/xlsx/TestIssueICFV1I_1_41_1/[Content_Types].xml
new file mode 100644
index 00000000..7ba678e5
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/[Content_Types].xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/_rels/.rels b/samples/xlsx/TestIssueICFV1I_1_41_1/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/app.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/app.xml
new file mode 100644
index 00000000..3db85d1a
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Demofalsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/core.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/core.xml
new file mode 100644
index 00000000..84719d57
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/docProps/core.xml
@@ -0,0 +1,2 @@
+
+WeiWei Lin2015-06-05T18:17:20Z2025-04-20T14:24:59Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..65485f71
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/_rels/drawing98482106b774449083d3adfa462f1707.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/_rels/drawing98482106b774449083d3adfa462f1707.xml.rels
new file mode 100644
index 00000000..dec5e486
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/_rels/drawing98482106b774449083d3adfa462f1707.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/drawing98482106b774449083d3adfa462f1707.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/drawing98482106b774449083d3adfa462f1707.xml
new file mode 100644
index 00000000..209cc8b1
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/drawings/drawing98482106b774449083d3adfa462f1707.xml
@@ -0,0 +1,114 @@
+
+
+
+
+ 2
+ 0
+ 2
+ 0
+
+
+ 3
+ 0
+ 3
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 8
+ 0
+
+
+ 3
+ 4762500
+ 9
+ 4762500
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7
+ 0
+ 8
+ 0
+
+ 8
+ 476250
+ 9
+ 476250
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image8d8065829ab5449aa3b52723e51a7b20.png b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image8d8065829ab5449aa3b52723e51a7b20.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image8d8065829ab5449aa3b52723e51a7b20.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image9f62c0e5edfb4a4fb4df39966f9e930f.png b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image9f62c0e5edfb4a4fb4df39966f9e930f.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/image9f62c0e5edfb4a4fb4df39966f9e930f.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/imagea8f3b74b2f8041e9ae2cad406188704c.png b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/imagea8f3b74b2f8041e9ae2cad406188704c.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/media/imagea8f3b74b2f8041e9ae2cad406188704c.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/sharedStrings.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/sharedStrings.xml
new file mode 100644
index 00000000..a74a5953
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/sharedStrings.xml
@@ -0,0 +1,2 @@
+
+Image1:Image2:
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/styles.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/styles.xml
new file mode 100644
index 00000000..04695051
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/theme/theme1.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/theme/theme1.xml
new file mode 100644
index 00000000..f82d9ebb
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/workbook.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/workbook.xml
new file mode 100644
index 00000000..2a833c3d
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..194fc9f1
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..0d58db40
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_1/xl/worksheets/sheet1.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 1
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2.xlsx b/samples/xlsx/TestIssueICFV1I_1_41_2.xlsx
new file mode 100644
index 00000000..41c44144
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_2.xlsx differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/[Content_Types].xml b/samples/xlsx/TestIssueICFV1I_1_41_2/[Content_Types].xml
new file mode 100644
index 00000000..5cf7020b
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/[Content_Types].xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/_rels/.rels b/samples/xlsx/TestIssueICFV1I_1_41_2/_rels/.rels
new file mode 100644
index 00000000..74bfd8d9
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/_rels/.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/app.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/app.xml
new file mode 100644
index 00000000..3db85d1a
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/app.xml
@@ -0,0 +1,2 @@
+
+Microsoft Excel0falseWorksheets1Demofalsefalsefalse16.0300
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/core.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/core.xml
new file mode 100644
index 00000000..84719d57
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/docProps/core.xml
@@ -0,0 +1,2 @@
+
+WeiWei Lin2015-06-05T18:17:20Z2025-04-20T14:24:59Z
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/_rels/workbook.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/_rels/workbook.xml.rels
new file mode 100644
index 00000000..65485f71
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/_rels/workbook.xml.rels
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/_rels/drawing2605be385d194157a1ed844bf85a6825.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/_rels/drawing2605be385d194157a1ed844bf85a6825.xml.rels
new file mode 100644
index 00000000..9b97e377
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/_rels/drawing2605be385d194157a1ed844bf85a6825.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/drawing2605be385d194157a1ed844bf85a6825.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/drawing2605be385d194157a1ed844bf85a6825.xml
new file mode 100644
index 00000000..005072ef
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/drawings/drawing2605be385d194157a1ed844bf85a6825.xml
@@ -0,0 +1,114 @@
+
+
+
+
+ 2
+ 0
+ 2
+ 0
+
+
+ 3
+ 0
+ 3
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 8
+ 0
+
+
+ 3
+ 4762500
+ 9
+ 4762500
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7
+ 0
+ 8
+ 0
+
+ 8
+ 476250
+ 9
+ 476250
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/image6c041a7f44094767b6c8f3d48a6f6a1f.png b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/image6c041a7f44094767b6c8f3d48a6f6a1f.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/image6c041a7f44094767b6c8f3d48a6f6a1f.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagec8cb923a01634a9489b256bae76a61b2.png b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagec8cb923a01634a9489b256bae76a61b2.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagec8cb923a01634a9489b256bae76a61b2.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagef69f64bf01fc457985842f20542262c5.png b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagef69f64bf01fc457985842f20542262c5.png
new file mode 100644
index 00000000..fe3479dd
Binary files /dev/null and b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/media/imagef69f64bf01fc457985842f20542262c5.png differ
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/sharedStrings.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/sharedStrings.xml
new file mode 100644
index 00000000..a74a5953
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/sharedStrings.xml
@@ -0,0 +1,2 @@
+
+Image1:Image2:
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/styles.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/styles.xml
new file mode 100644
index 00000000..04695051
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/styles.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/theme/theme1.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/theme/theme1.xml
new file mode 100644
index 00000000..f82d9ebb
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/theme/theme1.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/workbook.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/workbook.xml
new file mode 100644
index 00000000..2a833c3d
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/workbook.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/_rels/sheet1.xml.rels b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/_rels/sheet1.xml.rels
new file mode 100644
index 00000000..2891bcc5
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/_rels/sheet1.xml.rels
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/sheet1.xml b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/sheet1.xml
new file mode 100644
index 00000000..a9ca2b84
--- /dev/null
+++ b/samples/xlsx/TestIssueICFV1I_1_41_2/xl/worksheets/sheet1.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 1
+
+
+
+
+
\ No newline at end of file
diff --git a/src/MiniExcel/MiniExcelLibs.csproj b/src/MiniExcel/MiniExcelLibs.csproj
index 96e620ec..9cdeb482 100644
--- a/src/MiniExcel/MiniExcelLibs.csproj
+++ b/src/MiniExcel/MiniExcelLibs.csproj
@@ -1,7 +1,7 @@
net462;netstandard2.0;net8.0;net9.0
- 1.41.2
+ 1.41.3
8
diff --git a/src/MiniExcel/Picture/MiniExcelPicture.cs b/src/MiniExcel/Picture/MiniExcelPicture.cs
index 2ae40af3..d04668c5 100644
--- a/src/MiniExcel/Picture/MiniExcelPicture.cs
+++ b/src/MiniExcel/Picture/MiniExcelPicture.cs
@@ -10,7 +10,7 @@ public class MiniExcelPicture
public string CellAddress { get; set; }
internal int ColumnNumber => ReferenceHelper.ConvertCellToXY(CellAddress).Item1 -1;
internal int RowNumber => ReferenceHelper.ConvertCellToXY(CellAddress).Item2 - 1;
- public int WidthPx { get; set; }
- public int HeightPx { get; set; }
+ public int WidthPx { get; set; } = 80;
+ public int HeightPx { get; set; } = 24;
}
}
\ No newline at end of file
diff --git a/src/MiniExcel/Picture/MiniExcelPictureImplement.cs b/src/MiniExcel/Picture/MiniExcelPictureImplement.cs
index 24a470c6..b1fa21ff 100644
--- a/src/MiniExcel/Picture/MiniExcelPictureImplement.cs
+++ b/src/MiniExcel/Picture/MiniExcelPictureImplement.cs
@@ -1,17 +1,33 @@
-using MiniExcelLibs.OpenXml;
-using MiniExcelLibs.Zip;
-using System;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml;
-
-namespace MiniExcelLibs.Picture
+namespace MiniExcelLibs.Picture
{
- internal static partial class MiniExcelPictureImplement
+ using MiniExcelLibs.OpenXml;
+ using MiniExcelLibs.Zip;
+ using System;
+ using System.IO;
+ using System.IO.Compression;
+ using System.Linq;
+ using System.Xml;
+
+ internal static class MiniExcelPictureImplement
{
+ private static XmlNamespaceManager GetRNamespaceManager(XmlDocument doc)
+ {
+ var nsmgr = new XmlNamespaceManager(doc.NameTable);
+ nsmgr.AddNamespace("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
+ nsmgr.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
+ return nsmgr;
+ }
+
+ private static bool CheckRelationshipExists(XmlDocument doc, string id, string type, string target)
+ {
+ var namespaceManager = new XmlNamespaceManager(doc.NameTable);
+ namespaceManager.AddNamespace("x", "http://schemas.openxmlformats.org/package/2006/relationships");
+
+ var xpath = $"/x:Relationships/x:Relationship[@Id='{id}' and @Type='{type}' and @Target='{target}']";
+ var node = doc.SelectSingleNode(xpath, namespaceManager);
+
+ return node != null;
+ }
[Zomp.SyncMethodGenerator.CreateSyncVersion]
public static async Task AddPictureAsync(Stream excelStream, CancellationToken cancellationToken = default, params MiniExcelPicture[] images)
{
@@ -20,221 +36,130 @@ public static async Task AddPictureAsync(Stream excelStream, CancellationToken c
using var reader = await ExcelOpenXmlSheetReader.CreateAsync(excelStream, null, cancellationToken: cancellationToken).ConfigureAwait(false);
var sheetEntries = await reader.GetWorkbookRelsAsync(excelArchive.entries, cancellationToken).ConfigureAwait(false);
- var drawingRelId = $"rId{Guid.NewGuid():N}";
- var drawingId = Guid.NewGuid().ToString("N");
- var imageId = 2;
using (var archive = new ZipArchive(excelStream, ZipArchiveMode.Update, true))
{
- foreach (var image in images)
+ // Group images by sheet
+ var imagesBySheet = images.GroupBy(img => img.SheetName ?? sheetEntries.First().Name);
+ foreach (var sheetGroup in imagesBySheet)
{
- var imageBytes = image.ImageBytes;
- var sheetEnt = image?.SheetName == null
- ? sheetEntries[0]
- : sheetEntries.FirstOrDefault(x => x.Name == image.SheetName) ?? sheetEntries.First();
-
- var sheetName = sheetEnt.Path.Split('/').Last().Split('.')[0];
- var col = image.ColumnNumber;
- var row = image.RowNumber;
- var widthPx = image?.WidthPx;
- var heightPx = image?.HeightPx;
-
- // Step 1: Add image to /xl/media/
- var imageName = $"image{Guid.NewGuid():N}.png";
- var imagePath = $"xl/media/{imageName}";
- var imageEntry = archive.CreateEntry(imagePath);
- using (var entryStream = imageEntry.Open())
- {
-#if NET5_0_OR_GREATER
- await entryStream.WriteAsync(imageBytes.AsMemory(), cancellationToken).ConfigureAwait(false);
-#else
- await entryStream.WriteAsync(imageBytes, 0, imageBytes.Length, cancellationToken).ConfigureAwait(false);
-#endif
- }
-
- // Step 2: Update [Content_Types].xml
- var contentTypesEntry = archive.GetEntry("[Content_Types].xml");
- var contentTypesDoc = LoadXml(contentTypesEntry);
- if (!contentTypesDoc.DocumentElement.InnerXml.Contains("image/png"))
- {
- var defaultNode = contentTypesDoc.CreateElement("Default", contentTypesDoc.DocumentElement.NamespaceURI);
- defaultNode.SetAttribute("Extension", "png");
- defaultNode.SetAttribute("ContentType", "image/png");
- contentTypesDoc.DocumentElement.AppendChild(defaultNode);
- }
+ var sheetName = sheetGroup.Key;
+ var sheetEnt = sheetEntries.FirstOrDefault(x => x.Name == sheetName) ?? sheetEntries.First();
+ var sheetXmlName = sheetEnt.Path.Split('/').Last().Split('.')[0];
+ string sheetPath = $"xl/worksheets/{sheetXmlName}.xml";
- var overrideDrawingFileExists = contentTypesDoc.DocumentElement.ChildNodes
- .Cast()
- .Any(node => node.Name == "Override" && node.Attributes?["PartName"].Value == $"/xl/drawings/drawing{drawingId}.xml");
-
- if (!overrideDrawingFileExists)
- {
- var overrideNode = contentTypesDoc.CreateElement("Override", contentTypesDoc.DocumentElement.NamespaceURI);
- overrideNode.SetAttribute("PartName", $"/xl/drawings/drawing{drawingId}.xml");
- overrideNode.SetAttribute("ContentType", "application/vnd.openxmlformats-officedocument.drawing+xml");
- contentTypesDoc.DocumentElement.AppendChild(overrideNode);
- }
- SaveXml(contentTypesDoc, contentTypesEntry);
-
- // Step 3: Update xl/worksheets/sheetX.xml
- var sheetPath = $"xl/worksheets/{sheetName}.xml";
var sheetEntry = archive.GetEntry(sheetPath);
var sheetDoc = LoadXml(sheetEntry);
- var relId = $"rId{Guid.NewGuid():N}";
- // unique relId for drawing
-
- // existMiniExcelUniqueDrawingNode = check sheetDoc exist and check its attribut r:id = drawingRelId
- var uniqueDrawingNode = sheetDoc.SelectSingleNode(
- $"/x:worksheet/x:drawing[@r:id='{drawingRelId}']",
- GetRNamespaceManager(sheetDoc));
- if (uniqueDrawingNode != null)
+ // Check for existing node
+ var nsmgr = GetRNamespaceManager(sheetDoc);
+ var drawingNode = sheetDoc.SelectSingleNode("/x:worksheet/x:drawing", nsmgr) as XmlElement;
+ string drawingRelId;
+ string drawingId;
+ if (drawingNode != null)
{
- var drawingNode = sheetDoc.CreateElement("drawing", sheetDoc.DocumentElement?.NamespaceURI);
- drawingNode.Attributes
- .Append(sheetDoc.CreateAttribute("r", "id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"))
- .Value = drawingRelId;
- sheetDoc.DocumentElement.AppendChild(drawingNode);
+ // Drawing exists, get r:id
+ drawingRelId = drawingNode.GetAttribute("id", nsmgr.LookupNamespace("r"));
+ // Find the drawing target from .rels
+ string relsPath = $"xl/worksheets/_rels/{sheetXmlName}.xml.rels";
+ var relsEntry = archive.GetEntry(relsPath);
+ var relsDoc = LoadXml(relsEntry);
+ var namespaceManager = new XmlNamespaceManager(relsDoc.NameTable);
+ namespaceManager.AddNamespace("x", "http://schemas.openxmlformats.org/package/2006/relationships");
+ var xpath = $"/x:Relationships/x:Relationship[@Id='{drawingRelId}']";
+ var relNode = relsDoc.SelectSingleNode(xpath, namespaceManager);
+ string drawingTarget = relNode?.Attributes["Target"]?.Value;
+ drawingId = drawingTarget != null ? drawingTarget.Split('/').Last().Replace("drawing", "").Replace(".xml", "") : Guid.NewGuid().ToString("N");
}
- SaveXml(sheetDoc, sheetEntry);
-
+ else
{
- var drawingPath = $"xl/worksheets/_rels/{sheetName}.xml.rels";
- var isExistEntry = false;
- var sheetRelsEntry = archive.GetEntry(drawingPath);
- if (sheetRelsEntry != null)
- {
- isExistEntry = true;
- }
- else
+ // No drawing, create new
+ drawingRelId = $"rId{Guid.NewGuid().ToString("N")}";
+ drawingId = Guid.NewGuid().ToString("N");
+ // Add node
+ var newDrawingNode = sheetDoc.CreateElement("drawing", sheetDoc.DocumentElement.NamespaceURI);
+ newDrawingNode.SetAttribute("id", nsmgr.LookupNamespace("r"), drawingRelId);
+ sheetDoc.DocumentElement.AppendChild(newDrawingNode);
+ SaveXml(sheetDoc, sheetEntry);
+ // Add relationship
+ string relsPath = $"xl/worksheets/_rels/{sheetXmlName}.xml.rels";
+ var relsEntry = archive.GetEntry(relsPath) ?? archive.CreateEntry(relsPath);
+ var relsDoc = LoadXml(relsEntry);
+ var relNode = relsDoc.CreateElement("Relationship", relsDoc.DocumentElement.NamespaceURI);
+ relNode.SetAttribute("Id", drawingRelId);
+ relNode.SetAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing");
+ relNode.SetAttribute("Target", $"../drawings/drawing{drawingId}.xml");
+ relsDoc.DocumentElement.AppendChild(relNode);
+ SaveXml(relsDoc, relsEntry);
+ // Update [Content_Types].xml for drawing
+ var contentTypesEntry = archive.GetEntry("[Content_Types].xml");
+ var contentTypesDoc = LoadXml(contentTypesEntry);
+ var overrideDrawingFileExists = false;
+ foreach (XmlNode node in contentTypesDoc.DocumentElement.ChildNodes)
{
- sheetRelsEntry = archive.CreateEntry(drawingPath);
- }
-
- if (isExistEntry)
- {
- var sheetRelsDoc = LoadXml(sheetRelsEntry);
- var exists = CheckRelationshipExists(
- sheetRelsDoc,
- drawingRelId,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
- $"../drawings/drawing{drawingId}.xml"
- );
- if (!exists)
+ if (node.Name == "Override" && node.Attributes["PartName"].Value == $"/xl/drawings/drawing{drawingId}.xml")
{
- var relNode = sheetRelsDoc.CreateElement("Relationship", sheetRelsDoc.DocumentElement.NamespaceURI);
- relNode.SetAttribute("Id", drawingRelId);
- relNode.SetAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing");
- relNode.SetAttribute("Target", $"../drawings/drawing{drawingId}.xml");
- sheetRelsDoc.DocumentElement.AppendChild(relNode);
+ overrideDrawingFileExists = true;
+ break;
}
- SaveXml(sheetRelsDoc, sheetRelsEntry);
}
- else
+ if (!overrideDrawingFileExists)
{
- var sheetRelsDoc = new XmlDocument();
- sheetRelsDoc.LoadXml(@"");
- var relNode = sheetRelsDoc.CreateElement("Relationship", sheetRelsDoc.DocumentElement.NamespaceURI);
- relNode.SetAttribute("Id", drawingRelId);
- relNode.SetAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing");
- relNode.SetAttribute("Target", $"../drawings/drawing{drawingId}.xml");
- sheetRelsDoc.DocumentElement.AppendChild(relNode);
- SaveXml(sheetRelsDoc, sheetRelsEntry);
+ var overrideNode = contentTypesDoc.CreateElement("Override", contentTypesDoc.DocumentElement.NamespaceURI);
+ overrideNode.SetAttribute("PartName", $"/xl/drawings/drawing{drawingId}.xml");
+ overrideNode.SetAttribute("ContentType", "application/vnd.openxmlformats-officedocument.drawing+xml");
+ contentTypesDoc.DocumentElement.AppendChild(overrideNode);
}
-
+ SaveXml(contentTypesDoc, contentTypesEntry);
}
- // Step 4: Update exist xl/drawings/drawingX if not create one
- {
- XmlDocument drawingDoc;
- var drawingPath = $"xl/drawings/drawing{drawingId}.xml";
- var drawingEntry = archive.GetEntry(drawingPath);
- if (drawingEntry != null)
- {
- drawingDoc = LoadXml(drawingEntry);
- if (drawingDoc.DocumentElement != null)
- {
- // Create the new node
- var newTwoCellAnchor = drawingDoc.CreateElement("xdr", "twoCellAnchor", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
- newTwoCellAnchor.SetAttribute("editAs", "oneCell");
-
- // Add the node
- var fromNode = drawingDoc.CreateElement("xdr", "from", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
- fromNode.InnerXml = $@"
- {col}
- 0
- {row}
- 0";
- newTwoCellAnchor.AppendChild(fromNode);
-
- // Add the node
- var toNode = drawingDoc.CreateElement("xdr", "to", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
- toNode.InnerXml = $@"
- {col + 1}
- {widthPx * 9525}
- {row + 1}
- {heightPx * 9525}";
- newTwoCellAnchor.AppendChild(toNode);
-
- // Add the node
- var picNode = drawingDoc.CreateElement("xdr", "pic", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
- picNode.InnerXml = $@"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ";
- newTwoCellAnchor.AppendChild(picNode);
-
- // Add the node
- var clientDataNode = drawingDoc.CreateElement("xdr", "clientData", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
- newTwoCellAnchor.AppendChild(clientDataNode);
-
- // Append the new node after the last
- drawingDoc.DocumentElement.AppendChild(newTwoCellAnchor);
- }
- }
- else
- {
- drawingEntry = archive.CreateEntry(drawingPath);
- drawingDoc = CreateDrawingXml(col, row, widthPx, heightPx, relId);
- }
+ // Load or create drawing XML
+ string drawingPath = $"xl/drawings/drawing{drawingId}.xml";
+ var drawingEntry = archive.GetEntry(drawingPath) ?? archive.CreateEntry(drawingPath);
+ XmlDocument drawingDoc = LoadXml(drawingEntry);
- SaveXml(drawingDoc, drawingEntry);
- }
+ // Load or create drawing rels
+ string drawingRelsPath = $"xl/drawings/_rels/drawing{drawingId}.xml.rels";
+ var drawingRelsEntry = archive.GetEntry(drawingRelsPath) ?? archive.CreateEntry(drawingRelsPath);
+ var drawingRelsDoc = LoadXml(drawingRelsEntry);
- // Step 5: Create or update xl/drawings/_rels/drawingX.xml.rels
+ // Add each image to drawing and rels
+ foreach (var image in sheetGroup)
{
- var drawingRelsPath = $"xl/drawings/_rels/drawing{drawingId}.xml.rels";
- var drawingRelsEntry = archive.GetEntry(drawingRelsPath) ?? archive.CreateEntry(drawingRelsPath);
- var drawingRelsDoc = LoadXml(drawingRelsEntry);
-
- // Check if the relationship already exists
- var existingRel = drawingRelsDoc.SelectSingleNode($"/x:Relationships/x:Relationship[@Id='{relId}']", GetNamespaceManager(drawingRelsDoc)); //todo: why never used?
+ var imageBytes = image.ImageBytes;
+ var col = image.ColumnNumber;
+ var row = image.RowNumber;
+ var widthPx = image.WidthPx;
+ var heightPx = image.HeightPx;
+ // Step 1: Add image to /xl/media/
+ string imageName = $"image{Guid.NewGuid().ToString("N")}.png";
+ string imagePath = $"xl/media/{imageName}";
+ var imageEntry = archive.CreateEntry(imagePath);
+ using (var entryStream = imageEntry.Open())
+ entryStream.Write(imageBytes, 0, imageBytes.Length);
+ // Step 2: Update [Content_Types].xml for image
+ var contentTypesEntry = archive.GetEntry("[Content_Types].xml");
+ var contentTypesDoc = LoadXml(contentTypesEntry);
+ if (!contentTypesDoc.DocumentElement.InnerXml.Contains("image/png"))
+ {
+ var defaultNode = contentTypesDoc.CreateElement("Default", contentTypesDoc.DocumentElement.NamespaceURI);
+ defaultNode.SetAttribute("Extension", "png");
+ defaultNode.SetAttribute("ContentType", "image/png");
+ contentTypesDoc.DocumentElement.AppendChild(defaultNode);
+ SaveXml(contentTypesDoc, contentTypesEntry);
+ }
+ // Step 3: Add anchor to drawing XML
+ var relId = $"rId{Guid.NewGuid().ToString("N")}";
+ drawingDoc = CreateDrawingXml(drawingDoc, col, row, widthPx, heightPx, relId);
+ // Step 4: Add image relationship to drawing rels
var relNode = drawingRelsDoc.CreateElement("Relationship", drawingRelsDoc.DocumentElement.NamespaceURI);
relNode.SetAttribute("Id", relId);
relNode.SetAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
relNode.SetAttribute("Target", $"../media/{imageName}");
drawingRelsDoc.DocumentElement.AppendChild(relNode);
-
- SaveXml(drawingRelsDoc, drawingRelsEntry);
}
+ SaveXml(drawingDoc, drawingEntry);
+ SaveXml(drawingRelsDoc, drawingRelsEntry);
}
}
}
@@ -280,48 +205,175 @@ private static XmlNamespaceManager GetNamespaceManager(XmlDocument doc)
return nsmgr;
}
- private static XmlDocument CreateDrawingXml(int col, int row, int? widthPx, int? heightPx, string relId)
+ private static XmlDocument CreateDrawingXml(XmlDocument existingDoc, int col, int row, int widthPx, int heightPx, string relId)
{
- var doc = new XmlDocument();
- doc.LoadXml($@"
-
-
- {col}0{row}0
- {col + 1}{widthPx * 9525}{row + 1}{heightPx * 9525}
-
-
-
-
-
-
-
-
-
-
-
-
-
-");
- return doc;
+ return DrawingXmlHelper.CreateOrUpdateDrawingXml(existingDoc, col, row, widthPx, heightPx, relId);
}
- private static XmlNamespaceManager GetRNamespaceManager(XmlDocument doc)
- {
- var nsmgr = new XmlNamespaceManager(doc.NameTable);
- nsmgr.AddNamespace("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
- nsmgr.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
- return nsmgr;
- }
- private static bool CheckRelationshipExists(XmlDocument doc, string id, string type, string target)
+ public class DrawingXmlHelper
{
- var namespaceManager = new XmlNamespaceManager(doc.NameTable);
- namespaceManager.AddNamespace("x", "http://schemas.openxmlformats.org/package/2006/relationships");
+ private const string XdrNamespace = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing";
+ private const string ANamespace = "http://schemas.openxmlformats.org/drawingml/2006/main";
- var xpath = $"/x:Relationships/x:Relationship[@Id='{id}' and @Type='{type}' and @Target='{target}']";
- var node = doc.SelectSingleNode(xpath, namespaceManager);
+ private static long PixelsToEMU(int pixels) => (long)(pixels * 9525);
- return node != null;
+ private static string GetColumnName(int colIndex)
+ {
+ string columnName = "";
+ int dividend = colIndex + 1;
+ while (dividend > 0)
+ {
+ int modulo = (dividend - 1) % 26;
+ columnName = Convert.ToChar('A' + modulo).ToString() + columnName;
+ dividend = (dividend - modulo) / 26;
+ }
+ return columnName;
+ }
+
+ public static XmlDocument CreateOrUpdateDrawingXml(
+ XmlDocument existingDoc,
+ int col, int row,
+ int widthPx, int heightPx,
+ string relId)
+ {
+ var doc = existingDoc ?? new XmlDocument();
+ var ns = new XmlNamespaceManager(doc.NameTable);
+ ns.AddNamespace("xdr", XdrNamespace);
+ ns.AddNamespace("a", ANamespace);
+ ns.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
+
+
+ // check or create
+ XmlElement wsDr;
+ if (existingDoc == null)
+ {
+ wsDr = doc.CreateElement("xdr", "wsDr", XdrNamespace);
+ wsDr.SetAttribute("xmlns:xdr", XdrNamespace);
+ wsDr.SetAttribute("xmlns:a", ANamespace);
+ doc.AppendChild(wsDr);
+ }
+ else
+ {
+ wsDr = doc.DocumentElement;
+ }
+
+ // get current oneCellAnchor to get id 和 name
+ XmlNodeList anchors = wsDr.SelectNodes("//xdr:oneCellAnchor", ns);
+ int imageCount = anchors?.Count ?? 0;
+
+ // next ID(2)
+ int nextId = imageCount + 2;
+
+ // create oneCellAnchor
+ var oneCellAnchor = doc.CreateElement("xdr", "oneCellAnchor", XdrNamespace);
+
+ //
+ var from = doc.CreateElement("xdr", "from", XdrNamespace);
+ AppendXmlElement(doc, from, "xdr", "col", col.ToString());
+ AppendXmlElement(doc, from, "xdr", "colOff", "0");
+ AppendXmlElement(doc, from, "xdr", "row", row.ToString());
+ AppendXmlElement(doc, from, "xdr", "rowOff", "0");
+
+ //
+ var ext = doc.CreateElement("xdr", "ext", XdrNamespace);
+ ext.SetAttribute("cx", PixelsToEMU(widthPx).ToString());
+ ext.SetAttribute("cy", PixelsToEMU(heightPx).ToString());
+
+ //
+ var pic = doc.CreateElement("xdr", "pic", XdrNamespace);
+
+ //
+ var nvPicPr = doc.CreateElement("xdr", "nvPicPr", XdrNamespace);
+ var cNvPr = doc.CreateElement("xdr", "cNvPr", XdrNamespace);
+ cNvPr.SetAttribute("id", nextId.ToString());
+ cNvPr.SetAttribute("name", $"ImageAt{GetColumnName(col)}{row + 1}");
+
+ // ...
+ var extLst = doc.CreateElement("a", "extLst", ANamespace);
+ var extNode = doc.CreateElement("a", "ext", ANamespace);
+ extNode.SetAttribute("uri", "{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}");
+
+ var creationId = doc.CreateElement("a16", "creationId", "http://schemas.microsoft.com/office/drawing/2014/main");
+ creationId.SetAttribute("id", "http://schemas.microsoft.com/office/drawing/2014/main", $"{{00000000-0008-0000-0000-0000{nextId:D6}000000}}");
+
+ extNode.AppendChild(creationId);
+ extLst.AppendChild(extNode);
+ cNvPr.AppendChild(extLst);
+
+ //
+ var cNvPicPr = doc.CreateElement("xdr", "cNvPicPr", XdrNamespace);
+ var picLocks = doc.CreateElement("a", "picLocks", ANamespace);
+ picLocks.SetAttribute("noChangeAspect", "1");
+ cNvPicPr.AppendChild(picLocks);
+
+ nvPicPr.AppendChild(cNvPr);
+ nvPicPr.AppendChild(cNvPicPr);
+ pic.AppendChild(nvPicPr);
+
+ //
+
+ var blipFill = doc.CreateElement("xdr", "blipFill", XdrNamespace);
+ var blip = doc.CreateElement("a", "blip", ANamespace);
+
+ blip.SetAttribute("xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
+ blip.SetAttribute("embed", ns.LookupNamespace("r"), relId);
+ blip.SetAttribute("cstate", "print");
+
+
+ var stretch = doc.CreateElement("a", "stretch", ANamespace);
+ var fillRect = doc.CreateElement("a", "fillRect", ANamespace);
+ stretch.AppendChild(fillRect);
+
+ blipFill.AppendChild(blip);
+ blipFill.AppendChild(stretch);
+ pic.AppendChild(blipFill);
+
+ //
+ var spPr = doc.CreateElement("xdr", "spPr", XdrNamespace);
+ var xfrm = doc.CreateElement("a", "xfrm", ANamespace);
+
+ var off = doc.CreateElement("a", "off", ANamespace);
+ off.SetAttribute("x", "0");
+ off.SetAttribute("y", "0");
+
+ var spExt = doc.CreateElement("a", "ext", ANamespace);
+ spExt.SetAttribute("cx", "0");
+ spExt.SetAttribute("cy", "0");
+
+ xfrm.AppendChild(off);
+ xfrm.AppendChild(spExt);
+
+ var prstGeom = doc.CreateElement("a", "prstGeom", ANamespace);
+ prstGeom.SetAttribute("prst", "rect");
+
+ var avLst = doc.CreateElement("a", "avLst", ANamespace);
+ prstGeom.AppendChild(avLst);
+
+ spPr.AppendChild(xfrm);
+ spPr.AppendChild(prstGeom);
+
+ pic.AppendChild(spPr);
+
+ //
+ var clientData = doc.CreateElement("xdr", "clientData", XdrNamespace);
+
+ oneCellAnchor.AppendChild(from);
+ oneCellAnchor.AppendChild(ext);
+ oneCellAnchor.AppendChild(pic);
+ oneCellAnchor.AppendChild(clientData);
+
+ wsDr.AppendChild(oneCellAnchor);
+
+ return doc;
+ }
+
+ private static void AppendXmlElement(XmlDocument doc, XmlElement parent, string prefix, string localName, string value)
+ {
+ var el = doc.CreateElement(prefix, localName, prefix == "xdr" ? XdrNamespace : ANamespace);
+ el.InnerText = value;
+ parent.AppendChild(el);
+ }
}
}
}
\ No newline at end of file
diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs
index d08241a7..d36048c1 100644
--- a/tests/MiniExcelTests/MiniExcelIssueTests.cs
+++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs
@@ -20,8 +20,11 @@
using static MiniExcelLibs.Tests.MiniExcelOpenXmlTests;
using MiniExcelLibs.Picture;
using TableStyles = MiniExcelLibs.OpenXml.TableStyles;
+using ClosedXML.Excel;
+using System.Drawing;
using System.Threading.Tasks;
+
namespace MiniExcelLibs.Tests;
public class MiniExcelIssueTests(ITestOutputHelper output)
@@ -4396,6 +4399,233 @@ public void TestIssue789()
}
///
+ /// https://github.com/mini-software/MiniExcel/issues/814
+ ///
+ [Fact]
+ public void TestIssue814()
+ {
+ var originPath = PathHelper.GetFile("xlsx/TestIssue186_Template.xlsx");
+ using var path = AutoDeletingPath.Create();
+ File.Copy(originPath, path.FilePath);
+
+ MiniExcelPicture[] images =
+ [
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png")),
+ SheetName = null, // default null is first sheet
+ CellAddress = "C3", // required
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "C9", // required
+ WidthPx = 500,
+ HeightPx = 500
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "E9", // required
+ WidthPx = 800,
+ HeightPx = 850
+ }
+ ];
+
+ MiniExcel.AddPicture(path.FilePath, images);
+
+ using var package = new ExcelPackage(new FileInfo(path.FilePath));
+
+ // Check picture in the first sheet (C3)
+ var firstSheet = package.Workbook.Worksheets[0];
+ var pictureInC3 = firstSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 2);
+ Assert.NotNull(pictureInC3);
+
+ // Check picture in the "Demo" sheet (C9)
+ var demoSheet = package.Workbook.Worksheets["Demo"];
+ var pictureInC9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 8);
+ Assert.NotNull(pictureInC9);
+ }
+
+ ///
+ /// https://github.com/mini-software/MiniExcel/issues/815
+ ///
+ [Fact]
+ public void TestIssue815()
+ {
+ var originPath = PathHelper.GetFile("xlsx/TestIssue186_Template.xlsx");
+ using var path = AutoDeletingPath.Create();
+ File.Copy(originPath, path.FilePath);
+ {
+ MiniExcelPicture[] images =
+ [
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png")),
+ SheetName = null, // default null is first sheet
+ CellAddress = "C3", // required
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "C9", // required
+ WidthPx = 500,
+ HeightPx = 500
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "E9", // required
+ WidthPx = 800,
+ HeightPx = 850
+ }
+ ];
+
+ MiniExcel.AddPicture(path.FilePath, images);
+
+ using (var package = new ExcelPackage(new FileInfo(path.FilePath)))
+ {
+ // Check picture in the first sheet (C3)
+ var firstSheet = package.Workbook.Worksheets[0];
+ var pictureInC3 = firstSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 2);
+ Assert.NotNull(pictureInC3);
+
+ // Check picture in the "Demo" sheet (C9)
+ var demoSheet = package.Workbook.Worksheets["Demo"];
+ var pictureInC9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 8);
+ Assert.NotNull(pictureInC9);
+ }
+ }
+
+ // TODO:check C3 image WidthPx = 80px, HeightPx = 24px, C9 WidthPx=500,HeightPx=500
+ }
+
+ ///
+ /// https://github.com/mini-software/MiniExcel/issues/816
+ ///
+ [Fact]
+ public void TestIssue816()
+ {
+ var originPath = PathHelper.GetFile("xlsx/TestIssue186_Template.xlsx");
+ using var path = AutoDeletingPath.Create();
+ File.Copy(originPath, path.FilePath);
+ {
+ MiniExcelPicture[] images =
+ [
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png")),
+ SheetName = null, // default null is first sheet
+ CellAddress = "C3", // required
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "C9", // required
+ WidthPx = 500,
+ HeightPx = 500
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "E9", // required
+ WidthPx = 800,
+ HeightPx = 850
+ }
+ ];
+
+ MiniExcel.AddPicture(path.FilePath, images);
+
+ using (var package = new ExcelPackage(new FileInfo(path.FilePath)))
+ {
+ // Check picture in the first sheet (C3)
+ var firstSheet = package.Workbook.Worksheets[0];
+ var pictureInC3 = firstSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 2);
+ Assert.NotNull(pictureInC3);
+
+ // Check picture in the "Demo" sheet (C9)
+ var demoSheet = package.Workbook.Worksheets["Demo"];
+ var pictureInC9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 8);
+ Assert.NotNull(pictureInC9);
+ }
+ }
+
+ {
+ MiniExcelPicture[] images =
+ [
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/github_logo.png")),
+ SheetName = null, // default null is first sheet
+ CellAddress = "D3", // required
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "D9", // required
+ WidthPx = 500,
+ HeightPx = 500
+ },
+ new()
+ {
+ ImageBytes = File.ReadAllBytes(PathHelper.GetFile("images/google_logo.png")),
+ PictureType = "image/png", // default PictureType = image/png
+ SheetName = "Demo",
+ CellAddress = "F9", // required
+ WidthPx = 800,
+ HeightPx = 850
+ }
+ ];
+
+ MiniExcel.AddPicture(path.FilePath, images);
+
+ using (var package = new ExcelPackage(new FileInfo(path.FilePath)))
+ {
+ {
+ // Check picture in the first sheet (C3)
+ var firstSheet = package.Workbook.Worksheets[0];
+ var pictureInC3 = firstSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 2);
+ Assert.NotNull(pictureInC3);
+
+ // Check picture in the "Demo" sheet (C9)
+ var demoSheet = package.Workbook.Worksheets["Demo"];
+ var pictureInC9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 2 && p.From.Row == 8);
+ Assert.NotNull(pictureInC9);
+ }
+
+ {
+ // Check picture in the first sheet (D3)
+ var firstSheet = package.Workbook.Worksheets[0];
+ var pictureInD3 = firstSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 3 && p.From.Row == 2);
+ Assert.NotNull(pictureInD3);
+
+ // Check picture in the "Demo" sheet (D9)
+ var demoSheet = package.Workbook.Worksheets["Demo"];
+ var pictureInD9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 3 && p.From.Row == 8);
+ Assert.NotNull(pictureInD9);
+
+ // Check picture in the "Demo" sheet (F9)
+ var pictureInF9 = demoSheet.Drawings.OfType().FirstOrDefault(p => p.From.Column == 5 && p.From.Row == 8);
+ Assert.NotNull(pictureInF9);
+ }
+ }
+
+ }
+
/// https://github.com/mini-software/MiniExcel/issues/809
///
[Fact]
@@ -4406,5 +4636,6 @@ public void TestIssue809()
Assert.Equal(3, rows.Count);
Assert.Equal(null, rows[0].A);
Assert.Equal(2, rows[2].B);
+
}
}
\ No newline at end of file