diff --git a/demo/demo12.js b/demo/demo12.js new file mode 100644 index 0000000000..effd9166ff --- /dev/null +++ b/demo/demo12.js @@ -0,0 +1,21 @@ +const docx = require("../build"); + +var doc = new docx.Document(); + +var paragraph = new docx.Paragraph("Hello World"); +doc.addParagraph(paragraph); + +const image = doc.createImage("./demo/images/pizza.gif"); +const image2 = doc.createImage("./demo/images/pizza.gif"); +const image3 = doc.createImage("./demo/images/pizza.gif"); +const image4 = doc.createImage("./demo/images/pizza.gif"); + +image.scale(0.5); +image2.scale(1) +image4.scale(2.5); +image4.scale(4); + +var exporter = new docx.LocalPacker(doc); +exporter.pack("My Document"); + +console.log("Document created successfully at project root!"); diff --git a/src/file/document/document.ts b/src/file/document/document.ts index f4d580b9ca..fcf52ec27d 100644 --- a/src/file/document/document.ts +++ b/src/file/document/document.ts @@ -57,17 +57,17 @@ export class Document extends XmlComponent { return table; } - public addDrawing(imageData: IMediaData): void { + public addDrawing(pictureParagraph: Paragraph): void { + this.body.push(pictureParagraph); + } + + public createDrawing(imageData: IMediaData): PictureRun { const paragraph = new Paragraph(); const run = new PictureRun(imageData); + paragraph.addRun(run); + this.addDrawing(paragraph); - this.body.push(paragraph); - } - - public createDrawing(imageData: IMediaData): void { - this.addDrawing(imageData); - - return; + return run; } } diff --git a/src/file/drawing/drawing.ts b/src/file/drawing/drawing.ts index e6dab2f4d1..61c93592df 100644 --- a/src/file/drawing/drawing.ts +++ b/src/file/drawing/drawing.ts @@ -3,6 +3,8 @@ import { XmlComponent } from "file/xml-components"; import { Inline } from "./inline"; export class Drawing extends XmlComponent { + private inline: Inline; + constructor(imageData: IMediaData) { super("w:drawing"); @@ -10,6 +12,12 @@ export class Drawing extends XmlComponent { throw new Error("imageData cannot be undefined"); } - this.root.push(new Inline(imageData.referenceId, imageData.dimensions)); + this.inline = new Inline(imageData.referenceId, imageData.dimensions); + + this.root.push(this.inline); + } + + public scale(factorX: number, factorY: number): void { + this.inline.scale(factorX, factorY); } } diff --git a/src/file/drawing/inline/extent/extent.ts b/src/file/drawing/inline/extent/extent.ts index 8602cc4afe..0e22348cf1 100644 --- a/src/file/drawing/inline/extent/extent.ts +++ b/src/file/drawing/inline/extent/extent.ts @@ -2,14 +2,23 @@ import { XmlComponent } from "file/xml-components"; import { ExtentAttributes } from "./extent-attributes"; export class Extent extends XmlComponent { + private attributes: ExtentAttributes; + constructor(x: number, y: number) { super("wp:extent"); - this.root.push( - new ExtentAttributes({ - cx: x, - cy: y, - }), - ); + this.attributes = new ExtentAttributes({ + cx: x, + cy: y, + }); + + this.root.push(this.attributes); + } + + public setXY(x: number, y: number): void { + this.attributes.set({ + cx: x, + cy: y, + }); } } diff --git a/src/file/drawing/inline/graphic/graphic-data/graphic-data.ts b/src/file/drawing/inline/graphic/graphic-data/graphic-data.ts index abc75e3a04..ca3d4600be 100644 --- a/src/file/drawing/inline/graphic/graphic-data/graphic-data.ts +++ b/src/file/drawing/inline/graphic/graphic-data/graphic-data.ts @@ -3,6 +3,8 @@ import { GraphicDataAttributes } from "./graphic-data-attribute"; import { Pic } from "./pic"; export class GraphicData extends XmlComponent { + private pic: Pic; + constructor(referenceId: number, x: number, y: number) { super("a:graphicData"); @@ -12,6 +14,12 @@ export class GraphicData extends XmlComponent { }), ); - this.root.push(new Pic(referenceId, x, y)); + this.pic = new Pic(referenceId, x, y); + + this.root.push(this.pic); + } + + public setXY(x: number, y: number): void { + this.pic.setXY(x, y); } } diff --git a/src/file/drawing/inline/graphic/graphic-data/pic/pic.ts b/src/file/drawing/inline/graphic/graphic-data/pic/pic.ts index 98f70b4609..f8b555af00 100644 --- a/src/file/drawing/inline/graphic/graphic-data/pic/pic.ts +++ b/src/file/drawing/inline/graphic/graphic-data/pic/pic.ts @@ -6,6 +6,8 @@ import { PicAttributes } from "./pic-attributes"; import { ShapeProperties } from "./shape-properties/shape-properties"; export class Pic extends XmlComponent { + private shapeProperties: ShapeProperties; + constructor(referenceId: number, x: number, y: number) { super("pic:pic"); @@ -14,8 +16,15 @@ export class Pic extends XmlComponent { xmlns: "http://schemas.openxmlformats.org/drawingml/2006/picture", }), ); + + this.shapeProperties = new ShapeProperties(x, y); + this.root.push(new NonVisualPicProperties()); this.root.push(new BlipFill(referenceId)); this.root.push(new ShapeProperties(x, y)); } + + public setXY(x: number, y: number): void { + this.shapeProperties.setXY(x, y); + } } diff --git a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/extents/extents.ts b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/extents/extents.ts index bfcb052f72..74aea18a48 100644 --- a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/extents/extents.ts +++ b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/extents/extents.ts @@ -3,14 +3,23 @@ import { XmlComponent } from "file/xml-components"; import { ExtentsAttributes } from "./extents-attributes"; export class Extents extends XmlComponent { + private attributes: ExtentsAttributes; + constructor(x: number, y: number) { super("a:ext"); - this.root.push( - new ExtentsAttributes({ - cx: x, - cy: y, - }), - ); + this.attributes = new ExtentsAttributes({ + cx: x, + cy: y, + }); + + this.root.push(this.attributes); + } + + public setXY(x: number, y: number): void { + this.attributes.set({ + cx: x, + cy: y, + }); } } diff --git a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/form.ts b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/form.ts index 1d0aefbd7e..06523e0965 100644 --- a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/form.ts +++ b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/form/form.ts @@ -4,10 +4,18 @@ import { Extents } from "./extents/extents"; import { Offset } from "./offset/off"; export class Form extends XmlComponent { + private extents: Extents; + constructor(x: number, y: number) { super("a:xfrm"); - this.root.push(new Extents(x, y)); + this.extents = new Extents(x, y); + + this.root.push(this.extents); this.root.push(new Offset()); } + + public setXY(x: number, y: number): void { + this.extents.setXY(x, y); + } } diff --git a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/shape-properties.ts b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/shape-properties.ts index 5a245ca0f6..9c910f62e2 100644 --- a/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/shape-properties.ts +++ b/src/file/drawing/inline/graphic/graphic-data/pic/shape-properties/shape-properties.ts @@ -7,6 +7,8 @@ import { PresetGeometry } from "./preset-geometry/preset-geometry"; import { ShapePropertiesAttributes } from "./shape-properties-attributes"; export class ShapeProperties extends XmlComponent { + private form: Form; + constructor(x: number, y: number) { super("pic:spPr"); @@ -16,9 +18,15 @@ export class ShapeProperties extends XmlComponent { }), ); - this.root.push(new Form(x, y)); + this.form = new Form(x, y); + + this.root.push(this.form); this.root.push(new PresetGeometry()); // this.root.push(new NoFill()); // this.root.push(new Outline()); } + + public setXY(x: number, y: number): void { + this.form.setXY(x, y); + } } diff --git a/src/file/drawing/inline/graphic/graphic.ts b/src/file/drawing/inline/graphic/graphic.ts new file mode 100644 index 0000000000..ce61893e05 --- /dev/null +++ b/src/file/drawing/inline/graphic/graphic.ts @@ -0,0 +1,33 @@ +import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; +import { GraphicData } from "./graphic-data"; + +interface IGraphicProperties { + a: string; +} + +class GraphicAttributes extends XmlAttributeComponent { + protected xmlKeys = { + a: "xmlns:a", + }; +} + +export class Graphic extends XmlComponent { + private data: GraphicData; + + constructor(referenceId: number, x: number, y: number) { + super("a:graphic"); + this.root.push( + new GraphicAttributes({ + a: "http://schemas.openxmlformats.org/drawingml/2006/main", + }), + ); + + this.data = new GraphicData(referenceId, x, y); + + this.root.push(this.data); + } + + public setXY(x: number, y: number): void { + this.data.setXY(x, y); + } +} diff --git a/src/file/drawing/inline/graphic/index.ts b/src/file/drawing/inline/graphic/index.ts index 1e0f330932..246194dba6 100644 --- a/src/file/drawing/inline/graphic/index.ts +++ b/src/file/drawing/inline/graphic/index.ts @@ -1,24 +1 @@ -import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; -import { GraphicData } from "./graphic-data"; - -interface IGraphicProperties { - a: string; -} - -class GraphicAttributes extends XmlAttributeComponent { - protected xmlKeys = { - a: "xmlns:a", - }; -} - -export class Graphic extends XmlComponent { - constructor(referenceId: number, x: number, y: number) { - super("a:graphic"); - this.root.push( - new GraphicAttributes({ - a: "http://schemas.openxmlformats.org/drawingml/2006/main", - }), - ); - this.root.push(new GraphicData(referenceId, x, y)); - } -} +export * from "./graphic"; diff --git a/src/file/drawing/inline/inline.ts b/src/file/drawing/inline/inline.ts index 6bde46d8d9..d7b838844c 100644 --- a/src/file/drawing/inline/inline.ts +++ b/src/file/drawing/inline/inline.ts @@ -9,7 +9,10 @@ import { GraphicFrameProperties } from "./graphic-frame/graphic-frame-properties import { InlineAttributes } from "./inline-attributes"; export class Inline extends XmlComponent { - constructor(referenceId: number, dimensions: IMediaDataDimensions) { + private extent: Extent; + private graphic: Graphic; + + constructor(referenceId: number, private dimensions: IMediaDataDimensions) { super("wp:inline"); this.root.push( @@ -21,10 +24,21 @@ export class Inline extends XmlComponent { }), ); - this.root.push(new Extent(dimensions.emus.x, dimensions.emus.y)); + this.extent = new Extent(dimensions.emus.x, dimensions.emus.y); + this.graphic = new Graphic(referenceId, dimensions.emus.x, dimensions.emus.y); + + this.root.push(this.extent); this.root.push(new EffectExtent()); this.root.push(new DocProperties()); this.root.push(new GraphicFrameProperties()); - this.root.push(new Graphic(referenceId, dimensions.emus.x, dimensions.emus.y)); + this.root.push(this.graphic); + } + + public scale(factorX: number, factorY: number): void { + const newX = this.dimensions.emus.x * factorX; + const newY = this.dimensions.emus.y * factorY; + + this.extent.setXY(newX, newY); + this.graphic.setXY(newX, newY); } } diff --git a/src/file/file.ts b/src/file/file.ts index 81cc8405fb..67393a8c6f 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -7,7 +7,7 @@ import { FooterWrapper } from "./footer-wrapper"; import { HeaderWrapper } from "./header-wrapper"; import { Media } from "./media"; import { Numbering } from "./numbering"; -import { Paragraph } from "./paragraph"; +import { Paragraph, PictureRun } from "./paragraph"; import { Relationships } from "./relationships"; import { Styles } from "./styles"; import { DefaultStylesFactory } from "./styles/factory"; @@ -101,14 +101,14 @@ export class File { return this.document.createTable(rows, cols); } - public createImage(image: string): void { + public createImage(image: string): PictureRun { const mediaData = this.media.addMedia(image, this.docRelationships.RelationshipCount); this.docRelationships.createRelationship( mediaData.referenceId, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", `media/${mediaData.fileName}`, ); - this.document.createDrawing(mediaData); + return this.document.createDrawing(mediaData); } public get Document(): Document { diff --git a/src/file/paragraph/run/picture-run.ts b/src/file/paragraph/run/picture-run.ts index b949dc023e..1b256ea20d 100644 --- a/src/file/paragraph/run/picture-run.ts +++ b/src/file/paragraph/run/picture-run.ts @@ -3,6 +3,8 @@ import { IMediaData } from "../../media/data"; import { Run } from "../run"; export class PictureRun extends Run { + private drawing: Drawing; + constructor(imageData: IMediaData) { super(); @@ -10,6 +12,20 @@ export class PictureRun extends Run { throw new Error("imageData cannot be undefined"); } - this.root.push(new Drawing(imageData)); + this.drawing = new Drawing(imageData); + + this.root.push(this.drawing); + } + + public scale(factorX: number, factorY?: number): void { + if (!factorX) { + factorX = 1; + } + + if (!factorY) { + factorY = factorX; + } + + this.drawing.scale(factorX, factorY); } } diff --git a/src/file/xml-components/default-attributes.ts b/src/file/xml-components/default-attributes.ts index 2415124584..482546b59d 100644 --- a/src/file/xml-components/default-attributes.ts +++ b/src/file/xml-components/default-attributes.ts @@ -23,4 +23,8 @@ export abstract class XmlAttributeComponent extends BaseXmlComponent { }); return { _attr: attrs }; } + + public set(properties: T): void { + this.root = properties; + } }