Skip to content

Conversation

@rpg600
Copy link

@rpg600 rpg600 commented Nov 13, 2025

feat: add drawing pass-through support for unsupported elements

Add opt-in pass-through mechanism to preserve unsupported drawing
elements (shapes, textboxes etc) during read/write operations.

  • Add enableDrawingPassThrough property to BaseReader
  • Store original drawing XML when pass-through is enabled
  • Reuse stored XML in Writer instead of regenerating
  • Disabled by default for backward compatibility

This allows preservation of Excel elements not yet supported by
PhpSpreadsheet without requiring full implementation.

Currently, the pass-through mechanism works as follows:

  1. Reader: setEnableDrawingPassThrough(true) stores the original drawing XML
  2. Writer: Automatically uses the stored XML if:
    • The drawing collection is empty (no drawings added programmatically)
    • AND the unparsed data contains the original XML

I'm open to adding an explicit Writer flag if you believe it provides better clarity and control.

This addresses existing issue : #4037

@rpg600 rpg600 marked this pull request as ready for review November 14, 2025 11:46
@oleibman
Copy link
Collaborator

I am still evaluating whether this is a good idea or not. Will it work if you add or remove a row or a column on the sheet? Add a comment when there weren't any before, and when there were? Remove a comment?

Your commentary says that you are fixing 3 open issues. Are there tests for each of those?

@rpg600 rpg600 force-pushed the 5.1.0-patched branch 2 times, most recently from 47e62af to 4061cc0 Compare November 21, 2025 11:13
@rpg600
Copy link
Author

rpg600 commented Nov 21, 2025

Will it work if you add or remove a row or a column on the sheet?

Yes but the drawing's coordinates (col, row, offsets) will not be adjusted.

Add a comment when there weren't any before, and when there were? Remove a comment?

Comments are completely independent from drawings.

Your commentary says that you are fixing 3 open issues. Are there tests for each of those?

I was too quick when referencing the issues, this PR actually only addresses one of them.

I added several unit tests, including checks for unsupported elements (shapes/textboxes), behavior without pass-through, comment deletion, row/column operations, and correct flag handling between the Reader and Writer.

This feature isn’t ideal, as it’s essentially a workaround, but it will provide a temporary solution while we wait for those implementations, and it will help avoid patching the code.

@oleibman
Copy link
Collaborator

oleibman commented Nov 21, 2025

Thank you for adding the tests.

Comments are, alas, not completely independent from drawings. It's why I asked the question. Create a new spreadsheet with a comment. Notice that there is a drawings folder with a vml file in it in the saved spreadsheet. I can't offhand tell whether this will be a problem for your change.

@rpg600
Copy link
Author

rpg600 commented Nov 21, 2025

I have added testCommentsAndPassThroughCoexist
It shows that VML drawings and DrawingML coexist in the xl/drawings/ folder without interference. Both existing and new comments are preserved correctly when pass-through is enabled.

@oleibman
Copy link
Collaborator

It is not absolutely required that Coveralls doesn't report a decrease. However, we strive to eliminate that situation if possible, especially in code which is new in a change. In Writer\Xlsx\Drawing.php, you have the following new statements which include some "misses" around line 617:

        if (!isset($unparsedLoadedData['sheets'][$codeName])) {
            return null;
        }

        $sheetData = $unparsedLoadedData['sheets'][$codeName];
        if (!is_array($sheetData)) {
            return null;
        }

        // Only use pass-through XML if the Reader flag was explicitly enabled
        if (($sheetData['drawingPassThroughEnabled'] ?? false) !== true) {
            return null;
        }

        if (!isset($sheetData['Drawings']) || !is_array($sheetData['Drawings'])) {
            return null;
        }

I tthink if you changed that block as follows, your code would still work as planned and there would no longer be any coverage misses:

        $sheetData = $unparsedLoadedData['sheets'][$codeName] ?? null;
        // Only use pass-through XML if the Reader flag was explicitly enabled
        if (!is_array($sheetData) || ($sheetData['drawingPassThroughEnabled'] ?? false) !== true || !is_array($sheetData['Drawings'] ?? null)) {
            return null;
        }

Please give that a shot.

@oleibman
Copy link
Collaborator

Thank you - success on both fronts - no problems with unit tests, and no missed statements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants