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

Change column width not work #3609

Closed
2 of 11 tasks
mzawodzinski opened this issue Jun 7, 2023 · 5 comments · Fixed by #3610
Closed
2 of 11 tasks

Change column width not work #3609

mzawodzinski opened this issue Jun 7, 2023 · 5 comments · Fixed by #3610

Comments

@mzawodzinski
Copy link

mzawodzinski commented Jun 7, 2023

<?php
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();

$spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(0.45, 'cm');
$spreadsheet->getActiveSheet()->getColumnDimension('J')->setWidth(0.45, 'cm');



$writer = new PhpOffice\PhpSpreadsheet\Writer\Ods($spreadsheet);
$writer->save(__DIR__ . '/test.ods');

This code should change width columns A and J.
But Change A and B
image

Jeśli spróbuję zmienić tylko J, to skrypt zmieni kolumnę A

What features do you think are causing the issue

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

Which versions of PhpSpreadsheet and PHP are affected?

phpoffice/phpspreadsheet:1.28.0
php:8.1

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Jun 8, 2023
Fix PHPOffice#3609. Reporter created a spreadsheet with non-adjacent columns having non-default widths. Ods Writer needs to generate entries for the missing columns with default width.

The fix was fairly simple. Testing it was not. Ods Reader basically ignores all styles; they are complicated, declared in (at least) 2 places (content.xml and styles.xml). This change deals only with the problem as reported, in which the missing declarations should be in content.xml. If someone reports a real-world example of this involving styles.xml, I can look at that then. In the meantime, this toehold might serve as a template for adding other style processing to Ods Reader.

Looking at other formats, processing of column widths was also missing from Html Reader, and is now added. Note that this will work only with inline Css declarations on the `col` tags, which can be generated by Html Writer using `setUseInlineCss(true)`. This creates a much larger file than one created without inline CSS.

A general problem became evident when studying the code. Worksheet `columnDimensions` is an unsorted array. This is not a problem per se, but it can easily lead to unexpected results from a `getColumnDimensions` call. The code is changed to sort the array before returning it in `getColumnDimensions`.

One existing test failed as a result of this change. It errorneously tested `getHighestColumn` instead of `getHighestDataColumn`, which caused a problem because the final column declaration included a `number-columns-repeated` attribute. The new result for `getHighestColumn` is correct, and the test is changed to use `getHighestDataColumn` instead, which was certainly its intent.
@lukaszgasiorek
Copy link

lukaszgasiorek commented Jun 12, 2023

I have a similar problem from version 1.26 i cannot change width of columns in generated protected XLSX files. Up to version 1.25 everything worked fine

@oleibman
Copy link
Collaborator

Please upload file and/or code so that I can investigate.

@lukaszgasiorek
Copy link

@oleibman please, eample code to create XLSX from existsing file. Up to version 1.25 I can change column widths from 1.26 I can't.

test.xlsx

<?php
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;

$xlsxReader = new Xlsx();

$sheet = $xlsxReader->load('test.xlsx');
$sheet->setActiveSheetIndex(0);

$ws = $sheet->getActiveSheet();

$ws->getProtection()->setSheet(true);
$ws->getProtection()->setSort(true);
$ws->getProtection()->setInsertRows(true);
$ws->getProtection()->setFormatCells(true);

$writer = IOFactory::createWriter($sheet, 'Xlsx');
$writer->save('sheet-' . date('Ymd-His') . '.xlsx');

@oleibman
Copy link
Collaborator

oleibman commented Jun 13, 2023

I agree that this is a change in behavior. While I try to figure out what kind of fix is needed, you should be able to get the result you want via:

$ws->getProtection()->setFormatColumns(false);

@oleibman
Copy link
Collaborator

Here's the documentation:

<complexType name="CT_SheetProtection">
<attribute name="password" type="ST_UnsignedShortHex" use="optional"/>
<attribute name="sheet" type="xsd:boolean" use="optional" default="false"/>
<attribute name="objects" type="xsd:boolean" use="optional" default="false"/>
<attribute name="scenarios" type="xsd:boolean" use="optional" default="false"/>
<attribute name="formatCells" type="xsd:boolean" use="optional" default="true"/>
<attribute name="formatColumns" type="xsd:boolean" use="optional" default="true"/>
<attribute name="formatRows" type="xsd:boolean" use="optional" default="true"/>
<attribute name="insertColumns" type="xsd:boolean" use="optional" default="true"/>
<attribute name="insertRows" type="xsd:boolean" use="optional" default="true"/>
<attribute name="insertHyperlinks" type="xsd:boolean" use="optional" default="true"/>
<attribute name="deleteColumns" type="xsd:boolean" use="optional" default="true"/>
<attribute name="deleteRows" type="xsd:boolean" use="optional" default="true"/>
<attribute name="selectLockedCells" type="xsd:boolean" use="optional" default="false"/>
<attribute name="sort" type="xsd:boolean" use="optional" default="true"/>
<attribute name="autoFilter" type="xsd:boolean" use="optional" default="true"/>
<attribute name="pivotTables" type="xsd:boolean" use="optional" default="true"/>
<attribute name="selectUnlockedCells" type="xsd:boolean" use="optional" default="false"/>
</complexType>

I am not sure I can come up with a sensible approach that will not cause a lot of breaks to existing code. I will continue to think about it, but, for now, it would be best to explicitly set those Protections properties which you are interested in enabling or disabling. The version 25 code defaulted to its own set of initial values, and seems more likely to require you to explicitly set true when desired; the current code defaults to Excel's, and seems more likely to require you to explicitly set false when desired.

oleibman added a commit that referenced this issue Jun 14, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Fix #3609. Reporter created a spreadsheet with non-adjacent columns having non-default widths. Ods Writer needs to generate entries for the missing columns with default width.

The fix was fairly simple. Testing it was not. Ods Reader basically ignores all styles; they are complicated, declared in (at least) 2 places (content.xml and styles.xml). This change deals only with the problem as reported, in which the missing declarations should be in content.xml. If someone reports a real-world example of this involving styles.xml, I can look at that then. In the meantime, this toehold might serve as a template for adding other style processing to Ods Reader.

Looking at other formats, processing of column widths was also missing from Html Reader, and is now added. Note that this will work only with inline Css declarations on the `col` tags, which can be generated by Html Writer using `setUseInlineCss(true)`. This creates a much larger file than one created without inline CSS.

A general problem became evident when studying the code. Worksheet `columnDimensions` is an unsorted array. This is not a problem per se, but it can easily lead to unexpected results from a `getColumnDimensions` call. The code is changed to sort the array before returning it in `getColumnDimensions`.

One existing test failed as a result of this change. It errorneously tested `getHighestColumn` instead of `getHighestDataColumn`, which caused a problem because the final column declaration included a `number-columns-repeated` attribute. The new result for `getHighestColumn` is correct, and the test is changed to use `getHighestDataColumn` instead, which was certainly its intent.
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.

3 participants