Skip to content

Commit

Permalink
Merge pull request #1232 from Alanscut/issue_1131
Browse files Browse the repository at this point in the history
Fix issue #1131 headerFooter property doesn't work with WorksheetWriter!
  • Loading branch information
Siemienik committed May 26, 2020
2 parents 7c3fd11 + 5de20f1 commit 406c18d
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 66 deletions.
24 changes: 22 additions & 2 deletions README.md
Expand Up @@ -319,6 +319,17 @@ var sheet = workbook.addWorksheet('My Sheet', {views: [{showGridLines: false}]})

// create a sheet with the first row and column frozen
var sheet = workbook.addWorksheet('My Sheet', {views:[{state: 'frozen', xSplit: 1, ySplit:1}]});

// Create worksheets with headers and footers
var sheet = workbook.addWorksheet('My Sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});

// create new sheet with pageSetup settings for A4 - landscape
var worksheet = workbook.addWorksheet('My Sheet', {
pageSetup:{paperSize: 9, orientation:'landscape'}
});

```

## Remove a Worksheet [](#contents)<!-- Link generated with jump2header -->
Expand Down Expand Up @@ -384,7 +395,7 @@ Worksheets support a property bucket to allow control over some features of the
var worksheet = workbook.addWorksheet('sheet', {properties:{tabColor:{argb:'FF00FF00'}}});

// create a new sheet writer with properties
var worksheetWriter = workbookWriter.addSheet('sheet', {properties:{outlineLevelCol:1}});
var worksheetWriter = workbookWriter.addWorksheet('sheet', {properties:{outlineLevelCol:1}});

// adjust properties afterwards (not supported by worksheet-writer)
worksheet.properties.outlineLevelCol = 2;
Expand Down Expand Up @@ -425,7 +436,7 @@ var worksheet = workbook.addWorksheet('sheet', {
});

// create a new sheet writer with pageSetup settings for fit-to-page
var worksheetWriter = workbookWriter.addSheet('sheet', {
var worksheetWriter = workbookWriter.addWorksheet('sheet', {
pageSetup:{fitToPage: true, fitToHeight: 5, fitToWidth: 7}
});

Expand Down Expand Up @@ -500,6 +511,15 @@ In addition, you can set different texts for the first page and even page.
Note: Images are not currently supported.

```javascript

// Create worksheets with headers and footers
var sheet = workbook.addWorksheet('sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});
// Create worksheets with headers and footers
var worksheetWriter = workbookWriter.addWorksheet('sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});
// Set footer (default centered), result: "Page 2 of 16"
worksheet.headerFooter.oddFooter = "Page &P of &N";

Expand Down
36 changes: 30 additions & 6 deletions README_zh.md
Expand Up @@ -295,8 +295,22 @@ var sheet = workbook.addWorksheet('My Sheet', {properties:{tabColor:{argb:'FFC00
// 创建一个隐藏了网格线的工作表
var sheet = workbook.addWorksheet('My Sheet', {views: [{showGridLines: false}]});

// 创建一个第一行和列冻结的工作表
var sheet = workbook.addWorksheet('My Sheet', {views:[{xSplit: 1, ySplit:1}]});

// 使用A4设置的页面设置设置创建新工作表 - 横向
var worksheet = workbook.addWorksheet('My Sheet', {
pageSetup:{paperSize: 9, orientation:'landscape'}
});

// 创建一个具有页眉页脚的工作表
var sheet = workbook.addWorksheet('My Sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});

// 创建一个冻结了第一行和第一列的工作表
var sheet = workbook.addWorksheet('My Sheet', {views:[{state: 'frozen', xSplit: 1, ySplit:1}]});

```

## 删除工作表
Expand Down Expand Up @@ -349,8 +363,8 @@ worksheet.state = 'veryHidden';
// 创建具有属性的新工作表
var worksheet = workbook.addWorksheet('sheet', {properties:{tabColor:{argb:'FF00FF00'}}});

// 创建一个具有属性的新工作表读写器
var worksheetWriter = workbookWriter.addSheet('sheet', {properties:{outlineLevelCol:1}});
// 创建一个具有属性的可写的新工作表
var worksheetWriter = workbookWriter.addWorksheet('sheet', {properties:{outlineLevelCol:1}});

// 之后调整属性(工作表读写器不支持该操作)
worksheet.properties.outlineLevelCol = 2;
Expand Down Expand Up @@ -390,8 +404,8 @@ var worksheet = workbook.addWorksheet('sheet', {
pageSetup:{paperSize: 9, orientation:'landscape'}
});

// 使用适用于页面的页面设置配置创建新的表格读写器
var worksheetWriter = workbookWriter.addSheet('sheet', {
// 使用适合页面的pageSetup设置创建一个新的工作表编写器
var worksheetWriter = workbookWriter.addWorksheet('sheet', {
pageSetup:{fitToPage: true, fitToHeight: 5, fitToWidth: 7}
});

Expand Down Expand Up @@ -466,8 +480,18 @@ worksheet.pageSetup.printTitlesColumn = 'A:C';
注意:目前不支持图片。

```javascript
// 设置页脚(默认居中),结果:“第2页,共16页”
worksheet.headerFooter.oddFooter = "Page &P of &N";
// 创建一个带有页眉和页脚的工作表
var sheet = workbook.addWorksheet('My Sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});

// 创建一个带有页眉和页脚可写的工作表
var worksheetWriter = workbookWriter.addWorksheet('sheet', {
headerFooter:{firstHeader: "Hello Exceljs", firstFooter: "Hello World"}
});
// 代码中出现的&开头字符对应变量,相关信息可查阅下文的变量表
// 设置页脚(默认居中),结果:“第 2 页,共 16 页”
worksheet.headerFooter.oddFooter = "第 &P 页,共 &N 页";

// 将页脚(默认居中)设置为粗体,结果是:“第2页,共16页”
worksheet.headerFooter.oddFooter = "Page &P of &N";
Expand Down
89 changes: 45 additions & 44 deletions index.d.ts
Expand Up @@ -971,7 +971,7 @@ export interface WorksheetModel {
// dataValidations: this.dataValidations.model,
properties: WorksheetProperties;
pageSetup: Partial<PageSetup>;
headerFooter: HeaderFooter;
headerFooter: Partial<HeaderFooter>;
rowBreaks: RowBreak[];
views: WorksheetView[];
autoFilter: AutoFilter;
Expand All @@ -983,12 +983,12 @@ export type CellIsOperators = 'equal' | 'greaterThan' | 'lessThan' | 'between';

export type ContainsTextOperators = 'containsText' | 'containsBlanks' | 'notContainsBlanks' | 'containsErrors' | 'notContainsErrors';

export type TimePeriodTypes = 'lastWeek' | 'thisWeek' | 'nextWeek' | 'yesterday' | 'today' | 'tomorrow' | 'last7Days' | 'lastMonth'
| 'thisMonth' | 'nextMonth';
export type TimePeriodTypes = 'lastWeek' | 'thisWeek' | 'nextWeek' | 'yesterday' | 'today' | 'tomorrow' | 'last7Days' | 'lastMonth'
| 'thisMonth' | 'nextMonth';

export type IconSetTypes = '5Arrows' | '5ArrowsGray' | '5Boxes' | '5Quarters' | '5Rating' | '4Arrows' | '4ArrowsGray'
| '4Rating' | '4RedToBlack' | '4TrafficLights' | 'NoIcons' | '3Arrows' | '3ArrowsGray' | '3Flags' | '3Signs'
| '3Stars' | '3Symbols' | '3Symbols2' | '3TrafficLights1' | '3TrafficLights2' | '3Triangles';
export type IconSetTypes = '5Arrows' | '5ArrowsGray' | '5Boxes' | '5Quarters' | '5Rating' | '4Arrows' | '4ArrowsGray'
| '4Rating' | '4RedToBlack' | '4TrafficLights' | 'NoIcons' | '3Arrows' | '3ArrowsGray' | '3Flags' | '3Signs'
| '3Stars' | '3Symbols' | '3Symbols2' | '3TrafficLights1' | '3TrafficLights2' | '3Triangles';

export type CfvoTypes = 'percentile' | 'percent' | 'num' | 'min' | 'max' | 'formula' | 'autoMin' | 'autoMax';

Expand Down Expand Up @@ -1063,13 +1063,13 @@ export interface DataBarRuleType extends ConditionalFormattingBaseRule {
cfvo?: Cvfo[];
}

export type ConditionalFormattingRule = ExpressionRuleType | CellIsRuleType | Top10RuleType | AboveAverageRuleType | ColorScaleRuleType | IconSetRuleType
| ContainsTextRuleType | TimePeriodRuleType | DataBarRuleType;
export type ConditionalFormattingRule = ExpressionRuleType | CellIsRuleType | Top10RuleType | AboveAverageRuleType | ColorScaleRuleType | IconSetRuleType
| ContainsTextRuleType | TimePeriodRuleType | DataBarRuleType;

export interface ConditionalFormattingOptions {
ref: string;
rules: ConditionalFormattingRule[];
}
}

export interface Worksheet {
readonly id: number;
Expand All @@ -1086,7 +1086,7 @@ export interface Worksheet {
/**
* Worksheet Header and Footer
*/
headerFooter: HeaderFooter;
headerFooter: Partial<HeaderFooter>;

/**
* Worksheet State
Expand Down Expand Up @@ -1282,7 +1282,7 @@ export interface Worksheet {
* Using the image id from `Workbook.addImage`,
* embed an image within the worksheet to cover a range
*/
addImage(imageId: number, range: string | { editAs?: string; } & ImageRange & {hyperlinks?: ImageHyperlinkValue} | { editAs?: string; } & ImagePosition & {hyperlinks?: ImageHyperlinkValue}): void;
addImage(imageId: number, range: string | { editAs?: string; } & ImageRange & { hyperlinks?: ImageHyperlinkValue } | { editAs?: string; } & ImagePosition & { hyperlinks?: ImageHyperlinkValue }): void;

getImages(): Array<{
type: 'image',
Expand Down Expand Up @@ -1370,6 +1370,7 @@ export interface WorksheetProperties {
export interface AddWorksheetOptions {
properties: Partial<WorksheetProperties>;
pageSetup: Partial<PageSetup>;
headerFooter: Partial<HeaderFooter>;
views: Array<Partial<WorksheetView>>;
state: WorksheetState;
}
Expand Down Expand Up @@ -1860,42 +1861,42 @@ export namespace stream {
useStyles: boolean;
}

interface ArchiverZipOptions {
comment: string;
forceLocalTime: boolean;
forceZip64: boolean;
store: boolean;
zlib: Partial<ZlibOptions>;
}

interface ZlibOptions {
/**
* @default constants.Z_NO_FLUSH
*/
flush: number;
/**
* @default constants.Z_FINISH
*/
finishFlush: number;
/**
* @default 16*1024
*/
chunkSize: number;
windowBits: number;
level: number; // compression only
memLevel: number; // compression only
strategy: number; // compression only
dictionary: Buffer | NodeJS.TypedArray | DataView | ArrayBuffer; // deflate/inflate only, empty dictionary by default
}
interface ArchiverZipOptions {
comment: string;
forceLocalTime: boolean;
forceZip64: boolean;
store: boolean;
zlib: Partial<ZlibOptions>;
}

interface ZlibOptions {
/**
* @default constants.Z_NO_FLUSH
*/
flush: number;
/**
* @default constants.Z_FINISH
*/
finishFlush: number;
/**
* @default 16*1024
*/
chunkSize: number;
windowBits: number;
level: number; // compression only
memLevel: number; // compression only
strategy: number; // compression only
dictionary: Buffer | NodeJS.TypedArray | DataView | ArrayBuffer; // deflate/inflate only, empty dictionary by default
}

interface WorkbookStreamWriterOptions extends WorkbookWriterOptions {

/**
* Specifies whether to add style information to the workbook.
* Styles can add some performance overhead. Default is false
*/
zip: Partial<ArchiverZipOptions>;
}
/**
* Specifies whether to add style information to the workbook.
* Styles can add some performance overhead. Default is false
*/
zip: Partial<ArchiverZipOptions>;
}

class WorkbookWriter extends Workbook {
constructor(options: Partial<WorkbookStreamWriterOptions>);
Expand Down
29 changes: 17 additions & 12 deletions lib/doc/worksheet.js
@@ -1,6 +1,6 @@
const _ = require('../utils/under-dash');

const colCache = require('./../utils/col-cache');
const colCache = require('../utils/col-cache');
const Range = require('./range');
const Row = require('./row');
const Column = require('./column');
Expand Down Expand Up @@ -89,16 +89,20 @@ class Worksheet {
options.pageSetup
);

this.headerFooter = {
differentFirst: false,
differentOddEven: false,
oddHeader: null,
oddFooter: null,
evenHeader: null,
evenFooter: null,
firstHeader: null,
firstFooter: null,
};
this.headerFooter = Object.assign(
{},
{
differentFirst: false,
differentOddEven: false,
oddHeader: null,
oddFooter: null,
evenHeader: null,
evenFooter: null,
firstHeader: null,
firstFooter: null,
},
options.headerFooter
);

this.dataValidations = new DataValidations();

Expand Down Expand Up @@ -564,6 +568,7 @@ class Worksheet {
if (Array.isArray(results[0])) {
getResult = (row, col) => results[row - top][col - left];
} else {
// eslint-disable-next-line no-mixed-operators
getResult = (row, col) => results[(row - top) * width + (col - left)];
}
} else {
Expand Down Expand Up @@ -631,7 +636,7 @@ class Worksheet {
};
if (options && 'spinCount' in options) {
// force spinCount to be integer >= 0
options.spinCount = isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 100000;
options.spinCount = Number.isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 100000;
}
if (password) {
this.sheetProtection.algorithmName = 'SHA-512';
Expand Down
1 change: 1 addition & 0 deletions lib/stream/xlsx/workbook-writer.js
Expand Up @@ -157,6 +157,7 @@ class WorkbookWriter {
pageSetup: options.pageSetup,
views: options.views,
autoFilter: options.autoFilter,
headerFooter: options.headerFooter,
});

this._worksheets[id] = worksheet;
Expand Down
23 changes: 22 additions & 1 deletion lib/stream/xlsx/worksheet-writer.js
Expand Up @@ -31,6 +31,7 @@ const PageSetupXform = require('../../xlsx/xform/sheet/page-setup-xform');
const AutoFilterXform = require('../../xlsx/xform/sheet/auto-filter-xform');
const PictureXform = require('../../xlsx/xform/sheet/picture-xform');
const ConditionalFormattingsXform = require('../../xlsx/xform/sheet/cf/conditional-formattings-xform');
const HeaderFooterXform = require('../../xlsx/xform/sheet/header-footer-xform');
const RowBreaksXform = require('../../xlsx/xform/sheet/row-breaks-xform');

// since prepare and render are functional, we can use singletons
Expand All @@ -48,6 +49,7 @@ const xform = {
autoFilter: new AutoFilterXform(),
picture: new PictureXform(),
conditionalFormattings: new ConditionalFormattingsXform(),
headerFooter: new HeaderFooterXform(),
rowBreaks: new RowBreaksXform(),
};

Expand Down Expand Up @@ -117,6 +119,21 @@ class WorksheetWriter {
options.properties
);

this.headerFooter = Object.assign(
{},
{
differentFirst: false,
differentOddEven: false,
oddHeader: null,
oddFooter: null,
evenHeader: null,
evenFooter: null,
firstHeader: null,
firstFooter: null,
},
options.headerFooter
);

// for all things printing
this.pageSetup = Object.assign(
{},
Expand Down Expand Up @@ -219,6 +236,7 @@ class WorksheetWriter {
this._writePageMargins();
this._writePageSetup();
this._writeBackground();
this._writeHeaderFooter();
this._writeRowBreaks();

// Legacy Data tag for comments
Expand Down Expand Up @@ -434,7 +452,6 @@ class WorksheetWriter {
}

removeConditionalFormatting(filter) {
console.log('conditionalFormatting', this.conditionalFormatting);
if (typeof filter === 'number') {
this.conditionalFormatting.splice(filter, 1);
} else if (filter instanceof Function) {
Expand Down Expand Up @@ -606,6 +623,10 @@ class WorksheetWriter {
this.stream.write(xform.pageSeteup.toXml(this.pageSetup));
}

_writeHeaderFooter() {
this.stream.write(xform.headerFooter.toXml(this.headerFooter));
}

_writeAutoFilter() {
this.stream.write(xform.autoFilter.toXml(this.autoFilter));
}
Expand Down

0 comments on commit 406c18d

Please sign in to comment.