Compare commits

..

147 Commits
2.1.0 ... 3.2.0

Author SHA1 Message Date
cb8e9fdd36 Version bump 2018-02-08 01:19:00 +00:00
53ce3c1526 Formatting 2018-02-08 00:52:05 +00:00
a78f06b41b Remove all references to template 2018-02-08 00:12:59 +00:00
ce7ef30806 Fix Prettier styling changes 2018-02-05 01:44:28 +00:00
fd93c0776a Fix tests 2018-02-04 01:43:10 +00:00
6a762c6c0e Rename properties to core properties 2018-02-04 01:43:03 +00:00
23c5aef276 Add file relationships 2018-02-04 00:58:34 +00:00
69707a7207 Add more content type files 2018-02-03 20:56:20 +00:00
cfd3505414 Add content types initial files 2018-02-02 01:57:50 +00:00
ee958dc351 Fix exported type definitions 2018-02-02 01:56:08 +00:00
680f2325a3 Pin typescript version 2018-02-01 00:16:00 +00:00
2f0ad3eeb2 Add and fix tests 2018-01-31 23:24:55 +00:00
c895a9c7d9 Version bump 2018-01-31 21:10:15 +00:00
388a8404f5 Rename for further workaround 2018-01-31 20:12:09 +00:00
320cb1c418 Add workaround for files which only have an interface 2018-01-31 20:08:36 +00:00
8a6b73915f Update typescript 2018-01-31 19:09:30 +00:00
774355d608 Fix tests 2018-01-31 01:23:13 +00:00
35dbce3a68 Add File alias to Document for backwards compatability 2018-01-31 00:32:13 +00:00
6d0a267ba4 Add Header and Footer wrapper for their own relationship classes 2018-01-31 00:31:54 +00:00
df701be572 Merge pull request #58 from dolanmiu/feat/update-archiver
Update dependency
2018-01-30 01:47:20 +00:00
1edad47e6e Update dependency 2018-01-30 01:43:17 +00:00
c873abfe18 Fix referenceId +1 error and spelling mistakes
Add demo
2018-01-30 01:16:48 +00:00
989446ef36 Add tests 2018-01-29 23:09:54 +00:00
fc6daed620 Merge pull request #57 from dolanmiu/feat/footer
Add footer
2018-01-29 22:00:12 +00:00
5e921f1dfc Add footer 2018-01-29 21:53:22 +00:00
45bbf1b693 Merge pull request #56 from dolanmiu/feat/header
Feat/header
2018-01-29 03:00:07 +00:00
8b8c664f0f Add header objects and demo 2018-01-29 02:56:35 +00:00
079334f71b Make fields readonly 2018-01-29 01:55:25 +00:00
3fe0c76d54 Add header to type 2018-01-29 01:54:50 +00:00
1e55a3e6a8 Expose header 2018-01-29 01:54:10 +00:00
950a2f8b53 Add header class 2018-01-28 22:32:51 +00:00
bbe2e1e46e Fix styles 2018-01-28 20:34:49 +00:00
635c58c131 Fix tests 2018-01-28 20:23:30 +00:00
ba39d806b7 Add more demos to CI 2018-01-25 01:50:30 +00:00
355e97cb5e Landscape mode 2018-01-25 01:47:47 +00:00
4339f8cfc0 Add section properties 2018-01-25 01:21:03 +00:00
448572d7a1 Add section properties to root File 2018-01-24 13:09:34 +00:00
2132c7b6da Add watch to tests 2018-01-24 13:08:34 +00:00
d0bd83d6c5 Fix tests 2018-01-24 13:08:22 +00:00
1037b7c23d Merge branch 'master' of https://github.com/dolanmiu/docx 2018-01-24 00:04:29 +00:00
df197f73ea Create section properties section 2018-01-24 00:01:38 +00:00
ea08f603f5 Add build command before demos 2018-01-23 11:28:27 +00:00
fa2f1235f7 Run each demo in test 2018-01-23 11:24:44 +00:00
ff5d02c964 Add prettier badge 2018-01-23 01:36:27 +00:00
e93d6799fd Made project Prettier compliant 2018-01-23 01:33:12 +00:00
f2027230a0 Add prettier + style command 2018-01-22 23:38:49 +00:00
cb47d4f772 Merge pull request #55 from dolanmiu/feat/file-wrapper
Feat/file wrapper
2018-01-22 23:07:05 +00:00
eebc9fbcfa Merge pull request #51 from dolanmiu/feat/images
Feat/images support
2018-01-22 22:40:23 +00:00
0e698491f3 Merge pull request #52 from dolanmiu/feat/file-wrapper
Feat/file wrapper
2018-01-22 22:40:00 +00:00
ae52e8fabb Add gif support 2018-01-22 22:17:17 +00:00
ccd655ef8b Add support for jpg and bmp 2018-01-22 22:12:33 +00:00
3dc6e71aaf Add png support 2018-01-22 22:05:20 +00:00
e6d3577f74 Rename penguin 2018-01-22 21:34:09 +00:00
ef05024f2f Add image dimensions 2018-01-22 20:42:57 +00:00
d3bc784248 Add types to image-size 2018-01-22 20:42:33 +00:00
979701331e Install image-size 2018-01-22 19:34:30 +00:00
76b1682296 Put media in correct location 2018-01-22 00:53:22 +00:00
7c31b72f99 Got docx not crashing when adding image 2018-01-16 01:31:47 +00:00
f7c2072cff Progress on embeddding image 2018-01-16 00:43:00 +00:00
392db1cd11 Add more graphic files 2018-01-12 00:12:39 +00:00
ca244bcfe1 Add more files for creating a drawing 2018-01-11 01:47:09 +00:00
2d02f51f25 Offset reference id a little 2018-01-10 00:35:26 +00:00
592fb5ca9f Add dynamic relationships 2018-01-10 00:29:17 +00:00
a3945bc7f1 Media addMedia method 2018-01-09 21:57:10 +00:00
2adde9830c Add image demo 2018-01-09 21:54:48 +00:00
0355afe11c Rename IData to something more reasonable 2017-12-30 21:18:55 +00:00
998fe3f370 Made index into barrel and made seperate drawing file 2017-12-30 20:59:05 +00:00
eb71fc20e6 Use absolute path rather than silly relative path 2017-12-30 20:25:16 +00:00
ab348bd5f9 Add build before typedoc 2017-12-30 20:02:44 +00:00
c518d1c6c7 Fix tests using new mocha-webpack 2017-12-30 20:01:20 +00:00
d8d16b4a7d Absolute path imports! 2017-12-29 02:26:26 +00:00
928e4b9bc2 Turn off sourceRoot to hotfix typedoc 2017-12-29 02:06:44 +00:00
4f900d6566 Update typedoc 2017-12-29 02:05:34 +00:00
362a997187 Redundant library specification 2017-12-29 01:48:46 +00:00
89c658746d Use webpack as the main builder 2017-12-29 01:46:31 +00:00
75d699f7ef Enable dirname 2017-12-29 01:45:33 +00:00
f7412690b6 Fix library export 2017-12-29 01:36:42 +00:00
ece2b23407 Export as a library 2017-12-29 01:16:45 +00:00
f84af9a44b Move tsconfig files to root, and made webpack config build 2017-12-29 01:11:59 +00:00
90dc1103f6 Experimental webpack support 2017-12-22 16:49:25 +00:00
c469fb24db Fix imports 2017-12-20 01:41:53 +00:00
32be6e36da Add package-lock to ignore 2017-12-20 01:41:32 +00:00
b34ad22ad6 Add editorconfig 2017-12-20 01:40:52 +00:00
2358139a6b Change docx folder to more appropriate "file" folder 2017-12-20 01:03:20 +00:00
43ebfe7a2f Move properties to sub folder 2017-12-20 00:58:24 +00:00
0b8094dea8 Move styles to sub folder 2017-12-20 00:52:41 +00:00
f1d1570b10 Move relationships to sub folder 2017-12-20 00:09:01 +00:00
e9e68bc802 Move media to sub folder 2017-12-20 00:06:08 +00:00
4c369510ce Move numbering into sub folder 2017-12-20 00:01:23 +00:00
96413d6c47 Fix lint 2017-12-19 23:14:23 +00:00
df6c7cf19f Re-order package 2017-12-19 23:13:11 +00:00
49fc28d86c Updated demos 2017-12-19 21:49:44 +00:00
cc67a83ce8 For importing absolute path in future 2017-12-19 21:42:17 +00:00
742e2b5089 Make compiler take in a file 2017-12-15 02:15:44 +00:00
d19ff1e300 Add file class 2017-12-15 01:16:04 +00:00
01950ed443 Move ts to src folder for standards 2017-12-15 00:01:59 +00:00
cf1689a3c2 Version bump 2017-12-06 01:39:40 +00:00
66d0bab0a5 Add packPdf reference 2017-12-06 01:39:24 +00:00
5889f20f1e Simplify tests and made compile async 2017-12-06 01:32:57 +00:00
ebec10e312 Refactor 2017-12-06 01:03:14 +00:00
ae8a0c7fd0 Edit Tslint 2017-12-05 23:43:19 +00:00
bb49200fad Clean up code using request promise 2017-12-05 02:24:49 +00:00
a6bba0bc6c Enable pdf export 2017-12-05 00:16:21 +00:00
fb08f79344 Add initial conversion 2017-11-10 14:27:57 +00:00
741c74825e Class definition for Pdf converter wrapper 2017-09-30 18:23:02 +01:00
28539cd47b Initial scaffold of pdf convert 2017-09-30 18:15:33 +01:00
8ca7c5a343 Add test 2017-09-30 18:00:06 +01:00
32b56e7071 Move sub components of Paragraph into own folder 2017-09-30 01:52:37 +01:00
7dad717952 Add documentation links 2017-09-22 14:46:19 +01:00
34e928755f Add documentation links 2017-09-21 14:56:46 +01:00
51e0f311fe Refactor numbering into its own file 2017-09-20 13:37:39 +01:00
cc9dff6b94 Version bump 2017-09-19 16:02:32 +01:00
101cc0fdea Add docx keyword to package 2017-09-19 16:02:06 +01:00
d408262fa8 Remove unused class 2017-09-19 15:58:37 +01:00
ed53c30f42 Remove template file and placed in the Wiki
https://github.com/dolanmiu/docx/wiki/Contributing-Guidelines
2017-09-19 15:56:52 +01:00
ebbf6a99c1 Make exporting more consistent 2017-09-19 15:51:55 +01:00
b98c103e45 Export table into own file 2017-09-19 15:49:27 +01:00
518fec0595 Export like standard style 2017-09-19 15:47:29 +01:00
659936f3f0 Refactor xml component into own class 2017-09-19 15:46:20 +01:00
b0febf5054 Refactor run into own file 2017-09-19 15:42:40 +01:00
56b951a2b1 Refactor body into own file 2017-09-19 15:39:14 +01:00
a3a9958a69 Refactor document into own file 2017-09-19 15:36:41 +01:00
4f36bbf426 Refactor paragraph into its own file
Create barrel
2017-09-19 15:21:07 +01:00
357bc7f377 Add documentation reference 2017-09-19 15:17:58 +01:00
da8405b5b9 Add Right and Center tab stops 2017-09-19 12:51:37 +01:00
492face7ab 3.0.0 2017-09-17 00:20:18 +01:00
b6351f0260 Merge branch 'jacwright-indent-bc' 2017-09-17 00:09:57 +01:00
3a7f9053b9 Allow indent to use other options than left and hanging
This is a breaking change. Existing code using indent will break when padding in the number for left.
2017-09-16 17:05:40 -06:00
19b122684c Add lint to Travis
Fix linting
2017-09-17 00:01:09 +01:00
72e89cfc3c Move tests to respective folders as .spec
This is to keep to standards
2017-09-17 00:00:41 +01:00
5ae02c3342 Merge pull request #43 from jacwright/default-run-styles
Making it easier to work with default styles
2017-09-16 17:48:37 +01:00
258adba94c Version bump 2017-09-16 17:48:15 +01:00
190208d5df Making it easier to work with default styles
Adds the likely common styles, font and size, to be defined in defaults.
2017-09-16 08:24:15 -06:00
32cda4dfb3 Merge pull request #42 from jacwright/patch-1-test
Fix tests
2017-09-15 16:09:18 +01:00
b2c3dd2f7b Fix tests 2017-09-15 09:05:28 -06:00
58eca3ff5b Merge pull request #41 from jacwright/patch-1
Fix page/thematic breaks
2017-09-15 15:57:22 +01:00
d5c04f9042 Pin typescript to 2.4.1 2017-09-15 15:56:21 +01:00
67ea7c95de Just pagebreak, update test 2017-09-15 08:37:57 -06:00
e57fd8fc57 Fix page/thematic breaks
These items are not paragraph properties, but part of the content of the paragraph.
2017-09-15 08:25:43 -06:00
411c0dadb5 Add table demo 2017-07-29 01:58:29 +01:00
ee81f3c502 Version bump 2017-07-29 01:26:34 +01:00
8263b93c36 Add third demo 2017-07-29 01:26:04 +01:00
be709d082c Export formatting from paragraph folder 2017-07-29 01:15:33 +01:00
70c4e89a65 Version bump 2017-07-08 21:37:02 +01:00
8f632d4ecd Made XmlableObject non ambient typings to fix typescript problem 2017-07-08 20:45:19 +01:00
6784dc1f3d Updated archiver types 2017-07-08 01:24:25 +01:00
fd63a30298 Updated definitions 2017-07-07 16:51:22 +01:00
261 changed files with 4561 additions and 2664 deletions

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

