Skip to content

Print settings

Print settings are in the worksheet’s !print object. The reader fills it from existing files.

Key Meaning
area print area (range string or range object)
titles rows and columns repeated on every page (range object)
props page setup options (orientation, scale, paper, …)
margins page margins in inches
rowBreaks, colBreaks forced page breaks
header, footer header and footer text

The XLSX reader and writer support the !print object. You can also write margins through ws["!margins"] and use the defined names _xlnm.Print_Area / _xlnm.Print_Titles for areas and repeated titles. Template mode preserves existing print settings when you do not edit them.

const XLSX = require("@agent-sheet/wasm");
const assert = require("node:assert/strict");
const ws = XLSX.utils.aoa_to_sheet([["Report"], [1]]);
ws["!print"] = { area: "A1:A2", props: { orientation: "landscape", paper: "Legal", scale: 50 },
header: "Report", footer: "Page &P", rowBreaks: [{ R: 1 }] };
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "S");
const print = XLSX.read(XLSX.write(wb, { type: "buffer", bookType: "xlsx" })).Sheets.S["!print"];
assert.equal(print.props.orientation, "landscape");
assert.equal(print.props.scale, 50);
assert.equal(print.header.odd, "Report");
assert.equal(print.rowBreaks[0].R, 1);
const XLSX = require("@agent-sheet/wasm");
const ws = XLSX.utils.aoa_to_sheet([[1, 2], [3, 4]]);
ws["!margins"] = { left: 1, right: 1, top: 1, bottom: 1, header: 0.5, footer: 0.5 };
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "S");
wb.Workbook = { Names: [
{ Name: "_xlnm.Print_Area", Sheet: 0, Ref: "S!$A$1:$B$2" },
{ Name: "_xlnm.Print_Titles", Sheet: 0, Ref: "S!$1:$1" },
] };
const back = XLSX.read(XLSX.write(wb, { type: "buffer", bookType: "xlsx" }));
console.log(JSON.stringify(back.Sheets.S["!print"].area), JSON.stringify(back.Sheets.S["!margins"]), back.Workbook.Names.length);
Output
{"s":{"c":0,"r":0},"e":{"c":1,"r":1}} {"left":1,"right":1,"top":1,"bottom":1,"header":0.5,"footer":0.5} 2

The reader fills !print for every file that has print setup. This includes files saved by Excel. The example above reads the print area back from a file. Files from Excel can also have props, header, footer and rowBreaks:

const XLSX = require("@agent-sheet/wasm");
const report = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(report, XLSX.utils.aoa_to_sheet([["Report"]]), "S");
report.Workbook = { Names: [{ Name: "_xlnm.Print_Area", Sheet: 0, Ref: "S!$A$1:$A$1" }] };
XLSX.writeFile(report, "report.xlsx");
const wb = XLSX.readFile("report.xlsx");
const p = wb.Sheets[wb.SheetNames[0]]["!print"];
console.log(XLSX.utils.encode_range(p.area));
Output
A1

The rest of this page describes the !print object accepted by the writer and returned by the reader.

const XLSX = require("@agent-sheet/wasm");
const ws = XLSX.utils.aoa_to_sheet([["Report"]]);
ws["!print"] = {
area: { s: { r: 0, c: 0 }, e: { c: 4, r: 49 } }, // A1:E50
rowBreaks: [{ R: 3 }], // break before row 4 (one-based numbering)
colBreaks: [{ C: 3 }],
margins: { left: 0.7, right: 0.6, top: 0.5, bottom: 0.4, header: 0.3, footer: 0.2 },
header: "&&Report",
footer: { odd: { center: { R: [{ w: "&A", s: { bold: true } }, { w: "&D", s: { italic: true } }] } } },
props: { orientation: "landscape", paper: "Legal", scale: 50 },
};
require("node:assert/strict").equal(ws["!print"].props.orientation, "landscape");

area is a range string or object. Excel stores it in the name _xlnm.Print_Area, scoped to the sheet. The reader decodes that name into area.

const XLSX = require("@agent-sheet/wasm");
const ws = XLSX.utils.aoa_to_sheet([["Report"]]);
ws["!print"] = {};
ws["!print"].area = "A1:D20";
ws["!print"].area = { s: { r: 0, c: 0 }, e: { r: 19, c: 3 } };
require("node:assert/strict").equal(XLSX.utils.encode_range(ws["!print"].area), "A1:D20");

