nkuprins opened a new issue, #956:
URL: https://github.com/apache/fesod/issues/956

   ### Search before asking
   
   - [x] I searched in the [issues](https://github.com/apache/fesod/issues) and 
found nothing similar.
   
   
   ### Fesod version
   
   current main (4b426ba)
   
   ### JDK version
   
   Temurin 25 (code path is version-independent, affects 8+)
   
   ### Operating system
   
   Linux (not OS-specific)
   
   ### Steps To Reproduce
   
   A `@ContentStyle(dataFormat = N)` annotation's number format is silently 
overwritten by a registered cell style strategy, producing the wrong number 
format in the output file.
   
   ```java
   @Data
   public class DemoData {
       @ExcelProperty("value")
       @ContentStyle(dataFormat = 4) // "#,##0.00"
       private Double value;
   }
   
   // content style list alternating between a style WITH a data format and one 
WITHOUT
   WriteCellStyle withFormat = new WriteCellStyle();
   DataFormatData dfd = new DataFormatData();
   dfd.setIndex((short) 2); // "0.00"
   withFormat.setDataFormatData(dfd);
   WriteCellStyle withoutFormat = new WriteCellStyle();
   
   FesodSheet.write(file, DemoData.class)
           .registerWriteHandler(new HorizontalCellStyleStrategy(null, 
Arrays.asList(withFormat, withoutFormat)))
           .sheet()
           .doWrite(Arrays.asList(new DemoData(1111.5), new DemoData(2222.5), 
new DemoData(3333.5)));
   ```
   
   The second data row's strategy style defines **no** data format, so that 
cell should fall back to the annotation's `#,##0.00`.
   
   ### Current Behavior
   
   All three data rows come out with format index 2 (`0.00`). Reading the 
written file back with POI:
   
   ```
   dataRow0 format = 2 (expected 2)
   dataRow1 format = 2 (expected 4 - annotation)   <-- wrong
   dataRow2 format = 2 (expected 2)
   ```
   
   With `.filedCacheLocation(CacheLocationEnum.MEMORY)` it is worse: the 
corruption leaks into **later, completely unrelated writes** of the same bean 
class - a follow-up write with *no* custom handlers at all also emits format 2 
instead of the annotation's 4, because the static `ClassUtils.CONTENT_CACHE` 
now holds the mutated format.
   
   ### Expected Behavior
   
   Rows whose strategy style does not define a data format keep the 
`@ContentStyle(dataFormat = 4)` annotation format (`#,##0.00`), and the cached 
annotation metadata is never mutated by a style strategy.
   
   ### Anything else?
   
   Root cause: `WriteCellStyle.merge` aliases the source's `DataFormatData` 
into the target without cloning:
   
   
https://github.com/apache/fesod/blob/main/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/metadata/style/WriteCellStyle.java#L180-L186
   
   
   ```java
   if (target.getDataFormatData() == null) {
       target.setDataFormatData(source.getDataFormatData()); // shared 
reference, no copy
   }
   ```
   
   The annotation's `DataFormatData` is parsed once and cached. After this 
merge, the per-cell style points at that cached object, so when a second style 
source merges into the same cell, `DataFormatData.merge` writes into it and 
permanently changes the cached annotation format.
   
   The `writeFont` field a few lines below already handles this correctly by 
cloning:
   
   
   ```java
   target.setWriteFont(source.getWriteFont().clone());
   ```
   
   Doing the same for `DataFormatData` fixes it:
   
   ```java
   target.setDataFormatData(source.getDataFormatData().clone());
   ```
   
   
   ### Are you willing to submit a PR?
   
   - [x] I'm willing to submit a PR!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to