Skip to content

Commit 0f3a9ca

Browse files
authored
Merge branch 'master' into feature/specify-datatype-in-html
2 parents 4687456 + 2034864 commit 0f3a9ca

33 files changed

+907
-55
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2626
### Fixed
2727

2828
- Updates Cell formula absolute ranges/references, and Defined Name absolute ranges/references when inserting/deleting rows/columns [Issue #3368](https://github.com/PHPOffice/PhpSpreadsheet/issues/3368) [PR #3402](https://github.com/PHPOffice/PhpSpreadsheet/pull/3402)
29+
- EOMONTH() and EDATE() Functions should round date value before evaluation [Issue #3436](https://github.com/PHPOffice/PhpSpreadsheet/issues/3436) [PR #3437](https://github.com/PHPOffice/PhpSpreadsheet/pull/3437)
2930

3031

3132
## 1.28.0 - 2023-02-25

CONTRIBUTING.md

+28-7
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,40 @@
22

33
If you would like to contribute, here are some notes and guidelines:
44

5-
- All new development happens on feature/fix branches, and are then merged to the `master` branch once stable; so the `master` branch is always the most up-to-date, working code
6-
- Tagged releases are made from the `master` branch
7-
- If you are going to be submitting a pull request, please fork from `master`, and submit your pull request back as a fix/feature branch referencing the GitHub issue number
8-
- Code style might be automatically fixed by `composer fix`
9-
- All code changes must be validated by `composer check`
5+
- All new development should be on feature/fix branches, which are then merged to the `master` branch once stable and approved; so the `master` branch is always the most up-to-date, working code
6+
- If you are going to submit a pull request, please fork from `master`, and submit your pull request back as a fix/feature branch referencing the GitHub issue number
7+
- The code must work with all PHP versions that we support (currently PHP 7.4 to PHP 8.2).
8+
- You can call `composer versions` to test version compatibility.
9+
- Code style should be maintained.
10+
- `composer style` will identify any issues with Coding Style`.
11+
- `composer fix` will fix most issues with Coding Style.
12+
- All code changes must be validated by `composer check`.
13+
- Please include Unit Tests to verify that a bug exists, and that this PR fixes it.
14+
- Please include Unit Tests to show that a new Feature works as expected.
15+
- Please don't "bundle" several changes into a single PR; submit a PR for each discrete change/fix.
16+
1017
- [Helpful article about forking](https://help.github.com/articles/fork-a-repo/ "Forking a GitHub repository")
1118
- [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests/ "Pull Requests")
1219

20+
## Unit Tests
21+
22+
When writing Unit Tests, please
23+
- Always try to write Unit Tests for both the happy and unhappy paths.
24+
- Put all assertions in the Test itself, not in an abstract class that the Test extends (even if this means code duplication between tests).
25+
- Include any necessary `setup()` and `tearDown()` in the Test itself.
26+
- If you change any global settings (such as system locale, or Compatibility Mode for Excel Function tests), make sure that you reset to the default in the `tearDown()`.
27+
28+
This makes it easier to see exactly what is being tested when reviewing the PR. I want to be able to see it in the PR, not have to hunt in other classes to see what the test is doing.
29+
1330
## How to release
1431

1532
1. Complete CHANGELOG.md and commit
1633
2. Create an annotated tag
1734
1. `git tag -a 1.2.3`
1835
2. Tag subject must be the version number, eg: `1.2.3`
19-
3. Tag body must be a copy-paste of the changelog entries
20-
3. Push tag with `git push --tags`, GitHub Actions will create a GitHub release automatically
36+
3. Tag body must be a copy-paste of the changelog entries.
37+
3. Push the tag with `git push --tags`, GitHub Actions will create a GitHub release automatically, and the release details will automatically be sent to packagist.
38+
4. Github seems to remove markdown headings in the Release Notes, so you should edit to restore these.
39+
40+
> **Note:** Tagged releases are made from the `master` branch. Only in an emergency should a tagged release be made from the `release` branch. (i.e. cherry-picked hot-fixes.)
41+

composer.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,19 @@
4242
],
4343
"scripts": {
4444
"check": [
45+
"phpcs src/ tests/ --report=checkstyle",
46+
"phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PHPCompatibility --runtime-set testVersion 7.4- -n",
4547
"php-cs-fixer fix --ansi --dry-run --diff",
46-
"phpcs",
4748
"phpunit --color=always",
48-
"phpstan analyse --ansi"
49+
"phpstan analyse --ansi --memory-limit=2048M"
50+
],
51+
"style": [
52+
"phpcs src/ tests/ --report=checkstyle",
53+
"php-cs-fixer fix --ansi --dry-run --diff"
4954
],
5055
"fix": [
51-
"php-cs-fixer fix --ansi"
56+
"phpcbf src/ tests/ --report=checkstyle",
57+
"php-cs-fixer fix"
5258
],
5359
"versions": [
5460
"phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PHPCompatibility --runtime-set testVersion 7.4- -n"

docs/index.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ for details.
3333
LTS: Support for PHP versions will only be maintained for a period of six months beyond the
3434
[end of life of that PHP version](https://www.php.net/eol.php).
3535

36-
Currently the required PHP minimum version is PHP 7.4. The last PHP release was 7.4.32 on 29th September 2022, and security support ends on 28th November 2022, so PhpSpreadsheet will support PHP 7.4 until 28th May 2023.
36+
Currently the required PHP minimum version is PHP 7.4: the last release was 7.4.32 on 29th September 2022, and security support ends on 28th November 2022, so PhpSpreadsheet will support PHP 7.4 until 28th May 2023.
3737
PHP 8.0 is officially [End of Life](https://www.php.net/supported-versions.php) on 26th November 2023, and PhpSpreadsheet will continue to support PHP 8.0 for six months after that date.
3838

3939
See the `composer.json` for other requirements.
@@ -86,8 +86,8 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
8686
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
8787

8888
$spreadsheet = new Spreadsheet();
89-
$sheet = $spreadsheet->getActiveSheet();
90-
$sheet->setCellValue('A1', 'Hello World !');
89+
$activeWorksheet = $spreadsheet->getActiveSheet();
90+
$activeWorksheet->setCellValue('A1', 'Hello World !');
9191

9292
$writer = new Xlsx($spreadsheet);
9393
$writer->save('hello world.xlsx');
7.88 KB
Loading
8.69 KB
Loading
Loading
Loading
Loading
Loading
7.46 KB
Loading
21.5 KB
Loading
6.63 KB
Loading

docs/topics/recipes.md

+174-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ For example, [setting a worksheet's page orientation and size
1010
orientation to A4. Other paper formats, like US Letter, are not covered
1111
in this document, but in the PhpSpreadsheet [API documentation](https://phpoffice.github.io/PhpSpreadsheet).
1212

13+
My apologies if this documentation seems very basic to some of you; but I spend so much time having to provide help lessons in PHP 101 and Excel 101 that I feel I need to provide this level of very simple detail.
14+
1315
## Setting a spreadsheet's metadata
1416

1517
PhpSpreadsheet allows an easy way to set a spreadsheet's metadata, using
@@ -18,12 +20,42 @@ finding a specific document in a file repository or a document
1820
management system. For example Microsoft Sharepoint uses document
1921
metadata to search for a specific document in its document lists.
2022

21-
Setting spreadsheet metadata is done as follows:
23+
<details>
24+
<summary>Click here for details of Spreadsheet Document Properties</summary>
25+
26+
These are accessed in MS Excel from the "Info" option on the "File" menu:
27+
![99-Properties_File-Menu.png](images%2F99-Properties_File-Menu.png)
28+
29+
Some of these properties can be edited "in situ" in the Properties Block:
30+
![99-Properties_Block.png](images%2F99-Properties_Block.png)
31+
32+
For more advanced properties, click on the "Properties" dropdown:
33+
![99-Properties_Advanced.png](images%2F99-Properties_Advanced.png)
34+
35+
And you will be able to add/edit/delete a lot of different property values.
36+
![99-Properties_Advanced-Form.png](images%2F99-Properties_Advanced-Form.png)
37+
38+
Properties on the "General", "Statistics" and "Contents" tabs are informational, and cannot be user-defined in Excel itself.
39+
Properties on the "Summary" tab are all string values.
40+
41+
The "Custom" tab allows you to define your own properties. More information from the Microsoft Documentation can be found [here](https://support.microsoft.com/en-us/office/view-or-change-the-properties-for-an-office-file-21d604c2-481e-4379-8e54-1dd4622c6b75).
42+
![99-Properties_Advanced-Form-2.png](images%2F99-Properties_Advanced-Form-2.png)
43+
44+
You can select a property name from the dropdown, or type a new name of your choice; select a Type; enter a value; and then click on "Add".
45+
The new property will then be created and displayed in the list at the bottom of the form.
46+
47+
While "Text", "Number" (can be an integer or a floating point value) and "Yes or No" types are straightforward to add a value, "Date" types are more difficult, and Microsoft provide very little help.
48+
However, you need to enter the date in the format that matches your locale, so an American would enter "7/4/2023 for the 4th of July; but in the UK I would enter "4/7/2023" for the same date.
49+
Although typically recognised as a date elsewhere in MS Excel, the almost universally recognised `2022-12-31` date format is not recognised as valid here.
50+
51+
</details>
52+
53+
Setting spreadsheet metadata in PhpSpreadsheet is done as follows:
2254

2355
```php
2456
$spreadsheet->getProperties()
2557
->setCreator("Maarten Balliauw")
26-
->setLastModifiedBy("Maarten Balliauw")
58+
->setLastModifiedBy("Mark Baker")
2759
->setTitle("Office 2007 XLSX Test Document")
2860
->setSubject("Office 2007 XLSX Test Document")
2961
->setDescription(
@@ -33,23 +65,154 @@ $spreadsheet->getProperties()
3365
->setCategory("Test result file");
3466
```
3567

68+
You can choose which properties to set or ignore.
69+
70+
<details>
71+
<summary>Click here for details of Property Getters/Setters</summary>
72+
73+
PhpSpreadsheet provides specific getters/setters for a number of pre-defined properties.
74+
75+
| Property Name | DataType | Getter/Setter | Notes |
76+
|------------------|-------------------------|----------------------------------------------|-----------------------------------------------------------|
77+
| Creator | string | getCreator()<br />setCreator() | |
78+
| Last Modified By | string | getLastModifiedBy()<br />setLastModifiedBy() | |
79+
| Created | float/int<br/>timestamp | getCreated()<br />setCreated() | Cannot be modified in MS Excel; but is automatically set. |
80+
| Modified | float/int<br/>timestamp | getModified()<br />setModified() | Cannot be modified in MS Excel; but is automatically set. |
81+
| Title | string | getTitle()<br />setTitle() | |
82+
| Description | string | getDescription()<br />setDescription() | |
83+
| Subject | string | getSubject()<br />setSubject() | |
84+
| Keywords | string | getKeywords()<br />setKeywords() | |
85+
| Category | string | getCategory()<br />setCategory() | Not supported in xls files. |
86+
| Company | string | getCompany()<br />setCompany() | Not supported in xls files. |
87+
| Manager | string | getManager()<br />setManager() | Not supported in xls files. |
88+
> **Note:** Not all Spreadsheet File Formats support all of these properties.
89+
> For example: "Category", "Company" and "Manager" are not supported in `xls` files.
90+
91+
</details>
92+
93+
<details>
94+
<summary>Click here for details of Custom Properties</summary>
95+
96+
Additionally, PhpSpreadsheet supports the creation and reading of custom properties for those file formats that accept custom properties.
97+
The following methods of the Properties class can be used when working with custom properties.
98+
- `getCustomProperties()`<br />
99+
Will return an array listing the names of all custom properties that are defined.
100+
- `isCustomPropertySet(string $propertyName)`<br />
101+
Will return a boolean indicating if the named custom property is defined.
102+
- `getCustomPropertyValue(string $propertyName)`<br />
103+
Will return the "raw" value of the named custom property; or null if the property doesn't exist.
104+
- `getCustomPropertyType(string $propertyName)`<br />
105+
Will return the datatype of the named custom property; or null if the property doesn't exist.
106+
- `setCustomProperty(string $propertyName, $propertyValue = '', $propertyType = null)`<br />
107+
Will let you set (or modify) a custom property. If you don't provide a datatype, then PhpSpreadsheet will attempt to identify the datatype from the value that you set.
108+
109+
The recognised Property Types are:
110+
111+
| Constant | Datatype | Value |
112+
|-----------------------------------|----------|-------|
113+
| Properties::PROPERTY_TYPE_BOOLEAN | boolean | b |
114+
| Properties::PROPERTY_TYPE_INTEGER | integer | i |
115+
| Properties::PROPERTY_TYPE_FLOAT | float | f |
116+
| Properties::PROPERTY_TYPE_DATE | date | d |
117+
| Properties::PROPERTY_TYPE_STRING | string | s |
118+
119+
When reading property types, you might also encounter:
120+
121+
| Datatype | Value |
122+
|----------|--------------|
123+
| null | null value |
124+
| empty | empty string |
125+
| u | unknown |
126+
127+
Other more complex types, such as pointers and filetime, are not supported by PhpSpreadsheet; and are discarded when reading a file.
128+
129+
</details>
130+
131+
```php
132+
$spreadsheet->getProperties()
133+
->setCustomProperty('Editor', 'Mark Baker')
134+
->setCustomProperty('Version', 1.17)
135+
->setCustomProperty('Tested', true)
136+
->setCustomProperty('Test Date', '2021-03-17', Properties::PROPERTY_TYPE_DATE);
137+
```
138+
> **Warning:** If the datatype for a date is not explicitly used, then it will be treated as a string.
139+
140+
> **Note:** Although MS Excel doesn't recognise `2022-12-31` as valid date format when entering Custom Date Properties, PhpSpreadsheet will accept it.
141+
36142
## Setting a spreadsheet's active sheet
37143

38-
The following line of code sets the active sheet index to the first
39-
sheet:
144+
A Spreadsheet consists of (very rarely) none, one or more Worksheets. If you have 1 or more Worksheets, then one (and only one) of those Worksheets can be "Active" (viewed or updated) at a time, but there will always be an "Active" Worksheet (unless you explicitly delete all of the Worksheets in the Spreadsheet).
145+
146+
<details>
147+
<summary>Click here for details about Worksheets</summary>
148+
149+
When you create a new Spreadsheet in MS Excel, it creates the Spreadsheet with a single Worksheet ("Sheet1")
150+
151+
![101-Basic-Spreadsheet-with-Worksheet.png](images%2F101-Basic-Spreadsheet-with-Worksheet.png)
152+
153+
and that is the "Active" Worksheet.
154+
155+
![101-Active-Worksheet-1.png](images%2F101-Active-Worksheet-1.png)
40156

157+
This is the same as
41158
```php
42-
$spreadsheet->setActiveSheetIndex(0);
159+
$spreadsheet = new Spreadsheet();
160+
$activeWorksheet = $spreadsheet->getActiveSheet();
43161
```
162+
in PhpSpreadsheet.
163+
164+
And you can then write values to Cells in `$activeWorksheet` (`Sheet1`).
165+
166+
To create a new Worksheet in MS Excel, you click on the "+" button in the Worksheet Tab Bar. MS Excel will then create a new Worksheet ("Sheet2") in the Spreadsheet, and make that the current "Active" Worksheet.
167+
168+
![101-Active-Worksheet-2.png](images%2F101-Active-Worksheet-2.png)
44169

45-
You can also set the active sheet by its name/title
170+
Excel always shows the "Active" Worksheet in the Grid, and you can see which Worksheet is "Active" because it is highlighted in the Worksheet Tab Bar at the bottom of the Worksheet Grid.
46171

172+
This is the same as
47173
```php
48-
$spreadsheet->setActiveSheetIndexByName('DataSheet')
174+
$activeWorksheet = $spreadsheet->createSheet();
49175
```
176+
in PhpSpreadsheet.
177+
178+
And you can then write values to Cells in `$activeWorksheet` (`Sheet2`).
179+
180+
</details>
181+
182+
To switch between Worksheets in MS Excel, you click on the Tab for the Worksheet that you want to be "Active" in the Worksheet Tab Bar. Excel will then set that as the "Active" Worksheet.
50183

51-
will change the currently active sheet to the worksheet called
52-
"DataSheet".
184+
![101-Active-Worksheet-Change.png](images%2F101-Active-Worksheet-Change.png)
185+
186+
In PhpSpreadsheet, you do this by calling the Spreadsheet's `setActiveSheetIndex()` methods.
187+
Either:
188+
189+
```php
190+
$activeWorksheet = $spreadsheet->setActiveSheetIndexByName('Sheet1')
191+
```
192+
using the name/title of the Worksheet that you want as the "Active" Worksheet.
193+
194+
Or:
195+
```php
196+
$activeWorksheet = $spreadsheet->setActiveSheetIndex(0);
197+
```
198+
Where you set the "Active" Worksheet by its position in the Worksheet Tab Bar, with 0 as the first Worksheet, 1 as the second, etc.
199+
200+
And you can then write values to Cells in `$activeWorksheet` (`Sheet1`) again.
201+
202+
203+
You don't have to assign the return value from calls to `createSheet()` and `setActiveSheetIndex()` to a variable, but it means that you can call Worksheet methods directly against `$activeWorksheet`, rather than having to call `$spreadsheet->getActiveSheet()` all the time.
204+
And, unlike MS Excel where you can only update Cells in the "Active" Worksheet; PhpSpreadsheet allows you to update Cells in any Worksheet:
205+
```php
206+
// Create a Spreadsheet, with Worksheet Sheet1, which is the Active Worksheet
207+
$spreadsheet = new Spreadsheet();
208+
// Assign the Active Worksheet (Sheet1) to $worksheet1
209+
$worksheet1 = $spreadsheet->getActiveSheet();
210+
// Create a new Worksheet (Sheet2) and make that the Active Worksheet
211+
$worksheet2 = $spreadsheet->createSheet();
212+
213+
$worksheet1->setCellValue('A1', 'I am a cell on Sheet1');
214+
$worksheet2->setCellValue('A1', 'I am a cell on Sheet2');
215+
```
53216

54217
## Write a date or time into a cell
55218

@@ -1580,8 +1743,8 @@ Adding rich text to a cell can be done using
15801743
`\PhpOffice\PhpSpreadsheet\RichText\RichText` instances. Here''s an example, which
15811744
creates the following rich text string:
15821745

1583-
> This invoice is ***payable within thirty days after the end of the
1584-
> month*** unless specified otherwise on the invoice.
1746+
> This invoice is <font color="darkgreen">***payable within thirty days after the end of the
1747+
> month***</font> unless specified otherwise on the invoice.
15851748
15861749
```php
15871750
$richText = new \PhpOffice\PhpSpreadsheet\RichText\RichText();

0 commit comments

Comments
 (0)