12
.gitignore vendored
View File

@ -36,5 +36,13 @@ node_modules
build build
build-tests build-tests
# vscode # VSCode
.vscode .vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history
# Lock files
package-lock.json

View File

@ -4,7 +4,17 @@ node_js:
install: install:
- npm install - npm install
script: script:
- npm run lint
- npm test - npm test
- npm run style
- npm run build
- node ./demo/demo1.js
- node ./demo/demo2.js
- node ./demo/demo3.js
- node ./demo/demo4.js
- node ./demo/demo5.js
- node ./demo/demo6.js
- node ./demo/demo7.js
after_failure: after_failure:
- "cat /home/travis/builds/dolanmiu/docx/npm-debug.log" - "cat /home/travis/builds/dolanmiu/docx/npm-debug.log"
after_success: after_success:

9
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
"cSpell.words": ["clippy", "docx", "dolan", "miu", "officegen", "typedoc"],
"prettier.trailingComma": "all",
"prettier.printWidth": 140,
"editor.formatOnSave": false,
"prettier.tabWidth": 4,
"prettier.arrowParens": "always",
"prettier.bracketSpacing": true
}

View File

@ -8,7 +8,12 @@
----- -----
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][gemnasium-image]][gemnasium-url] [![Known Vulnerabilities][snky-image]][snky-url] [![Chat on Gitter][gitter-image]][gitter-url] [![NPM version][npm-image]][npm-url]
[![Build Status][travis-image]][travis-url]
[![Dependency Status][gemnasium-image]][gemnasium-url]
[![Known Vulnerabilities][snky-image]][snky-url]
[![Chat on Gitter][gitter-image]][gitter-url]
[![code style: prettier][prettier-image]][prettier-url]
[![NPM](https://nodei.co/npm/docx.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/docx/) [![NPM](https://nodei.co/npm/docx.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/docx/)
@ -57,6 +62,8 @@ var exporter = new docx.LocalPacker(doc);
var exporter = new docx.ExpressPacker(doc, res); var exporter = new docx.ExpressPacker(doc, res);
exporter.pack('My First Document'); exporter.pack('My First Document');
// If you want to export it as a .pdf file instead
exporter.packPdf('My First Document');
// done! A file called 'My First Document.docx' // done! A file called 'My First Document.docx'
// will be in your file system if you used LocalPacker // will be in your file system if you used LocalPacker
@ -66,6 +73,10 @@ exporter.pack('My First Document');
## Examples ## Examples
Check [the Wiki](https://github.com/dolanmiu/docx/wiki/Examples) for examples. Check [the Wiki](https://github.com/dolanmiu/docx/wiki/Examples) for examples.
# Contributing
Read the contribution guidelines [here](https://github.com/dolanmiu/docx/wiki/Contributing-Guidelines).
----- -----
Made with 💖 Made with 💖
@ -84,4 +95,5 @@ Huge thanks to [@felipeochoa](https://github.com/felipeochoa) for awesome contri
[gitter-url]: https://gitter.im/docx-lib/Lobby [gitter-url]: https://gitter.im/docx-lib/Lobby
[gemnasium-image]: https://gemnasium.com/badges/github.com/dolanmiu/docx.svg [gemnasium-image]: https://gemnasium.com/badges/github.com/dolanmiu/docx.svg
[gemnasium-url]: https://gemnasium.com/github.com/dolanmiu/docx [gemnasium-url]: https://gemnasium.com/github.com/dolanmiu/docx
[prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg
[prettier-url]: https://github.com/prettier/prettier

View File

@ -10,13 +10,7 @@ paragraph.addRun(dateText);
doc.addParagraph(paragraph); doc.addParagraph(paragraph);
// Feature coming soon
// var media = new docx.Media();
// media.addMedia("happy-penguins", "./demo/penguins.jpg");
// var pictureRun = new docx.PictureRun(media.getMedia("happy-penguins"));
// var exporter = new docx.LocalPacker(doc);
var exporter = new docx.LocalPacker(doc); var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document'); exporter.pack('My Document');
console.log('Document created succesfully at project root!'); console.log('Document created successfully at project root!');

View File

@ -1,7 +1,12 @@
const docx = require('../build'); const docx = require('../build');
const styles = new docx.Styles(); const doc = new docx.Document({
styles.createParagraphStyle('Heading1', 'Heading 1') creator: 'Clippy',
title: 'Sample Document',
description: 'A brief example of using docx',
});
doc.Styles.createParagraphStyle('Heading1', 'Heading 1')
.basedOn("Normal") .basedOn("Normal")
.next("Normal") .next("Normal")
.quickFormat() .quickFormat()
@ -10,7 +15,7 @@ styles.createParagraphStyle('Heading1', 'Heading 1')
.italics() .italics()
.spacing({after: 120}); .spacing({after: 120});
styles.createParagraphStyle('Heading2', 'Heading 2') doc.Styles.createParagraphStyle('Heading2', 'Heading 2')
.basedOn("Normal") .basedOn("Normal")
.next("Normal") .next("Normal")
.quickFormat() .quickFormat()
@ -19,7 +24,7 @@ styles.createParagraphStyle('Heading2', 'Heading 2')
.underline('double', 'FF0000') .underline('double', 'FF0000')
.spacing({before: 240, after: 120}); .spacing({before: 240, after: 120});
styles.createParagraphStyle('aside', 'Aside') doc.Styles.createParagraphStyle('aside', 'Aside')
.basedOn('Normal') .basedOn('Normal')
.next('Normal') .next('Normal')
.color('999999') .color('999999')
@ -27,31 +32,24 @@ styles.createParagraphStyle('aside', 'Aside')
.indent(720) .indent(720)
.spacing({line: 276}); .spacing({line: 276});
styles.createParagraphStyle('wellSpaced', 'Well Spaced') doc.Styles.createParagraphStyle('wellSpaced', 'Well Spaced')
.basedOn('Normal') .basedOn('Normal')
.spacing({line: 276, before: 20 * 72 * .1, after: 20 * 72 * .05}); .spacing({line: 276, before: 20 * 72 * .1, after: 20 * 72 * .05});
styles.createParagraphStyle('ListParagraph', 'List Paragraph') doc.Styles.createParagraphStyle('ListParagraph', 'List Paragraph')
.quickFormat() .quickFormat()
.basedOn('Normal'); .basedOn('Normal');
const numbering = new docx.Numbering(); const numberedAbstract = doc.Numbering.createAbstractNumbering();
const numberedAbstract = numbering.createAbstractNumbering();
numberedAbstract.createLevel(0, "lowerLetter", "%1)", "left"); numberedAbstract.createLevel(0, "lowerLetter", "%1)", "left");
const doc = new docx.Document({
creator: 'Clippy',
title: 'Sample Document',
description: 'A brief example of using docx',
});
doc.createParagraph('Test heading1, bold and italicized').heading1(); doc.createParagraph('Test heading1, bold and italicized').heading1();
doc.createParagraph('Some simple content'); doc.createParagraph('Some simple content');
doc.createParagraph('Test heading2 with double red underline').heading2(); doc.createParagraph('Test heading2 with double red underline').heading2();
const letterNumbering = numbering.createConcreteNumbering(numberedAbstract); const letterNumbering = doc.Numbering.createConcreteNumbering(numberedAbstract);
const letterNumbering5 = numbering.createConcreteNumbering(numberedAbstract); const letterNumbering5 = doc.Numbering.createConcreteNumbering(numberedAbstract);
letterNumbering5.overrideLevel(0, 5); letterNumbering5.overrideLevel(0, 5);
doc.createParagraph('Option1').setNumbering(letterNumbering, 0); doc.createParagraph('Option1').setNumbering(letterNumbering, 0);
@ -70,5 +68,7 @@ para.createTextRun(' switching to normal ');
para.createTextRun('and then underlined ').underline(); para.createTextRun('and then underlined ').underline();
para.createTextRun('and back to normal.'); para.createTextRun('and back to normal.');
const exporter = new docx.LocalPacker(doc, styles, undefined, numbering); const exporter = new docx.LocalPacker(doc);
exporter.pack('test.docx'); exporter.pack('My Document');
console.log('Document created successfully at project root!');

35
demo/demo3.js Normal file
View File

@ -0,0 +1,35 @@
const docx = require('../build');
var doc = new docx.Document();
const numbering = new docx.Numbering();
const abstractNum = numbering.createAbstractNumbering();
abstractNum.createLevel(0, "upperRoman", "%1", "start")
.addParagraphProperty(new docx.Indent(720, 260));
abstractNum.createLevel(1, "decimal", "%2.", "start")
.addParagraphProperty(new docx.Indent(1440, 980));
abstractNum.createLevel(2, "lowerLetter", "%3)", "start")
.addParagraphProperty(new docx.Indent(2160, 1700));
const concrete = numbering.createConcreteNumbering(abstractNum);
var topLevelP = new docx.Paragraph("Hey you");
var subP = new docx.Paragraph("What's up fam");
var secondSubP = new docx.Paragraph("Hello World 2");
var subSubP = new docx.Paragraph("Yeah boi");
topLevelP.setNumbering(concrete, 0);
subP.setNumbering(concrete, 1);
secondSubP.setNumbering(concrete, 1);
subSubP.setNumbering(concrete, 2);
doc.addParagraph(topLevelP);
doc.addParagraph(subP);
doc.addParagraph(secondSubP);
doc.addParagraph(subSubP);
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

12
demo/demo4.js Normal file
View File

@ -0,0 +1,12 @@
const docx = require('../build');
var doc = new docx.Document();
const table = doc.createTable(4, 4);
table.getCell(2, 2).addContent(new docx.Paragraph('Hello'));
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

17
demo/demo5.js Normal file
View File

@ -0,0 +1,17 @@
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/image1.jpeg");
const image2 = doc.createImage("./demo/images/dog.png");
const image3 = doc.createImage("./demo/images/cat.jpg");
const image4 = doc.createImage("./demo/images/parrots.bmp");
const image5 = doc.createImage("./demo/images/pizza.gif");
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

25
demo/demo6.js Normal file
View File

@ -0,0 +1,25 @@
const docx = require("../build");
var doc = new docx.Document(undefined, {
top: 0,
right: 0,
bottom: 0,
left: 0,
});
var paragraph = new docx.Paragraph("Hello World");
var institutionText = new docx.TextRun("University College London").bold();
var dateText = new docx.TextRun("5th Dec 2015").tab().bold();
paragraph.addRun(institutionText);
paragraph.addRun(dateText);
doc.addParagraph(paragraph);
doc.createParagraph("Hello World").heading1();
doc.createParagraph("University College London");
doc.createParagraph("5th Dec 2015");
var exporter = new docx.LocalPacker(doc);
exporter.pack("My Document");
console.log("Document created successfully at project root!");

14
demo/demo7.js Normal file
View File

@ -0,0 +1,14 @@
const docx = require("../build");
var doc = new docx.Document(undefined, {
orientation: "landscape",
});
var paragraph = new docx.Paragraph("Hello World");
doc.addParagraph(paragraph);
var exporter = new docx.LocalPacker(doc);
exporter.pack("My Document");
console.log("Document created successfully at project root!");

13
demo/demo8.js Normal file
View File

@ -0,0 +1,13 @@
const docx = require('../build');
var doc = new docx.Document();
doc.createParagraph("Hello World");
doc.Header.createParagraph("Header text");
doc.Footer.createParagraph("Footer text");
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

13
demo/demo9.js Normal file
View File

@ -0,0 +1,13 @@
const docx = require('../build');
var doc = new docx.Document();
doc.createParagraph("Hello World");
doc.Header.createImage("./demo/images/pizza.gif");
doc.Footer.createImage("./demo/images/pizza.gif");
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

BIN
demo/images/cat.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
demo/images/dog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

View File

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 162 KiB

BIN
demo/images/parrots.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 KiB

BIN
demo/images/pizza.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

View File

@ -1,19 +1,24 @@
{ {
"name": "docx", "name": "docx",
"version": "2.1.0", "version": "3.2.0",
"description": "Generate .docx documents with JavaScript (formerly Office-Clippy)", "description": "Generate .docx documents with JavaScript (formerly Office-Clippy)",
"main": "build/index.js", "main": "build/index.js",
"scripts": { "scripts": {
"pretest": "rimraf ./build-tests && tsc -p ts/test-tsconfig.json", "pretest": "rimraf ./build",
"test": "mocha ./build-tests --recursive", "test": "mocha-webpack \"src/**/*.ts\"",
"test-watch": "mocha-webpack \"src/**/*.ts\" --watch",
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
"lint": "tslint --project ./ts", "lint": "tslint --project .",
"build": "rimraf ./build && tsc -p ts", "build": "npm run webpack && npm run fix-types",
"tsc": "rimraf ./build && tsc -p .",
"webpack": "rimraf ./build && webpack",
"demo": "npm run build && node ./demo", "demo": "npm run build && node ./demo",
"typedoc": "typedoc --out docs/ ts/ --module commonjs --target ES6 --disableOutputCheck" "typedoc": "npm run build && typedoc --out docs/ src/ --module commonjs --target ES6 --disableOutputCheck",
"style": "prettier -l --trailing-comma all --print-width 140 --arrow-parens always \"src/**/*.ts\"",
"fix-types": "node types-absolute-fixer.js"
}, },
"files": [ "files": [
"ts", "src",
"build", "build",
"template" "template"
], ],
@ -22,6 +27,7 @@
"url": "git+https://github.com/dolanmiu/docx.git" "url": "git+https://github.com/dolanmiu/docx.git"
}, },
"keywords": [ "keywords": [
"docx",
"office", "office",
"word", "word",
"generate", "generate",
@ -34,9 +40,14 @@
], ],
"types": "./build/index.d.ts", "types": "./build/index.d.ts",
"dependencies": { "dependencies": {
"@types/archiver": "^1.3.2", "@types/archiver": "^2.1.0",
"@types/express": "^4.0.35", "@types/express": "^4.0.35",
"archiver": "^1.3.0", "@types/image-size": "0.0.29",
"@types/request-promise": "^4.1.41",
"archiver": "^2.1.1",
"image-size": "^0.6.2",
"request": "^2.83.0",
"request-promise": "^4.2.2",
"xml": "^1.0.1" "xml": "^1.0.1"
}, },
"author": "Dolan Miu", "author": "Dolan Miu",
@ -48,13 +59,19 @@
"devDependencies": { "devDependencies": {
"@types/chai": "^3.4.35", "@types/chai": "^3.4.35",
"@types/mocha": "^2.2.39", "@types/mocha": "^2.2.39",
"awesome-typescript-loader": "^3.4.1",
"chai": "^3.5.0", "chai": "^3.5.0",
"glob": "^7.1.2",
"mocha": "^3.2.0", "mocha": "^3.2.0",
"mocha-webpack": "^1.0.1",
"prettier": "^1.10.2",
"prompt": "^1.0.0", "prompt": "^1.0.0",
"replace-in-file": "^3.1.0",
"rimraf": "^2.5.2", "rimraf": "^2.5.2",
"shelljs": "^0.7.7", "shelljs": "^0.7.7",
"tslint": "^5.1.0", "tslint": "^5.1.0",
"typedoc": "^0.5.10", "typedoc": "^0.9.0",
"typescript": "^2.2.1" "typescript": "2.6.2",
"webpack": "^3.10.0"
} }
} }

View File

@ -1,10 +1,10 @@
import { assert } from "chai"; import { assert } from "chai";
import * as docx from "../../docx"; import { Formatter } from "../export/formatter";
import { Attributes } from "../../docx/xml-components"; import * as file from "../file";
import { Formatter } from "../../export/formatter"; import { CoreProperties } from "../file/core-properties";
import { Properties } from "../../properties"; import { Attributes } from "../file/xml-components";
import { Utility } from "../utility"; import { Utility } from "../tests/utility";
describe("Formatter", () => { describe("Formatter", () => {
let formatter: Formatter; let formatter: Formatter;
@ -15,21 +15,21 @@ describe("Formatter", () => {
describe("#format()", () => { describe("#format()", () => {
it("should format simple paragraph", () => { it("should format simple paragraph", () => {
const paragraph = new docx.Paragraph(); const paragraph = new file.Paragraph();
const newJson = formatter.format(paragraph); const newJson = formatter.format(paragraph);
assert.isDefined(newJson["w:p"]); assert.isDefined(newJson["w:p"]);
}); });
it("should remove xmlKeys", () => { it("should remove xmlKeys", () => {
const paragraph = new docx.Paragraph(); const paragraph = new file.Paragraph();
const newJson = formatter.format(paragraph); const newJson = formatter.format(paragraph);
const stringifiedJson = JSON.stringify(newJson); const stringifiedJson = JSON.stringify(newJson);
assert(stringifiedJson.indexOf("xmlKeys") < 0); assert(stringifiedJson.indexOf("xmlKeys") < 0);
}); });
it("should format simple paragraph with bold text", () => { it("should format simple paragraph with bold text", () => {
const paragraph = new docx.Paragraph(); const paragraph = new file.Paragraph();
paragraph.addRun(new docx.TextRun("test").bold()); paragraph.addRun(new file.TextRun("test").bold());
const newJson = formatter.format(paragraph); const newJson = formatter.format(paragraph);
assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"][0]._attr["w:val"]); assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"][0]._attr["w:val"]);
}); });
@ -61,13 +61,13 @@ describe("Formatter", () => {
}); });
it("should should change 'p' tag into 'w:p' tag", () => { it("should should change 'p' tag into 'w:p' tag", () => {
const paragraph = new docx.Paragraph(); const paragraph = new file.Paragraph();
const newJson = formatter.format(paragraph); const newJson = formatter.format(paragraph);
assert.isDefined(newJson["w:p"]); assert.isDefined(newJson["w:p"]);
}); });
it("should format Properties object correctly", () => { it("should format Properties object correctly", () => {
const properties = new Properties({ const properties = new CoreProperties({
title: "test document", title: "test document",
creator: "Dolan", creator: "Dolan",
}); });

7
src/export/formatter.ts Normal file
View File

@ -0,0 +1,7 @@
import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
export class Formatter {
public format(input: BaseXmlComponent): IXmlableObject {
return input.prepForXml();
}
}

3
src/export/index.ts Normal file
View File

@ -0,0 +1,3 @@
export * from "./packer/local";
export * from "./packer/express";
export * from "./packer/packer";

View File

@ -0,0 +1,105 @@
import * as archiver from "archiver";
import * as express from "express";
import * as fs from "fs";
import * as xml from "xml";
import { File } from "file";
import { Formatter } from "../formatter";
export class Compiler {
protected archive: archiver.Archiver;
private formatter: Formatter;
constructor(private file: File) {
this.formatter = new Formatter();
this.archive = archiver.create("zip", {});
this.archive.on("error", (err) => {
throw err;
});
}
public async compile(output: fs.WriteStream | express.Response): Promise<void> {
this.archive.pipe(output);
const xmlDocument = xml(this.formatter.format(this.file.Document), true);
const xmlStyles = xml(this.formatter.format(this.file.Styles));
const xmlProperties = xml(this.formatter.format(this.file.CoreProperties), {
declaration: {
standalone: "yes",
encoding: "UTF-8",
},
});
const xmlNumbering = xml(this.formatter.format(this.file.Numbering));
const xmlRelationships = xml(this.formatter.format(this.file.DocumentRelationships));
const xmlFileRelationships = xml(this.formatter.format(this.file.FileRelationships));
const xmlHeader = xml(this.formatter.format(this.file.Header.Header));
const xmlFooter = xml(this.formatter.format(this.file.Footer.Footer));
const xmlHeaderRelationships = xml(this.formatter.format(this.file.Header.Relationships));
const xmlFooterRelationships = xml(this.formatter.format(this.file.Footer.Relationships));
const xmlContentTypes = xml(this.formatter.format(this.file.ContentTypes));
const xmlAppProperties = xml(this.formatter.format(this.file.AppProperties));
this.archive.append(xmlDocument, {
name: "word/document.xml",
});
this.archive.append(xmlStyles, {
name: "word/styles.xml",
});
this.archive.append(xmlProperties, {
name: "docProps/core.xml",
});
this.archive.append(xmlAppProperties, {
name: "docProps/app.xml",
});
this.archive.append(xmlNumbering, {
name: "word/numbering.xml",
});
this.archive.append(xmlHeader, {
name: "word/header1.xml",
});
this.archive.append(xmlFooter, {
name: "word/footer1.xml",
});
this.archive.append(xmlRelationships, {
name: "word/_rels/document.xml.rels",
});
this.archive.append(xmlHeaderRelationships, {
name: "word/_rels/header1.xml.rels",
});
this.archive.append(xmlFooterRelationships, {
name: "word/_rels/footer1.xml.rels",
});
this.archive.append(xmlContentTypes, {
name: "[Content_Types].xml",
});
this.archive.append(xmlFileRelationships, {
name: "_rels/.rels",
});
for (const data of this.file.Media.array) {
this.archive.append(data.stream, {
name: `word/media/${data.fileName}`,
});
}
this.archive.finalize();
return new Promise<void>((resolve) => {
output.on("close", () => {
resolve();
});
});
}
}

View File

@ -0,0 +1,29 @@
import * as express from "express";
import { File } from "file";
import { Compiler } from "./compiler";
import { IPacker } from "./packer";
export class ExpressPacker implements IPacker {
private readonly packer: Compiler;
constructor(file: File, private readonly res: express.Response) {
this.packer = new Compiler(file);
this.res = res;
this.res.on("close", () => {
return res
.status(200)
.send("OK")
.end();
});
}
public async pack(name: string): Promise<void> {
name = name.replace(/.docx$/, "");
this.res.attachment(`${name}.docx`);
await this.packer.compile(this.res);
}
}

View File

@ -0,0 +1,42 @@
/* tslint:disable:typedef space-before-function-paren */
import * as fs from "fs";
import { LocalPacker } from "../../export/packer/local";
import { File, Paragraph } from "../../file";
describe("LocalPacker", () => {
let packer: LocalPacker;
beforeEach(() => {
const file = new File({
creator: "Dolan Miu",
revision: "1",
lastModifiedBy: "Dolan Miu",
});
const paragraph = new Paragraph("test text");
const heading = new Paragraph("Hello world").heading1();
file.addParagraph(new Paragraph("title").title());
file.addParagraph(heading);
file.addParagraph(new Paragraph("heading 2").heading2());
file.addParagraph(paragraph);
packer = new LocalPacker(file);
});
describe("#pack()", () => {
it("should create a standard docx file", async function() {
this.timeout(99999999);
await packer.pack("build/tests/test");
fs.statSync("build/tests/test.docx");
});
});
describe("#packPdf", () => {
it("should create a standard PDF file", async function() {
this.timeout(99999999);
await packer.packPdf("build/tests/pdf-test");
fs.statSync("build/tests/pdf-test.pdf");
});
});
});

View File

@ -0,0 +1,47 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import { File } from "../../file";
import { Compiler } from "./compiler";
import { IPacker } from "./packer";
import { PdfConvertWrapper } from "./pdf-convert-wrapper";
export class LocalPacker implements IPacker {
private stream: fs.WriteStream;
private readonly pdfConverter: PdfConvertWrapper;
private readonly packer: Compiler;
constructor(file: File) {
this.pdfConverter = new PdfConvertWrapper();
this.packer = new Compiler(file);
}
public async pack(filePath: string): Promise<void> {
filePath = filePath.replace(/.docx$/, "");
this.stream = fs.createWriteStream(`${filePath}.docx`);
await this.packer.compile(this.stream);
}
public async packPdf(filePath: string): Promise<void> {
filePath = filePath.replace(/.pdf$/, "");
const fileName = path.basename(filePath, path.extname(filePath));
const tempPath = path.join(os.tmpdir(), `${fileName}.docx`);
this.stream = fs.createWriteStream(tempPath);
await this.packer.compile(this.stream);
const text = await this.pdfConverter.convert(tempPath);
// const writeFile = util.promisify(fs.writeFile); --use this in future, in 3 years time. Only in node 8
// return writeFile(`${filePath}.pdf`, text);
return new Promise<void>((resolve, reject) => {
fs.writeFile(`${filePath}.pdf`, text, (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
}
}

View File

@ -0,0 +1,6 @@
export interface IPacker {
pack(path: string): void;
}
// Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432
export const WORKAROUND = "";

View File

@ -0,0 +1,35 @@
/* tslint:disable:object-literal-key-quotes */
// This tslint disable is needed, or it simply won't work
import * as fs from "fs";
import * as request from "request-promise";
export interface IConvertOutput {
data: string;
}
export class PdfConvertWrapper {
public convert(filePath: string): request.RequestPromise {
return request.post({
url: "http://mirror1.convertonlinefree.com",
encoding: null,
headers: {
"User-Agent":
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36",
},
formData: {
__EVENTTARGET: "",
__EVENTARGUMENT: "",
__VIEWSTATE: "",
ctl00$MainContent$fu: {
value: fs.readFileSync(filePath),
options: {
filename: "output.docx",
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
},
},
ctl00$MainContent$btnConvert: "Convert",
ctl00$MainContent$fuZip: "",
},
});
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IAppPropertiesAttributes {
xmlns: string;
vt: string;
}
export class AppPropertiesAttributes extends XmlAttributeComponent<IAppPropertiesAttributes> {
protected xmlKeys = {
xmlns: "xmlns",
vt: "xmlns:vt",
};
}

View File

@ -0,0 +1,15 @@
import { XmlComponent } from "file/xml-components";
import { AppPropertiesAttributes } from "./app-properties-attributes";
export class AppProperties extends XmlComponent {
constructor() {
super("Properties");
this.root.push(
new AppPropertiesAttributes({
xmlns: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
vt: "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes",
}),
);
}
}

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IContentTypeAttributes {
xmlns?: string;
}
export class ContentTypeAttributes extends XmlAttributeComponent<IContentTypeAttributes> {
protected xmlKeys = {
xmlns: "xmlns",
};
}

View File

@ -0,0 +1,34 @@
import { XmlComponent } from "file/xml-components";
import { ContentTypeAttributes } from "./content-types-attributes";
import { Default } from "./default/default";
import { Override } from "./override/override";
export class ContentTypes extends XmlComponent {
constructor() {
super("Types");
this.root.push(
new ContentTypeAttributes({
xmlns: "http://schemas.openxmlformats.org/package/2006/content-types",
}),
);
this.root.push(new Default("image/png", "png"));
this.root.push(new Default("image/jpeg", "jpeg"));
this.root.push(new Default("image/jpeg", "jpg"));
this.root.push(new Default("image/bmp", "bmp"));
this.root.push(new Default("image/gif", "gif"));
this.root.push(new Default("application/vnd.openxmlformats-package.relationships+xml", "rels"));
this.root.push(new Default("application/xml", "xml"));
this.root.push(
new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "/word/document.xml"),
);
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "/word/header1.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", "/word/footer1.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", "/word/styles.xml"));
this.root.push(new Override("application/vnd.openxmlformats-package.core-properties+xml", "/docProps/core.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.extended-properties+xml", "/docProps/app.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml", "/word/numbering.xml"));
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IDefaultAttributes {
contentType: string;
extension?: string;
}
export class DefaultAttributes extends XmlAttributeComponent<IDefaultAttributes> {
protected xmlKeys = {
contentType: "ContentType",
extension: "Extension",
};
}

View File

@ -0,0 +1,15 @@
import { XmlComponent } from "file/xml-components";
import { DefaultAttributes } from "./default-attributes";
export class Default extends XmlComponent {
constructor(contentType: string, extension?: string) {
super("Default");
this.root.push(
new DefaultAttributes({
contentType: contentType,
extension: extension,
}),
);
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IOverrideAttributes {
contentType: string;
partName?: string;
}
export class OverrideAttributes extends XmlAttributeComponent<IOverrideAttributes> {
protected xmlKeys = {
contentType: "ContentType",
partName: "PartName",
};
}

View File

@ -0,0 +1,15 @@
import { XmlComponent } from "file/xml-components";
import { OverrideAttributes } from "./override-attributes";
export class Override extends XmlComponent {
constructor(contentType: string, partName?: string) {
super("Override");
this.root.push(
new OverrideAttributes({
contentType: contentType,
partName: partName,
}),
);
}
}

View File

@ -1,8 +1,7 @@
import { DocumentAttributes } from "../docx/document/document-attributes"; import { XmlComponent } from "file/xml-components";
import { XmlComponent } from "../docx/xml-components"; import { DocumentAttributes } from "../document/document-attributes";
export class Title extends XmlComponent { export class Title extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("dc:title"); super("dc:title");
this.root.push(value); this.root.push(value);
@ -10,7 +9,6 @@ export class Title extends XmlComponent {
} }
export class Subject extends XmlComponent { export class Subject extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("dc:subject"); super("dc:subject");
this.root.push(value); this.root.push(value);
@ -18,7 +16,6 @@ export class Subject extends XmlComponent {
} }
export class Creator extends XmlComponent { export class Creator extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("dc:creator"); super("dc:creator");
this.root.push(value); this.root.push(value);
@ -26,7 +23,6 @@ export class Creator extends XmlComponent {
} }
export class Keywords extends XmlComponent { export class Keywords extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("cp:keywords"); super("cp:keywords");
this.root.push(value); this.root.push(value);
@ -34,7 +30,6 @@ export class Keywords extends XmlComponent {
} }
export class Description extends XmlComponent { export class Description extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("dc:description"); super("dc:description");
this.root.push(value); this.root.push(value);
@ -42,7 +37,6 @@ export class Description extends XmlComponent {
} }
export class LastModifiedBy extends XmlComponent { export class LastModifiedBy extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("cp:lastModifiedBy"); super("cp:lastModifiedBy");
this.root.push(value); this.root.push(value);
@ -50,7 +44,6 @@ export class LastModifiedBy extends XmlComponent {
} }
export class Revision extends XmlComponent { export class Revision extends XmlComponent {
constructor(value: string) { constructor(value: string) {
super("cp:revision"); super("cp:revision");
this.root.push(value); this.root.push(value);
@ -72,23 +65,25 @@ export abstract class DateComponent extends XmlComponent {
} }
export class Created extends DateComponent { export class Created extends DateComponent {
constructor() { constructor() {
super("dcterms:created"); super("dcterms:created");
this.root.push(new DocumentAttributes({ this.root.push(
new DocumentAttributes({
type: "dcterms:W3CDTF", type: "dcterms:W3CDTF",
})); }),
);
this.root.push(this.getCurrentDate()); this.root.push(this.getCurrentDate());
} }
} }
export class Modified extends DateComponent { export class Modified extends DateComponent {
constructor() { constructor() {
super("dcterms:modified"); super("dcterms:modified");
this.root.push(new DocumentAttributes({ this.root.push(
new DocumentAttributes({
type: "dcterms:W3CDTF", type: "dcterms:W3CDTF",
})); }),
);
this.root.push(this.getCurrentDate()); this.root.push(this.getCurrentDate());
} }
} }

View File

@ -0,0 +1 @@
export * from "./properties";

View File

@ -1,13 +1,12 @@
import { expect } from "chai"; import { expect } from "chai";
import { Formatter } from "../export/formatter"; import { Formatter } from "../../export/formatter";
import { Properties } from "../properties"; import { CoreProperties } from "./properties";
describe("Properties", () => { describe("Properties", () => {
describe("#constructor()", () => { describe("#constructor()", () => {
it("sets the appropriate attributes on the top-level", () => { it("sets the appropriate attributes on the top-level", () => {
const properties = new Properties({}); const properties = new CoreProperties({});
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]); expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]);
expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array); expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array);
@ -23,18 +22,16 @@ describe("Properties", () => {
}); });
it("should create properties with a title", () => { it("should create properties with a title", () => {
const properties = new Properties({title: "test document"}); const properties = new CoreProperties({ title: "test document" });
const tree = new Formatter().format(properties); const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]); expect(Object.keys(tree)).to.deep.equal(["cp:coreProperties"]);
expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array); expect(tree["cp:coreProperties"]).to.be.an.instanceof(Array);
expect(Object.keys(tree["cp:coreProperties"][0])).to.deep.equal(["_attr"]); expect(Object.keys(tree["cp:coreProperties"][0])).to.deep.equal(["_attr"]);
expect(tree["cp:coreProperties"][1]).to.deep.equal( expect(tree["cp:coreProperties"][1]).to.deep.equal({ "dc:title": ["test document"] });
{"dc:title": ["test document"]},
);
}); });
it("should create properties with all the attributes given", () => { it("should create properties with all the attributes given", () => {
const properties = new Properties({ const properties = new CoreProperties({
title: "test document", title: "test document",
subject: "test subject", subject: "test subject",
creator: "me", creator: "me",
@ -60,7 +57,7 @@ describe("Properties", () => {
"dcterms:created", "dcterms:created",
"dcterms:modified", "dcterms:modified",
]); ]);
expect(tree["cp:coreProperties"].slice(1, -2).sort((a, b) => key(a) < key(b) ? -1 : 1)).to.deep.equal([ expect(tree["cp:coreProperties"].slice(1, -2).sort((a, b) => (key(a) < key(b) ? -1 : 1))).to.deep.equal([
{ "cp:keywords": ["test docx"] }, { "cp:keywords": ["test docx"] },
{ "cp:lastModifiedBy": ["the author"] }, { "cp:lastModifiedBy": ["the author"] },
{ "cp:revision": ["123"] }, { "cp:revision": ["123"] },

View File

@ -1,5 +1,5 @@
import { DocumentAttributes } from "../docx/document/document-attributes"; import { XmlComponent } from "file/xml-components";
import { XmlComponent } from "../docx/xml-components"; import { DocumentAttributes } from "../document/document-attributes";
import { Created, Creator, Description, Keywords, LastModifiedBy, Modified, Revision, Subject, Title } from "./components"; import { Created, Creator, Description, Keywords, LastModifiedBy, Modified, Revision, Subject, Title } from "./components";
export interface IPropertiesOptions { export interface IPropertiesOptions {
@ -12,17 +12,18 @@ export interface IPropertiesOptions {
revision?: string; revision?: string;
} }
export class Properties extends XmlComponent { export class CoreProperties extends XmlComponent {
constructor(options: IPropertiesOptions) { constructor(options: IPropertiesOptions) {
super("cp:coreProperties"); super("cp:coreProperties");
this.root.push(new DocumentAttributes({ this.root.push(
new DocumentAttributes({
cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties", cp: "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
dc: "http://purl.org/dc/elements/1.1/", dc: "http://purl.org/dc/elements/1.1/",
dcterms: "http://purl.org/dc/terms/", dcterms: "http://purl.org/dc/terms/",
dcmitype: "http://purl.org/dc/dcmitype/", dcmitype: "http://purl.org/dc/dcmitype/",
xsi: "http://www.w3.org/2001/XMLSchema-instance", xsi: "http://www.w3.org/2001/XMLSchema-instance",
})); }),
);
if (options.title) { if (options.title) {
this.root.push(new Title(options.title)); this.root.push(new Title(options.title));
} }

View File

@ -0,0 +1,39 @@
// import { assert } from "chai";
// import { Utility } from "../../../tests/utility";
// import { Body } from "./";
describe("Body", () => {
// let body: Body;
beforeEach(() => {
// body = new Body();
});
// describe("#constructor()", () => {
// it("should create the Section Properties", () => {
// const newJson = Utility.jsonify(body);
// assert.equal(newJson.root[0].rootKey, "w:sectPr");
// });
// it("should create the Page Size", () => {
// const newJson = Utility.jsonify(body);
// assert.equal(newJson.root[1].rootKey, "w:pgSz");
// });
// it("should create the Page Margin", () => {
// const newJson = Utility.jsonify(body);
// assert.equal(newJson.root[2].rootKey, "w:pgMar");
// });
// it("should create the Columns", () => {
// const newJson = Utility.jsonify(body);
// assert.equal(newJson.root[3].rootKey, "w:cols");
// });
// it("should create the Document Grid", () => {
// const newJson = Utility.jsonify(body);
// assert.equal(newJson.root[4].rootKey, "w:docGrid");
// });
// });
});

View File

@ -0,0 +1,14 @@
import { XmlComponent } from "file/xml-components";
import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties";
export class Body extends XmlComponent {
constructor(sectionPropertiesOptions?: SectionPropertiesOptions) {
super("w:body");
this.root.push(new SectionProperties(sectionPropertiesOptions));
}
public push(component: XmlComponent): void {
this.root.push(component);
}
}

View File

@ -0,0 +1 @@
export * from "./body";

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IColumnsAttributes {
space?: number;
}
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
protected xmlKeys = {
space: "w:space",
};
}

View File

@ -0,0 +1,13 @@
import { XmlComponent } from "file/xml-components";
import { ColumnsAttributes } from "./columns-attributes";
export class Columns extends XmlComponent {
constructor(space: number) {
super("w:cols");
this.root.push(
new ColumnsAttributes({
space: space,
}),
);
}
}

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IDocGridAttributesProperties {
linePitch?: number;
}
export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesProperties> {
protected xmlKeys = {
linePitch: "w:linePitch",
};
}

View File

@ -0,0 +1,13 @@
import { XmlComponent } from "file/xml-components";
import { DocGridAttributes } from "./doc-grid-attributes";
export class DocumentGrid extends XmlComponent {
constructor(linePitch: number) {
super("w:docGrid");
this.root.push(
new DocGridAttributes({
linePitch: linePitch,
}),
);
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IFooterReferenceAttributes {
type: string;
id: string;
}
export class FooterReferenceAttributes extends XmlAttributeComponent<IFooterReferenceAttributes> {
protected xmlKeys = {
type: "w:type",
id: "r:id",
};
}

View File

@ -0,0 +1,14 @@
import { XmlComponent } from "file/xml-components";
import { FooterReferenceAttributes } from "./footer-reference-attributes";
export class FooterReference extends XmlComponent {
constructor() {
super("w:footerReference");
this.root.push(
new FooterReferenceAttributes({
type: "default",
id: `rId${4}`,
}),
);
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IHeaderReferenceAttributes {
type: string;
id: string;
}
export class HeaderReferenceAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
protected xmlKeys = {
type: "w:type",
id: "r:id",
};
}

View File

@ -0,0 +1,14 @@
import { XmlComponent } from "file/xml-components";
import { HeaderReferenceAttributes } from "./header-reference-attributes";
export class HeaderReference extends XmlComponent {
constructor() {
super("w:headerReference");
this.root.push(
new HeaderReferenceAttributes({
type: "default",
id: `rId${3}`,
}),
);
}
}

View File

@ -0,0 +1,23 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IPageMarginAttributes {
top?: number;
right?: number;
bottom?: number;
left?: number;
header?: number;
footer?: number;
gutter?: number;
}
export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttributes> {
protected xmlKeys = {
top: "w:top",
right: "w:right",
bottom: "w:bottom",
left: "w:left",
header: "w:header",
footer: "w:footer",
gutter: "w:gutter",
};
}

View File

@ -0,0 +1,19 @@
import { XmlComponent } from "file/xml-components";
import { PageMarginAttributes } from "./page-margin-attributes";
export class PageMargin extends XmlComponent {
constructor(top: number, right: number, bottom: number, left: number, header: number, footer: number, gutter: number) {
super("w:pgMar");
this.root.push(
new PageMarginAttributes({
top: top,
right: right,
bottom: bottom,
left: left,
header: header,
footer: footer,
gutter: gutter,
}),
);
}
}

View File

@ -0,0 +1,15 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IPageSizeAttributes {
width?: number;
height?: number;
orientation?: string;
}
export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttributes> {
protected xmlKeys = {
width: "w:w",
height: "w:h",
orientation: "w:orient",
};
}

View File

@ -0,0 +1,26 @@
import { expect } from "chai";
import { Formatter } from "../../../../../export/formatter";
import { PageSize } from "./page-size";
describe("PageSize", () => {
describe("#constructor()", () => {
it("should create page size with portrait", () => {
const properties = new PageSize(100, 200, "portrait");
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array);
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 200, "w:w": 100, "w:orient": "portrait" } });
});
it("should create page size with horizontal and invert the lengths", () => {
const properties = new PageSize(100, 200, "landscape");
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:pgSz"]);
expect(tree["w:pgSz"]).to.be.an.instanceof(Array);
expect(tree["w:pgSz"][0]).to.deep.equal({ _attr: { "w:h": 100, "w:w": 200, "w:orient": "landscape" } });
});
});
});

View File

@ -0,0 +1,18 @@
import { XmlComponent } from "file/xml-components";
import { PageSizeAttributes } from "./page-size-attributes";
export class PageSize extends XmlComponent {
constructor(width: number, height: number, orientation: string) {
super("w:pgSz");
const flip = orientation === "landscape";
this.root.push(
new PageSizeAttributes({
width: flip ? height : width,
height: flip ? width : height,
orientation: orientation,
}),
);
}
}

View File

@ -0,0 +1,142 @@
import { expect } from "chai";
import { Formatter } from "../../../../export/formatter";
import { SectionProperties } from "./section-properties";
describe("SectionProperties", () => {
describe("#constructor()", () => {
it("should create section properties with options", () => {
const properties = new SectionProperties({
width: 11906,
height: 16838,
top: 1440,
right: 1440,
bottom: 1440,
left: 1440,
header: 708,
footer: 708,
gutter: 0,
space: 708,
linePitch: 360,
});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
},
},
],
});
});
it("should create section properties with no options", () => {
const properties = new SectionProperties();
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
},
},
],
});
});
it("should create section properties with changed options", () => {
const properties = new SectionProperties({
top: 0,
});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 0,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
},
},
],
});
});
it("should create section properties with changed options", () => {
const properties = new SectionProperties({
bottom: 0,
});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 16838, "w:w": 11906, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 0,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
},
},
],
});
});
it("should create section properties with changed options", () => {
const properties = new SectionProperties({
width: 0,
height: 0,
});
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
expect(tree["w:sectPr"][0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 0, "w:w": 0, "w:orient": "portrait" } }] });
expect(tree["w:sectPr"][1]).to.deep.equal({
"w:pgMar": [
{
_attr: {
"w:bottom": 1440,
"w:footer": 708,
"w:top": 1440,
"w:right": 1440,
"w:left": 1440,
"w:header": 708,
"w:gutter": 0,
},
},
],
});
});
});
});

View File

@ -0,0 +1,57 @@
// http://officeopenxml.com/WPsection.php
import { XmlComponent } from "file/xml-components";
import { Columns } from "./columns/columns";
import { IColumnsAttributes } from "./columns/columns-attributes";
import { DocumentGrid } from "./doc-grid/doc-grid";
import { IDocGridAttributesProperties } from "./doc-grid/doc-grid-attributes";
import { FooterReference } from "./footer-reference/footer-reference";
import { HeaderReference } from "./header-reference/header-reference";
import { PageMargin } from "./page-margin/page-margin";
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
import { PageSize } from "./page-size/page-size";
import { IPageSizeAttributes } from "./page-size/page-size-attributes";
export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties;
export class SectionProperties extends XmlComponent {
constructor(options?: SectionPropertiesOptions) {
super("w:sectPr");
const defaultOptions = {
width: 11906,
height: 16838,
top: 1440,
right: 1440,
bottom: 1440,
left: 1440,
header: 708,
footer: 708,
gutter: 0,
space: 708,
linePitch: 360,
orientation: "portrait",
};
const mergedOptions = {
...defaultOptions,
...options,
};
this.root.push(new PageSize(mergedOptions.width, mergedOptions.height, mergedOptions.orientation));
this.root.push(
new PageMargin(
mergedOptions.top,
mergedOptions.right,
mergedOptions.bottom,
mergedOptions.left,
mergedOptions.header,
mergedOptions.footer,
mergedOptions.gutter,
),
);
this.root.push(new Columns(mergedOptions.space));
this.root.push(new DocumentGrid(mergedOptions.linePitch));
this.root.push(new HeaderReference());
this.root.push(new FooterReference());
}
}

View File

@ -1,4 +1,4 @@
import { XmlAttributeComponent } from "../xml-components"; import { XmlAttributeComponent } from "file/xml-components";
export interface IDocumentAttributesProperties { export interface IDocumentAttributesProperties {
wpc?: string; wpc?: string;

View File

@ -0,0 +1,83 @@
import { assert, expect } from "chai";
import { Formatter } from "../../export/formatter";
import { Paragraph } from "../paragraph";
import { Table } from "../table";
import { Document } from "./document";
describe("Document", () => {
let document: Document;
beforeEach(() => {
document = new Document();
});
describe("#constructor()", () => {
it("should create valid JSON", () => {
const stringifiedJson = JSON.stringify(document);
try {
JSON.parse(stringifiedJson);
} catch (e) {
assert.isTrue(false);
}
assert.isTrue(true);
});
});
describe("#createParagraph", () => {
it("should create a new paragraph and append it to body", () => {
const para = document.createParagraph();
expect(para).to.be.an.instanceof(Paragraph);
const body = new Formatter().format(document)["w:document"][1]["w:body"];
expect(body)
.to.be.an("array")
.which.has.length.at.least(1);
expect(body[1]).to.have.property("w:p");
});
it("should use the text given to create a run in the paragraph", () => {
const para = document.createParagraph("sample paragraph text");
expect(para).to.be.an.instanceof(Paragraph);
const body = new Formatter().format(document)["w:document"][1]["w:body"];
expect(body)
.to.be.an("array")
.which.has.length.at.least(1);
expect(body[1])
.to.have.property("w:p")
.which.includes({
"w:r": [{ "w:rPr": [] }, { "w:t": [{ _attr: { "xml:space": "preserve" } }, "sample paragraph text"] }],
});
});
});
describe("#createTable", () => {
it("should create a new table and append it to body", () => {
const table = document.createTable(2, 3);
expect(table).to.be.an.instanceof(Table);
const body = new Formatter().format(document)["w:document"][1]["w:body"];
expect(body)
.to.be.an("array")
.which.has.length.at.least(1);
expect(body[1]).to.have.property("w:tbl");
});
it("should create a table with the correct dimensions", () => {
document.createTable(2, 3);
const body = new Formatter().format(document)["w:document"][1]["w:body"];
expect(body)
.to.be.an("array")
.which.has.length.at.least(1);
expect(body[1])
.to.have.property("w:tbl")
.which.includes({
"w:tblGrid": [
{ "w:gridCol": [{ _attr: { "w:w": 1 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 1 } }] },
{ "w:gridCol": [{ _attr: { "w:w": 1 } }] },
],
});
expect(body[1]["w:tbl"].filter((x) => x["w:tr"])).to.have.length(2);
});
});
});

View File

@ -0,0 +1,73 @@
// http://officeopenxml.com/WPdocument.php
import { IMediaData } from "file/media";
import { XmlComponent } from "file/xml-components";
import { Paragraph, PictureRun } from "../paragraph";
import { Table } from "../table";
import { Body } from "./body";
import { SectionPropertiesOptions } from "./body/section-properties/section-properties";
import { DocumentAttributes } from "./document-attributes";
export class Document extends XmlComponent {
private readonly body: Body;
constructor(sectionPropertiesOptions?: SectionPropertiesOptions) {
super("w:document");
this.root.push(
new DocumentAttributes({
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
m: "http://schemas.openxmlformats.org/officeDocument/2006/math",
v: "urn:schemas-microsoft-com:vml",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
w10: "urn:schemas-microsoft-com:office:word",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
w15: "http://schemas.microsoft.com/office/word/2012/wordml",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
Ignorable: "w14 w15 wp14",
}),
);
this.body = new Body(sectionPropertiesOptions);
this.root.push(this.body);
}
public addParagraph(paragraph: Paragraph): void {
this.body.push(paragraph);
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addParagraph(para);
return para;
}
public addTable(table: Table): void {
this.body.push(table);
}
public createTable(rows: number, cols: number): Table {
const table = new Table(rows, cols);
this.addTable(table);
return table;
}
public addDrawing(imageData: IMediaData): void {
const paragraph = new Paragraph();
const run = new PictureRun(imageData);
paragraph.addRun(run);
this.body.push(paragraph);
}
public createDrawing(imageData: IMediaData): void {
this.addDrawing(imageData);
return;
}
}

View File

@ -0,0 +1 @@
export * from "./document";

View File

@ -1,18 +1,29 @@
import { assert } from "chai"; import { assert } from "chai";
import * as fs from "fs"; import * as fs from "fs";
import { Drawing } from "../../../../docx/run/run-components/drawing";
import { Utility } from "../../../utility"; import { Utility } from "../../tests/utility";
import { Drawing } from "./";
describe("Drawing", () => { describe("Drawing", () => {
let currentBreak: Drawing; let currentBreak: Drawing;
beforeEach(() => { beforeEach(() => {
const path = "./demo/penguins.jpg"; const path = "./demo/images/image1.jpeg";
currentBreak = new Drawing({ currentBreak = new Drawing({
fileName: "test.jpg", fileName: "test.jpg",
referenceId: 1, referenceId: 1,
stream: fs.createReadStream(path), stream: fs.createReadStream(path),
path: path, path: path,
dimensions: {
pixels: {
x: 100,
y: 100,
},
emus: {
x: 100 * 9525,
y: 100 * 9525,
},
},
}); });
}); });

View File

@ -1,16 +1,15 @@
import { IData } from "../../../../media/data"; import { IMediaData } from "file/media";
import { XmlComponent } from "../../../xml-components"; import { XmlComponent } from "file/xml-components";
import { Inline } from "./inline"; import { Inline } from "./inline";
export class Drawing extends XmlComponent { export class Drawing extends XmlComponent {
constructor(imageData: IMediaData) {
constructor(imageData: IData) {
super("w:drawing"); super("w:drawing");
if (imageData === undefined) { if (imageData === undefined) {
throw new Error("imageData cannot be undefined"); throw new Error("imageData cannot be undefined");
} }
this.root.push(new Inline(imageData.referenceId)); this.root.push(new Inline(imageData.referenceId, imageData.dimensions));
} }
} }

View File

@ -0,0 +1 @@
export { Drawing } from "./drawing";

View File

@ -0,0 +1,15 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IDocPropertiesAttributes {
id?: number;
name?: string;
descr?: string;
}
export class DocPropertiesAttributes extends XmlAttributeComponent<IDocPropertiesAttributes> {
protected xmlKeys = {
id: "id",
name: "name",
descr: "descr",
};
}

View File

@ -0,0 +1,16 @@
import { XmlComponent } from "file/xml-components";
import { DocPropertiesAttributes } from "./doc-properties-attributes";
export class DocProperties extends XmlComponent {
constructor() {
super("wp:docPr");
this.root.push(
new DocPropertiesAttributes({
id: 0,
name: "",
descr: "",
}),
);
}
}

View File

@ -0,0 +1,17 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IEffectExtentAttributes {
b?: number;
l?: number;
r?: number;
t?: number;
}
export class EffectExtentAttributes extends XmlAttributeComponent<IEffectExtentAttributes> {
protected xmlKeys = {
b: "b",
l: "l",
r: "r",
t: "t",
};
}

View File

@ -0,0 +1,17 @@
import { XmlComponent } from "file/xml-components";
import { EffectExtentAttributes } from "./effect-extent-attributes";
export class EffectExtent extends XmlComponent {
constructor() {
super("wp:effectExtent");
this.root.push(
new EffectExtentAttributes({
b: 0,
l: 0,
r: 0,
t: 0,
}),
);
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IExtentAttributes {
cx?: number;
cy?: number;
}
export class ExtentAttributes extends XmlAttributeComponent<IExtentAttributes> {
protected xmlKeys = {
cx: "cx",
cy: "cy",
};
}

View File

@ -0,0 +1,15 @@
import { XmlComponent } from "file/xml-components";
import { ExtentAttributes } from "./extent-attributes";
export class Extent extends XmlComponent {
constructor(x: number, y: number) {
super("wp:extent");
this.root.push(
new ExtentAttributes({
cx: x,
cy: y,
}),
);
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IGraphicFrameLockAttributes {
xmlns?: string;
noChangeAspect?: number;
}
export class GraphicFrameLockAttributes extends XmlAttributeComponent<IGraphicFrameLockAttributes> {
protected xmlKeys = {
xmlns: "xmlns:a",
noChangeAspect: "noChangeAspect",
};
}

View File

@ -0,0 +1,15 @@
import { XmlComponent } from "file/xml-components";
import { GraphicFrameLockAttributes } from "./graphic-frame-lock-attributes";
export class GraphicFrameLocks extends XmlComponent {
constructor() {
super("a:graphicFrameLocks");
this.root.push(
new GraphicFrameLockAttributes({
xmlns: "http://schemas.openxmlformats.org/drawingml/2006/main",
noChangeAspect: 1,
}),
);
}
}

View File

@ -0,0 +1,10 @@
import { XmlComponent } from "file/xml-components";
import { GraphicFrameLocks } from "./graphic-frame-locks/graphic-frame-locks";
export class GraphicFrameProperties extends XmlComponent {
constructor() {
super("wp:cNvGraphicFramePr");
this.root.push(new GraphicFrameLocks());
}
}

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IGraphicDataAttributes {
uri?: string;
}
export class GraphicDataAttributes extends XmlAttributeComponent<IGraphicDataAttributes> {
protected xmlKeys = {
uri: "uri",
};
}

View File

@ -0,0 +1,17 @@
import { XmlComponent } from "file/xml-components";
import { GraphicDataAttributes } from "./graphic-data-attribute";
import { Pic } from "./pic";
export class GraphicData extends XmlComponent {
constructor(referenceId: number, x: number, y: number) {
super("a:graphicData");
this.root.push(
new GraphicDataAttributes({
uri: "http://schemas.openxmlformats.org/drawingml/2006/picture",
}),
);
this.root.push(new Pic(referenceId, x, y));
}
}

View File

@ -0,0 +1 @@
export * from "./graphic-data";

View File

@ -1,10 +1,9 @@
import { XmlComponent } from "../../../../../../../../xml-components"; import { XmlComponent } from "file/xml-components";
import { Blip } from "./blip"; import { Blip } from "./blip";
import { SourceRectangle } from "./source-rectangle"; import { SourceRectangle } from "./source-rectangle";
import { Stretch } from "./stretch"; import { Stretch } from "./stretch";
export class BlipFill extends XmlComponent { export class BlipFill extends XmlComponent {
constructor(referenceId: number) { constructor(referenceId: number) {
super("pic:blipFill"); super("pic:blipFill");
this.root.push(new Blip(referenceId)); this.root.push(new Blip(referenceId));

View File

@ -1,21 +1,25 @@
import { XmlAttributeComponent, XmlComponent } from "../../../../../../../../xml-components"; import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
interface IBlipProperties { interface IBlipProperties {
embed: string; embed: string;
cstate: string;
} }
class BlipAttributes extends XmlAttributeComponent<IBlipProperties> { class BlipAttributes extends XmlAttributeComponent<IBlipProperties> {
protected xmlKeys = { protected xmlKeys = {
embed: "r:embed", embed: "r:embed",
cstate: "cstate",
}; };
} }
export class Blip extends XmlComponent { export class Blip extends XmlComponent {
constructor(referenceId: number) { constructor(referenceId: number) {
super("a:blip"); super("a:blip");
this.root.push(new BlipAttributes({ this.root.push(
new BlipAttributes({
embed: `rId${referenceId}`, embed: `rId${referenceId}`,
})); cstate: "none",
}),
);
} }
} }

View File

@ -1,7 +1,6 @@
import { XmlComponent } from "../../../../../../../../xml-components"; import { XmlComponent } from "file/xml-components";
export class SourceRectangle extends XmlComponent { export class SourceRectangle extends XmlComponent {
constructor() { constructor() {
super("a:srcRect"); super("a:srcRect");
} }

View File

@ -1,14 +1,12 @@
import { XmlComponent } from "../../../../../../../../xml-components"; import { XmlComponent } from "file/xml-components";
class FillRectangle extends XmlComponent { class FillRectangle extends XmlComponent {
constructor() { constructor() {
super("a:fillRect"); super("a:fillRect");
} }
} }
export class Stretch extends XmlComponent { export class Stretch extends XmlComponent {
constructor() { constructor() {
super("a:stretch"); super("a:stretch");
this.root.push(new FillRectangle()); this.root.push(new FillRectangle());

View File

@ -0,0 +1 @@
export * from "./pic";

View File

@ -0,0 +1,10 @@
import { XmlComponent } from "file/xml-components";
import { PicLocks } from "./pic-locks/pic-locks";
export class ChildNonVisualProperties extends XmlComponent {
constructor() {
super("pic:cNvPicPr");
this.root.push(new PicLocks());
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IPicLocksAttributes {
noChangeAspect?: number;
noChangeArrowheads?: number;
}
export class PicLocksAttributes extends XmlAttributeComponent<IPicLocksAttributes> {
protected xmlKeys = {
noChangeAspect: "noChangeAspect",
noChangeArrowheads: "noChangeArrowheads",
};
}

View File

@ -0,0 +1,14 @@
import { XmlComponent } from "file/xml-components";
import { PicLocksAttributes } from "./pic-locks-attributes";
export class PicLocks extends XmlComponent {
constructor() {
super("a:picLocks");
this.root.push(
new PicLocksAttributes({
noChangeAspect: 1,
noChangeArrowheads: 1,
}),
);
}
}

View File

@ -0,0 +1,12 @@
import { XmlComponent } from "file/xml-components";
import { ChildNonVisualProperties } from "./child-non-visual-pic-properties/child-non-visual-pic-properties";
import { NonVisualProperties } from "./non-visual-properties/non-visual-properties";
export class NonVisualPicProperties extends XmlComponent {
constructor() {
super("pic:nvPicPr");
this.root.push(new NonVisualProperties());
this.root.push(new ChildNonVisualProperties());
}
}

View File

@ -0,0 +1,15 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface INonVisualPropertiesAttributes {
id?: number;
name?: string;
descr?: string;
}
export class NonVisualPropertiesAttributes extends XmlAttributeComponent<INonVisualPropertiesAttributes> {
protected xmlKeys = {
id: "id",
name: "name",
descr: "desc",
};
}

View File

@ -0,0 +1,16 @@
import { XmlComponent } from "file/xml-components";
import { NonVisualPropertiesAttributes } from "./non-visual-properties-attributes";
export class NonVisualProperties extends XmlComponent {
constructor() {
super("pic:cNvPr");
this.root.push(
new NonVisualPropertiesAttributes({
id: 0,
name: "",
descr: "",
}),
);
}
}

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IPicAttributes {
xmlns?: string;
}
export class PicAttributes extends XmlAttributeComponent<IPicAttributes> {
protected xmlKeys = {
xmlns: "xmlns:pic",
};
}

View File

@ -0,0 +1,21 @@
// http://officeopenxml.com/drwPic.php
import { XmlComponent } from "file/xml-components";
import { BlipFill } from "./blip/blip-fill";
import { NonVisualPicProperties } from "./non-visual-pic-properties/non-visual-pic-properties";
import { PicAttributes } from "./pic-attributes";
import { ShapeProperties } from "./shape-properties/shape-properties";
export class Pic extends XmlComponent {
constructor(referenceId: number, x: number, y: number) {
super("pic:pic");
this.root.push(
new PicAttributes({
xmlns: "http://schemas.openxmlformats.org/drawingml/2006/picture",
}),
);
this.root.push(new NonVisualPicProperties());
this.root.push(new BlipFill(referenceId));
this.root.push(new ShapeProperties(x, y));
}
}

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IExtentsAttributes {
cx?: number;
cy?: number;
}
export class ExtentsAttributes extends XmlAttributeComponent<IExtentsAttributes> {
protected xmlKeys = {
cx: "cx",
cy: "cy",
};
}

View File

@ -0,0 +1,16 @@
// http://officeopenxml.com/drwSp-size.php
import { XmlComponent } from "file/xml-components";
import { ExtentsAttributes } from "./extents-attributes";
export class Extents extends XmlComponent {
constructor(x: number, y: number) {
super("a:ext");
this.root.push(
new ExtentsAttributes({
cx: x,
cy: y,
}),
);
}
}

View File

@ -0,0 +1,13 @@
// http://officeopenxml.com/drwSp-size.php
import { XmlComponent } from "file/xml-components";
import { Extents } from "./extents/extents";
import { Offset } from "./offset/off";
export class Form extends XmlComponent {
constructor(x: number, y: number) {
super("a:xfrm");
this.root.push(new Extents(x, y));
this.root.push(new Offset());
}
}

View File

@ -0,0 +1 @@
export * from "./form";

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IOffsetAttributes {
x?: number;
y?: number;
}
export class OffsetAttributes extends XmlAttributeComponent<IOffsetAttributes> {
protected xmlKeys = {
x: "x",
y: "y",
};
}

View File

@ -0,0 +1,16 @@
// http://officeopenxml.com/drwSp-size.php
import { XmlComponent } from "file/xml-components";
import { OffsetAttributes } from "./off-attributes";
export class Offset extends XmlComponent {
constructor() {
super("a:off");
this.root.push(
new OffsetAttributes({
x: 0,
y: 0,
}),
);
}
}

View File

@ -0,0 +1,7 @@
import { XmlComponent } from "file/xml-components";
export class NoFill extends XmlComponent {
constructor() {
super("a:noFill");
}
}

View File

@ -0,0 +1,7 @@
import { XmlComponent } from "file/xml-components";
export class NoFill extends XmlComponent {
constructor() {
super("a:noFill");
}
}

View File

@ -0,0 +1,11 @@
// http://officeopenxml.com/drwSp-outline.php
import { XmlComponent } from "file/xml-components";
import { NoFill } from "./no-fill";
export class Outline extends XmlComponent {
constructor() {
super("a:ln");
this.root.push(new NoFill());
}
}

Some files were not shown because too many files have changed in this diff Show More