Files
oleibman 9c279679aa Use Less Space When Inserting Rows and Columns
Fix #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.
2024-01-03 18:03:28 -08:00

68 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Worksheet;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class InsertTest extends TestCase
{
public function testInsertRow(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
]);
$sheet->getRowDimension(1000)->setVisible(false);
$sheet->getStyle('C3')->getFont()->setBold(true);
self::assertSame(1000, $sheet->getHighestRow());
self::assertSame(5, $sheet->getHighestDataRow());
$currentRow = 4;
$sheet->insertNewRowBefore($currentRow, 1);
self::assertSame(1001, $sheet->getHighestRow());
self::assertSame(6, $sheet->getHighestDataRow());
self::assertTrue($sheet->getStyle('C3')->getFont()->getBold());
self::assertSame(11, $sheet->getCell('C3')->getValue());
self::assertTrue($sheet->getStyle('C4')->getFont()->getBold());
self::assertNull($sheet->getCell('C4')->getValue());
self::assertFalse($sheet->getRowDimension(1001)->getVisible());
self::assertTrue($sheet->getRowDimension(1000)->getVisible());
$spreadsheet->disconnectWorksheets();
}
public function testInsertColumn(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->fromArray([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
]);
$sheet->getColumnDimension('ZY')->setVisible(false);
$sheet->getStyle('C3')->getFont()->setBold(true);
self::assertSame('ZY', $sheet->getHighestColumn());
self::assertSame('D', $sheet->getHighestDataColumn());
$currentColumn = 'D';
$sheet->insertNewColumnBefore($currentColumn, 1);
self::assertSame('ZZ', $sheet->getHighestColumn());
self::assertSame('E', $sheet->getHighestDataColumn());
self::assertTrue($sheet->getStyle('C3')->getFont()->getBold());
self::assertSame(11, $sheet->getCell('C3')->getValue());
self::assertTrue($sheet->getStyle('D3')->getFont()->getBold());
self::assertNull($sheet->getCell('D3')->getValue());
self::assertFalse($sheet->getColumnDimension('ZZ')->getVisible());
self::assertTrue($sheet->getColumnDimension('ZY')->getVisible());
$spreadsheet->disconnectWorksheets();
}
}