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