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

insertNewRowBefore increases file size #3687

Closed
7 tasks
kik-krsk opened this issue Aug 28, 2023 · 0 comments · Fixed by #3856
Closed
7 tasks

insertNewRowBefore increases file size #3687

kik-krsk opened this issue Aug 28, 2023 · 0 comments · Fixed by #3856

Comments

@kik-krsk
Copy link

This is:

- [x] a bug report
- [ ] a feature request
- [ x] **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 using insertNewRowBefore, the number of rows becomes $sheet->getHighestRow() + $numberOfRow
After saving the file becomes ~350Kbytes. Template source file 15Kbytes

What is the current behavior?

i think the rows should be $sheet->getHighestDataRow() + $numberOfRow

What are the steps to reproduce?

<?php

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

// Create new Spreadsheet object
$spreadsheet = IOFactory::load(__DIR__ . '/template.xlsx');
$sheet = $spreadsheet->getSheet(0);
$currentRow = 24;
$before = $sheet->getHighestDataRow(); \\36
$sheet->insertNewRowBefore($currentRow, 10);
$after = $sheet->getHighestDataRow(); \\65542

What features do you think are causing the issue

  • [ x] 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?

xlsx

Which versions of PhpSpreadsheet and PHP are affected?

1.29.0

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Jan 4, 2024
Fix PHPOffice#3687. Worksheet methods insertNewRowBefore and insertNewColumnBefore call ReferenceHelper insertNewBefore. That function fills in "missing" cells with null values. However, for boundaries, it uses getHighestRow and getHighestColumn. It should be sufficient to use getHighestDataRow and getHighestDataColumn. When there is a big gap between getHighest... and getHighestData..., this can result in a big increase in memory usage, and in file space when saving the spreadsheet. New test InsertTest demonstrates the problem by populating a worksheet with cells A1:D5 (so highestDataRow is 5), but also setting row 1000 to invisible (so highestRow is 1000).

The major part of the change is in ReferenceHelper::insertNewBefore, which will now use getHighestData... for its boundaries when filling in the missing cells. Changes of less impact are made to duplicateStylesByColumn and duplicateStylesByRow so that cells which don't yet exist are not created unless the style that will be applied is not the workbook default style.

As for reducing the file size, Writer/Xlsx/Worksheet is changed so that cells whose value is null or null-string and which use the workbook default style are not written to the output spreadsheet. This requires some changes to existing test ReadBlankCellsTest; I don't think the difference should matter to the end-user.
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.

1 participant