pjfanning opened a new issue, #1409:
URL: https://github.com/apache/poi/issues/1409

   ## Problem
   
   `FormatTrackingHSSFListener.getFormatString(int formatIndex)` ignores FORMAT 
records that the file defines for built-in format indexes:
   
   ```java
   if (formatIndex >= HSSFDataFormat.getNumberOfBuiltinBuiltinFormats()) {
       FormatRecord tfr = _customFormatRecords.get(formatIndex);
       ...
   } else {
       format = HSSFDataFormat.getBuiltinFormat((short) formatIndex);
   }
   ```
   
   The listener already collects every `FormatRecord` into 
`_customFormatRecords`, including those with index codes below 50, but for 
those indexes it never looks them up and returns POI's hard-coded built-in 
string instead.
   
   Excel does write FORMAT records for some built-in indexes, and their content 
depends on the locale. A `.xls` saved by a Chinese, German, etc. Excel defines 
indexes 5–8, 42 and 44 (the currency/accounting formats) with that locale's 
currency symbol. Through the event API these files come back with POI's `$` 
strings.
   
   The usermodel API behaves differently. `HSSFDataFormat.getFormat(short)` 
returns the file's string when a built-in index has been overridden ("It's been 
overridden, use that value"). So the same cell gets a different format string 
depending on whether it is read with `HSSFWorkbook` or with the event API.
   
   Downstream impact: Apache Fesod (incubating) is adding its own 
`FormatTrackingHSSFListener` subclass to get the file's format string back for 
indexes 1–22 and 37–49 (apache/fesod#1195).
   
   ## Proposed fix
   
   When a `FormatRecord` exists for the index, use it whatever the index is. 
Fall back to `HSSFDataFormat.getBuiltinFormat` only when the file defines 
nothing for it.
   
   ## Behaviour-change risk for existing users
   
   This would change output for existing callers:
   
   - Anyone reading `.xls` files saved by a non-English Excel (with 
`DataFormatter.formatRawCellContents(value, index, formatString)` or by 
inspecting the format string) would see results change for currency/accounting 
cells. For example `$1,234.50` would become `¥1,234.50` or `1.234,50 €`. That 
is arguably more correct, but it is visible, and some users may have tests or 
downstream parsing that depend on the current `$` output.
   - Files that override other built-in indexes (dates 14/22 are sometimes 
redefined) would also change.
   - Indexes 23–36 are reserved placeholders in POI's built-in table. A file's 
FORMAT record there would now be returned rather than POI's `reserved-0x..` 
string. That is probably desirable, but it is still a change.
   
   ## Suggestions for making it opt-in
   
   Any of these would keep current behaviour by default:
   
   1. **Flag on the listener** (smallest change): a 
`setUseFileFormatsForBuiltinIndexes(boolean)` setter or a constructor overload. 
It defaults to `false` in 5.x and could switch to `true` in the next major 
release.
   2. **New method**: add something like `getFileFormatString(int formatIndex)` 
that returns the file's FORMAT record string, or `null` when there isn't one. 
Callers can then choose. `getFormatString` stays unchanged.
   3. **Protected accessor**: expose `_customFormatRecords`, or a `protected 
FormatRecord getFormatRecord(int)`, so subclasses can implement the lookup 
without re-tracking FORMAT records in `processRecordInternally`. Fesod 
currently has to do that re-tracking.
   
   Option 1 plus a release note seems best: it fixes the inconsistency with 
`HSSFDataFormat` for anyone who opts in, and gives a migration path towards 
making it the default.
   


-- 
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