Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong foreground color for Mac Numbers XLSX spreadsheet (missing indexed colors) #3093

Closed
2 of 8 tasks
joseph101039 opened this issue Sep 30, 2022 · 1 comment · Fixed by #3096
Closed
2 of 8 tasks

Comments

@joseph101039
Copy link

joseph101039 commented Sep 30, 2022

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

After we save a Numbers XLSX file on MAC and simply loaded and saved the file by the library,
the foreground colors of cells should be same as the original one.

What is the current behavior?

The foreground colors of cells are changed after saved.

What are the steps to reproduce?

  1. Install the latest version of library
    composer require phpoffice/phpspreadsheet:1.25.2

  2. Open a xlsx file by macOS (version 10.15.7) Numbers (version 6.2).

  3. Add foreground colors at some cells

  4. Export to xlsx file formats in Numbers on Mac (File > Export to > Excel). For example, we get excel_file1_mac.xlsx

  5. Simply load and save the xlsx file (see the sample code).
    We get the output xlsx file excel_file1_mac_ouput.xlsx which has different foreground colors.

<?php

require __DIR__ . '/vendor/autoload.php';

  $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
  $spreadsheet = $reader->load("excel_file1_mac.xlsx");
  (new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet))
      ->save("excel_file1_mac_output.xlsx");

Possible root cause

The issue may be the xlsx reader loses the indexed color styles after loading spreadsheet.

Unzip the source file excel_file1_mac.xlsx and open the stylesheet. (xl/styles.xml)

<?xml version="1.0" encoding="UTF-8"?>
<styleSheet>
     <!-- ignore -->
    <fills count="7">
        <fill>
            <patternFill patternType="solid">
                <fgColor indexed="11"/>
                <bgColor auto="1"/>
            </patternFill>
        </fill>
        <fill>
            <patternFill patternType="solid">
                <fgColor indexed="12"/>
                <bgColor auto="1"/>
            </patternFill>
        </fill>
        <!-- ignore -->
   </fills>
    <colors>
        <indexedColors>
            <!-- ignore -->
            <rgbColor rgb="ffaaaaaa"/>
            <rgbColor rgb="ffc0c0c0"/>
            <rgbColor rgb="ffffff00"/>
            <rgbColor rgb="ffdfa7a6"/>
            <rgbColor rgb="ff7ba0cd"/>
        </indexedColors>
    </colors>
</styleSheet>

The sample xlsx file has totally 16 indexed colors.

When I see the function extractPalette(), it filters all the indexed colors if there are not exactly 64 indexed colors.

PhpOffice\PhpSpreadsheet\Reader\Xlsx::extractPalette()

    private static function extractPalette(?SimpleXMLElement $sxml): array
    {
        $array = [];
        if ($sxml && $sxml->colors->indexedColors) {
            foreach ($sxml->colors->indexedColors->rgbColor as $node) {
                if ($node !== null) {
                    $attr = $node->attributes();
                    if (isset($attr['rgb'])) {
                        $array[] = (string) $attr['rgb'];
                    }
                }
            }
        }
        return (count($array) === 64) ? $array : [];
    }

Because there is not indexedColors palette, but still has some cells refer to the indexed color. The program use default palette PhpOffice\PhpSpreadsheet\Style\Color::INDEXED_COLORS to render the spreadsheet. Therefore the output xlsx file has wrong colors.

I think that replace the line

return (count($array) === 64) ? $array : [];

with

return $array;

can fix the problem.

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

The issue affects all the border, font, cell foreground colors of the xlsx spreadsheet which is exported by Numbers.

Which versions of PhpSpreadsheet and PHP are affected?

php: 7.4.30
phpoffice/phpspreadsheet: 1.25.2

@oleibman
Copy link
Collaborator

