Fix unable to set mutiple print area in HSSF#1706
Merged
Merged
Conversation
…gClass handling Co-authored-by: tonyqus <772561+tonyqus@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix issue with setting multiple print areas in XLS
Fix multiple print areas in XLS (HSSF) - wrong PTG operand class in union formulas
Mar 1, 2026
Copilot stopped work on behalf of
tonyqus due to an error
March 1, 2026 14:01
Copilot
AI
changed the title
Fix multiple print areas in XLS (HSSF) - wrong PTG operand class in union formulas
Fix multiple print areas in XLS: wrong PTG operand class in union/intersection formulas
Mar 1, 2026
Co-authored-by: tonyqus <772561+tonyqus@users.noreply.github.com>
Copilot
AI
changed the title
Fix multiple print areas in XLS: wrong PTG operand class in union/intersection formulas
Fix multiple print areas in XLS (HSSF) — wrong PTG operand class in union formulas
Mar 1, 2026
Co-authored-by: tonyqus <772561+tonyqus@users.noreply.github.com>
Copilot
AI
changed the title
Fix multiple print areas in XLS (HSSF) — wrong PTG operand class in union formulas
Add single and multiple print area demo XLS files for Excel verification
Mar 1, 2026
Co-authored-by: tonyqus <772561+tonyqus@users.noreply.github.com>
Copilot
AI
changed the title
Add single and multiple print area demo XLS files for Excel verification
Remove generated demo XLS files from PR
Mar 1, 2026
This was referenced Apr 6, 2026
This was referenced Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The OperandClassTransformer processes a formula tree. For a NamedRange formula (print area), the root operand class should be CLASS_REF.
When the formula contains a union (multiple areas), the parse tree looks like:
MemAreaPtg (root, CLASS_REF desired)
└─ UnionPtg
├─ Area3DPtg (Area1)
└─ Area3DPtg (Area2)
When TransformNode is called with the MemAreaPtg node and desiredOperandClass = CLASS_REF, it matches the MemAreaPtg branch and flips the desired class to CLASS_VALUE, which then propagates down to the UnionPtg and its Area3DPtg children, leaving them all marked as CLASS_VALUE instead of the correct CLASS_REF.
The real issue is that reference-like tokens such as MemAreaPtg, MemFuncPtg, UnionPtg, and IntersectionPtg shouldn't be flipping the operand class at all—only value operators and control flow tokens should perform that transformation. Looking at the Apache POI source code that NPOI is based on, I can see the distinction being made between which token types should actually change the class.
For a union like Sheet1!$A$1:$C$5,Sheet1!$E$6:$F$9, the parse tree wraps everything in MemAreaPtg containing a UnionPtg with multiple Area3DPtg children. The problem is that MemAreaPtg forces the operand class to CLASS_VALUE, which then propagates down to all the Area3DPtg tokens, when they should actually stay as CLASS_REF for print areas. So the fix needs to handle this case where unions in named ranges should preserve CLASS_REF for the individual areas rather than converting them to CLASS_VALUE. The real fix is to differentiate how we handle these token types: value operators should convert CLASS_REF to CLASS_VALUE, but reference-type tokens like MemAreaPtg, UnionPtg, and IntersectionPtg should preserve CLASS_REF unchanged through their children.
For the specific print area bug with multiple ranges like $A$1:$C$5,$E$6:$F$9, the formula HSSFWorkbook builds becomes 'Sheet1'!$A$1:$C$5,'Sheet1'!$E$6:$F$9. When parsed as a NamedRange, I'd expect a MemAreaPtg wrapping two Area3DPtg tokens, both with CLASS_REF (0x3B), but I need to verify what the actual parsed structure looks like.
The issue is that the current code converts these Area3DPtg tokens to CLASS_VALUE (0x5B) when they should stay as CLASS_REF. The fix involves skipping the CLASS_REF to CLASS_VALUE conversion when processing MemAreaPtg, UnionPtg, IntersectionPtg, or MemFuncPtg nodes. However, I need to be careful not to break cell formula contexts where CLASS_VALUE is already correct—though actually, when desiredOperandClass is already CLASS_VALUE, the conversion becomes a no-op anyway, so the fix should only affect cases where desiredOperandClass is CLASS_REF.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.