titles is a range. Set a row or column bound to -1 to leave that axis out.

const XLSX = require("@agent-sheet/wasm");
const ws = XLSX.utils.aoa_to_sheet([["Report"]]);
ws["!print"] = {};
ws["!print"].titles = { s: { r: 0, c: -1 }, e: { r: 2, c: -1 } }; // repeat rows 1:3
ws["!print"].titles = { s: { r: -1, c: 1 }, e: { r: -1, c: 3 } }; // repeat columns B:D
ws["!print"].titles = { s: { r: 1, c: 0 }, e: { r: 2, c: 1 } }; // rows 2:3 and columns A:B
require("node:assert/strict").deepEqual(ws["!print"].titles, { s: { r: 1, c: 0 }, e: { r: 2, c: 1 } });
Key Values
orientation "landscape", "portrait", "default"
scale percent, 10 to 400 (default 100). Stored alongside fit; Excel uses the fit-to-page settings while fit is active
fit { width, height } pages; 0 means automatic. { width: 1, height: 1 } fits the sheet on one page. { width: 1, height: 0 } puts all columns on one page. With fit: false inside the object, scale wins
paper paper code, alias, or { width: "9.5in", height: "4.125in" }
dpi print quality (600, 1200)
first first page number; null for automatic
centerX, centerY center the content horizontally or vertically
gridlines, bw, draft, headings print gridlines; black and white; draft quality; row and column headings
comments "displayed" (as on sheet), "end", "none"
errors "displayed", "none" (blank), "dash" (--), "n/a"
order true or "over" for “over, then down”; false or "down" (default)

Paper codes, with the alias in parentheses: 1 Letter ("Letter"), 2 Letter Small, 3 Tabloid ("Tabloid"), 4 Ledger, 5 Legal ("Legal"), 6 Statement, 7 Executive ("Executive"), 8 A3 ("A3"), 9 A4 ("A4"), 10 A4 Small, 11 A5 ("A5"), 12 B4 ("B4"), 13 B5 ("B5"), 14 Folio ("Folio"), 20 Envelope #10 ("Envelope"), 27 Envelope DL, 28 C5, 29 C3, 30 C4, 31 C6, 34 Envelope B5, 37 Monarch ("Monarch"), 43 Japanese postcard, 69 Japanese double postcard, 70 A6 ("A6").

margins holds inches: left, right, top, bottom, header, footer.

Preset left / right top / bottom header / footer
Normal 0.7 0.75 0.3
Wide 1.0 1.0 0.5
Narrow 0.25 0.75 0.3

rowBreaks: [{ R: 3 }, { R: 7 }] forces a break before the zero-based rows 3 and 7. colBreaks: [{ C: 3 }] forces a break before zero-based column 3. Natural breaks are not affected.

header and footer are either a raw Excel format string or an object with odd, even and first entries. If even is missing, odd applies to even pages. If first is missing, odd applies to the first page. Set an entry to "" to clear it.

const XLSX = require("@agent-sheet/wasm");
const ws = XLSX.utils.aoa_to_sheet([["Report"]]);
ws["!print"] = {};
ws["!print"].header = { odd: "Hello", first: "" }; // every page except the first
ws["!print"].footer = { first: "First", even: "Even", odd: "" };
require("node:assert/strict").equal(ws["!print"].footer.even, "Even");

An entry is a string in Excel’s code language, or an object with left, center and right. Each of those is a string, a { w, s } object (text or field, plus style) or { R: [ ...runs ] }.

Code Meaning Code Meaning
&L &C &R left, center, right section (centered if none) &P page number (&P+n, &P-n add an offset)
&N page count &D &T date, time
&A sheet name &F &Z file name, file path
&& a literal & &B &I toggle bold, italic
&U &E toggle underline, double underline &S &H &O toggle strike, shadow, outline
&X &Y toggle superscript, subscript &K + RRGGBB font color (or theme ##+###)
&16 size in points &"Font" font name (&"+" heading font, &"-" body font)

For example "&CPage &P of &N" centers Page 3 of 9, and "foo&Bbold&Bbar" bolds only the middle word.