You are correct about the cause. I had never actually seen indexed colors before the issue which caused me to add support for it, and, since the only example I had used the full complement of 64 colors (and documentation of this possibility is lacking), I was unwilling to extrapolate for any other number. Complicating this is the fact that I don't have a Mac, but perhaps your sample file is sufficient and I don't need such access. I will certainly look into it.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Oct 1, 2022
Fix PHPOffice#3093. PR PHPOffice#2595 added the ability for Xlsx Reader to accept a custom color palette. With no examples other than the one at hand, which included a full complement of 64 colors, that PR required 64 colors in the palette. It turns out that Mac Numbers exports to Excel with a palette with less than 64 colors. So, with an example of that at hand, relax the original restriction and accept a palette of any size.
@joseph101039 joseph101039 changed the title [Bug][Numbers] Wrong foreground color for Mac Numbers XLSX spreadsheet (missing indexed colors) Wrong foreground color for Mac Numbers XLSX spreadsheet (missing indexed colors) Oct 1, 2022
oleibman added a commit that referenced this issue Oct 3, 2022
Fix #3093. PR #2595 added the ability for Xlsx Reader to accept a custom color palette. With no examples other than the one at hand, which included a full complement of 64 colors, that PR required 64 colors in the palette. It turns out that Mac Numbers exports to Excel with a palette with less than 64 colors. So, with an example of that at hand, relax the original restriction and accept a palette of any size.
MarkBaker added a commit that referenced this issue Dec 21, 2022
### Added

- Extended flag options for the Reader `load()` and Writer `save()` methods
- Apply Row/Column limits (1048576 and XFD) in ReferenceHelper [PR #3213](#3213)
- Allow the creation of In-Memory Drawings from a string of binary image data, or from a stream. [PR #3157](#3157)
- Xlsx Reader support for Pivot Tables [PR #2829](#2829)
- Permit Date/Time Entered on Spreadsheet to be calculated as Float [Issue #1416](#1416) [PR #3121](#3121)

### Changed

- Nothing

### Deprecated

- Direct update of Calculation::suppressFormulaErrors is replaced with setter.
- Font public static variable defaultColumnWidths replaced with constant DEFAULT_COLUMN_WIDTHS.
- ExcelError public static variable errorCodes replaced with constant ERROR_CODES.
- NumberFormat constant FORMAT_DATE_YYYYMMDD2 replaced with existing identical FORMAT_DATE_YYYYMMDD.

### Removed

- Nothing

### Fixed

- Fixed handling for `_xlws` prefixed functions from Office365 [Issue #3245](#3245) [PR #3247](#3247)
- Conditionals formatting rules applied to rows/columns are removed [Issue #3184](#3184) [PR #3213](#3213)
- Treat strings containing currency or accounting values as floats in Calculation Engine operations [Issue #3165](#3165) [PR #3189](#3189)
- Treat strings containing percentage values as floats in Calculation Engine operations [Issue #3155](#3155) [PR #3156](#3156) and [PR #3164](#3164)
- Xlsx Reader Accept Palette of Fewer than 64 Colors [Issue #3093](#3093) [PR #3096](#3096)
- Use Locale-Independent Float Conversion for Xlsx Writer Custom Property [Issue #3095](#3095) [PR #3099](#3099)
- Allow setting AutoFilter range on a single cell or row [Issue #3102](#3102) [PR #3111](#3111)
- Xlsx Reader External Data Validations Flag Missing [Issue #2677](#2677) [PR #3078](#3078)
- Reduces extra memory usage on `__destruct()` calls [PR #3092](#3092)
- Additional properties for Trendlines [Issue #3011](#3011) [PR #3028](#3028)
- Calculation suppressFormulaErrors fix [Issue #1531](#1531) [PR #3092](#3092)
- Permit Date/Time Entered on Spreadsheet to be Calculated as Float [Issue #1416](#1416) [PR #3121](#3121)
- Incorrect Handling of Data Validation Formula Containing Ampersand [Issue #3145](#3145) [PR #3146](#3146)
- Xlsx Namespace Handling of Drawings, RowAndColumnAttributes, MergeCells [Issue #3138](#3138) [PR #3136](#3137)
- Generation3 Copy With Image in Footer [Issue #3126](#3126) [PR #3140](#3140)
- MATCH Function Problems with Int/Float Compare and Wildcards [Issue #3141](#3141) [PR #3142](#3142)
- Fix ODS Read Filter on number-columns-repeated cell [Issue #3148](#3148) [PR #3149](#3149)
- Problems Formatting Very Small and Very Large Numbers [Issue #3128](#3128) [PR #3152](#3152)
- XlsxWrite preserve line styles for y-axis, not just x-axis [PR #3163](#3163)
- Xlsx Namespace Handling of Drawings, RowAndColumnAttributes, MergeCells [Issue #3138](#3138) [PR #3137](#3137)
- More Detail for Cyclic Error Messages [Issue #3169](#3169) [PR #3170](#3170)
- Improved Documentation for Deprecations - many PRs [Issue #3162](#3162)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants