Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
8dc590746b | |||
de5f5c9a77 | |||
ca5f6a56a5 | |||
8f6984580a | |||
da0fa86345 | |||
78b310e1dd | |||
4541d7c977 |
44
demo/demo38.ts
Normal file
44
demo/demo38.ts
Normal file
@ -0,0 +1,44 @@
|
||||
// Example of how to add images to the document - You can use Buffers, UInt8Arrays or Base64 strings
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
// import { Document, Packer, Paragraph } from "../build";
|
||||
import { Document, Packer, TextWrappingSide, TextWrappingType } from "../build";
|
||||
|
||||
const doc = new Document();
|
||||
|
||||
doc.createParagraph(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vehicula nec nulla vitae efficitur. Ut interdum mauris eu ipsum rhoncus, nec pharetra velit placerat. Sed vehicula libero ac urna molestie, id pharetra est pellentesque. Praesent iaculis vehicula fringilla. Duis pretium gravida orci eu vestibulum. Mauris tincidunt ipsum dolor, ut ornare dolor pellentesque id. Integer in nulla gravida, lacinia ante non, commodo ex. Vivamus vulputate nisl id lectus finibus vulputate. Ut et nisl mi. Cras fermentum augue arcu, ac accumsan elit euismod id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed ac posuere nisi. Pellentesque tincidunt vehicula bibendum. Phasellus eleifend viverra nisl.",
|
||||
);
|
||||
|
||||
doc.createParagraph(
|
||||
"Proin ac purus faucibus, porttitor magna ut, cursus nisl. Vivamus ante purus, porta accumsan nibh eget, eleifend dignissim odio. Integer sed dictum est, aliquam lacinia justo. Donec ultrices auctor venenatis. Etiam interdum et elit nec elementum. Pellentesque nec viverra mauris. Etiam suscipit leo nec velit fringilla mattis. Pellentesque justo lacus, sodales eu condimentum in, dapibus finibus lacus. Morbi vitae nibh sit amet sem molestie feugiat. In non porttitor enim.",
|
||||
);
|
||||
|
||||
doc.createParagraph(
|
||||
"Ut eget diam cursus quam accumsan interdum at id ante. Ut mollis mollis arcu, eu scelerisque dui tempus in. Quisque aliquam, augue quis ornare aliquam, ex purus ultrices mauris, ut porta dolor dolor nec justo. Nunc a tempus odio, eu viverra arcu. Suspendisse vitae nibh nec mi pharetra tempus. Mauris ut ullamcorper sapien, et sagittis sapien. Vestibulum in urna metus. In scelerisque, massa id bibendum tempus, quam orci rutrum turpis, a feugiat nisi ligula id metus. Praesent id dictum purus. Proin interdum ipsum nulla.",
|
||||
);
|
||||
|
||||
doc.createImage(fs.readFileSync("./demo/images/pizza.gif"), 200, 200, {
|
||||
floating: {
|
||||
horizontalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
verticalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.SQUARE,
|
||||
side: TextWrappingSide.BOTH_SIDES,
|
||||
},
|
||||
margins: {
|
||||
top: 201440,
|
||||
bottom: 201440,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const packer = new Packer();
|
||||
|
||||
packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
33
demo/demo39.ts
Normal file
33
demo/demo39.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// Scaling images
|
||||
// Import from 'docx' rather than '../build' if you install from npm
|
||||
import * as fs from "fs";
|
||||
import { Document, Packer, PageNumberFormat, TextRun } from "../build";
|
||||
|
||||
const doc = new Document(
|
||||
{},
|
||||
{
|
||||
pageNumberStart: 1,
|
||||
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||
},
|
||||
);
|
||||
|
||||
doc.Header.createParagraph("Foo Bar corp. ")
|
||||
.addRun(new TextRun("Page Number ").pageNumber())
|
||||
.addRun(new TextRun(" to ").numberOfTotalPages());
|
||||
|
||||
doc.Footer.createParagraph("Foo Bar corp. ")
|
||||
.center()
|
||||
.addRun(new TextRun("Page Number: ").pageNumber())
|
||||
.addRun(new TextRun(" to ").numberOfTotalPages());
|
||||
|
||||
doc.createParagraph("Hello World 1").pageBreak();
|
||||
doc.createParagraph("Hello World 2").pageBreak();
|
||||
doc.createParagraph("Hello World 3").pageBreak();
|
||||
doc.createParagraph("Hello World 4").pageBreak();
|
||||
doc.createParagraph("Hello World 5").pageBreak();
|
||||
|
||||
const packer = new Packer();
|
||||
|
||||
packer.toBuffer(doc).then((buffer) => {
|
||||
fs.writeFileSync("My Document.docx", buffer);
|
||||
});
|
@ -17,6 +17,7 @@
|
||||
* [Numbering](usage/numbering.md)
|
||||
* [Tab Stops](usage/tab-stops.md)
|
||||
* [Table of Contents](usage/table-of-contents.md)
|
||||
* [Page Numbers](usage/page-numbers.md)
|
||||
* Styling
|
||||
* [Styling with JS](usage/styling-with-js.md)
|
||||
* [Styling with XML](usage/styling-with-xml.md)
|
||||
|
@ -56,7 +56,6 @@ Adding images can be done in two ways:
|
||||
Three types of image positioning is supported:
|
||||
|
||||
- Floating
|
||||
- Wrapped around the text
|
||||
- Inline
|
||||
|
||||
By default, picture are exported as `Inline` elements.
|
||||
@ -65,7 +64,7 @@ By default, picture are exported as `Inline` elements.
|
||||
|
||||
Pass `options` into the `[POSITION_OPTIONS]` metioned in the [Intro above](#Intro).
|
||||
|
||||
### Floating
|
||||
## Floating
|
||||
|
||||
To change the position the image to be on top of the text, simply add the `floating` property to the last argument. By default, the offsets are relative to the top left corner of the `page`. Offset units are in [emus](https://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/):
|
||||
|
||||
@ -97,7 +96,7 @@ const imageData = document.createImage(buffer, 903, 1149, {
|
||||
});
|
||||
```
|
||||
|
||||
#### Options
|
||||
### Options
|
||||
|
||||
Full options you can pass into `floating` are:
|
||||
|
||||
@ -126,32 +125,83 @@ Full options you can pass into `floating` are:
|
||||
| align | `VerticalPositionAlign` | You can either have `align` or `offset`, not both | `BOTTOM`, `CENTER`, `INSIDE`, `OUTSIDE`, `TOP` |
|
||||
| offset | `number` | You can either have `align` or `offset`, not both | `0` to `Infinity` |
|
||||
|
||||
### Wrap text
|
||||
## Wrap text
|
||||
|
||||
!> **In progress** Documentation may potentially be changing
|
||||
Wrapping only works for floating elements. Text will "wrap" around the floating `image`.
|
||||
|
||||
for `drawingOptions.textWrapping` we can define various options. `textWrapping` has the following properties:
|
||||
Add `wrap` options inside the `floating` options:
|
||||
|
||||
```js
|
||||
interface TextWrapping {
|
||||
textWrapStyle: TextWrapStyle;
|
||||
wrapTextOption?: WrapTextOption;
|
||||
distanceFromText?: Distance;
|
||||
}
|
||||
```ts
|
||||
wrap: {
|
||||
type: [TextWrappingType],
|
||||
side: [TextWrappingSide],
|
||||
},
|
||||
```
|
||||
|
||||
enum TextWrapStyle {
|
||||
NONE,
|
||||
SQUARE,
|
||||
TIGHT,
|
||||
TOP_AND_BOTTOM,
|
||||
}
|
||||
For example:
|
||||
|
||||
enum WrapTextOption {
|
||||
BOTH_SIDES = "bothSides",
|
||||
LEFT = "left",
|
||||
RIGHT = "right",
|
||||
LARGEST = "largest",
|
||||
}
|
||||
```ts
|
||||
doc.createImage(fs.readFileSync("./demo/images/pizza.gif"), 200, 200, {
|
||||
floating: {
|
||||
horizontalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
verticalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.SQUARE,
|
||||
side: TextWrappingSide.BOTH_SIDES,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Wrap options have the following properties are:
|
||||
|
||||
| Property | Type | Notes | Possible Values |
|
||||
| -------- | ------------------ | -------- | ------------------------------------------- |
|
||||
| type | `TextWrappingType` | Optional | `NONE`, `SQUARE`, `TIGHT`, `TOP_AND_BOTTOM` |
|
||||
| side | `TextWrappingSide` | Optional | `BOTH_SIDES`, `LEFT`, `RIGHT`, `LARGEST` |
|
||||
|
||||
## Margins
|
||||
|
||||
Margins give some space between the text and the image. Margins [only work for floating elements](http://officeopenxml.com/drwPicInline.php). Additionally, the image must also be in wrap mode (see above).
|
||||
|
||||
?> Be sure to also set `wrap` in your options!
|
||||
|
||||
To use, add the `margins` options inside the `floating` options:
|
||||
|
||||
```ts
|
||||
margins: {
|
||||
top: number,
|
||||
bottom: number,
|
||||
left: number,
|
||||
right: number
|
||||
},
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
doc.createImage(fs.readFileSync("./demo/images/pizza.gif"), 200, 200, {
|
||||
floating: {
|
||||
horizontalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
verticalPosition: {
|
||||
offset: 2014400,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.SQUARE,
|
||||
side: TextWrappingSide.BOTH_SIDES,
|
||||
},
|
||||
margins: {
|
||||
top: 201440,
|
||||
bottom: 201440,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Examples
|
||||
@ -171,3 +221,11 @@ Example showing how to add image to headers and footers
|
||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo9.ts ":include")
|
||||
|
||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo9.ts_
|
||||
|
||||
### Floating images
|
||||
|
||||
Example showing how to float images on top of text and optimally give a `margin`
|
||||
|
||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo38.ts ":include")
|
||||
|
||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo38.ts_
|
||||
|
66
docs/usage/page-numbers.md
Normal file
66
docs/usage/page-numbers.md
Normal file
@ -0,0 +1,66 @@
|
||||
# Page Numbers
|
||||
|
||||
> This feature allows you to set page numbers on each page
|
||||
|
||||
?> **Note:** This feature only works on Headers and Footers
|
||||
|
||||
```ts
|
||||
doc.Header.createParagraph().addRun(new TextRun("Page Number: ").pageNumber()).addRun(new TextRun("to ").numberOfTotalPages());
|
||||
```
|
||||
|
||||
## Current page number
|
||||
|
||||
To get the current page number, call the `.pageNumber()` method on a `TextRun`. Then add the newly created `TextRun` into a paragraph
|
||||
|
||||
```ts
|
||||
pageNumber();
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const currentPageRun = new TextRun("Current Page Number: ").pageNumber();
|
||||
paragraph.addRun(currentPageRun);
|
||||
```
|
||||
|
||||
## Total number of pages
|
||||
|
||||
```ts
|
||||
numberOfTotalPages();
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const lastPage = new TextRun("Total Page Number: ").numberOfTotalPages();
|
||||
paragraph.addRun(lastPage);
|
||||
```
|
||||
|
||||
|
||||
## Both
|
||||
|
||||
You can combine the two to get "Page 2 of 10" effect:
|
||||
|
||||
```ts
|
||||
const currentPageRun = new TextRun("Page ").pageNumber();
|
||||
const lastPage = new TextRun("of ").numberOfTotalPages();
|
||||
|
||||
paragraph.addRun(currentPageRun);
|
||||
paragraph.addRun(lastPage);
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```ts
|
||||
doc.Header.createParagraph().addRun(new TextRun("Page ").pageNumber()).addRun(new TextRun("of ").numberOfTotalPages());
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple Example
|
||||
|
||||
Adding page numbers to Header and Footer
|
||||
|
||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo39.ts ":include")
|
||||
|
||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo39.ts_
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docx",
|
||||
"version": "4.5.0",
|
||||
"version": "4.7.0",
|
||||
"description": "Generate .docx documents with JavaScript (formerly Office-Clippy)",
|
||||
"main": "build/index.js",
|
||||
"scripts": {
|
||||
|
@ -3,7 +3,7 @@ import { assert } from "chai";
|
||||
import { Utility } from "tests/utility";
|
||||
|
||||
import { IDrawingOptions } from "../drawing";
|
||||
import { TextWrapStyle } from "../text-wrap";
|
||||
import { TextWrappingType } from "../text-wrap";
|
||||
import { Anchor } from "./anchor";
|
||||
|
||||
function createAnchor(drawingOptions: IDrawingOptions): Anchor {
|
||||
@ -123,9 +123,6 @@ describe("Anchor", () => {
|
||||
|
||||
it("should create a Drawing with square text wrapping", () => {
|
||||
anchor = createAnchor({
|
||||
textWrapping: {
|
||||
textWrapStyle: TextWrapStyle.SQUARE,
|
||||
},
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
@ -133,6 +130,9 @@ describe("Anchor", () => {
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.SQUARE,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
@ -145,9 +145,6 @@ describe("Anchor", () => {
|
||||
|
||||
it("should create a Drawing with no text wrapping", () => {
|
||||
anchor = createAnchor({
|
||||
textWrapping: {
|
||||
textWrapStyle: TextWrapStyle.NONE,
|
||||
},
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
@ -155,6 +152,9 @@ describe("Anchor", () => {
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.NONE,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
@ -166,9 +166,6 @@ describe("Anchor", () => {
|
||||
|
||||
it("should create a Drawing with tight text wrapping", () => {
|
||||
anchor = createAnchor({
|
||||
textWrapping: {
|
||||
textWrapStyle: TextWrapStyle.TIGHT,
|
||||
},
|
||||
floating: {
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
@ -176,6 +173,9 @@ describe("Anchor", () => {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.TIGHT,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
@ -187,9 +187,6 @@ describe("Anchor", () => {
|
||||
|
||||
it("should create a Drawing with tight text wrapping", () => {
|
||||
anchor = createAnchor({
|
||||
textWrapping: {
|
||||
textWrapStyle: TextWrapStyle.TOP_AND_BOTTOM,
|
||||
},
|
||||
floating: {
|
||||
verticalPosition: {
|
||||
offset: 0,
|
||||
@ -197,6 +194,9 @@ describe("Anchor", () => {
|
||||
horizontalPosition: {
|
||||
offset: 0,
|
||||
},
|
||||
wrap: {
|
||||
type: TextWrappingType.TOP_AND_BOTTOM,
|
||||
},
|
||||
},
|
||||
});
|
||||
const newJson = Utility.jsonify(anchor);
|
||||
|
@ -4,7 +4,7 @@ import { XmlComponent } from "file/xml-components";
|
||||
import { IDrawingOptions } from "../drawing";
|
||||
import { HorizontalPosition, IFloating, SimplePos, VerticalPosition } from "../floating";
|
||||
import { Graphic } from "../inline/graphic";
|
||||
import { TextWrapStyle, WrapNone, WrapSquare, WrapTight, WrapTopAndBottom } from "../text-wrap";
|
||||
import { TextWrappingType, WrapNone, WrapSquare, WrapTight, WrapTopAndBottom } from "../text-wrap";
|
||||
import { DocProperties } from "./../doc-properties/doc-properties";
|
||||
import { EffectExtent } from "./../effect-extent/effect-extent";
|
||||
import { Extent } from "./../extent/extent";
|
||||
@ -25,15 +25,22 @@ export class Anchor extends XmlComponent {
|
||||
super("wp:anchor");
|
||||
|
||||
const floating = {
|
||||
margins: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
...defaultOptions,
|
||||
...drawingOptions.floating,
|
||||
};
|
||||
|
||||
this.root.push(
|
||||
new AnchorAttributes({
|
||||
distT: 0,
|
||||
distB: 0,
|
||||
distL: 0,
|
||||
distR: 0,
|
||||
distT: floating.margins.top || 0,
|
||||
distB: floating.margins.bottom || 0,
|
||||
distL: floating.margins.left || 0,
|
||||
distR: floating.margins.right || 0,
|
||||
simplePos: "0", // note: word doesn't fully support - so we use 0
|
||||
allowOverlap: floating.allowOverlap === true ? "1" : "0",
|
||||
behindDoc: floating.behindDocument === true ? "1" : "0",
|
||||
@ -49,18 +56,18 @@ export class Anchor extends XmlComponent {
|
||||
this.root.push(new Extent(dimensions.emus.x, dimensions.emus.y));
|
||||
this.root.push(new EffectExtent());
|
||||
|
||||
if (drawingOptions.textWrapping !== undefined) {
|
||||
switch (drawingOptions.textWrapping.textWrapStyle) {
|
||||
case TextWrapStyle.SQUARE:
|
||||
this.root.push(new WrapSquare(drawingOptions.textWrapping));
|
||||
if (drawingOptions.floating !== undefined && drawingOptions.floating.wrap !== undefined) {
|
||||
switch (drawingOptions.floating.wrap.type) {
|
||||
case TextWrappingType.SQUARE:
|
||||
this.root.push(new WrapSquare(drawingOptions.floating.wrap, drawingOptions.floating.margins));
|
||||
break;
|
||||
case TextWrapStyle.TIGHT:
|
||||
this.root.push(new WrapTight(drawingOptions.textWrapping.distanceFromText));
|
||||
case TextWrappingType.TIGHT:
|
||||
this.root.push(new WrapTight(drawingOptions.floating.margins));
|
||||
break;
|
||||
case TextWrapStyle.TOP_AND_BOTTOM:
|
||||
this.root.push(new WrapTopAndBottom(drawingOptions.textWrapping.distanceFromText));
|
||||
case TextWrappingType.TOP_AND_BOTTOM:
|
||||
this.root.push(new WrapTopAndBottom(drawingOptions.floating.margins));
|
||||
break;
|
||||
case TextWrapStyle.NONE:
|
||||
case TextWrappingType.NONE:
|
||||
default:
|
||||
this.root.push(new WrapNone());
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import { XmlComponent } from "file/xml-components";
|
||||
import { Anchor } from "./anchor";
|
||||
import { IFloating } from "./floating";
|
||||
import { Inline } from "./inline";
|
||||
import { ITextWrapping } from "./text-wrap";
|
||||
|
||||
export interface IDistance {
|
||||
readonly distT?: number;
|
||||
@ -13,7 +12,6 @@ export interface IDistance {
|
||||
}
|
||||
|
||||
export interface IDrawingOptions {
|
||||
readonly textWrapping?: ITextWrapping;
|
||||
readonly floating?: IFloating;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// http://officeopenxml.com/drwPicFloating-position.php
|
||||
import { ITextWrapping } from "../text-wrap";
|
||||
|
||||
export enum HorizontalPositionRelativeFrom {
|
||||
CHARACTER = "character",
|
||||
@ -50,6 +51,13 @@ export interface IVerticalPositionOptions {
|
||||
readonly offset?: number;
|
||||
}
|
||||
|
||||
export interface IMargins {
|
||||
readonly left?: number;
|
||||
readonly bottom?: number;
|
||||
readonly top?: number;
|
||||
readonly right?: number;
|
||||
}
|
||||
|
||||
export interface IFloating {
|
||||
readonly horizontalPosition: IHorizontalPositionOptions;
|
||||
readonly verticalPosition: IVerticalPositionOptions;
|
||||
@ -57,4 +65,6 @@ export interface IFloating {
|
||||
readonly lockAnchor?: boolean;
|
||||
readonly behindDocument?: boolean;
|
||||
readonly layoutInCell?: boolean;
|
||||
readonly margins?: IMargins;
|
||||
readonly wrap?: ITextWrapping;
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
import { XmlAttributeComponent } from "file/xml-components";
|
||||
import { IDistance } from "../drawing";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
export interface IInlineAttributes extends IDistance {}
|
||||
// distT, distB etc have no effect on inline images, only floating
|
||||
export interface IInlineAttributes extends IDistance {
|
||||
readonly distT?: number;
|
||||
readonly distB?: number;
|
||||
readonly distL?: number;
|
||||
readonly distR?: number;
|
||||
}
|
||||
|
||||
export class InlineAttributes extends XmlAttributeComponent<IInlineAttributes> {
|
||||
protected readonly xmlKeys = {
|
||||
|
@ -1,14 +1,14 @@
|
||||
// http://officeopenxml.com/drwPicFloating-textWrap.php
|
||||
import { IDistance } from "../drawing";
|
||||
|
||||
export enum TextWrapStyle {
|
||||
export enum TextWrappingType {
|
||||
NONE,
|
||||
SQUARE,
|
||||
TIGHT,
|
||||
TOP_AND_BOTTOM,
|
||||
}
|
||||
|
||||
export enum WrapTextOption {
|
||||
export enum TextWrappingSide {
|
||||
BOTH_SIDES = "bothSides",
|
||||
LEFT = "left",
|
||||
RIGHT = "right",
|
||||
@ -16,7 +16,7 @@ export enum WrapTextOption {
|
||||
}
|
||||
|
||||
export interface ITextWrapping {
|
||||
readonly textWrapStyle: TextWrapStyle;
|
||||
readonly wrapTextOption?: WrapTextOption;
|
||||
readonly distanceFromText?: IDistance;
|
||||
readonly type: TextWrappingType;
|
||||
readonly side?: TextWrappingSide;
|
||||
readonly margins?: IDistance;
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
// http://officeopenxml.com/drwPicFloating-textWrap.php
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
import { ITextWrapping, WrapTextOption } from ".";
|
||||
import { ITextWrapping, TextWrappingSide } from ".";
|
||||
import { IDistance } from "../drawing";
|
||||
import { IMargins } from "../floating";
|
||||
|
||||
interface IWrapSquareAttributes extends IDistance {
|
||||
readonly wrapText?: WrapTextOption;
|
||||
readonly wrapText?: TextWrappingSide;
|
||||
readonly distT?: number;
|
||||
readonly distB?: number;
|
||||
readonly distL?: number;
|
||||
readonly distR?: number;
|
||||
}
|
||||
|
||||
class WrapSquareAttributes extends XmlAttributeComponent<IWrapSquareAttributes> {
|
||||
@ -18,13 +23,24 @@ class WrapSquareAttributes extends XmlAttributeComponent<IWrapSquareAttributes>
|
||||
}
|
||||
|
||||
export class WrapSquare extends XmlComponent {
|
||||
constructor(textWrapping: ITextWrapping) {
|
||||
constructor(
|
||||
textWrapping: ITextWrapping,
|
||||
margins: IMargins = {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
) {
|
||||
super("wp:wrapSquare");
|
||||
|
||||
this.root.push(
|
||||
new WrapSquareAttributes({
|
||||
wrapText: textWrapping.wrapTextOption || WrapTextOption.BOTH_SIDES,
|
||||
...textWrapping.distanceFromText,
|
||||
wrapText: textWrapping.side || TextWrappingSide.BOTH_SIDES,
|
||||
distT: margins.top,
|
||||
distB: margins.bottom,
|
||||
distL: margins.left,
|
||||
distR: margins.right,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// http://officeopenxml.com/drwPicFloating-textWrap.php
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
import { IDistance } from "../drawing";
|
||||
|
||||
import { IMargins } from "../floating";
|
||||
|
||||
interface IWrapTightAttributes {
|
||||
readonly distT?: number;
|
||||
@ -16,17 +17,17 @@ class WrapTightAttributes extends XmlAttributeComponent<IWrapTightAttributes> {
|
||||
|
||||
export class WrapTight extends XmlComponent {
|
||||
constructor(
|
||||
distanceFromText: IDistance = {
|
||||
distT: 0,
|
||||
distB: 0,
|
||||
margins: IMargins = {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
) {
|
||||
super("wp:wrapTight");
|
||||
|
||||
this.root.push(
|
||||
new WrapTightAttributes({
|
||||
distT: distanceFromText.distT,
|
||||
distB: distanceFromText.distB,
|
||||
distT: margins.top,
|
||||
distB: margins.bottom,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// http://officeopenxml.com/drwPicFloating-textWrap.php
|
||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||
import { IDistance } from "../drawing";
|
||||
|
||||
import { IMargins } from "../floating";
|
||||
|
||||
interface IWrapTopAndBottomAttributes {
|
||||
readonly distT?: number;
|
||||
@ -16,17 +17,17 @@ class WrapTopAndBottomAttributes extends XmlAttributeComponent<IWrapTopAndBottom
|
||||
|
||||
export class WrapTopAndBottom extends XmlComponent {
|
||||
constructor(
|
||||
distanceFromText: IDistance = {
|
||||
distT: 0,
|
||||
distB: 0,
|
||||
margins: IMargins = {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
) {
|
||||
super("wp:wrapTopAndBottom");
|
||||
|
||||
this.root.push(
|
||||
new WrapTopAndBottomAttributes({
|
||||
distT: distanceFromText.distT,
|
||||
distB: distanceFromText.distB,
|
||||
distT: margins.top,
|
||||
distB: margins.bottom,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { ContentTypes } from "./content-types/content-types";
|
||||
import { CoreProperties, IPropertiesOptions } from "./core-properties";
|
||||
import { Document } from "./document";
|
||||
import {
|
||||
FooterReference,
|
||||
FooterReferenceType,
|
||||
HeaderReference,
|
||||
HeaderReferenceType,
|
||||
@ -218,6 +219,32 @@ export class File {
|
||||
return headerWrapper;
|
||||
}
|
||||
|
||||
public createFirstPageFooter(): FooterWrapper {
|
||||
const footerWrapper = this.createFooter();
|
||||
|
||||
this.document.Body.DefaultSection.addChildElement(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.FIRST,
|
||||
footerId: footerWrapper.Footer.ReferenceId,
|
||||
}),
|
||||
);
|
||||
|
||||
return footerWrapper;
|
||||
}
|
||||
|
||||
public createEvenPageFooter(): FooterWrapper {
|
||||
const footerWrapper = this.createFooter();
|
||||
|
||||
this.document.Body.DefaultSection.addChildElement(
|
||||
new FooterReference({
|
||||
footerType: FooterReferenceType.EVEN,
|
||||
footerId: footerWrapper.Footer.ReferenceId,
|
||||
}),
|
||||
);
|
||||
|
||||
return footerWrapper;
|
||||
}
|
||||
|
||||
public getFooterByReferenceNumber(refId: number): FooterWrapper {
|
||||
const entry = this.footers.map((item) => item.footer).find((h) => h.Footer.ReferenceId === refId);
|
||||
if (entry) {
|
||||
|
23
src/file/paragraph/run/page-number.spec.ts
Normal file
23
src/file/paragraph/run/page-number.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { Formatter } from "export/formatter";
|
||||
|
||||
import { NumberOfPages, Page } from "./page-number";
|
||||
|
||||
describe("Page", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("uses the font name for both ascii and hAnsi", () => {
|
||||
const tree = new Formatter().format(new Page());
|
||||
expect(tree).to.deep.equal({ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "PAGE"] });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("NumberOfPages", () => {
|
||||
describe("#constructor()", () => {
|
||||
it("uses the font name for both ascii and hAnsi", () => {
|
||||
const tree = new Formatter().format(new NumberOfPages());
|
||||
expect(tree).to.deep.equal({ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "NUMPAGES"] });
|
||||
});
|
||||
});
|
||||
});
|
@ -12,3 +12,11 @@ export class Page extends XmlComponent {
|
||||
this.root.push("PAGE");
|
||||
}
|
||||
}
|
||||
|
||||
export class NumberOfPages extends XmlComponent {
|
||||
constructor() {
|
||||
super("w:instrText");
|
||||
this.root.push(new TextAttributes({ space: SpaceType.PRESERVE }));
|
||||
this.root.push("NUMPAGES");
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +156,38 @@ describe("Run", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#numberOfTotalPages", () => {
|
||||
it("should set the run to the RTL mode", () => {
|
||||
run.numberOfTotalPages();
|
||||
const tree = new Formatter().format(run);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:r": [
|
||||
{ "w:rPr": [] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
|
||||
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "NUMPAGES"] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] },
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#pageNumber", () => {
|
||||
it("should set the run to the RTL mode", () => {
|
||||
run.pageNumber();
|
||||
const tree = new Formatter().format(run);
|
||||
expect(tree).to.deep.equal({
|
||||
"w:r": [
|
||||
{ "w:rPr": [] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "begin" } }] },
|
||||
{ "w:instrText": [{ _attr: { "xml:space": "preserve" } }, "PAGE"] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "separate" } }] },
|
||||
{ "w:fldChar": [{ _attr: { "w:fldCharType": "end" } }] },
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#style", () => {
|
||||
it("should set the style to the given styleId", () => {
|
||||
run.style("myRunStyle");
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
SizeComplexScript,
|
||||
Strike,
|
||||
} from "./formatting";
|
||||
import { Page } from "./page-number";
|
||||
import { NumberOfPages, Page } from "./page-number";
|
||||
import { RunProperties } from "./properties";
|
||||
import { RunFonts } from "./run-fonts";
|
||||
import { SubScript, SuperScript } from "./script";
|
||||
@ -84,6 +84,14 @@ export class Run extends XmlComponent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public numberOfTotalPages(): Run {
|
||||
this.root.push(new Begin());
|
||||
this.root.push(new NumberOfPages());
|
||||
this.root.push(new Separate());
|
||||
this.root.push(new End());
|
||||
return this;
|
||||
}
|
||||
|
||||
public smallCaps(): Run {
|
||||
this.properties.push(new SmallCaps());
|
||||
return this;
|
||||
|
Reference in New Issue
Block a user