diff --git a/demo/demo5.ts b/demo/demo5.ts index e56cdfc01e..7163a5db60 100644 --- a/demo/demo5.ts +++ b/demo/demo5.ts @@ -1,7 +1,8 @@ // 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, Paragraph } from "../build"; +import { Document, HorizontalPositionAlign, HorizontalPositionRelativeFrom, Packer, Paragraph, VerticalPositionAlign, VerticalPositionRelativeFrom} from "../build"; const doc = new Document(); @@ -13,6 +14,29 @@ doc.createImage(fs.readFileSync("./demo/images/dog.png").toString("base64")); doc.createImage(fs.readFileSync("./demo/images/cat.jpg")); doc.createImage(fs.readFileSync("./demo/images/parrots.bmp")); doc.createImage(fs.readFileSync("./demo/images/pizza.gif")); +doc.createImage(fs.readFileSync("./demo/images/pizza.gif"), 200, 200, { + floating: { + horizontalPosition: { + offset: 1014400, + }, + verticalPosition: { + offset: 1014400, + }, + }, +}); + +doc.createImage(fs.readFileSync("./demo/images/cat.jpg"), 200, 200, { + floating: { + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.PAGE, + align: HorizontalPositionAlign.RIGHT, + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.PAGE, + align: VerticalPositionAlign.BOTTOM, + }, + }, +}); const packer = new Packer(); diff --git a/docs/usage/images.md b/docs/usage/images.md index a89fa893cd..054df0e6a2 100644 --- a/docs/usage/images.md +++ b/docs/usage/images.md @@ -1,71 +1,135 @@ # Images -## Intro +To create a `floating` image on top of text: -Adding images is very simple - -Simply call the `createImage` method: - -```js -const image = doc.createImage([BUFFER_OF_YOUR_IMAGE]); -``` - -`docx` supports `jpeg`, `jpg`, `bmp`, `gif` and `png` - -Check `demo5.js` for an example - -## Positioning - -Images can be: - -* floating position of images -* Wrapped around the text -* Inline - -By default, picture are exported as `INLINE` elements. - -In Word this is found in: - -![Word Image Positiong](https://user-images.githubusercontent.com/34742290/41765548-b0946302-7604-11e8-96f9-166a9f0b8f39.png) - -### Usage - -The `PictureRun` element support various options to define the positioning of the element in the document. - -```js -interface DrawingOptions { - position?: PlacementPosition; - textWrapping?: TextWrapping; - floating?: Floating; -} -``` - -can be passed when creating `PictureRun()` for example: - -```js -const imageData = document.createImage(buffer, 903, 1149); - -new docx.PictureRun(imageData, { - position: docx.PlacementPosition.FLOATING, +```ts +doc.createImage(fs.readFileSync("./demo/images/pizza.gif"), 200, 200, { floating: { horizontalPosition: { - relative: HorizontalPositionRelativeFrom.PAGE, - align: HorizontalPositionAlign.LEFT, + offset: 1014400, }, verticalPosition: { - relative: VerticalPositionRelativeFrom.PAGE, - align: VerticalPositionAlign.TOP, + offset: 1014400, }, }, }); ``` -So, the first thing is to define the placement position: `INLINE` or `FLOATING`. Inline is the default one so there is no need to pass drawing options for inline. +By default with no arguments, its an `inline` image: -When placement position is FLOATING then we can use two options: +```ts +doc.createImage(fs.readFileSync("./demo/images/parrots.bmp")); +``` + +You can also create images manually and add them later: + +```ts +const image = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif")); +doc.addImage(image); +``` + +## Intro + +Adding images can be done in two ways: + +1. Call the `createImage` method to add the image directly into the `document`: + + ```js + doc.createImage([IMAGE_BUFFER], [WIDTH], [HEIGHT], [POSITION_OPTIONS]); + ``` + +2. Create an `image` first, then add it into the `document`: + + ```ts + const image = Media.addImage(doc, [IMAGE_BUFFER]); + doc.addImage(image); + ``` + +`docx` supports `jpeg`, `jpg`, `bmp`, `gif` and `png` + +## Positioning + +> Positioning is the method on how to place the image on the document + +![Word Image Positiong](https://user-images.githubusercontent.com/34742290/41765548-b0946302-7604-11e8-96f9-166a9f0b8f39.png) + +Three types of image positioning is supported: + +- Floating +- Wrapped around the text +- Inline + +By default, picture are exported as `Inline` elements. + +### Usage + +Pass `options` into the `[POSITION_OPTIONS]` metioned in the [Intro above](#Intro). + +### 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/): + +```ts +const imageData = document.createImage(buffer, 903, 1149, { + floating: { + horizontalPosition: { + offset: 1014400, // relative: HorizontalPositionRelativeFrom.PAGE by default + }, + verticalPosition: { + offset: 1014400, // relative: VerticalPositionRelativeFrom.PAGE by default + }, + }, +}); +``` + +```ts +const imageData = document.createImage(buffer, 903, 1149, { + floating: { + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.RIGHT_MARGIN, + offset: 1014400, + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.BOTTOM_MARGIN, + offset: 1014400, + }, + }, +}); +``` + +#### Options + +Full options you can pass into `floating` are: + +| Property | Type | Notes | +| ------------------ | --------------------------- | -------- | +| horizontalPosition | `HorizontalPositionOptions` | Required | +| verticalPosition | `VerticalPositionOptions` | Required | +| allowOverlap | `boolean` | Optional | +| lockAnchor | `boolean` | Optional | +| behindDocument | `boolean` | Optional | +| layoutInCell | `boolean` | Optional | + +`HorizontalPositionOptions` are: + +| Property | Type | Notes | Possible Values | +| -------- | -------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| relative | `HorizontalPositionRelativeFrom` | Required | `CHARACTER`, `COLUMN`, `INSIDE_MARGIN`, `LEFT_MARGIN`, `MARGIN`, `OUTSIDE_MARGIN`, `PAGE`, `RIGHT_MARGIN` | +| align | `HorizontalPositionAlign` | You can either have `align` or `offset`, not both | `CENTER`, `INSIDE`, `LEFT`, `OUTSIDE`, `RIGHT` | +| offset | `number` | You can either have `align` or `offset`, not both | `0` to `Infinity` | + +`VerticalPositionOptions` are: + +| Property | Type | Notes | Possible Values | +| -------- | ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| relative | `VerticalPositionRelativeFrom` | Required | `BOTTOM_MARGIN`, `INSIDE_MARGIN`, `LINE`, `MARGIN`, `OUTSIDE_MARGIN`, `PAGE`, `PARAGRAPH`, `TOP_MARGIN` | +| 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 +!> **In progress** Documentation may potentially be changing + for `drawingOptions.textWrapping` we can define various options. `textWrapping` has the following properties: ```js @@ -90,67 +154,20 @@ enum WrapTextOption { } ``` -### Floating position +## Examples -When we want to position the image relative or absolute then we need to use option `drawingOptions.floating`: +### Add image to the document -```js -export interface Floating { - horizontalPosition: HorizontalPositionOptions; - verticalPosition: VerticalPositionOptions; - allowOverlap?: boolean; - lockAnchor?: boolean; - behindDocument?: boolean; - layoutInCell?: boolean; -} +Importing Images from file system path -export interface HorizontalPositionOptions { - relative: HorizontalPositionRelativeFrom; - align?: HorizontalPositionAlign; - offset?: number; -} +[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo5.ts ":include") -export interface VerticalPositionOptions { - relative: VerticalPositionRelativeFrom; - align?: VerticalPositionAlign; - offset?: number; -} +_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo5.ts_ -export enum HorizontalPositionRelativeFrom { - CHARACTER = "character", - COLUMN = "column", - INSIDE_MARGIN = "insideMargin", - LEFT_MARGIN = "leftMargin", - MARGIN = "margin", - OUTSIDE_MARGIN = "outsideMargin", - PAGE = "page", - RIGHT_MARGIN = "rightMargin", -} +### Add images to header and footer -export enum VerticalPositionRelativeFrom { - BOTTOM_MARGIN = "bottomMargin", - INSIDE_MARGIN = "insideMargin", - LINE = "line", - MARGIN = "margin", - OUTSIDE_MARGIN = "outsideMargin", - PAGE = "page", - PARAGRAPH = "paragraph", - TOP_MARGIN = "topMargin", -} +Example showing how to add image to headers and footers -export enum HorizontalPositionAlign { - CENTER = "center", - INSIDE = "inside", - LEFT = "left", - OUTSIDE = "outside", - RIGHT = "right", -} +[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo9.ts ":include") -export enum VerticalPositionAlign { - BOTTOM = "bottom", - CENTER = "center", - INSIDE = "inside", - OUTSIDE = "outside", - TOP = "top", -} -``` +_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo9.ts_ diff --git a/package.json b/package.json index 24325883aa..780c92f1a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx", - "version": "4.4.1", + "version": "4.5.0", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "main": "build/index.js", "scripts": { diff --git a/src/file/drawing/anchor/anchor.spec.ts b/src/file/drawing/anchor/anchor.spec.ts index 44ea916a9a..733d60c769 100644 --- a/src/file/drawing/anchor/anchor.spec.ts +++ b/src/file/drawing/anchor/anchor.spec.ts @@ -6,7 +6,7 @@ import { IDrawingOptions } from "../drawing"; import { TextWrapStyle } from "../text-wrap"; import { Anchor } from "./anchor"; -function createDrawing(drawingOptions: IDrawingOptions): Anchor { +function createAnchor(drawingOptions: IDrawingOptions): Anchor { return new Anchor( { fileName: "test.png", @@ -41,14 +41,32 @@ describe("Anchor", () => { describe("#constructor()", () => { it("should create a Drawing with correct root key", () => { - anchor = createDrawing({}); + anchor = createAnchor({ + floating: { + verticalPosition: { + offset: 0, + }, + horizontalPosition: { + offset: 0, + }, + }, + }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.rootKey, "wp:anchor"); assert.equal(newJson.root.length, 10); }); it("should create a Drawing with all default options", () => { - anchor = createDrawing({}); + anchor = createAnchor({ + floating: { + verticalPosition: { + offset: 0, + }, + horizontalPosition: { + offset: 0, + }, + }, + }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.root.length, 10); @@ -73,7 +91,7 @@ describe("Anchor", () => { const horizontalPosition = newJson.root[2]; assert.equal(horizontalPosition.rootKey, "wp:positionH"); assert.include(horizontalPosition.root[0].root, { - relativeFrom: "column", + relativeFrom: "page", }); assert.equal(horizontalPosition.root[1].rootKey, "wp:posOffset"); assert.include(horizontalPosition.root[1].root[0], 0); @@ -82,7 +100,7 @@ describe("Anchor", () => { const verticalPosition = newJson.root[3]; assert.equal(verticalPosition.rootKey, "wp:positionV"); assert.include(verticalPosition.root[0].root, { - relativeFrom: "paragraph", + relativeFrom: "page", }); assert.equal(verticalPosition.root[1].rootKey, "wp:posOffset"); assert.include(verticalPosition.root[1].root[0], 0); @@ -117,10 +135,18 @@ describe("Anchor", () => { }); it("should create a Drawing with square text wrapping", () => { - anchor = createDrawing({ + anchor = createAnchor({ textWrapping: { textWrapStyle: TextWrapStyle.SQUARE, }, + floating: { + verticalPosition: { + offset: 0, + }, + horizontalPosition: { + offset: 0, + }, + }, }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.root.length, 10); @@ -131,10 +157,18 @@ describe("Anchor", () => { }); it("should create a Drawing with no text wrapping", () => { - anchor = createDrawing({ + anchor = createAnchor({ textWrapping: { textWrapStyle: TextWrapStyle.NONE, }, + floating: { + verticalPosition: { + offset: 0, + }, + horizontalPosition: { + offset: 0, + }, + }, }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.root.length, 10); @@ -144,10 +178,18 @@ describe("Anchor", () => { }); it("should create a Drawing with tight text wrapping", () => { - anchor = createDrawing({ + anchor = createAnchor({ textWrapping: { textWrapStyle: TextWrapStyle.TIGHT, }, + floating: { + horizontalPosition: { + offset: 0, + }, + verticalPosition: { + offset: 0, + }, + }, }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.root.length, 10); @@ -157,10 +199,18 @@ describe("Anchor", () => { }); it("should create a Drawing with tight text wrapping", () => { - anchor = createDrawing({ + anchor = createAnchor({ textWrapping: { textWrapStyle: TextWrapStyle.TOP_AND_BOTTOM, }, + floating: { + verticalPosition: { + offset: 0, + }, + horizontalPosition: { + offset: 0, + }, + }, }); const newJson = Utility.jsonify(anchor); assert.equal(newJson.root.length, 10); diff --git a/src/file/drawing/anchor/anchor.ts b/src/file/drawing/anchor/anchor.ts index a000e9b311..b3b88ad1f6 100644 --- a/src/file/drawing/anchor/anchor.ts +++ b/src/file/drawing/anchor/anchor.ts @@ -2,14 +2,7 @@ import { IMediaData, IMediaDataDimensions } from "file/media"; import { XmlComponent } from "file/xml-components"; import { IDrawingOptions } from "../drawing"; -import { - HorizontalPosition, - HorizontalPositionRelativeFrom, - IFloating, - SimplePos, - VerticalPosition, - VerticalPositionRelativeFrom, -} from "../floating"; +import { HorizontalPosition, IFloating, SimplePos, VerticalPosition } from "../floating"; import { Graphic } from "../inline/graphic"; import { TextWrapStyle, WrapNone, WrapSquare, WrapTight, WrapTopAndBottom } from "../text-wrap"; import { DocProperties } from "./../doc-properties/doc-properties"; @@ -23,14 +16,8 @@ const defaultOptions: IFloating = { behindDocument: false, lockAnchor: false, layoutInCell: true, - verticalPosition: { - relative: VerticalPositionRelativeFrom.PARAGRAPH, - offset: 0, - }, - horizontalPosition: { - relative: HorizontalPositionRelativeFrom.COLUMN, - offset: 0, - }, + verticalPosition: {}, + horizontalPosition: {}, }; export class Anchor extends XmlComponent { diff --git a/src/file/drawing/drawing.spec.ts b/src/file/drawing/drawing.spec.ts index ea47d74422..5ab77f28d0 100644 --- a/src/file/drawing/drawing.spec.ts +++ b/src/file/drawing/drawing.spec.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { Utility } from "tests/utility"; -import { Drawing, IDrawingOptions, PlacementPosition } from "./drawing"; +import { Drawing, IDrawingOptions } from "./drawing"; const imageBase64Data = `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`; @@ -46,7 +46,14 @@ describe("Drawing", () => { it("should create a drawing with anchor element when there options are passed", () => { currentBreak = createDrawing({ - position: PlacementPosition.FLOATING, + floating: { + horizontalPosition: { + offset: 0, + }, + verticalPosition: { + offset: 0, + }, + }, }); const newJson = Utility.jsonify(currentBreak); assert.equal(newJson.root[0].rootKey, "wp:anchor"); diff --git a/src/file/drawing/drawing.ts b/src/file/drawing/drawing.ts index e2786cd8e9..e7474dd5c4 100644 --- a/src/file/drawing/drawing.ts +++ b/src/file/drawing/drawing.ts @@ -5,11 +5,6 @@ import { IFloating } from "./floating"; import { Inline } from "./inline"; import { ITextWrapping } from "./text-wrap"; -export enum PlacementPosition { - INLINE, - FLOATING, -} - export interface IDistance { readonly distT?: number; readonly distB?: number; @@ -18,31 +13,21 @@ export interface IDistance { } export interface IDrawingOptions { - readonly position?: PlacementPosition; readonly textWrapping?: ITextWrapping; readonly floating?: IFloating; } -const defaultDrawingOptions: IDrawingOptions = { - position: PlacementPosition.INLINE, -}; - export class Drawing extends XmlComponent { private readonly inline: Inline; - constructor(imageData: IMediaData, drawingOptions?: IDrawingOptions) { + constructor(imageData: IMediaData, drawingOptions: IDrawingOptions = {}) { super("w:drawing"); - const mergedOptions = { - ...defaultDrawingOptions, - ...drawingOptions, - }; - - if (mergedOptions.position === PlacementPosition.INLINE) { + if (!drawingOptions.floating) { this.inline = new Inline(imageData, imageData.dimensions); this.root.push(this.inline); - } else if (mergedOptions.position === PlacementPosition.FLOATING) { - this.root.push(new Anchor(imageData, imageData.dimensions, mergedOptions)); + } else { + this.root.push(new Anchor(imageData, imageData.dimensions, drawingOptions)); } } diff --git a/src/file/drawing/floating/floating-position.ts b/src/file/drawing/floating/floating-position.ts index 041bb94828..330264ba5c 100644 --- a/src/file/drawing/floating/floating-position.ts +++ b/src/file/drawing/floating/floating-position.ts @@ -39,13 +39,13 @@ export enum VerticalPositionAlign { } export interface IHorizontalPositionOptions { - readonly relative: HorizontalPositionRelativeFrom; + readonly relative?: HorizontalPositionRelativeFrom; readonly align?: HorizontalPositionAlign; readonly offset?: number; } export interface IVerticalPositionOptions { - readonly relative: VerticalPositionRelativeFrom; + readonly relative?: VerticalPositionRelativeFrom; readonly align?: VerticalPositionAlign; readonly offset?: number; } diff --git a/src/file/drawing/floating/horizontal-position.ts b/src/file/drawing/floating/horizontal-position.ts index a2d9f865f7..64f3e38e74 100644 --- a/src/file/drawing/floating/horizontal-position.ts +++ b/src/file/drawing/floating/horizontal-position.ts @@ -20,7 +20,7 @@ export class HorizontalPosition extends XmlComponent { this.root.push( new HorizontalPositionAttributes({ - relativeFrom: horizontalPosition.relative, + relativeFrom: horizontalPosition.relative || HorizontalPositionRelativeFrom.PAGE, }), ); diff --git a/src/file/drawing/floating/vertical-position.ts b/src/file/drawing/floating/vertical-position.ts index a030234109..bc4f6febe6 100644 --- a/src/file/drawing/floating/vertical-position.ts +++ b/src/file/drawing/floating/vertical-position.ts @@ -20,7 +20,7 @@ export class VerticalPosition extends XmlComponent { this.root.push( new VerticalPositionAttributes({ - relativeFrom: verticalPosition.relative, + relativeFrom: verticalPosition.relative || VerticalPositionRelativeFrom.PAGE, }), ); diff --git a/src/file/file.ts b/src/file/file.ts index 5f01d71dad..a74a2c284f 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -9,6 +9,7 @@ import { IHeaderFooterGroup, SectionPropertiesOptions, } from "./document/body/section-properties"; +import { IDrawingOptions } from "./drawing"; import { IFileProperties } from "./file-properties"; import { FooterWrapper, IDocumentFooter } from "./footer-wrapper"; import { FootNotes } from "./footnotes"; @@ -134,8 +135,13 @@ export class File { return this; } - public createImage(buffer: Buffer | string | Uint8Array | ArrayBuffer, width?: number, height?: number): Image { - const image = Media.addImage(this, buffer, width, height); + public createImage( + buffer: Buffer | string | Uint8Array | ArrayBuffer, + width?: number, + height?: number, + drawingOptions?: IDrawingOptions, + ): Image { + const image = Media.addImage(this, buffer, width, height, drawingOptions); this.document.addParagraph(image.Paragraph); return image; @@ -200,6 +206,19 @@ export class File { return headerWrapper; } + public createEvenPageHeader(): HeaderWrapper { + const headerWrapper = this.createHeader(); + + this.document.Body.DefaultSection.addChildElement( + new HeaderReference({ + headerType: HeaderReferenceType.EVEN, + headerId: headerWrapper.Header.ReferenceId, + }), + ); + + return headerWrapper; + } + public getFooterByReferenceNumber(refId: number): FooterWrapper { const entry = this.footers.map((item) => item.footer).find((h) => h.Footer.ReferenceId === refId); if (entry) {