exceljs / exceljs/exceljs

pageSetup fitToPage, fitToWidth, fitToHeight, scale confusing and documentation is incomplete.

Open
#388 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
15.5k
Forks
2k
PR merge metrics
No merged PRs in 30d

Description

I have been trying to output pages that will print all columns/rows on a page. The package was not operating as I had expected.

When I reverse engineer the `.xlsx` file I found this data:

Fit to page | Attribute(s) from XLSX | Attribute(s) that work | Comments
----- | ----- | ----- | -----
All columns | `scale=XX fitToHeight="0"` | `fitToHeight="0"`
All rows| `scale=XX fitToWidth="0"` | `fitToWidth="0"`
One page | `scale=XX fitToWidth="1" fitToHeight="1"` | `fitToWidth="1" fitToHeight="1"`

I think excel adds in the calculated scale for caching, if it doesn't find the scale then it will simply add it for later saves. The scale setting is ignored in the presence of `fitToPage`.

As a test, I took the output of a file that had "fit all columns on one page" print setting, the results were:
`scale="70", fitToPageHeight="0"`

I manually changed the scale setting to `scale="89"`and found that it loaded up in "fit all columns on one page" print mode. Then I saved the file. The value was changed back to `scale="70"`. So I am assuming that scale is ignored and is overridden by `fitToPage`

I propose that the settings:
```
fitToPage
fitToWidth
fitToHeight
scale
```
be emitted in a consistent way with how excel will interpret them.

The `fitToPage` documentation was a little confusing to me:

> name | default | description
> -- | -- | --
> fitToPage |   | Whether to use fitToWidth and fitToHeight or scale settings. Default is based on presence of these settings in the pageSetup object - if both are present, scale wins (i.e. default will be false)

This kind of implies:
- `fitToPage` is calculated depending on the values of `fitToWidth` and `fitToHeight`.
- `scale` overrides `fitToPage` settings
- there is no default value

Looking through the code and testing it I do not think either of those statements are true.

### Proposal code to add to [worksheet-xform.js](https://github.com/guyonroche/exceljs/blob/master/lib/xlsx/xform/sheet/worksheet-xform.js#L153)
```
const PS = model.pageSetup;
if (PS.fitToPage) {
// if there are page fit constraints, ignore the scale
PS.scale = undefined;
if (PS.fitToWidth !== undefined || PS.fitToHeight !== undefined) {
if (PS.fitToWidth === 0 && PS.fitToHeight === 0) {
// 0 means unconstrained, this is essentially 100% scale
// ignore the fitToPage settings because they will imply a weird
// custom custom scaling which is essentially 100% scaling
PS.fitToWidth = undefined;
PS.fitToHeight = undefined;
PS.fitToPage = false;
}
} else {
// don't assume default settings for these
PS.fitToWidth = 1;
PS.fitToHeight = 1;
}
} else {
// Don't output these if fitToPage is not set
PS.fitToWidth = undefined;
PS.fitToHeight = undefined;
}
```

### Update documentation changes with above
Clarify that setting fitToWidth or fitToHeight to `0` essentially says those parameters are not constrained.
Clarify that setting both fitToWidth and fitToHeight to `0` is the same as `scale=100` and will not emit `fitToPage`, `fitToWidth` or `fitToColumn`.
Clarify that `fitToPage` is a setting that the user controls.
- if `fitToPage` is true, then `fitToWidth` & `fitToColumn` values will be used, `scale` will not be emitted.
- if `fittoPage` is falsy then `fitToPage`, `fitToWidth` & `fitToColumn` will not be emitted.
Add an example of how to use these parameters for common scenarios:
- Sheet all on one page
- Sheet columns all on one page
- Sheet Rows all on one page

### PR
I have a code PR ready to go.
I can develop the documentation PR pending a discussion here and approval.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.