Compare commits
107 Commits
Author | SHA1 | Date | |
---|---|---|---|
e5bfa99b92 | |||
f640f17fa6 | |||
494a32d45d | |||
8040a455be | |||
f091cff7c9 | |||
401ef7336b | |||
18134519be | |||
7980f14efb | |||
40d6a41305 | |||
9cfd835171 | |||
95a9f592eb | |||
61411fd0f3 | |||
a84eb16392 | |||
3355a6f472 | |||
071a8ea9f7 | |||
ea3777d28b | |||
3346b97ee7 | |||
2b834a75a8 | |||
21df53d547 | |||
9143c1c2c1 | |||
83cab7563d | |||
b05fbe7f6e | |||
e6a57738f4 | |||
cc6e35165a | |||
7791ddf76e | |||
4742cf0f3f | |||
8858970491 | |||
f7d18bfead | |||
0ce1b7fa15 | |||
4633592711 | |||
54697ab6b1 | |||
1eed844b9a | |||
dd89fe2463 | |||
9c66db97ff | |||
fea6afdfe4 | |||
6ec2e742ef | |||
3f80b054fc | |||
96d81873d8 | |||
c429ae9920 | |||
6b4e769f48 | |||
b67a9de0e9 | |||
ac9f65a068 | |||
7e8ebb2af2 | |||
f53fe2f881 | |||
6fdd88527a | |||
b6f431e14d | |||
23dee01f06 | |||
5532f91423 | |||
c849d5f3e5 | |||
3f3fd05cb1 | |||
a5bedf9a5b | |||
9d9dd62f00 | |||
a466578467 | |||
3a9420fedf | |||
8ac19a83b2 | |||
9f0b2f7074 | |||
97f76fb62c | |||
3508fd97ec | |||
90f6f68693 | |||
733775d3b9 | |||
f3aa6a9203 | |||
ffdcc7baca | |||
a1e20f4c9a | |||
048ae6a58c | |||
fafa54e4c9 | |||
60dbb32e9e | |||
52b07fd9cb | |||
8ec5bc05e0 | |||
6e0c12afb3 | |||
466e880bfc | |||
0a8feca6ab | |||
f2b50478bf | |||
fc71ebdfef | |||
10114bb12d | |||
e6d4741955 | |||
4d7387524c | |||
5fe4405d76 | |||
79dffc873a | |||
26ee12759c | |||
2e00634bc4 | |||
d63e6bf6b1 | |||
a95366e54e | |||
1c376abeb6 | |||
353d888abd | |||
b6bd532295 | |||
c5b004166d | |||
2f43600daf | |||
b39c7ce323 | |||
5b00279996 | |||
d1d1e01aff | |||
980bc597e2 | |||
a05c5edd49 | |||
985452f5f4 | |||
482674b3b3 | |||
fcbfed9068 | |||
a9167b4809 | |||
f1b176670c | |||
11ce9a5206 | |||
385ad92331 | |||
571f8b526b | |||
7688aa99f6 | |||
4994bca34c | |||
1a3603dbfb | |||
e382dbff84 | |||
e08be3d7a4 | |||
03c4190c2c | |||
010fde6258 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -60,3 +60,6 @@ My Document.docx
|
|||||||
|
|
||||||
# Temporary folder
|
# Temporary folder
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
|
# nyc
|
||||||
|
.nyc_output
|
||||||
|
25
.nycrc
Normal file
25
.nycrc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"check-coverage": true,
|
||||||
|
"lines": 87.54,
|
||||||
|
"functions": 83.61,
|
||||||
|
"branches": 72.57,
|
||||||
|
"statements": 87.32,
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"src/**/*.spec.ts"
|
||||||
|
],
|
||||||
|
"reporter": [
|
||||||
|
"lcov",
|
||||||
|
"text",
|
||||||
|
"json"
|
||||||
|
],
|
||||||
|
"extension": [
|
||||||
|
".ts"
|
||||||
|
],
|
||||||
|
"cache": true,
|
||||||
|
"all": true,
|
||||||
|
"instrument": false,
|
||||||
|
"sourceMap": true
|
||||||
|
}
|
14
.travis.yml
14
.travis.yml
@ -3,9 +3,10 @@ node_js:
|
|||||||
- 9
|
- 9
|
||||||
install:
|
install:
|
||||||
- npm install
|
- npm install
|
||||||
|
- npm install -g codecov
|
||||||
script:
|
script:
|
||||||
- npm run lint
|
- npm run lint
|
||||||
- npm test
|
- npm run test.coverage
|
||||||
- npm run style
|
- npm run style
|
||||||
- npm run build
|
- npm run build
|
||||||
- npm run ts-node -- ./demo/demo1.ts
|
- npm run ts-node -- ./demo/demo1.ts
|
||||||
@ -32,12 +33,23 @@ script:
|
|||||||
- npm run ts-node -- ./demo/demo22.ts
|
- npm run ts-node -- ./demo/demo22.ts
|
||||||
- npm run ts-node -- ./demo/demo23.ts
|
- npm run ts-node -- ./demo/demo23.ts
|
||||||
- npm run ts-node -- ./demo/demo24.ts
|
- npm run ts-node -- ./demo/demo24.ts
|
||||||
|
# - npm run ts-node -- ./demo/demo25.ts
|
||||||
|
- npm run ts-node -- ./demo/demo26.ts
|
||||||
|
- npm run ts-node -- ./demo/demo27.ts
|
||||||
|
- npm run ts-node -- ./demo/demo28.ts
|
||||||
|
- npm run ts-node -- ./demo/demo29.ts
|
||||||
|
- npm run ts-node -- ./demo/demo30.ts
|
||||||
|
- npm run ts-node -- ./demo/demo31.ts
|
||||||
|
- npm run ts-node -- ./demo/demo32.ts
|
||||||
|
- npm run ts-node -- ./demo/demo33.ts
|
||||||
|
- npm run ts-node -- ./demo/demo34.ts
|
||||||
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:
|
||||||
- npm run typedoc
|
- npm run typedoc
|
||||||
- echo "docx.js.org" > docs/.nojekyll
|
- echo "docx.js.org" > docs/.nojekyll
|
||||||
- echo "docx.js.org" > docs/CNAME
|
- echo "docx.js.org" > docs/CNAME
|
||||||
|
- codecov
|
||||||
deploy:
|
deploy:
|
||||||
provider: pages
|
provider: pages
|
||||||
skip-cleanup: true
|
skip-cleanup: true
|
||||||
|
24
.vscode/tasks.json
vendored
Normal file
24
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "typescript",
|
||||||
|
"tsconfig": "tsconfig.json",
|
||||||
|
"option": "watch",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$tsc-watch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "ts-node",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
[![Known Vulnerabilities][snky-image]][snky-url]
|
[![Known Vulnerabilities][snky-image]][snky-url]
|
||||||
[![Chat on Gitter][gitter-image]][gitter-url]
|
[![Chat on Gitter][gitter-image]][gitter-url]
|
||||||
[![PRs Welcome][pr-image]][pr-url]
|
[![PRs Welcome][pr-image]][pr-url]
|
||||||
|
[![codecov][codecov-image]][codecov-url]
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://i.imgur.com/H5FA1Qy.gif" alt="drawing" width="800"/>
|
<img src="https://i.imgur.com/H5FA1Qy.gif" alt="drawing" width="800"/>
|
||||||
@ -29,6 +30,10 @@ Here are examples of `docx` being used with basic `HTML/JS` in a browser environ
|
|||||||
* https://codepen.io/anon/pen/dqoVgQ
|
* https://codepen.io/anon/pen/dqoVgQ
|
||||||
* https://jsfiddle.net/3xhezb5w/2
|
* https://jsfiddle.net/3xhezb5w/2
|
||||||
|
|
||||||
|
Here is an example of `docx` working in `Angular`:
|
||||||
|
|
||||||
|
* https://stackblitz.com/edit/angular-afvxtz
|
||||||
|
|
||||||
## Node
|
## Node
|
||||||
|
|
||||||
Press `endpoint` on the `RunKit` website:
|
Press `endpoint` on the `RunKit` website:
|
||||||
@ -77,3 +82,5 @@ Made with 💖
|
|||||||
[gitter-url]: https://gitter.im/docx-lib/Lobby
|
[gitter-url]: https://gitter.im/docx-lib/Lobby
|
||||||
[pr-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
|
[pr-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
|
||||||
[pr-url]: http://makeapullrequest.com
|
[pr-url]: http://makeapullrequest.com
|
||||||
|
[codecov-image]: https://codecov.io/gh/dolanmiu/docx/branch/master/graph/badge.svg
|
||||||
|
[codecov-url]: https://codecov.io/gh/dolanmiu/docx
|
||||||
|
@ -15,8 +15,12 @@ const footer = doc.createFooter();
|
|||||||
footer.createParagraph("Footer on another page");
|
footer.createParagraph("Footer on another page");
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
headerId: header.Header.ReferenceId,
|
headers: {
|
||||||
footerId: footer.Footer.ReferenceId,
|
default: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
},
|
||||||
pageNumberStart: 1,
|
pageNumberStart: 1,
|
||||||
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||||
});
|
});
|
||||||
@ -24,8 +28,12 @@ doc.addSection({
|
|||||||
doc.createParagraph("hello");
|
doc.createParagraph("hello");
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
headerId: header.Header.ReferenceId,
|
headers: {
|
||||||
footerId: footer.Footer.ReferenceId,
|
default: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
},
|
||||||
pageNumberStart: 1,
|
pageNumberStart: 1,
|
||||||
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||||
orientation: PageOrientation.LANDSCAPE,
|
orientation: PageOrientation.LANDSCAPE,
|
||||||
|
@ -8,11 +8,11 @@ const doc = new Document();
|
|||||||
const paragraph = new Paragraph("Hello World");
|
const paragraph = new Paragraph("Hello World");
|
||||||
doc.addParagraph(paragraph);
|
doc.addParagraph(paragraph);
|
||||||
|
|
||||||
const image = Media.addImage(doc, "./demo/images/image1.jpeg");
|
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
const image2 = Media.addImage(doc, "./demo/images/dog.png");
|
const image2 = Media.addImage(doc, fs.readFileSync("./demo/images/dog.png"));
|
||||||
const image3 = Media.addImage(doc, "./demo/images/cat.jpg");
|
const image3 = Media.addImage(doc, fs.readFileSync("./demo/images/cat.jpg"));
|
||||||
const image4 = Media.addImage(doc, "./demo/images/parrots.bmp");
|
const image4 = Media.addImage(doc, fs.readFileSync("./demo/images/parrots.bmp"));
|
||||||
const image5 = Media.addImage(doc, "./demo/images/pizza.gif");
|
const image5 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||||
|
|
||||||
const imageBase64Data = `iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAACzVBMVEUAAAAAAAAAAAAAAAA/AD8zMzMqKiokJCQfHx8cHBwZGRkuFxcqFSonJyckJCQiIiIfHx8eHh4cHBwoGhomGSYkJCQhISEfHx8eHh4nHR0lHBwkGyQjIyMiIiIgICAfHx8mHh4lHh4kHR0jHCMiGyIhISEgICAfHx8lHx8kHh4jHR0hHCEhISEgICAlHx8kHx8jHh4jHh4iHSIhHCEhISElICAkHx8jHx8jHh4iHh4iHSIhHSElICAkICAjHx8jHx8iHh4iHh4hHiEhHSEkICAjHx8iHx8iHx8hHh4hHiEkHSEjHSAjHx8iHx8iHx8hHh4kHiEkHiEjHSAiHx8hHx8hHh4kHiEjHiAjHSAiHx8iHx8hHx8kHh4jHiEjHiAjHiAiICAiHx8kHx8jHh4jHiEjHiAiHiAiHSAiHx8jHx8jHx8jHiAiHiAiHiAiHSAiHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8iHx8iHSAiHiAjHiAjHx8jHx8hHx8iHx8iHyAiHiAjHiAjHiAjHh4hHx8iHx8iHx8iHyAjHSAjHiAjHiAjHh4hHx8iHx8iHx8jHyAjHiAhHh4iHx8iHx8jHyAjHSAjHSAhHiAhHh4iHx8iHx8jHx8jHyAjHSAjHSAiHh4iHh4jHx8jHx8jHyAjHyAhHSAhHSAiHh4iHh4jHx8jHx8jHyAhHyAhHSAiHSAiHh4jHh4jHx8jHx8jHyAhHyAhHSAiHSAjHR4jHh4jHx8jHx8hHyAhHyAiHSAjHSAjHR4jHh4jHx8hHx8hHyAhHyAiHyAjHSAjHR4jHR4hHh4hHx8hHyAiHyAjHyAjHSAjHR4jHR4hHh4hHx8hHyAjHyAjHyAjHSAjHR4hHR4hHR4hHx8iHyAjHyAjHyAjHSAhHR4hHR4hHR4hHx8jHyAjHyAjHyAjHyC9S2xeAAAA7nRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFxgZGhscHR4fICEiIyQlJicoKSorLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZISUpLTE1OUFFSU1RVVllaW1xdXmBhYmNkZWZnaGprbG1ub3Byc3R1dnd4eXp8fn+AgYKDhIWGiImKi4yNj5CRkpOUlZaXmJmam5ydnp+goaKjpKaoqqusra6vsLGys7S1tri5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+fkZpVQAABcBJREFUGBntwftjlQMcBvDnnLNL22qzJjWlKLHFVogyty3SiFq6EZliqZGyhnSxsLlMRahYoZKRFcul5dKFCatYqWZaNKvWtrPz/A2+7/b27qRzec/lPfvl/XxgMplMJpPJZDKZAtA9HJ3ppnIez0KnSdtC0RCNznHdJrbrh85wdSlVVRaEXuoGamYi5K5430HNiTiEWHKJg05eRWgNfKeV7RxbqUhGKPV/207VupQ8is0IoX5vtFC18SqEHaK4GyHTZ2kzVR8PBTCO4oANIZL4ShNVZcOhKKeYg9DoWdhI1ec3os2VFI0JCIUez5+i6st0qJZRrEAIJCw+QdW223BG/EmKwTBc/IJ/qfp2FDrkUnwFo8U9dZyqnaPhxLqfYjyM1S3vb6p+GGOBszsojoTDSDFz6qj66R4LzvYJxVMwUNRjf1H1ywQr/megg2RzLximy8waqvbda8M5iijegVEiHjlM1W/3h+FcXesphsMY4dMOUnUgOxyuPEzxPQwRNvV3qg5Nj4BreyimwADWe/dRVTMjEm6MoGLzGwtystL6RyOY3qSqdlYU3FpLZw1VW0sK5943MvUCKwJ1noNtjs6Ohge76Zq9ZkfpigU5WWkDYuCfbs1U5HWFR8/Qq4a9W0uK5k4ZmdrTCl8spGIePLPlbqqsc1Afe83O0hULc8alDYiBd7ZyitYMeBfR55rR2fOKP6ioPk2dGvZ+UVI0d8rtqT2tcCexlqK2F3wRn5Q+YVbBqrLKOupkr9lZujAOrmS0UpTb4JeIPkNHZ+cXr6uoPk2vyuBSPhWLEKj45PQJuQWryyqP0Z14uGLdROHIRNBEXDR09EP5r62rOHCazhrD4VKPwxTH+sIA3ZPTJ+YuWV22n+IruHFDC8X2CBjnPoolcGc2FYUwzmsUWXDHsoGKLBhmN0VvuBVfTVE/AAbpaid5CB4MbaLY1QXGuIViLTyZQcVyGGMuxWPwaA0Vk2GI9RRp8Ci2iuLkIBjhT5LNUfAspZFiTwyC72KK7+DNg1SsRvCNp3gZXq2k4iEEXSHFJHgVXUlxejCCbTvFAHiXdIJiXxyCK7KJ5FHoMZGK9xBcwyg2QpdlVMxEUM2iyIMuXXZQNF+HswxMsSAAJRQjoE//eoqDCXBSTO6f1xd+O0iyNRY6jaWi1ALNYCocZROj4JdEikroVkjFk9DcStXxpdfCD2MoXodu4RUU9ptxxmXssOfxnvDVcxRTod9FxyhqLoAqis5aPhwTDp9spRgEH2Q6KLbYoKqlaKTm6Isp0C/sJMnjFvhiERXPQvUNRe9p29lhR04CdBpC8Sl8YiuncIxEuzUUg4Dkgj+paVozygY9plPMh28SaymO9kabAopREGF3vt9MzeFFl8G7lRSZ8FFGK8XX4VA8QjEd7XrM3M0OXz8YCy+qKBLgq3wqnofiTorF0Ax56Rg1J1elW+BBAsVe+My6iYq7IK6keBdOIseV2qn5Pb8f3MqkWAXf9ThM8c8lAOIotuFsF875lRrH5klRcG0+xcPwQ1oLxfeRAP4heQTnGL78X2rqlw2DK59SXAV/zKaiGMAuko5InCt68mcOan5+ohf+z1pP8lQY/GHZQMV4YD3FpXDp4qerqbF/lBWBswyi+AL+ia+maLgcRRQj4IYlY/UpauqKBsPJAxQF8NM1TRQ/RudSPAD34rK3scOuR8/HGcspxsJfOVS8NZbiGXiUtPgINU3v3WFDmx8pEuG3EiqKKVbCC1vm2iZqap5LAtCtleQf8F9sFYWDohzeJczYyQ4V2bEZFGsQgJRGqqqhS2phHTWn9lDkIhBTqWqxQZ+IsRvtdHY9AvI2VX2hW68nfqGmuQsCEl3JdjfCF8OW1bPdtwhQ0gm2mQzfRE3a7KCYj0BNZJs8+Kxf/r6WtTEI2FIqlsMfFgRB5A6KUnSe/vUkX0AnuvUIt8SjM1m6wWQymUwmk8lkMgXRf5vi8rLQxtUhAAAAAElFTkSuQmCC`;
|
const imageBase64Data = `iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAACzVBMVEUAAAAAAAAAAAAAAAA/AD8zMzMqKiokJCQfHx8cHBwZGRkuFxcqFSonJyckJCQiIiIfHx8eHh4cHBwoGhomGSYkJCQhISEfHx8eHh4nHR0lHBwkGyQjIyMiIiIgICAfHx8mHh4lHh4kHR0jHCMiGyIhISEgICAfHx8lHx8kHh4jHR0hHCEhISEgICAlHx8kHx8jHh4jHh4iHSIhHCEhISElICAkHx8jHx8jHh4iHh4iHSIhHSElICAkICAjHx8jHx8iHh4iHh4hHiEhHSEkICAjHx8iHx8iHx8hHh4hHiEkHSEjHSAjHx8iHx8iHx8hHh4kHiEkHiEjHSAiHx8hHx8hHh4kHiEjHiAjHSAiHx8iHx8hHx8kHh4jHiEjHiAjHiAiICAiHx8kHx8jHh4jHiEjHiAiHiAiHSAiHx8jHx8jHx8jHiAiHiAiHiAiHSAiHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8jHx8iHiAiHiAiHiAjHx8jHx8jHx8iHx8iHSAiHiAjHiAjHx8jHx8hHx8iHx8iHyAiHiAjHiAjHiAjHh4hHx8iHx8iHx8iHyAjHSAjHiAjHiAjHh4hHx8iHx8iHx8jHyAjHiAhHh4iHx8iHx8jHyAjHSAjHSAhHiAhHh4iHx8iHx8jHx8jHyAjHSAjHSAiHh4iHh4jHx8jHx8jHyAjHyAhHSAhHSAiHh4iHh4jHx8jHx8jHyAhHyAhHSAiHSAiHh4jHh4jHx8jHx8jHyAhHyAhHSAiHSAjHR4jHh4jHx8jHx8hHyAhHyAiHSAjHSAjHR4jHh4jHx8hHx8hHyAhHyAiHyAjHSAjHR4jHR4hHh4hHx8hHyAiHyAjHyAjHSAjHR4jHR4hHh4hHx8hHyAjHyAjHyAjHSAjHR4hHR4hHR4hHx8iHyAjHyAjHyAjHSAhHR4hHR4hHR4hHx8jHyAjHyAjHyAjHyC9S2xeAAAA7nRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFxgZGhscHR4fICEiIyQlJicoKSorLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZISUpLTE1OUFFSU1RVVllaW1xdXmBhYmNkZWZnaGprbG1ub3Byc3R1dnd4eXp8fn+AgYKDhIWGiImKi4yNj5CRkpOUlZaXmJmam5ydnp+goaKjpKaoqqusra6vsLGys7S1tri5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+fkZpVQAABcBJREFUGBntwftjlQMcBvDnnLNL22qzJjWlKLHFVogyty3SiFq6EZliqZGyhnSxsLlMRahYoZKRFcul5dKFCatYqWZaNKvWtrPz/A2+7/b27qRzec/lPfvl/XxgMplMJpPJZDKZAtA9HJ3ppnIez0KnSdtC0RCNznHdJrbrh85wdSlVVRaEXuoGamYi5K5430HNiTiEWHKJg05eRWgNfKeV7RxbqUhGKPV/207VupQ8is0IoX5vtFC18SqEHaK4GyHTZ2kzVR8PBTCO4oANIZL4ShNVZcOhKKeYg9DoWdhI1ec3os2VFI0JCIUez5+i6st0qJZRrEAIJCw+QdW223BG/EmKwTBc/IJ/qfp2FDrkUnwFo8U9dZyqnaPhxLqfYjyM1S3vb6p+GGOBszsojoTDSDFz6qj66R4LzvYJxVMwUNRjf1H1ywQr/megg2RzLximy8waqvbda8M5iijegVEiHjlM1W/3h+FcXesphsMY4dMOUnUgOxyuPEzxPQwRNvV3qg5Nj4BreyimwADWe/dRVTMjEm6MoGLzGwtystL6RyOY3qSqdlYU3FpLZw1VW0sK5943MvUCKwJ1noNtjs6Ohge76Zq9ZkfpigU5WWkDYuCfbs1U5HWFR8/Qq4a9W0uK5k4ZmdrTCl8spGIePLPlbqqsc1Afe83O0hULc8alDYiBd7ZyitYMeBfR55rR2fOKP6ioPk2dGvZ+UVI0d8rtqT2tcCexlqK2F3wRn5Q+YVbBqrLKOupkr9lZujAOrmS0UpTb4JeIPkNHZ+cXr6uoPk2vyuBSPhWLEKj45PQJuQWryyqP0Z14uGLdROHIRNBEXDR09EP5r62rOHCazhrD4VKPwxTH+sIA3ZPTJ+YuWV22n+IruHFDC8X2CBjnPoolcGc2FYUwzmsUWXDHsoGKLBhmN0VvuBVfTVE/AAbpaid5CB4MbaLY1QXGuIViLTyZQcVyGGMuxWPwaA0Vk2GI9RRp8Ci2iuLkIBjhT5LNUfAspZFiTwyC72KK7+DNg1SsRvCNp3gZXq2k4iEEXSHFJHgVXUlxejCCbTvFAHiXdIJiXxyCK7KJ5FHoMZGK9xBcwyg2QpdlVMxEUM2iyIMuXXZQNF+HswxMsSAAJRQjoE//eoqDCXBSTO6f1xd+O0iyNRY6jaWi1ALNYCocZROj4JdEikroVkjFk9DcStXxpdfCD2MoXodu4RUU9ptxxmXssOfxnvDVcxRTod9FxyhqLoAqis5aPhwTDp9spRgEH2Q6KLbYoKqlaKTm6Isp0C/sJMnjFvhiERXPQvUNRe9p29lhR04CdBpC8Sl8YiuncIxEuzUUg4Dkgj+paVozygY9plPMh28SaymO9kabAopREGF3vt9MzeFFl8G7lRSZ8FFGK8XX4VA8QjEd7XrM3M0OXz8YCy+qKBLgq3wqnofiTorF0Ax56Rg1J1elW+BBAsVe+My6iYq7IK6keBdOIseV2qn5Pb8f3MqkWAXf9ThM8c8lAOIotuFsF875lRrH5klRcG0+xcPwQ1oLxfeRAP4heQTnGL78X2rqlw2DK59SXAV/zKaiGMAuko5InCt68mcOan5+ohf+z1pP8lQY/GHZQMV4YD3FpXDp4qerqbF/lBWBswyi+AL+ia+maLgcRRQj4IYlY/UpauqKBsPJAxQF8NM1TRQ/RudSPAD34rK3scOuR8/HGcspxsJfOVS8NZbiGXiUtPgINU3v3WFDmx8pEuG3EiqKKVbCC1vm2iZqap5LAtCtleQf8F9sFYWDohzeJczYyQ4V2bEZFGsQgJRGqqqhS2phHTWn9lDkIhBTqWqxQZ+IsRvtdHY9AvI2VX2hW68nfqGmuQsCEl3JdjfCF8OW1bPdtwhQ0gm2mQzfRE3a7KCYj0BNZJs8+Kxf/r6WtTEI2FIqlsMfFgRB5A6KUnSe/vUkX0AnuvUIt8SjM1m6wWQymUwmk8lkMgXRf5vi8rLQxtUhAAAAAElFTkSuQmCC`;
|
||||||
const image6 = Media.addImage(doc, Buffer.from(imageBase64Data, "base64"), 100, 100);
|
const image6 = Media.addImage(doc, Buffer.from(imageBase64Data, "base64"), 100, 100);
|
||||||
|
@ -8,7 +8,7 @@ const doc = new Document();
|
|||||||
const table = doc.createTable(4, 4);
|
const table = doc.createTable(4, 4);
|
||||||
table.getCell(2, 2).addContent(new Paragraph("Hello"));
|
table.getCell(2, 2).addContent(new Paragraph("Hello"));
|
||||||
|
|
||||||
const image = Media.addImage(doc, "./demo/images/image1.jpeg");
|
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
table.getCell(1, 1).addContent(image.Paragraph);
|
table.getCell(1, 1).addContent(image.Paragraph);
|
||||||
|
|
||||||
const packer = new Packer();
|
const packer = new Packer();
|
||||||
|
@ -30,5 +30,4 @@ const packer = new Packer();
|
|||||||
|
|
||||||
packer.toBuffer(doc).then((buffer) => {
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
console.log("Document created successfully at project root!");
|
|
||||||
});
|
});
|
||||||
|
29
demo/demo30.ts
Normal file
29
demo/demo30.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, ImportDotx, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
|
const importDotx = new ImportDotx();
|
||||||
|
const filePath = "./demo/dotx/template.dotx";
|
||||||
|
|
||||||
|
fs.readFile(filePath, (err, data) => {
|
||||||
|
if (err) {
|
||||||
|
throw new Error(`Failed to read file ${filePath}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
importDotx.extract(data).then((templateDocument) => {
|
||||||
|
// This any needs fixing
|
||||||
|
const sectionProps = {
|
||||||
|
titlePage: templateDocument.titlePageIsDefined,
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
const doc = new Document(undefined, sectionProps, {
|
||||||
|
template: templateDocument,
|
||||||
|
});
|
||||||
|
const paragraph = new Paragraph("Hello World");
|
||||||
|
doc.addParagraph(paragraph);
|
||||||
|
|
||||||
|
const packer = new Packer();
|
||||||
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
26
demo/demo31.ts
Normal file
26
demo/demo31.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Example of how you would create a table and add data to it
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Packer, Paragraph, VerticalAlign } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const table = doc.createTable(2, 2);
|
||||||
|
table
|
||||||
|
.getCell(1, 1)
|
||||||
|
.addContent(new Paragraph("This text should be in the middle of the cell"))
|
||||||
|
.CellProperties.setVerticalAlign(VerticalAlign.CENTER);
|
||||||
|
|
||||||
|
table
|
||||||
|
.getCell(1, 0)
|
||||||
|
.addContent(
|
||||||
|
new Paragraph(
|
||||||
|
"Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah",
|
||||||
|
).heading1(),
|
||||||
|
);
|
||||||
|
|
||||||
|
const packer = new Packer();
|
||||||
|
|
||||||
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
35
demo/demo32.ts
Normal file
35
demo/demo32.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Example of how you would create a table and add data to it
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
let table = doc.createTable(2, 2);
|
||||||
|
|
||||||
|
table.getCell(0, 0).addContent(new Paragraph("Hello"));
|
||||||
|
table.getRow(0).mergeCells(0, 1);
|
||||||
|
|
||||||
|
doc.createParagraph("Another table").heading2();
|
||||||
|
|
||||||
|
table = doc.createTable(2, 3);
|
||||||
|
table.getCell(0, 0).addContent(new Paragraph("World"));
|
||||||
|
table.getRow(0).mergeCells(0, 2);
|
||||||
|
|
||||||
|
doc.createParagraph("Another table").heading2();
|
||||||
|
|
||||||
|
table = doc.createTable(2, 4);
|
||||||
|
table.getCell(0, 0).addContent(new Paragraph("Foo"));
|
||||||
|
|
||||||
|
table.getCell(1, 0).addContent(new Paragraph("Bar1"));
|
||||||
|
table.getCell(1, 1).addContent(new Paragraph("Bar2"));
|
||||||
|
table.getCell(1, 2).addContent(new Paragraph("Bar3"));
|
||||||
|
table.getCell(1, 3).addContent(new Paragraph("Bar4"));
|
||||||
|
|
||||||
|
table.getRow(0).mergeCells(0, 3);
|
||||||
|
|
||||||
|
const packer = new Packer();
|
||||||
|
|
||||||
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
22
demo/demo33.ts
Normal file
22
demo/demo33.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Sequential Captions
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Packer, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const paragraph = new Paragraph("Hello World 1->").addSequentialIdentifier("Caption").addRun(new TextRun(" text after sequencial caption 2->")).addSequentialIdentifier("Caption");
|
||||||
|
const paragraph2 = new Paragraph("Hello World 1->").addSequentialIdentifier("Label").addRun(new TextRun(" text after sequencial caption 2->")).addSequentialIdentifier("Label");
|
||||||
|
const paragraph3 = new Paragraph("Hello World 1->").addSequentialIdentifier("Another").addRun(new TextRun(" text after sequencial caption 3->")).addSequentialIdentifier("Label");
|
||||||
|
const paragraph4 = new Paragraph("Hello World 2->").addSequentialIdentifier("Another").addRun(new TextRun(" text after sequencial caption 4->")).addSequentialIdentifier("Label");
|
||||||
|
|
||||||
|
doc.addParagraph(paragraph);
|
||||||
|
doc.addParagraph(paragraph2);
|
||||||
|
doc.addParagraph(paragraph3);
|
||||||
|
doc.addParagraph(paragraph4);
|
||||||
|
|
||||||
|
const packer = new Packer();
|
||||||
|
|
||||||
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
32
demo/demo34.ts
Normal file
32
demo/demo34.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Example of how you would create a table with float positions
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {
|
||||||
|
Document,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
RelativeHorizontalPosition,
|
||||||
|
RelativeVerticalPosition,
|
||||||
|
TableAnchorType,
|
||||||
|
WidthType,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const table = doc.createTable(2, 2).float({
|
||||||
|
horizontalAnchor: TableAnchorType.MARGIN,
|
||||||
|
verticalAnchor: TableAnchorType.MARGIN,
|
||||||
|
relativeHorizontalPosition: RelativeHorizontalPosition.RIGHT,
|
||||||
|
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
|
||||||
|
});
|
||||||
|
table.setFixedWidthLayout();
|
||||||
|
table.setWidth(WidthType.DXA, 4535);
|
||||||
|
|
||||||
|
table.getCell(0, 0).addContent(new Paragraph("Hello"));
|
||||||
|
table.getRow(0).mergeCells(0, 1);
|
||||||
|
|
||||||
|
const packer = new Packer();
|
||||||
|
|
||||||
|
packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
BIN
demo/dotx/template.dotx
Normal file
BIN
demo/dotx/template.dotx
Normal file
Binary file not shown.
@ -1,7 +1,5 @@
|
|||||||
# Contribution Guidelines
|
# Contribution Guidelines
|
||||||
|
|
||||||
## Writing Code
|
|
||||||
|
|
||||||
* Include documentation reference(s) at the top of each file:
|
* Include documentation reference(s) at the top of each file:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@ -12,6 +10,59 @@
|
|||||||
|
|
||||||
* Follow the `TSLint` rules
|
* Follow the `TSLint` rules
|
||||||
|
|
||||||
|
## Always think about the user
|
||||||
|
|
||||||
|
The number one pillar for contribution is to **ALWAYS** think about how the user will use the library.
|
||||||
|
|
||||||
|
Put yourself in their position, and imagine how they would feel about your feature you wrote.
|
||||||
|
|
||||||
|
1. Is it easy to use?
|
||||||
|
2. Has it been documented well?
|
||||||
|
3. Is it intuative?
|
||||||
|
4. Is it consistent with the rest of the API?
|
||||||
|
5. Is it fun to use?
|
||||||
|
|
||||||
|
## Good Commit Names
|
||||||
|
|
||||||
|
Please write good commit messages when making a commit: https://chris.beams.io/posts/git-commit/
|
||||||
|
|
||||||
|
**Do not:**
|
||||||
|
```
|
||||||
|
c // What?
|
||||||
|
rtl // Adding acryonyms without explaining anything else is not helpful
|
||||||
|
works! // Glad its working, but the message is not helpful
|
||||||
|
demo updated // Getting better, but capitalize the first letter
|
||||||
|
Unesesary coment removed // Make sure to use correct spelling
|
||||||
|
```
|
||||||
|
|
||||||
|
## No leaky components in API interface
|
||||||
|
|
||||||
|
This mainly applies to the API the end user will consume.
|
||||||
|
|
||||||
|
Try to make method parameters accept primatives, or `json` objects, so that child components are created **inside** the component, rather than being **injected** in.
|
||||||
|
|
||||||
|
This is so that:
|
||||||
|
|
||||||
|
1. Imports are much cleaner, no need for:
|
||||||
|
```js
|
||||||
|
import { ChildComponent } from "./my-feature/sub-component/deeper/.../my-deep.component";
|
||||||
|
```
|
||||||
|
|
||||||
|
2. This is what I consider "leakage". The code is aware of the underlying implementation of the component.
|
||||||
|
3. It means the end user does not need to import and create the child component to be injected.
|
||||||
|
|
||||||
|
**Do not**
|
||||||
|
`TableFloatProperties` is a class. The outside world would have to construct the object, and inject it in
|
||||||
|
```js
|
||||||
|
public float(tableFloatProperties: TableFloatProperties): Table
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do**
|
||||||
|
`ITableFloatOptions` is an interface for a JSON of primatives.
|
||||||
|
```js
|
||||||
|
public float(tableFloatOptions: ITableFloatOptions): Table
|
||||||
|
```
|
||||||
|
|
||||||
## Add vs Create
|
## Add vs Create
|
||||||
|
|
||||||
This is just a guideline, and the rules can sometimes be broken.
|
This is just a guideline, and the rules can sometimes be broken.
|
||||||
@ -39,7 +90,7 @@ Getters and Setters are done with a capital letter like so:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
public get Level() {
|
public get Level() {
|
||||||
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -57,6 +108,86 @@ private get _level: string;
|
|||||||
private get level: string;
|
private get level: string;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Interfaces over type alias
|
||||||
|
|
||||||
|
Do not use `type`, but rather use `Interfaces`. `type` cannot be extended, and a class cannot implement it.
|
||||||
|
|
||||||
|
> "In general, use what you want ( type alias / interface ) just be consistent"
|
||||||
|
> "always use interface for public API's definition when authoring a library or 3rd party ambient type definitions"
|
||||||
|
>
|
||||||
|
> * https://medium.com/@martin_hotell/interface-vs-type-alias-in-typescript-2-7-2a8f1777af4c
|
||||||
|
|
||||||
|
`Interface` is generally preferred over `type`: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
|
||||||
|
|
||||||
|
**Do not:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
type RelationshipFileInfo = { id: number, target: string };
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
interface IRelationshipFileInfo {
|
||||||
|
id: number;
|
||||||
|
target: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## String enums vs type
|
||||||
|
|
||||||
|
To take full advantage of TypeScript's typing system, its best to use `string enums`:
|
||||||
|
|
||||||
|
**Do not:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
type WeaponType = "bow" | "sword" | "wand";
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
enum WeaponType = {
|
||||||
|
BOW = "bow",
|
||||||
|
SWORD = "sword",
|
||||||
|
WAND = "wand",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Spell correctly, full and in American English
|
||||||
|
|
||||||
|
I am not sure where these habits in software development come from, but I do not believe it is beneficial:
|
||||||
|
|
||||||
|
**Do not:**
|
||||||
|
```js
|
||||||
|
readdy // misspelling
|
||||||
|
perm // abbreviation
|
||||||
|
conf // abbreviation
|
||||||
|
cnty // abbreviation
|
||||||
|
relationFile // abbreviation
|
||||||
|
colour // U.K. English
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do:**
|
||||||
|
```js
|
||||||
|
ready
|
||||||
|
permission
|
||||||
|
config
|
||||||
|
country
|
||||||
|
relationshipFile
|
||||||
|
color
|
||||||
|
```
|
||||||
|
|
||||||
|
## Keep files small (within reason)
|
||||||
|
|
||||||
|
To minimize merge conflicts, reduce complexity, and improve readability, keep the files small.
|
||||||
|
|
||||||
|
## Name files and folders with `/foo-bar/kebab-case.ts`
|
||||||
|
|
||||||
|
To be consistent and in-line with the project, name files `like-this.ts`.
|
||||||
|
|
||||||
|
https://stackoverflow.com/questions/7273316/what-is-the-javascript-filename-naming-convention
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Please write a test of every file you make and suffix it with `.spec.ts`.
|
Please write a test of every file you make and suffix it with `.spec.ts`.
|
||||||
@ -78,3 +209,5 @@ describe("ClassName", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Try not to use the `tests/utility.ts` file as this is being deprecated.
|
||||||
|
@ -75,7 +75,7 @@ abstractNum.createLevel(0, "upperRoman", "%1", "start").addParagraphProperty(new
|
|||||||
abstractNum.createLevel(1, "decimal", "%2.", "start").addParagraphProperty(new Indent(1440, 980));
|
abstractNum.createLevel(1, "decimal", "%2.", "start").addParagraphProperty(new Indent(1440, 980));
|
||||||
abstractNum.createLevel(2, "lowerLetter", "%3)", "start").addParagraphProperty(new Indent(2160, 1700));
|
abstractNum.createLevel(2, "lowerLetter", "%3)", "start").addParagraphProperty(new Indent(2160, 1700));
|
||||||
|
|
||||||
const concrete = numbering.createConcreteNumbering(numberedAbstract);
|
const concrete = numbering.createConcreteNumbering(abstractNum);
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then apply your concrete style to paragraphs using their
|
You can then apply your concrete style to paragraphs using their
|
||||||
|
17
package.json
17
package.json
@ -1,22 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "docx",
|
"name": "docx",
|
||||||
"version": "4.2.0",
|
"version": "4.4.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",
|
"pretest": "rimraf ./build",
|
||||||
"test": "mocha-webpack \"src/**/*.ts\"",
|
"test": "mocha-webpack \"src/**/*.ts\"",
|
||||||
"test-watch": "mocha-webpack \"src/**/*.ts\" --watch",
|
"test.coverage": "nyc npm test",
|
||||||
|
"test.watch": "npm test -- --watch",
|
||||||
"prepublishOnly": "npm run build",
|
"prepublishOnly": "npm run build",
|
||||||
"lint": "tslint --project .",
|
"lint": "tslint --project .",
|
||||||
"build": "npm run webpack && npm run fix-types",
|
"build": "npm run webpack && npm run fix-types",
|
||||||
"tsc": "rimraf ./build && tsc -p .",
|
"tsc": "rimraf ./build && tsc -p .",
|
||||||
"webpack": "rimraf ./build && webpack",
|
"webpack": "rimraf ./build && webpack",
|
||||||
"build.web": "webpack --config webpack.web.config.js",
|
|
||||||
"demo": "npm run build && npm run ts-node ./demo",
|
"demo": "npm run build && npm run ts-node ./demo",
|
||||||
"typedoc": "typedoc src/index.ts",
|
"typedoc": "typedoc src/index.ts",
|
||||||
"style": "prettier -l \"src/**/*.ts\"",
|
"style": "prettier -l \"src/**/*.ts\"",
|
||||||
"style.fix": "prettier \"src/**/*.ts\" --write",
|
"style.fix": "npm run style -- --write",
|
||||||
"fix-types": "node types-absolute-fixer.js",
|
"fix-types": "node types-absolute-fixer.js",
|
||||||
"ts-node": "ts-node"
|
"ts-node": "ts-node"
|
||||||
},
|
},
|
||||||
@ -48,11 +48,11 @@
|
|||||||
"types": "./build/index.d.ts",
|
"types": "./build/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/image-size": "0.0.29",
|
"@types/image-size": "0.0.29",
|
||||||
"@types/jszip": "^3.1.3",
|
"@types/jszip": "^3.1.4",
|
||||||
"fast-xml-parser": "^3.3.6",
|
|
||||||
"image-size": "^0.6.2",
|
"image-size": "^0.6.2",
|
||||||
"jszip": "^3.1.5",
|
"jszip": "^3.1.5",
|
||||||
"xml": "^1.0.1"
|
"xml": "^1.0.1",
|
||||||
|
"xml-js": "^1.6.8"
|
||||||
},
|
},
|
||||||
"author": "Dolan Miu",
|
"author": "Dolan Miu",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -67,9 +67,11 @@
|
|||||||
"awesome-typescript-loader": "^3.4.1",
|
"awesome-typescript-loader": "^3.4.1",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
|
"istanbul-instrumenter-loader": "^3.0.1",
|
||||||
"jszip": "^3.1.5",
|
"jszip": "^3.1.5",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"mocha-webpack": "^1.0.1",
|
"mocha-webpack": "^1.0.1",
|
||||||
|
"nyc": "^13.1.0",
|
||||||
"pre-commit": "^1.2.2",
|
"pre-commit": "^1.2.2",
|
||||||
"prettier": "^1.12.1",
|
"prettier": "^1.12.1",
|
||||||
"prompt": "^1.0.0",
|
"prompt": "^1.0.0",
|
||||||
@ -79,6 +81,7 @@
|
|||||||
"sinon": "^5.0.7",
|
"sinon": "^5.0.7",
|
||||||
"ts-node": "^7.0.1",
|
"ts-node": "^7.0.1",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^5.11.0",
|
||||||
|
"tslint-immutable": "^4.9.0",
|
||||||
"typedoc": "^0.11.1",
|
"typedoc": "^0.11.1",
|
||||||
"typescript": "2.9.2",
|
"typescript": "2.9.2",
|
||||||
"webpack": "^3.10.0"
|
"webpack": "^3.10.0"
|
||||||
|
@ -2,6 +2,12 @@ import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
|
|||||||
|
|
||||||
export class Formatter {
|
export class Formatter {
|
||||||
public format(input: BaseXmlComponent): IXmlableObject {
|
public format(input: BaseXmlComponent): IXmlableObject {
|
||||||
return input.prepForXml();
|
const output = input.prepForXml();
|
||||||
|
|
||||||
|
if (output) {
|
||||||
|
return output;
|
||||||
|
} else {
|
||||||
|
throw Error("XMLComponent did not format correctly");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* tslint:disable:typedef space-before-function-paren */
|
/* tslint:disable:typedef space-before-function-paren */
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import { File } from "../../file";
|
|
||||||
|
import { File } from "file";
|
||||||
|
|
||||||
import { Compiler } from "./next-compiler";
|
import { Compiler } from "./next-compiler";
|
||||||
|
|
||||||
describe("Compiler", () => {
|
describe("Compiler", () => {
|
||||||
|
@ -5,25 +5,25 @@ import { File } from "file";
|
|||||||
import { Formatter } from "../formatter";
|
import { Formatter } from "../formatter";
|
||||||
|
|
||||||
interface IXmlifyedFile {
|
interface IXmlifyedFile {
|
||||||
data: string;
|
readonly data: string;
|
||||||
path: string;
|
readonly path: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IXmlifyedFileMapping {
|
interface IXmlifyedFileMapping {
|
||||||
Document: IXmlifyedFile;
|
readonly Document: IXmlifyedFile;
|
||||||
Styles: IXmlifyedFile;
|
readonly Styles: IXmlifyedFile;
|
||||||
Properties: IXmlifyedFile;
|
readonly Properties: IXmlifyedFile;
|
||||||
Numbering: IXmlifyedFile;
|
readonly Numbering: IXmlifyedFile;
|
||||||
Relationships: IXmlifyedFile;
|
readonly Relationships: IXmlifyedFile;
|
||||||
FileRelationships: IXmlifyedFile;
|
readonly FileRelationships: IXmlifyedFile;
|
||||||
Headers: IXmlifyedFile[];
|
readonly Headers: IXmlifyedFile[];
|
||||||
Footers: IXmlifyedFile[];
|
readonly Footers: IXmlifyedFile[];
|
||||||
HeaderRelationships: IXmlifyedFile[];
|
readonly HeaderRelationships: IXmlifyedFile[];
|
||||||
FooterRelationships: IXmlifyedFile[];
|
readonly FooterRelationships: IXmlifyedFile[];
|
||||||
ContentTypes: IXmlifyedFile;
|
readonly ContentTypes: IXmlifyedFile;
|
||||||
AppProperties: IXmlifyedFile;
|
readonly AppProperties: IXmlifyedFile;
|
||||||
FootNotes: IXmlifyedFile;
|
readonly FootNotes: IXmlifyedFile;
|
||||||
Settings: IXmlifyedFile;
|
readonly Settings: IXmlifyedFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Compiler {
|
export class Compiler {
|
||||||
@ -59,6 +59,18 @@ export class Compiler {
|
|||||||
zip.file(`word/media/${data.fileName}`, mediaData);
|
zip.file(`word/media/${data.fileName}`, mediaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const header of file.Headers) {
|
||||||
|
for (const data of header.Media.Array) {
|
||||||
|
zip.file(`word/media/${data.fileName}`, data.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const footer of file.Footers) {
|
||||||
|
for (const data of footer.Media.Array) {
|
||||||
|
zip.file(`word/media/${data.fileName}`, data.stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,4 +140,13 @@ export class Compiler {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* By default docx collapse empty tags. <a></a> -> <a/>. this function mimic it
|
||||||
|
so comparing (diff) original docx file and the library output is easier
|
||||||
|
Currently not used, so commenting out */
|
||||||
|
// private collapseEmptyTags(xmlData: string): string {
|
||||||
|
// const regEx = /<(([^ <>]+)[^<>]*)><\/\2>/g;
|
||||||
|
// const collapsed = xmlData.replace(regEx, "<$1/>");
|
||||||
|
// return collapsed;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
import { stub } from "sinon";
|
import { stub } from "sinon";
|
||||||
|
|
||||||
import { File, Paragraph } from "../../file";
|
import { File, Paragraph } from "file";
|
||||||
|
|
||||||
import { Packer } from "./packer";
|
import { Packer } from "./packer";
|
||||||
|
|
||||||
describe("Packer", () => {
|
describe("Packer", () => {
|
||||||
|
@ -10,21 +10,30 @@ export class Packer {
|
|||||||
|
|
||||||
public async toBuffer(file: File): Promise<Buffer> {
|
public async toBuffer(file: File): Promise<Buffer> {
|
||||||
const zip = await this.compiler.compile(file);
|
const zip = await this.compiler.compile(file);
|
||||||
const zipData = (await zip.generateAsync({ type: "nodebuffer" })) as Buffer;
|
const zipData = (await zip.generateAsync({
|
||||||
|
type: "nodebuffer",
|
||||||
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
})) as Buffer;
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async toBase64String(file: File): Promise<string> {
|
public async toBase64String(file: File): Promise<string> {
|
||||||
const zip = await this.compiler.compile(file);
|
const zip = await this.compiler.compile(file);
|
||||||
const zipData = (await zip.generateAsync({ type: "base64" })) as string;
|
const zipData = (await zip.generateAsync({
|
||||||
|
type: "base64",
|
||||||
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
})) as string;
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async toBlob(file: File): Promise<Blob> {
|
public async toBlob(file: File): Promise<Blob> {
|
||||||
const zip = await this.compiler.compile(file);
|
const zip = await this.compiler.compile(file);
|
||||||
const zipData = (await zip.generateAsync({ type: "blob" })) as Blob;
|
const zipData = (await zip.generateAsync({
|
||||||
|
type: "blob",
|
||||||
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
|
})) as Blob;
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IAppPropertiesAttributes {
|
export interface IAppPropertiesAttributes {
|
||||||
xmlns: string;
|
readonly xmlns: string;
|
||||||
vt: string;
|
readonly vt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppPropertiesAttributes extends XmlAttributeComponent<IAppPropertiesAttributes> {
|
export class AppPropertiesAttributes extends XmlAttributeComponent<IAppPropertiesAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
xmlns: "xmlns",
|
xmlns: "xmlns",
|
||||||
vt: "xmlns:vt",
|
vt: "xmlns:vt",
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IContentTypeAttributes {
|
export interface IContentTypeAttributes {
|
||||||
xmlns?: string;
|
readonly xmlns?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContentTypeAttributes extends XmlAttributeComponent<IContentTypeAttributes> {
|
export class ContentTypeAttributes extends XmlAttributeComponent<IContentTypeAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
xmlns: "xmlns",
|
xmlns: "xmlns",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
// tslint:disable:no-string-literal
|
// tslint:disable:no-string-literal
|
||||||
|
|
||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import { Formatter } from "../../export/formatter";
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { ContentTypes } from "./content-types";
|
import { ContentTypes } from "./content-types";
|
||||||
|
|
||||||
describe("ContentTypes", () => {
|
describe("ContentTypes", () => {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IDefaultAttributes {
|
export interface IDefaultAttributes {
|
||||||
contentType: string;
|
readonly contentType: string;
|
||||||
extension?: string;
|
readonly extension?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DefaultAttributes extends XmlAttributeComponent<IDefaultAttributes> {
|
export class DefaultAttributes extends XmlAttributeComponent<IDefaultAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
contentType: "ContentType",
|
contentType: "ContentType",
|
||||||
extension: "Extension",
|
extension: "Extension",
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IOverrideAttributes {
|
export interface IOverrideAttributes {
|
||||||
contentType: string;
|
readonly contentType: string;
|
||||||
partName?: string;
|
readonly partName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OverrideAttributes extends XmlAttributeComponent<IOverrideAttributes> {
|
export class OverrideAttributes extends XmlAttributeComponent<IOverrideAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
contentType: "ContentType",
|
contentType: "ContentType",
|
||||||
partName: "PartName",
|
partName: "PartName",
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { CoreProperties } from "./properties";
|
import { CoreProperties } from "./properties";
|
||||||
|
|
||||||
describe("Properties", () => {
|
describe("Properties", () => {
|
||||||
|
@ -3,14 +3,14 @@ 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 {
|
||||||
title?: string;
|
readonly title?: string;
|
||||||
subject?: string;
|
readonly subject?: string;
|
||||||
creator?: string;
|
readonly creator?: string;
|
||||||
keywords?: string;
|
readonly keywords?: string;
|
||||||
description?: string;
|
readonly description?: string;
|
||||||
lastModifiedBy?: string;
|
readonly lastModifiedBy?: string;
|
||||||
revision?: string;
|
readonly revision?: string;
|
||||||
externalStyles?: string;
|
readonly externalStyles?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CoreProperties extends XmlComponent {
|
export class CoreProperties extends XmlComponent {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { Body } from "./body";
|
import { Body } from "./body";
|
||||||
|
|
||||||
describe("Body", () => {
|
describe("Body", () => {
|
||||||
@ -16,11 +17,11 @@ describe("Body", () => {
|
|||||||
expect(formatted)
|
expect(formatted)
|
||||||
.to.have.property("w:sectPr")
|
.to.have.property("w:sectPr")
|
||||||
.and.to.be.an.instanceof(Array);
|
.and.to.be.an.instanceof(Array);
|
||||||
expect(formatted["w:sectPr"]).to.have.length(7);
|
expect(formatted["w:sectPr"]).to.have.length(5);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("addSection", () => {
|
describe("#addSection", () => {
|
||||||
it("should add section with options", () => {
|
it("should add section with options", () => {
|
||||||
body.addSection({
|
body.addSection({
|
||||||
width: 10000,
|
width: 10000,
|
||||||
@ -38,5 +39,93 @@ describe("Body", () => {
|
|||||||
const newSection = formatted[1]["w:sectPr"];
|
const newSection = formatted[1]["w:sectPr"];
|
||||||
expect(newSection[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } }] });
|
expect(newSection[0]).to.deep.equal({ "w:pgSz": [{ _attr: { "w:h": 10000, "w:w": 10000, "w:orient": "portrait" } }] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should add section with default parameters", () => {
|
||||||
|
body.addSection({
|
||||||
|
width: 10000,
|
||||||
|
height: 10000,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(body);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:body": [
|
||||||
|
{
|
||||||
|
"w:p": [
|
||||||
|
{ "w:pPr": [] },
|
||||||
|
{
|
||||||
|
"w:pPr": [
|
||||||
|
{
|
||||||
|
"w:sectPr": [
|
||||||
|
{ "w:pgSz": [{ _attr: { "w:w": 11906, "w:h": 16838, "w:orient": "portrait" } }] },
|
||||||
|
{
|
||||||
|
"w:pgMar": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:top": 1440,
|
||||||
|
"w:right": 1440,
|
||||||
|
"w:bottom": 1440,
|
||||||
|
"w:left": 1440,
|
||||||
|
"w:header": 708,
|
||||||
|
"w:footer": 708,
|
||||||
|
"w:gutter": 0,
|
||||||
|
"w:mirrorMargins": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ "w:cols": [{ _attr: { "w:space": 708 } }] },
|
||||||
|
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] },
|
||||||
|
{ "w:pgNumType": [{ _attr: { "w:fmt": "decimal" } }] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:sectPr": [
|
||||||
|
{ "w:pgSz": [{ _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } }] },
|
||||||
|
{
|
||||||
|
"w:pgMar": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"w:top": 1440,
|
||||||
|
"w:right": 1440,
|
||||||
|
"w:bottom": 1440,
|
||||||
|
"w:left": 1440,
|
||||||
|
"w:header": 708,
|
||||||
|
"w:footer": 708,
|
||||||
|
"w:gutter": 0,
|
||||||
|
"w:mirrorMargins": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ "w:cols": [{ _attr: { "w:space": 708 } }] },
|
||||||
|
{ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] },
|
||||||
|
{ "w:pgNumType": [{ _attr: { "w:fmt": "decimal" } }] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#getParagraphs", () => {
|
||||||
|
it("should get no paragraphs", () => {
|
||||||
|
const paragraphs = body.getParagraphs();
|
||||||
|
|
||||||
|
expect(paragraphs).to.be.an.instanceof(Array);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#DefaultSection", () => {
|
||||||
|
it("should get section", () => {
|
||||||
|
const section = body.DefaultSection;
|
||||||
|
|
||||||
|
const tree = new Formatter().format(section);
|
||||||
|
expect(tree["w:sectPr"]).to.be.an.instanceof(Array);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -35,11 +35,9 @@ export class Body extends XmlComponent {
|
|||||||
this.sections.push(new SectionProperties(params));
|
this.sections.push(new SectionProperties(params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public prepForXml(): IXmlableObject {
|
public prepForXml(): IXmlableObject | undefined {
|
||||||
if (this.sections.length === 1) {
|
if (this.sections.length === 1) {
|
||||||
this.root.push(this.sections[0]);
|
this.root.push(this.sections[0]);
|
||||||
} else if (this.sections.length > 1) {
|
|
||||||
throw new Error("Invalid usage of sections. At the end of the body element there must be ONE section.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.prepForXml();
|
return super.prepForXml();
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IColumnsAttributes {
|
export interface IColumnsAttributes {
|
||||||
space?: number;
|
readonly space?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
space: "w:space",
|
space: "w:space",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IDocGridAttributesProperties {
|
export interface IDocGridAttributesProperties {
|
||||||
linePitch?: number;
|
readonly linePitch?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesProperties> {
|
export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
linePitch: "w:linePitch",
|
linePitch: "w:linePitch",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@ export enum FooterReferenceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IFooterReferenceAttributes {
|
export interface IFooterReferenceAttributes {
|
||||||
type: string;
|
readonly type: string;
|
||||||
id: string;
|
readonly id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FooterReferenceAttributes extends XmlAttributeComponent<IFooterReferenceAttributes> {
|
export class FooterReferenceAttributes extends XmlAttributeComponent<IFooterReferenceAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
type: "w:type",
|
type: "w:type",
|
||||||
id: "r:id",
|
id: "r:id",
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@ import { XmlComponent } from "file/xml-components";
|
|||||||
import { FooterReferenceAttributes, FooterReferenceType } from "./footer-reference-attributes";
|
import { FooterReferenceAttributes, FooterReferenceType } from "./footer-reference-attributes";
|
||||||
|
|
||||||
export interface IFooterOptions {
|
export interface IFooterOptions {
|
||||||
footerType?: FooterReferenceType;
|
readonly footerType?: FooterReferenceType;
|
||||||
footerId?: number;
|
readonly footerId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FooterReference extends XmlComponent {
|
export class FooterReference extends XmlComponent {
|
||||||
|
@ -7,12 +7,12 @@ export enum HeaderReferenceType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IHeaderReferenceAttributes {
|
export interface IHeaderReferenceAttributes {
|
||||||
type: string;
|
readonly type: string;
|
||||||
id: string;
|
readonly id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HeaderReferenceAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
|
export class HeaderReferenceAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
type: "w:type",
|
type: "w:type",
|
||||||
id: "r:id",
|
id: "r:id",
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@ import { XmlComponent } from "file/xml-components";
|
|||||||
import { HeaderReferenceAttributes, HeaderReferenceType } from "./header-reference-attributes";
|
import { HeaderReferenceAttributes, HeaderReferenceType } from "./header-reference-attributes";
|
||||||
|
|
||||||
export interface IHeaderOptions {
|
export interface IHeaderOptions {
|
||||||
headerType?: HeaderReferenceType;
|
readonly headerType?: HeaderReferenceType;
|
||||||
headerId?: number;
|
readonly headerId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HeaderReference extends XmlComponent {
|
export class HeaderReference extends XmlComponent {
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../../../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
import { BorderStyle } from "../../../../styles";
|
import { BorderStyle } from "file/styles";
|
||||||
|
|
||||||
import { PageBorderDisplay, PageBorders, PageBorderZOrder } from "./page-borders";
|
import { PageBorderDisplay, PageBorders, PageBorderZOrder } from "./page-borders";
|
||||||
|
|
||||||
describe("PageBorders", () => {
|
describe("PageBorders", () => {
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
it("should create empty element when no options are passed", () => {
|
it("should create empty element when no options are passed", () => {
|
||||||
const properties = new PageBorders();
|
const properties = new PageBorders();
|
||||||
const tree = new Formatter().format(properties);
|
expect(() => new Formatter().format(properties)).to.throw();
|
||||||
|
|
||||||
expect(tree).to.equal("");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create page borders with some configuration", () => {
|
it("should create page borders with some configuration", () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// http://officeopenxml.com/WPsectionBorders.php
|
// http://officeopenxml.com/WPsectionBorders.php
|
||||||
|
import { BorderStyle } from "file/styles";
|
||||||
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
import { BorderStyle } from "../../../../styles";
|
|
||||||
|
|
||||||
export enum PageBorderDisplay {
|
export enum PageBorderDisplay {
|
||||||
ALL_PAGES = "allPages",
|
ALL_PAGES = "allPages",
|
||||||
@ -19,28 +19,28 @@ export enum PageBorderZOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageBorderAttributes {
|
export interface IPageBorderAttributes {
|
||||||
display?: PageBorderDisplay;
|
readonly display?: PageBorderDisplay;
|
||||||
offsetFrom?: PageBorderOffsetFrom;
|
readonly offsetFrom?: PageBorderOffsetFrom;
|
||||||
zOrder?: PageBorderZOrder;
|
readonly zOrder?: PageBorderZOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageBorderConfiguration {
|
export interface IPageBorderConfiguration {
|
||||||
style?: BorderStyle;
|
readonly style?: BorderStyle;
|
||||||
size?: number;
|
readonly size?: number;
|
||||||
color?: string;
|
readonly color?: string;
|
||||||
space?: number;
|
readonly space?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageBordersOptions {
|
export interface IPageBordersOptions {
|
||||||
pageBorders?: IPageBorderAttributes;
|
readonly pageBorders?: IPageBorderAttributes;
|
||||||
pageBorderTop?: IPageBorderConfiguration;
|
readonly pageBorderTop?: IPageBorderConfiguration;
|
||||||
pageBorderRight?: IPageBorderConfiguration;
|
readonly pageBorderRight?: IPageBorderConfiguration;
|
||||||
pageBorderBottom?: IPageBorderConfiguration;
|
readonly pageBorderBottom?: IPageBorderConfiguration;
|
||||||
pageBorderLeft?: IPageBorderConfiguration;
|
readonly pageBorderLeft?: IPageBorderConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PageBordeAttributes extends XmlAttributeComponent<IPageBorderConfiguration> {
|
class PageBordeAttributes extends XmlAttributeComponent<IPageBorderConfiguration> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
style: "w:val",
|
style: "w:val",
|
||||||
size: "w:size",
|
size: "w:size",
|
||||||
color: "w:color",
|
color: "w:color",
|
||||||
@ -57,7 +57,7 @@ class PageBorder extends XmlComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes> {
|
class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
display: "w:display",
|
display: "w:display",
|
||||||
offsetFrom: "w:offsetFrom",
|
offsetFrom: "w:offsetFrom",
|
||||||
zOrder: "w:zOrder",
|
zOrder: "w:zOrder",
|
||||||
@ -98,7 +98,9 @@ export class PageBorders extends XmlComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepForXml(): IXmlableObject {
|
public prepForXml(): IXmlableObject | undefined {
|
||||||
return this.root.length > 0 ? super.prepForXml() : "";
|
if (this.root.length > 0) {
|
||||||
|
return super.prepForXml();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IPageMarginAttributes {
|
export interface IPageMarginAttributes {
|
||||||
top?: number;
|
readonly top?: number;
|
||||||
right?: number;
|
readonly right?: number;
|
||||||
bottom?: number;
|
readonly bottom?: number;
|
||||||
left?: number;
|
readonly left?: number;
|
||||||
header?: number;
|
readonly header?: number;
|
||||||
footer?: number;
|
readonly footer?: number;
|
||||||
gutter?: number;
|
readonly gutter?: number;
|
||||||
mirror?: boolean;
|
readonly mirror?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttributes> {
|
export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
top: "w:top",
|
top: "w:top",
|
||||||
right: "w:right",
|
right: "w:right",
|
||||||
bottom: "w:bottom",
|
bottom: "w:bottom",
|
||||||
|
@ -17,12 +17,12 @@ export enum PageNumberFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageNumberTypeAttributes {
|
export interface IPageNumberTypeAttributes {
|
||||||
pageNumberStart?: number;
|
readonly pageNumberStart?: number;
|
||||||
pageNumberFormatType?: PageNumberFormat;
|
readonly pageNumberFormatType?: PageNumberFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberTypeAttributes> {
|
export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberTypeAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
pageNumberStart: "w:start",
|
pageNumberStart: "w:start",
|
||||||
pageNumberFormatType: "w:fmt",
|
pageNumberFormatType: "w:fmt",
|
||||||
};
|
};
|
||||||
|
@ -6,13 +6,13 @@ export enum PageOrientation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageSizeAttributes {
|
export interface IPageSizeAttributes {
|
||||||
width?: number;
|
readonly width?: number;
|
||||||
height?: number;
|
readonly height?: number;
|
||||||
orientation?: PageOrientation;
|
readonly orientation?: PageOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttributes> {
|
export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
width: "w:w",
|
width: "w:w",
|
||||||
height: "w:h",
|
height: "w:h",
|
||||||
orientation: "w:orient",
|
orientation: "w:orient",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../../../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { PageSize } from "./page-size";
|
import { PageSize } from "./page-size";
|
||||||
import { PageOrientation } from "./page-size-attributes";
|
import { PageOrientation } from "./page-size-attributes";
|
||||||
|
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
import { FooterReferenceType, PageBorderOffsetFrom, PageNumberFormat } from "./";
|
import { FooterWrapper } from "file/footer-wrapper";
|
||||||
|
import { HeaderWrapper } from "file/header-wrapper";
|
||||||
|
import { Media } from "file/media";
|
||||||
|
|
||||||
|
import { PageBorderOffsetFrom } from "./page-border";
|
||||||
|
import { PageNumberFormat } from "./page-number";
|
||||||
import { SectionProperties } from "./section-properties";
|
import { SectionProperties } from "./section-properties";
|
||||||
|
|
||||||
describe("SectionProperties", () => {
|
describe("SectionProperties", () => {
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
it("should create section properties with options", () => {
|
it("should create section properties with options", () => {
|
||||||
|
const media = new Media();
|
||||||
|
|
||||||
const properties = new SectionProperties({
|
const properties = new SectionProperties({
|
||||||
width: 11906,
|
width: 11906,
|
||||||
height: 16838,
|
height: 16838,
|
||||||
@ -20,9 +27,12 @@ describe("SectionProperties", () => {
|
|||||||
mirror: false,
|
mirror: false,
|
||||||
space: 708,
|
space: 708,
|
||||||
linePitch: 360,
|
linePitch: 360,
|
||||||
headerId: 100,
|
headers: {
|
||||||
footerId: 200,
|
default: new HeaderWrapper(media, 100),
|
||||||
footerType: FooterReferenceType.EVEN,
|
},
|
||||||
|
footers: {
|
||||||
|
even: new FooterWrapper(media, 200),
|
||||||
|
},
|
||||||
pageNumberStart: 10,
|
pageNumberStart: 10,
|
||||||
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,
|
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,
|
||||||
});
|
});
|
||||||
@ -78,9 +88,7 @@ describe("SectionProperties", () => {
|
|||||||
});
|
});
|
||||||
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] });
|
expect(tree["w:sectPr"][2]).to.deep.equal({ "w:cols": [{ _attr: { "w:space": 708 } }] });
|
||||||
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] });
|
expect(tree["w:sectPr"][3]).to.deep.equal({ "w:docGrid": [{ _attr: { "w:linePitch": 360 } }] });
|
||||||
expect(tree["w:sectPr"][4]).to.deep.equal({ "w:headerReference": [{ _attr: { "r:id": "rId0", "w:type": "default" } }] });
|
expect(tree["w:sectPr"][4]).to.deep.equal({ "w:pgNumType": [{ _attr: { "w:fmt": "decimal" } }] });
|
||||||
expect(tree["w:sectPr"][5]).to.deep.equal({ "w:footerReference": [{ _attr: { "r:id": "rId0", "w:type": "default" } }] });
|
|
||||||
expect(tree["w:sectPr"][6]).to.deep.equal({ "w:pgNumType": [{ _attr: { "w:fmt": "decimal" } }] });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create section properties with changed options", () => {
|
it("should create section properties with changed options", () => {
|
||||||
@ -170,7 +178,8 @@ describe("SectionProperties", () => {
|
|||||||
});
|
});
|
||||||
const tree = new Formatter().format(properties);
|
const tree = new Formatter().format(properties);
|
||||||
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
expect(Object.keys(tree)).to.deep.equal(["w:sectPr"]);
|
||||||
expect(tree["w:sectPr"][7]).to.deep.equal({
|
const pgBorders = tree["w:sectPr"].find((item) => item["w:pgBorders"] !== undefined);
|
||||||
|
expect(pgBorders).to.deep.equal({
|
||||||
"w:pgBorders": [{ _attr: { "w:offsetFrom": "page" } }],
|
"w:pgBorders": [{ _attr: { "w:offsetFrom": "page" } }],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,115 +1,172 @@
|
|||||||
// http://officeopenxml.com/WPsection.php
|
// http://officeopenxml.com/WPsection.php
|
||||||
|
import { FooterWrapper } from "file/footer-wrapper";
|
||||||
|
import { HeaderWrapper } from "file/header-wrapper";
|
||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
import { FooterReferenceType, IPageBordersOptions, IPageNumberTypeAttributes, PageBorders, PageNumberFormat, PageNumberType } from "./";
|
|
||||||
import { Columns } from "./columns/columns";
|
import { Columns } from "./columns/columns";
|
||||||
import { IColumnsAttributes } from "./columns/columns-attributes";
|
import { IColumnsAttributes } from "./columns/columns-attributes";
|
||||||
import { DocumentGrid } from "./doc-grid/doc-grid";
|
import { DocumentGrid } from "./doc-grid/doc-grid";
|
||||||
import { IDocGridAttributesProperties } from "./doc-grid/doc-grid-attributes";
|
import { IDocGridAttributesProperties } from "./doc-grid/doc-grid-attributes";
|
||||||
import { FooterReference, IFooterOptions } from "./footer-reference/footer-reference";
|
import { FooterReferenceType } from "./footer-reference";
|
||||||
import { HeaderReference, IHeaderOptions } from "./header-reference/header-reference";
|
import { FooterReference } from "./footer-reference/footer-reference";
|
||||||
import { HeaderReferenceType } from "./header-reference/header-reference-attributes";
|
import { HeaderReferenceType } from "./header-reference";
|
||||||
|
import { HeaderReference } from "./header-reference/header-reference";
|
||||||
|
import { IPageBordersOptions, PageBorders } from "./page-border";
|
||||||
import { PageMargin } from "./page-margin/page-margin";
|
import { PageMargin } from "./page-margin/page-margin";
|
||||||
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
|
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
|
||||||
|
import { IPageNumberTypeAttributes, PageNumberFormat, PageNumberType } from "./page-number";
|
||||||
import { PageSize } from "./page-size/page-size";
|
import { PageSize } from "./page-size/page-size";
|
||||||
import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes";
|
import { IPageSizeAttributes, PageOrientation } from "./page-size/page-size-attributes";
|
||||||
|
import { TitlePage } from "./title-page/title-page";
|
||||||
|
|
||||||
|
export interface IHeaderFooterGroup<T> {
|
||||||
|
readonly default?: T;
|
||||||
|
readonly first?: T;
|
||||||
|
readonly even?: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IHeadersOptions {
|
||||||
|
readonly headers?: IHeaderFooterGroup<HeaderWrapper>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IFootersOptions {
|
||||||
|
readonly footers?: IHeaderFooterGroup<FooterWrapper>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITitlePageOptions {
|
||||||
|
readonly titlePage?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export type SectionPropertiesOptions = IPageSizeAttributes &
|
export type SectionPropertiesOptions = IPageSizeAttributes &
|
||||||
IPageMarginAttributes &
|
IPageMarginAttributes &
|
||||||
IColumnsAttributes &
|
IColumnsAttributes &
|
||||||
IDocGridAttributesProperties &
|
IDocGridAttributesProperties &
|
||||||
IHeaderOptions &
|
IHeadersOptions &
|
||||||
IFooterOptions &
|
IFootersOptions &
|
||||||
IPageNumberTypeAttributes &
|
IPageNumberTypeAttributes &
|
||||||
IPageBordersOptions;
|
IPageBordersOptions &
|
||||||
|
ITitlePageOptions;
|
||||||
|
|
||||||
export class SectionProperties extends XmlComponent {
|
export class SectionProperties extends XmlComponent {
|
||||||
private readonly options: SectionPropertiesOptions;
|
private readonly options: SectionPropertiesOptions;
|
||||||
|
|
||||||
constructor(options?: SectionPropertiesOptions) {
|
constructor(options: SectionPropertiesOptions = {}) {
|
||||||
super("w:sectPr");
|
super("w:sectPr");
|
||||||
|
|
||||||
const defaultOptions = {
|
const {
|
||||||
width: 11906,
|
width = 11906,
|
||||||
height: 16838,
|
height = 16838,
|
||||||
top: 1440,
|
top = 1440,
|
||||||
right: 1440,
|
right = 1440,
|
||||||
bottom: 1440,
|
bottom = 1440,
|
||||||
left: 1440,
|
left = 1440,
|
||||||
header: 708,
|
header = 708,
|
||||||
footer: 708,
|
footer = 708,
|
||||||
gutter: 0,
|
gutter = 0,
|
||||||
mirror: false,
|
mirror = false,
|
||||||
space: 708,
|
space = 708,
|
||||||
linePitch: 360,
|
linePitch = 360,
|
||||||
orientation: PageOrientation.PORTRAIT,
|
orientation = PageOrientation.PORTRAIT,
|
||||||
headerType: HeaderReferenceType.DEFAULT,
|
headers,
|
||||||
headerId: 0,
|
footers,
|
||||||
footerType: FooterReferenceType.DEFAULT,
|
pageNumberFormatType = PageNumberFormat.DECIMAL,
|
||||||
footerId: 0,
|
pageNumberStart,
|
||||||
pageNumberStart: undefined,
|
pageBorders,
|
||||||
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
pageBorderTop,
|
||||||
pageBorders: undefined,
|
pageBorderRight,
|
||||||
pageBorderTop: undefined,
|
pageBorderBottom,
|
||||||
pageBorderRight: undefined,
|
pageBorderLeft,
|
||||||
pageBorderBottom: undefined,
|
titlePage = false,
|
||||||
pageBorderLeft: undefined,
|
} = options;
|
||||||
};
|
|
||||||
|
|
||||||
const mergedOptions = {
|
this.options = options;
|
||||||
...defaultOptions,
|
this.root.push(new PageSize(width, height, orientation));
|
||||||
...options,
|
this.root.push(new PageMargin(top, right, bottom, left, header, footer, gutter, mirror));
|
||||||
};
|
this.root.push(new Columns(space));
|
||||||
|
this.root.push(new DocumentGrid(linePitch));
|
||||||
|
|
||||||
this.root.push(new PageSize(mergedOptions.width, mergedOptions.height, mergedOptions.orientation));
|
this.addHeaders(headers);
|
||||||
this.root.push(
|
this.addFooters(footers);
|
||||||
new PageMargin(
|
|
||||||
mergedOptions.top,
|
|
||||||
mergedOptions.right,
|
|
||||||
mergedOptions.bottom,
|
|
||||||
mergedOptions.left,
|
|
||||||
mergedOptions.header,
|
|
||||||
mergedOptions.footer,
|
|
||||||
mergedOptions.gutter,
|
|
||||||
mergedOptions.mirror,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
this.root.push(new Columns(mergedOptions.space));
|
|
||||||
this.root.push(new DocumentGrid(mergedOptions.linePitch));
|
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(new PageNumberType(pageNumberStart, pageNumberFormatType));
|
||||||
new HeaderReference({
|
|
||||||
headerType: mergedOptions.headerType,
|
|
||||||
headerId: mergedOptions.headerId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
this.root.push(
|
|
||||||
new FooterReference({
|
|
||||||
footerType: mergedOptions.footerType,
|
|
||||||
footerId: mergedOptions.footerId,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.root.push(new PageNumberType(mergedOptions.pageNumberStart, mergedOptions.pageNumberFormatType));
|
if (pageBorders || pageBorderTop || pageBorderRight || pageBorderBottom || pageBorderLeft) {
|
||||||
|
|
||||||
if (
|
|
||||||
mergedOptions.pageBorders ||
|
|
||||||
mergedOptions.pageBorderTop ||
|
|
||||||
mergedOptions.pageBorderRight ||
|
|
||||||
mergedOptions.pageBorderBottom ||
|
|
||||||
mergedOptions.pageBorderLeft
|
|
||||||
) {
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new PageBorders({
|
new PageBorders({
|
||||||
pageBorders: mergedOptions.pageBorders,
|
pageBorders: pageBorders,
|
||||||
pageBorderTop: mergedOptions.pageBorderTop,
|
pageBorderTop: pageBorderTop,
|
||||||
pageBorderRight: mergedOptions.pageBorderRight,
|
pageBorderRight: pageBorderRight,
|
||||||
pageBorderBottom: mergedOptions.pageBorderBottom,
|
pageBorderBottom: pageBorderBottom,
|
||||||
pageBorderLeft: mergedOptions.pageBorderLeft,
|
pageBorderLeft: pageBorderLeft,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.options = mergedOptions;
|
if (titlePage) {
|
||||||
|
this.root.push(new TitlePage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addHeaders(headers?: IHeaderFooterGroup<HeaderWrapper>): void {
|
||||||
|
if (headers) {
|
||||||
|
if (headers.default) {
|
||||||
|
this.root.push(
|
||||||
|
new HeaderReference({
|
||||||
|
headerType: HeaderReferenceType.DEFAULT,
|
||||||
|
headerId: headers.default.Header.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers.first) {
|
||||||
|
this.root.push(
|
||||||
|
new HeaderReference({
|
||||||
|
headerType: HeaderReferenceType.FIRST,
|
||||||
|
headerId: headers.first.Header.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers.even) {
|
||||||
|
this.root.push(
|
||||||
|
new HeaderReference({
|
||||||
|
headerType: HeaderReferenceType.EVEN,
|
||||||
|
headerId: headers.even.Header.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addFooters(footers?: IHeaderFooterGroup<FooterWrapper>): void {
|
||||||
|
if (footers) {
|
||||||
|
if (footers.default) {
|
||||||
|
this.root.push(
|
||||||
|
new FooterReference({
|
||||||
|
footerType: FooterReferenceType.DEFAULT,
|
||||||
|
footerId: footers.default.Footer.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (footers.first) {
|
||||||
|
this.root.push(
|
||||||
|
new FooterReference({
|
||||||
|
footerType: FooterReferenceType.FIRST,
|
||||||
|
footerId: footers.first.Footer.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (footers.even) {
|
||||||
|
this.root.push(
|
||||||
|
new FooterReference({
|
||||||
|
footerType: FooterReferenceType.EVEN,
|
||||||
|
footerId: footers.even.Footer.ReferenceId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get Options(): SectionPropertiesOptions {
|
public get Options(): SectionPropertiesOptions {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IHeaderReferenceAttributes {
|
export interface IHeaderReferenceAttributes {
|
||||||
value: string;
|
readonly value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TitlePageAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
|
export class TitlePageAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
value: "w:val",
|
value: "w:val",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../../../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { TitlePage } from "./title-page";
|
import { TitlePage } from "./title-page";
|
||||||
|
|
||||||
describe("PageSize", () => {
|
describe("PageSize", () => {
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IDocumentAttributesProperties {
|
export interface IDocumentAttributesProperties {
|
||||||
wpc?: string;
|
readonly wpc?: string;
|
||||||
mc?: string;
|
readonly mc?: string;
|
||||||
o?: string;
|
readonly o?: string;
|
||||||
r?: string;
|
readonly r?: string;
|
||||||
m?: string;
|
readonly m?: string;
|
||||||
v?: string;
|
readonly v?: string;
|
||||||
wp14?: string;
|
readonly wp14?: string;
|
||||||
wp?: string;
|
readonly wp?: string;
|
||||||
w10?: string;
|
readonly w10?: string;
|
||||||
w?: string;
|
readonly w?: string;
|
||||||
w14?: string;
|
readonly w14?: string;
|
||||||
w15?: string;
|
readonly w15?: string;
|
||||||
wpg?: string;
|
readonly wpg?: string;
|
||||||
wpi?: string;
|
readonly wpi?: string;
|
||||||
wne?: string;
|
readonly wne?: string;
|
||||||
wps?: string;
|
readonly wps?: string;
|
||||||
Ignorable?: string;
|
readonly Ignorable?: string;
|
||||||
cp?: string;
|
readonly cp?: string;
|
||||||
dc?: string;
|
readonly dc?: string;
|
||||||
dcterms?: string;
|
readonly dcterms?: string;
|
||||||
dcmitype?: string;
|
readonly dcmitype?: string;
|
||||||
xsi?: string;
|
readonly xsi?: string;
|
||||||
type?: string;
|
readonly type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
|
export class DocumentAttributes extends XmlAttributeComponent<IDocumentAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
wpc: "xmlns:wpc",
|
wpc: "xmlns:wpc",
|
||||||
mc: "xmlns:mc",
|
mc: "xmlns:mc",
|
||||||
o: "xmlns:o",
|
o: "xmlns:o",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { assert, expect } from "chai";
|
import { assert, expect } from "chai";
|
||||||
|
|
||||||
import { Formatter } from "../../export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { Paragraph } from "../paragraph";
|
import { Paragraph } from "../paragraph";
|
||||||
import { Table } from "../table";
|
import { Table } from "../table";
|
||||||
import { Document } from "./document";
|
import { Document } from "./document";
|
||||||
|
@ -2,16 +2,16 @@ import { XmlAttributeComponent } from "file/xml-components";
|
|||||||
import { IDistance } from "../drawing";
|
import { IDistance } from "../drawing";
|
||||||
|
|
||||||
export interface IAnchorAttributes extends IDistance {
|
export interface IAnchorAttributes extends IDistance {
|
||||||
allowOverlap?: "0" | "1";
|
readonly allowOverlap?: "0" | "1";
|
||||||
behindDoc?: "0" | "1";
|
readonly behindDoc?: "0" | "1";
|
||||||
layoutInCell?: "0" | "1";
|
readonly layoutInCell?: "0" | "1";
|
||||||
locked?: "0" | "1";
|
readonly locked?: "0" | "1";
|
||||||
relativeHeight?: number;
|
readonly relativeHeight?: number;
|
||||||
simplePos?: "0" | "1";
|
readonly simplePos?: "0" | "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AnchorAttributes extends XmlAttributeComponent<IAnchorAttributes> {
|
export class AnchorAttributes extends XmlAttributeComponent<IAnchorAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
distT: "distT",
|
distT: "distT",
|
||||||
distB: "distB",
|
distB: "distB",
|
||||||
distL: "distL",
|
distL: "distL",
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { Utility } from "../../../tests/utility";
|
import { Utility } from "tests/utility";
|
||||||
import { IDrawingOptions, TextWrapStyle } from ".././";
|
|
||||||
import { Anchor } from "./";
|
import { IDrawingOptions } from "../drawing";
|
||||||
|
import { TextWrapStyle } from "../text-wrap";
|
||||||
|
import { Anchor } from "./anchor";
|
||||||
|
|
||||||
function createDrawing(drawingOptions: IDrawingOptions): Anchor {
|
function createDrawing(drawingOptions: IDrawingOptions): Anchor {
|
||||||
return new Anchor(
|
return new Anchor(
|
||||||
@ -101,7 +103,7 @@ describe("Anchor", () => {
|
|||||||
assert.equal(graphic.rootKey, "a:graphic");
|
assert.equal(graphic.rootKey, "a:graphic");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create a Drawing with text wrapping", () => {
|
it("should create a Drawing with square text wrapping", () => {
|
||||||
anchor = createDrawing({
|
anchor = createDrawing({
|
||||||
textWrapping: {
|
textWrapping: {
|
||||||
textWrapStyle: TextWrapStyle.SQUARE,
|
textWrapStyle: TextWrapStyle.SQUARE,
|
||||||
@ -114,5 +116,44 @@ describe("Anchor", () => {
|
|||||||
const textWrap = newJson.root[6];
|
const textWrap = newJson.root[6];
|
||||||
assert.equal(textWrap.rootKey, "wp:wrapSquare");
|
assert.equal(textWrap.rootKey, "wp:wrapSquare");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should create a Drawing with no text wrapping", () => {
|
||||||
|
anchor = createDrawing({
|
||||||
|
textWrapping: {
|
||||||
|
textWrapStyle: TextWrapStyle.NONE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const newJson = Utility.jsonify(anchor);
|
||||||
|
assert.equal(newJson.root.length, 10);
|
||||||
|
|
||||||
|
const textWrap = newJson.root[6];
|
||||||
|
assert.equal(textWrap.rootKey, "wp:wrapNone");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a Drawing with tight text wrapping", () => {
|
||||||
|
anchor = createDrawing({
|
||||||
|
textWrapping: {
|
||||||
|
textWrapStyle: TextWrapStyle.TIGHT,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const newJson = Utility.jsonify(anchor);
|
||||||
|
assert.equal(newJson.root.length, 10);
|
||||||
|
|
||||||
|
const textWrap = newJson.root[6];
|
||||||
|
assert.equal(textWrap.rootKey, "wp:wrapTight");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a Drawing with tight text wrapping", () => {
|
||||||
|
anchor = createDrawing({
|
||||||
|
textWrapping: {
|
||||||
|
textWrapStyle: TextWrapStyle.TOP_AND_BOTTOM,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const newJson = Utility.jsonify(anchor);
|
||||||
|
assert.equal(newJson.root.length, 10);
|
||||||
|
|
||||||
|
const textWrap = newJson.root[6];
|
||||||
|
assert.equal(textWrap.rootKey, "wp:wrapTopAndBottom");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IDocPropertiesAttributes {
|
export interface IDocPropertiesAttributes {
|
||||||
id?: number;
|
readonly id?: number;
|
||||||
name?: string;
|
readonly name?: string;
|
||||||
descr?: string;
|
readonly descr?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DocPropertiesAttributes extends XmlAttributeComponent<IDocPropertiesAttributes> {
|
export class DocPropertiesAttributes extends XmlAttributeComponent<IDocPropertiesAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
id: "id",
|
id: "id",
|
||||||
name: "name",
|
name: "name",
|
||||||
descr: "descr",
|
descr: "descr",
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { Utility } from "../../tests/utility";
|
import { Utility } from "tests/utility";
|
||||||
import { Drawing, IDrawingOptions, PlacementPosition } from "./";
|
|
||||||
|
import { Drawing, IDrawingOptions, PlacementPosition } from "./drawing";
|
||||||
|
|
||||||
const imageBase64Data = `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`;
|
const imageBase64Data = `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`;
|
||||||
|
|
||||||
|
@ -11,16 +11,16 @@ export enum PlacementPosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IDistance {
|
export interface IDistance {
|
||||||
distT?: number;
|
readonly distT?: number;
|
||||||
distB?: number;
|
readonly distB?: number;
|
||||||
distL?: number;
|
readonly distL?: number;
|
||||||
distR?: number;
|
readonly distR?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDrawingOptions {
|
export interface IDrawingOptions {
|
||||||
position?: PlacementPosition;
|
readonly position?: PlacementPosition;
|
||||||
textWrapping?: ITextWrapping;
|
readonly textWrapping?: ITextWrapping;
|
||||||
floating?: IFloating;
|
readonly floating?: IFloating;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDrawingOptions: IDrawingOptions = {
|
const defaultDrawingOptions: IDrawingOptions = {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IEffectExtentAttributes {
|
export interface IEffectExtentAttributes {
|
||||||
b?: number;
|
readonly b?: number;
|
||||||
l?: number;
|
readonly l?: number;
|
||||||
r?: number;
|
readonly r?: number;
|
||||||
t?: number;
|
readonly t?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EffectExtentAttributes extends XmlAttributeComponent<IEffectExtentAttributes> {
|
export class EffectExtentAttributes extends XmlAttributeComponent<IEffectExtentAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
b: "b",
|
b: "b",
|
||||||
l: "l",
|
l: "l",
|
||||||
r: "r",
|
r: "r",
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IExtentAttributes {
|
export interface IExtentAttributes {
|
||||||
cx?: number;
|
readonly cx?: number;
|
||||||
cy?: number;
|
readonly cy?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExtentAttributes extends XmlAttributeComponent<IExtentAttributes> {
|
export class ExtentAttributes extends XmlAttributeComponent<IExtentAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
cx: "cx",
|
cx: "cx",
|
||||||
cy: "cy",
|
cy: "cy",
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
import { ExtentAttributes } from "./extent-attributes";
|
import { ExtentAttributes } from "./extent-attributes";
|
||||||
|
|
||||||
export class Extent extends XmlComponent {
|
export class Extent extends XmlComponent {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { VerticalPositionAlign } from ".";
|
import { Utility } from "tests/utility";
|
||||||
import { Utility } from "../../../tests/utility";
|
|
||||||
import { Align } from "./align";
|
import { Align } from "./align";
|
||||||
|
import { VerticalPositionAlign } from "./floating-position";
|
||||||
|
|
||||||
describe("Align", () => {
|
describe("Align", () => {
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
|
@ -39,22 +39,22 @@ export enum VerticalPositionAlign {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IHorizontalPositionOptions {
|
export interface IHorizontalPositionOptions {
|
||||||
relative: HorizontalPositionRelativeFrom;
|
readonly relative: HorizontalPositionRelativeFrom;
|
||||||
align?: HorizontalPositionAlign;
|
readonly align?: HorizontalPositionAlign;
|
||||||
offset?: number;
|
readonly offset?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IVerticalPositionOptions {
|
export interface IVerticalPositionOptions {
|
||||||
relative: VerticalPositionRelativeFrom;
|
readonly relative: VerticalPositionRelativeFrom;
|
||||||
align?: VerticalPositionAlign;
|
readonly align?: VerticalPositionAlign;
|
||||||
offset?: number;
|
readonly offset?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IFloating {
|
export interface IFloating {
|
||||||
horizontalPosition: IHorizontalPositionOptions;
|
readonly horizontalPosition: IHorizontalPositionOptions;
|
||||||
verticalPosition: IVerticalPositionOptions;
|
readonly verticalPosition: IVerticalPositionOptions;
|
||||||
allowOverlap?: boolean;
|
readonly allowOverlap?: boolean;
|
||||||
lockAnchor?: boolean;
|
readonly lockAnchor?: boolean;
|
||||||
behindDocument?: boolean;
|
readonly behindDocument?: boolean;
|
||||||
layoutInCell?: boolean;
|
readonly layoutInCell?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { HorizontalPositionAlign, HorizontalPositionRelativeFrom } from ".";
|
import { Utility } from "tests/utility";
|
||||||
import { Utility } from "../../../tests/utility";
|
|
||||||
|
import { HorizontalPositionAlign, HorizontalPositionRelativeFrom } from "./floating-position";
|
||||||
import { HorizontalPosition } from "./horizontal-position";
|
import { HorizontalPosition } from "./horizontal-position";
|
||||||
|
|
||||||
describe("HorizontalPosition", () => {
|
describe("HorizontalPosition", () => {
|
||||||
|
@ -5,11 +5,11 @@ import { HorizontalPositionRelativeFrom, IHorizontalPositionOptions } from "./fl
|
|||||||
import { PositionOffset } from "./position-offset";
|
import { PositionOffset } from "./position-offset";
|
||||||
|
|
||||||
interface IHorizontalPositionAttributes {
|
interface IHorizontalPositionAttributes {
|
||||||
relativeFrom: HorizontalPositionRelativeFrom;
|
readonly relativeFrom: HorizontalPositionRelativeFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HorizontalPositionAttributes extends XmlAttributeComponent<IHorizontalPositionAttributes> {
|
class HorizontalPositionAttributes extends XmlAttributeComponent<IHorizontalPositionAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
relativeFrom: "relativeFrom",
|
relativeFrom: "relativeFrom",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { Utility } from "../../../tests/utility";
|
import { Utility } from "tests/utility";
|
||||||
|
|
||||||
import { PositionOffset } from "./position-offset";
|
import { PositionOffset } from "./position-offset";
|
||||||
|
|
||||||
describe("PositionOffset", () => {
|
describe("PositionOffset", () => {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { Utility } from "../../../tests/utility";
|
import { Utility } from "tests/utility";
|
||||||
|
|
||||||
import { SimplePos } from "./simple-pos";
|
import { SimplePos } from "./simple-pos";
|
||||||
|
|
||||||
describe("SimplePos", () => {
|
describe("SimplePos", () => {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
interface ISimplePosAttributes {
|
interface ISimplePosAttributes {
|
||||||
x: number;
|
readonly x: number;
|
||||||
y: number;
|
readonly y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimplePosAttributes extends XmlAttributeComponent<ISimplePosAttributes> {
|
class SimplePosAttributes extends XmlAttributeComponent<ISimplePosAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
x: "x",
|
x: "x",
|
||||||
y: "y",
|
y: "y",
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { assert } from "chai";
|
import { assert } from "chai";
|
||||||
|
|
||||||
import { VerticalPositionAlign, VerticalPositionRelativeFrom } from ".";
|
import { Utility } from "tests/utility";
|
||||||
import { Utility } from "../../../tests/utility";
|
|
||||||
|
import { VerticalPositionAlign, VerticalPositionRelativeFrom } from "./floating-position";
|
||||||
import { VerticalPosition } from "./vertical-position";
|
import { VerticalPosition } from "./vertical-position";
|
||||||
|
|
||||||
describe("VerticalPosition", () => {
|
describe("VerticalPosition", () => {
|
||||||
|
@ -5,11 +5,11 @@ import { IVerticalPositionOptions, VerticalPositionRelativeFrom } from "./floati
|
|||||||
import { PositionOffset } from "./position-offset";
|
import { PositionOffset } from "./position-offset";
|
||||||
|
|
||||||
interface IVerticalPositionAttributes {
|
interface IVerticalPositionAttributes {
|
||||||
relativeFrom: VerticalPositionRelativeFrom;
|
readonly relativeFrom: VerticalPositionRelativeFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
class VerticalPositionAttributes extends XmlAttributeComponent<IVerticalPositionAttributes> {
|
class VerticalPositionAttributes extends XmlAttributeComponent<IVerticalPositionAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
relativeFrom: "relativeFrom",
|
relativeFrom: "relativeFrom",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IGraphicFrameLockAttributes {
|
export interface IGraphicFrameLockAttributes {
|
||||||
xmlns?: string;
|
readonly xmlns?: string;
|
||||||
noChangeAspect?: number;
|
readonly noChangeAspect?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GraphicFrameLockAttributes extends XmlAttributeComponent<IGraphicFrameLockAttributes> {
|
export class GraphicFrameLockAttributes extends XmlAttributeComponent<IGraphicFrameLockAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
xmlns: "xmlns:a",
|
xmlns: "xmlns:a",
|
||||||
noChangeAspect: "noChangeAspect",
|
noChangeAspect: "noChangeAspect",
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IGraphicDataAttributes {
|
export interface IGraphicDataAttributes {
|
||||||
uri?: string;
|
readonly uri?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GraphicDataAttributes extends XmlAttributeComponent<IGraphicDataAttributes> {
|
export class GraphicDataAttributes extends XmlAttributeComponent<IGraphicDataAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
uri: "uri",
|
uri: "uri",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
interface IBlipProperties {
|
interface IBlipProperties {
|
||||||
embed: string;
|
readonly embed: string;
|
||||||
cstate: string;
|
readonly cstate: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlipAttributes extends XmlAttributeComponent<IBlipProperties> {
|
class BlipAttributes extends XmlAttributeComponent<IBlipProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
embed: "r:embed",
|
embed: "r:embed",
|
||||||
cstate: "cstate",
|
cstate: "cstate",
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IPicLocksAttributes {
|
export interface IPicLocksAttributes {
|
||||||
noChangeAspect?: number;
|
readonly noChangeAspect?: number;
|
||||||
noChangeArrowheads?: number;
|
readonly noChangeArrowheads?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PicLocksAttributes extends XmlAttributeComponent<IPicLocksAttributes> {
|
export class PicLocksAttributes extends XmlAttributeComponent<IPicLocksAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
noChangeAspect: "noChangeAspect",
|
noChangeAspect: "noChangeAspect",
|
||||||
noChangeArrowheads: "noChangeArrowheads",
|
noChangeArrowheads: "noChangeArrowheads",
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface INonVisualPropertiesAttributes {
|
export interface INonVisualPropertiesAttributes {
|
||||||
id?: number;
|
readonly id?: number;
|
||||||
name?: string;
|
readonly name?: string;
|
||||||
descr?: string;
|
readonly descr?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NonVisualPropertiesAttributes extends XmlAttributeComponent<INonVisualPropertiesAttributes> {
|
export class NonVisualPropertiesAttributes extends XmlAttributeComponent<INonVisualPropertiesAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
id: "id",
|
id: "id",
|
||||||
name: "name",
|
name: "name",
|
||||||
descr: "desc",
|
descr: "desc",
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IPicAttributes {
|
export interface IPicAttributes {
|
||||||
xmlns?: string;
|
readonly xmlns?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PicAttributes extends XmlAttributeComponent<IPicAttributes> {
|
export class PicAttributes extends XmlAttributeComponent<IPicAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
xmlns: "xmlns:pic",
|
xmlns: "xmlns:pic",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IExtentsAttributes {
|
export interface IExtentsAttributes {
|
||||||
cx?: number;
|
readonly cx?: number;
|
||||||
cy?: number;
|
readonly cy?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExtentsAttributes extends XmlAttributeComponent<IExtentsAttributes> {
|
export class ExtentsAttributes extends XmlAttributeComponent<IExtentsAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
cx: "cx",
|
cx: "cx",
|
||||||
cy: "cy",
|
cy: "cy",
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IOffsetAttributes {
|
export interface IOffsetAttributes {
|
||||||
x?: number;
|
readonly x?: number;
|
||||||
y?: number;
|
readonly y?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OffsetAttributes extends XmlAttributeComponent<IOffsetAttributes> {
|
export class OffsetAttributes extends XmlAttributeComponent<IOffsetAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
x: "x",
|
x: "x",
|
||||||
y: "y",
|
y: "y",
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IPresetGeometryAttributes {
|
export interface IPresetGeometryAttributes {
|
||||||
prst?: string;
|
readonly prst?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PresetGeometryAttributes extends XmlAttributeComponent<IPresetGeometryAttributes> {
|
export class PresetGeometryAttributes extends XmlAttributeComponent<IPresetGeometryAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
prst: "prst",
|
prst: "prst",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IShapePropertiesAttributes {
|
export interface IShapePropertiesAttributes {
|
||||||
bwMode?: string;
|
readonly bwMode?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ShapePropertiesAttributes extends XmlAttributeComponent<IShapePropertiesAttributes> {
|
export class ShapePropertiesAttributes extends XmlAttributeComponent<IShapePropertiesAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
bwMode: "bwMode",
|
bwMode: "bwMode",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
|||||||
import { GraphicData } from "./graphic-data";
|
import { GraphicData } from "./graphic-data";
|
||||||
|
|
||||||
interface IGraphicProperties {
|
interface IGraphicProperties {
|
||||||
a: string;
|
readonly a: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GraphicAttributes extends XmlAttributeComponent<IGraphicProperties> {
|
class GraphicAttributes extends XmlAttributeComponent<IGraphicProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
a: "xmlns:a",
|
a: "xmlns:a",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { IDistance } from "../drawing";
|
|||||||
export interface IInlineAttributes extends IDistance {}
|
export interface IInlineAttributes extends IDistance {}
|
||||||
|
|
||||||
export class InlineAttributes extends XmlAttributeComponent<IInlineAttributes> {
|
export class InlineAttributes extends XmlAttributeComponent<IInlineAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
distT: "distT",
|
distT: "distT",
|
||||||
distB: "distB",
|
distB: "distB",
|
||||||
distL: "distL",
|
distL: "distL",
|
||||||
|
@ -16,7 +16,7 @@ export enum WrapTextOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ITextWrapping {
|
export interface ITextWrapping {
|
||||||
textWrapStyle: TextWrapStyle;
|
readonly textWrapStyle: TextWrapStyle;
|
||||||
wrapTextOption?: WrapTextOption;
|
readonly wrapTextOption?: WrapTextOption;
|
||||||
distanceFromText?: IDistance;
|
readonly distanceFromText?: IDistance;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ import { ITextWrapping, WrapTextOption } from ".";
|
|||||||
import { IDistance } from "../drawing";
|
import { IDistance } from "../drawing";
|
||||||
|
|
||||||
interface IWrapSquareAttributes extends IDistance {
|
interface IWrapSquareAttributes extends IDistance {
|
||||||
wrapText?: WrapTextOption;
|
readonly wrapText?: WrapTextOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrapSquareAttributes extends XmlAttributeComponent<IWrapSquareAttributes> {
|
class WrapSquareAttributes extends XmlAttributeComponent<IWrapSquareAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
distT: "distT",
|
distT: "distT",
|
||||||
distB: "distB",
|
distB: "distB",
|
||||||
distL: "distL",
|
distL: "distL",
|
||||||
|
@ -3,25 +3,25 @@ import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
|||||||
import { IDistance } from "../drawing";
|
import { IDistance } from "../drawing";
|
||||||
|
|
||||||
interface IWrapTightAttributes {
|
interface IWrapTightAttributes {
|
||||||
distT?: number;
|
readonly distT?: number;
|
||||||
distB?: number;
|
readonly distB?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrapTightAttributes extends XmlAttributeComponent<IWrapTightAttributes> {
|
class WrapTightAttributes extends XmlAttributeComponent<IWrapTightAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
distT: "distT",
|
distT: "distT",
|
||||||
distB: "distB",
|
distB: "distB",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WrapTight extends XmlComponent {
|
export class WrapTight extends XmlComponent {
|
||||||
constructor(distanceFromText?: IDistance) {
|
constructor(
|
||||||
super("wp:wrapTight");
|
distanceFromText: IDistance = {
|
||||||
|
|
||||||
distanceFromText = distanceFromText || {
|
|
||||||
distT: 0,
|
distT: 0,
|
||||||
distB: 0,
|
distB: 0,
|
||||||
};
|
},
|
||||||
|
) {
|
||||||
|
super("wp:wrapTight");
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new WrapTightAttributes({
|
new WrapTightAttributes({
|
||||||
|
@ -3,25 +3,25 @@ import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
|||||||
import { IDistance } from "../drawing";
|
import { IDistance } from "../drawing";
|
||||||
|
|
||||||
interface IWrapTopAndBottomAttributes {
|
interface IWrapTopAndBottomAttributes {
|
||||||
distT?: number;
|
readonly distT?: number;
|
||||||
distB?: number;
|
readonly distB?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrapTopAndBottomAttributes extends XmlAttributeComponent<IWrapTopAndBottomAttributes> {
|
class WrapTopAndBottomAttributes extends XmlAttributeComponent<IWrapTopAndBottomAttributes> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
distT: "distT",
|
distT: "distT",
|
||||||
distB: "distB",
|
distB: "distB",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WrapTopAndBottom extends XmlComponent {
|
export class WrapTopAndBottom extends XmlComponent {
|
||||||
constructor(distanceFromText?: IDistance) {
|
constructor(
|
||||||
super("wp:wrapTopAndBottom");
|
distanceFromText: IDistance = {
|
||||||
|
|
||||||
distanceFromText = distanceFromText || {
|
|
||||||
distT: 0,
|
distT: 0,
|
||||||
distB: 0,
|
distB: 0,
|
||||||
};
|
},
|
||||||
|
) {
|
||||||
|
super("wp:wrapTopAndBottom");
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new WrapTopAndBottomAttributes({
|
new WrapTopAndBottomAttributes({
|
||||||
|
11
src/file/file-properties.ts
Normal file
11
src/file/file-properties.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { IDocumentTemplate } from "../import-dotx";
|
||||||
|
|
||||||
|
export interface IFileProperties {
|
||||||
|
readonly template?: IDocumentTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed because of: https://github.com/s-panferov/awesome-typescript-loader/issues/432
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
export const WORKAROUND = "";
|
58
src/file/file.spec.ts
Normal file
58
src/file/file.spec.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
|
import { File } from "./file";
|
||||||
|
|
||||||
|
describe("File", () => {
|
||||||
|
describe("#constructor", () => {
|
||||||
|
it("should create with correct headers", () => {
|
||||||
|
const doc = new File();
|
||||||
|
const header = doc.createHeader();
|
||||||
|
const footer = doc.createFooter();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
headers: {
|
||||||
|
default: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(doc.Document.Body);
|
||||||
|
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default");
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][5]["w:footerReference"][0]._attr["w:type"]).to.equal("default");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create with correct headers", () => {
|
||||||
|
const doc = new File();
|
||||||
|
const header = doc.createHeader();
|
||||||
|
const footer = doc.createFooter();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
headers: {
|
||||||
|
default: header,
|
||||||
|
first: header,
|
||||||
|
even: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
first: footer,
|
||||||
|
even: footer,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(doc.Document.Body);
|
||||||
|
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][4]["w:headerReference"][0]._attr["w:type"]).to.equal("default");
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][5]["w:headerReference"][0]._attr["w:type"]).to.equal("first");
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][6]["w:headerReference"][0]._attr["w:type"]).to.equal("even");
|
||||||
|
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][7]["w:footerReference"][0]._attr["w:type"]).to.equal("default");
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][8]["w:footerReference"][0]._attr["w:type"]).to.equal("first");
|
||||||
|
expect(tree["w:body"][1]["w:sectPr"][9]["w:footerReference"][0]._attr["w:type"]).to.equal("even");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
341
src/file/file.ts
341
src/file/file.ts
@ -2,10 +2,17 @@ import { AppProperties } from "./app-properties/app-properties";
|
|||||||
import { ContentTypes } from "./content-types/content-types";
|
import { ContentTypes } from "./content-types/content-types";
|
||||||
import { CoreProperties, IPropertiesOptions } from "./core-properties";
|
import { CoreProperties, IPropertiesOptions } from "./core-properties";
|
||||||
import { Document } from "./document";
|
import { Document } from "./document";
|
||||||
import { FooterReferenceType, HeaderReference, HeaderReferenceType, SectionPropertiesOptions } from "./document/body/section-properties";
|
import {
|
||||||
import { FooterWrapper } from "./footer-wrapper";
|
FooterReferenceType,
|
||||||
|
HeaderReference,
|
||||||
|
HeaderReferenceType,
|
||||||
|
IHeaderFooterGroup,
|
||||||
|
SectionPropertiesOptions,
|
||||||
|
} from "./document/body/section-properties";
|
||||||
|
import { IFileProperties } from "./file-properties";
|
||||||
|
import { FooterWrapper, IDocumentFooter } from "./footer-wrapper";
|
||||||
import { FootNotes } from "./footnotes";
|
import { FootNotes } from "./footnotes";
|
||||||
import { HeaderWrapper } from "./header-wrapper";
|
import { HeaderWrapper, IDocumentHeader } from "./header-wrapper";
|
||||||
import { Image, Media } from "./media";
|
import { Image, Media } from "./media";
|
||||||
import { Numbering } from "./numbering";
|
import { Numbering } from "./numbering";
|
||||||
import { Bookmark, Hyperlink, Paragraph } from "./paragraph";
|
import { Bookmark, Hyperlink, Paragraph } from "./paragraph";
|
||||||
@ -18,33 +25,53 @@ import { Table } from "./table";
|
|||||||
import { TableOfContents } from "./table-of-contents";
|
import { TableOfContents } from "./table-of-contents";
|
||||||
|
|
||||||
export class File {
|
export class File {
|
||||||
|
// tslint:disable-next-line:readonly-keyword
|
||||||
|
private currentRelationshipId: number = 1;
|
||||||
|
|
||||||
private readonly document: Document;
|
private readonly document: Document;
|
||||||
private styles: Styles;
|
private readonly headers: IDocumentHeader[] = [];
|
||||||
|
private readonly footers: IDocumentFooter[] = [];
|
||||||
|
private readonly docRelationships: Relationships;
|
||||||
private readonly coreProperties: CoreProperties;
|
private readonly coreProperties: CoreProperties;
|
||||||
private readonly numbering: Numbering;
|
private readonly numbering: Numbering;
|
||||||
private readonly media: Media;
|
private readonly media: Media;
|
||||||
private readonly docRelationships: Relationships;
|
|
||||||
private readonly fileRelationships: Relationships;
|
private readonly fileRelationships: Relationships;
|
||||||
private readonly headerWrapper: HeaderWrapper[] = [];
|
|
||||||
private readonly footerWrapper: FooterWrapper[] = [];
|
|
||||||
private readonly footNotes: FootNotes;
|
private readonly footNotes: FootNotes;
|
||||||
private readonly settings: Settings;
|
private readonly settings: Settings;
|
||||||
|
|
||||||
private readonly contentTypes: ContentTypes;
|
private readonly contentTypes: ContentTypes;
|
||||||
private readonly appProperties: AppProperties;
|
private readonly appProperties: AppProperties;
|
||||||
|
// tslint:disable-next-line:readonly-keyword
|
||||||
|
private styles: Styles;
|
||||||
|
|
||||||
private currentRelationshipId: number = 1;
|
constructor(
|
||||||
|
options: IPropertiesOptions = {
|
||||||
constructor(options?: IPropertiesOptions, sectionPropertiesOptions?: SectionPropertiesOptions) {
|
|
||||||
if (!options) {
|
|
||||||
options = {
|
|
||||||
creator: "Un-named",
|
creator: "Un-named",
|
||||||
revision: "1",
|
revision: "1",
|
||||||
lastModifiedBy: "Un-named",
|
lastModifiedBy: "Un-named",
|
||||||
};
|
},
|
||||||
|
sectionPropertiesOptions: SectionPropertiesOptions = {},
|
||||||
|
fileProperties: IFileProperties = {},
|
||||||
|
) {
|
||||||
|
this.coreProperties = new CoreProperties(options);
|
||||||
|
this.numbering = new Numbering();
|
||||||
|
this.docRelationships = new Relationships();
|
||||||
|
this.media = new Media();
|
||||||
|
this.fileRelationships = new Relationships();
|
||||||
|
this.appProperties = new AppProperties();
|
||||||
|
this.footNotes = new FootNotes();
|
||||||
|
this.contentTypes = new ContentTypes();
|
||||||
|
|
||||||
|
if (fileProperties.template) {
|
||||||
|
this.currentRelationshipId = fileProperties.template.currentRelationshipId + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.externalStyles) {
|
// set up styles
|
||||||
|
if (fileProperties.template && options.externalStyles) {
|
||||||
|
throw Error("can not use both template and external styles");
|
||||||
|
}
|
||||||
|
if (fileProperties.template) {
|
||||||
|
this.styles = fileProperties.template.styles;
|
||||||
|
} else if (options.externalStyles) {
|
||||||
const stylesFactory = new ExternalStylesFactory();
|
const stylesFactory = new ExternalStylesFactory();
|
||||||
this.styles = stylesFactory.newInstance(options.externalStyles);
|
this.styles = stylesFactory.newInstance(options.externalStyles);
|
||||||
} else {
|
} else {
|
||||||
@ -52,62 +79,31 @@ export class File {
|
|||||||
this.styles = stylesFactory.newInstance();
|
this.styles = stylesFactory.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.coreProperties = new CoreProperties(options);
|
this.addDefaultRelationships();
|
||||||
this.numbering = new Numbering();
|
|
||||||
this.docRelationships = new Relationships();
|
|
||||||
this.docRelationships.createRelationship(
|
|
||||||
this.currentRelationshipId++,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
|
|
||||||
"styles.xml",
|
|
||||||
);
|
|
||||||
this.docRelationships.createRelationship(
|
|
||||||
this.currentRelationshipId++,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
|
|
||||||
"numbering.xml",
|
|
||||||
);
|
|
||||||
this.contentTypes = new ContentTypes();
|
|
||||||
|
|
||||||
this.docRelationships.createRelationship(
|
if (fileProperties.template && fileProperties.template.headers) {
|
||||||
this.currentRelationshipId++,
|
for (const templateHeader of fileProperties.template.headers) {
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
|
this.addHeaderToDocument(templateHeader.header, templateHeader.type);
|
||||||
"footnotes.xml",
|
|
||||||
);
|
|
||||||
this.media = new Media();
|
|
||||||
|
|
||||||
const header = this.createHeader();
|
|
||||||
const footer = this.createFooter();
|
|
||||||
|
|
||||||
this.fileRelationships = new Relationships();
|
|
||||||
this.fileRelationships.createRelationship(
|
|
||||||
1,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
|
|
||||||
"word/document.xml",
|
|
||||||
);
|
|
||||||
this.fileRelationships.createRelationship(
|
|
||||||
2,
|
|
||||||
"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
|
|
||||||
"docProps/core.xml",
|
|
||||||
);
|
|
||||||
this.fileRelationships.createRelationship(
|
|
||||||
3,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
|
|
||||||
"docProps/app.xml",
|
|
||||||
);
|
|
||||||
this.appProperties = new AppProperties();
|
|
||||||
|
|
||||||
this.footNotes = new FootNotes();
|
|
||||||
if (!sectionPropertiesOptions) {
|
|
||||||
sectionPropertiesOptions = {
|
|
||||||
footerType: FooterReferenceType.DEFAULT,
|
|
||||||
headerType: HeaderReferenceType.DEFAULT,
|
|
||||||
headerId: header.Header.ReferenceId,
|
|
||||||
footerId: footer.Footer.ReferenceId,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
sectionPropertiesOptions.headerId = header.Header.ReferenceId;
|
|
||||||
sectionPropertiesOptions.footerId = footer.Footer.ReferenceId;
|
|
||||||
}
|
}
|
||||||
this.document = new Document(sectionPropertiesOptions);
|
} else {
|
||||||
|
this.createHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileProperties.template && fileProperties.template.footers) {
|
||||||
|
for (const templateFooter of fileProperties.template.footers) {
|
||||||
|
this.addFooterToDocument(templateFooter.footer, templateFooter.type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.createFooter();
|
||||||
|
}
|
||||||
|
|
||||||
|
const newSectionPropertiesOptions = {
|
||||||
|
...sectionPropertiesOptions,
|
||||||
|
headers: this.groupHeaders(this.headers, sectionPropertiesOptions.headers),
|
||||||
|
footers: this.groupFooters(this.footers, sectionPropertiesOptions.footers),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.document = new Document(newSectionPropertiesOptions);
|
||||||
this.settings = new Settings();
|
this.settings = new Settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +111,9 @@ export class File {
|
|||||||
this.document.addTableOfContents(toc);
|
this.document.addTableOfContents(toc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addParagraph(paragraph: Paragraph): void {
|
public addParagraph(paragraph: Paragraph): File {
|
||||||
this.document.addParagraph(paragraph);
|
this.document.addParagraph(paragraph);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createParagraph(text?: string): Paragraph {
|
public createParagraph(text?: string): Paragraph {
|
||||||
@ -144,8 +141,8 @@ export class File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public createHyperlink(link: string, text?: string): Hyperlink {
|
public createHyperlink(link: string, text?: string): Hyperlink {
|
||||||
text = text === undefined ? link : text;
|
const newText = text === undefined ? link : text;
|
||||||
const hyperlink = new Hyperlink(text, this.docRelationships.RelationshipCount);
|
const hyperlink = new Hyperlink(newText, this.docRelationships.RelationshipCount);
|
||||||
this.docRelationships.createRelationship(
|
this.docRelationships.createRelationship(
|
||||||
hyperlink.linkId,
|
hyperlink.linkId,
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
||||||
@ -156,16 +153,16 @@ export class File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public createInternalHyperLink(anchor: string, text?: string): Hyperlink {
|
public createInternalHyperLink(anchor: string, text?: string): Hyperlink {
|
||||||
text = text === undefined ? anchor : text;
|
const newText = text === undefined ? anchor : text;
|
||||||
const hyperlink = new Hyperlink(text, this.docRelationships.RelationshipCount, anchor);
|
const hyperlink = new Hyperlink(newText, this.docRelationships.RelationshipCount, anchor);
|
||||||
// NOTE: unlike File#createHyperlink(), since the link is to an internal bookmark
|
// NOTE: unlike File#createHyperlink(), since the link is to an internal bookmark
|
||||||
// we don't need to create a new relationship.
|
// we don't need to create a new relationship.
|
||||||
return hyperlink;
|
return hyperlink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createBookmark(name: string, text?: string): Bookmark {
|
public createBookmark(name: string, text?: string): Bookmark {
|
||||||
text = text === undefined ? name : text;
|
const newText = text === undefined ? name : text;
|
||||||
const bookmark = new Bookmark(name, text, this.docRelationships.RelationshipCount);
|
const bookmark = new Bookmark(name, newText, this.docRelationships.RelationshipCount);
|
||||||
return bookmark;
|
return bookmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,25 +176,13 @@ export class File {
|
|||||||
|
|
||||||
public createHeader(): HeaderWrapper {
|
public createHeader(): HeaderWrapper {
|
||||||
const header = new HeaderWrapper(this.media, this.currentRelationshipId++);
|
const header = new HeaderWrapper(this.media, this.currentRelationshipId++);
|
||||||
this.headerWrapper.push(header);
|
this.addHeaderToDocument(header);
|
||||||
this.docRelationships.createRelationship(
|
|
||||||
header.Header.ReferenceId,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
|
||||||
`header${this.headerWrapper.length}.xml`,
|
|
||||||
);
|
|
||||||
this.contentTypes.addHeader(this.headerWrapper.length);
|
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createFooter(): FooterWrapper {
|
public createFooter(): FooterWrapper {
|
||||||
const footer = new FooterWrapper(this.media, this.currentRelationshipId++);
|
const footer = new FooterWrapper(this.media, this.currentRelationshipId++);
|
||||||
this.footerWrapper.push(footer);
|
this.addFooterToDocument(footer);
|
||||||
this.docRelationships.createRelationship(
|
|
||||||
footer.Footer.ReferenceId,
|
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
|
||||||
`footer${this.footerWrapper.length}.xml`,
|
|
||||||
);
|
|
||||||
this.contentTypes.addFooter(this.footerWrapper.length);
|
|
||||||
return footer;
|
return footer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +199,152 @@ export class File {
|
|||||||
return headerWrapper;
|
return headerWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getFooterByReferenceNumber(refId: number): FooterWrapper {
|
||||||
|
const entry = this.footers.map((item) => item.footer).find((h) => h.Footer.ReferenceId === refId);
|
||||||
|
if (entry) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new Error(`There is no footer with given reference id ${refId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHeaderByReferenceNumber(refId: number): HeaderWrapper {
|
||||||
|
const entry = this.headers.map((item) => item.header).find((h) => h.Header.ReferenceId === refId);
|
||||||
|
if (entry) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
throw new Error(`There is no header with given reference id ${refId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public verifyUpdateFields(): void {
|
||||||
|
if (this.document.getTablesOfContents().length) {
|
||||||
|
this.settings.addUpdateFields();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addHeaderToDocument(header: HeaderWrapper, type: HeaderReferenceType = HeaderReferenceType.DEFAULT): void {
|
||||||
|
this.headers.push({ header, type });
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
header.Header.ReferenceId,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
||||||
|
`header${this.headers.length}.xml`,
|
||||||
|
);
|
||||||
|
this.contentTypes.addHeader(this.headers.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private addFooterToDocument(footer: FooterWrapper, type: FooterReferenceType = FooterReferenceType.DEFAULT): void {
|
||||||
|
this.footers.push({ footer, type });
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
footer.Footer.ReferenceId,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
||||||
|
`footer${this.footers.length}.xml`,
|
||||||
|
);
|
||||||
|
this.contentTypes.addFooter(this.footers.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private addDefaultRelationships(): void {
|
||||||
|
this.fileRelationships.createRelationship(
|
||||||
|
1,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
|
||||||
|
"word/document.xml",
|
||||||
|
);
|
||||||
|
this.fileRelationships.createRelationship(
|
||||||
|
2,
|
||||||
|
"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
|
||||||
|
"docProps/core.xml",
|
||||||
|
);
|
||||||
|
this.fileRelationships.createRelationship(
|
||||||
|
3,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
|
||||||
|
"docProps/app.xml",
|
||||||
|
);
|
||||||
|
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
this.currentRelationshipId++,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
|
||||||
|
"styles.xml",
|
||||||
|
);
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
this.currentRelationshipId++,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
|
||||||
|
"numbering.xml",
|
||||||
|
);
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
this.currentRelationshipId++,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
|
||||||
|
"footnotes.xml",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private groupHeaders(headers: IDocumentHeader[], group: IHeaderFooterGroup<HeaderWrapper> = {}): IHeaderFooterGroup<HeaderWrapper> {
|
||||||
|
let newGroup = group;
|
||||||
|
|
||||||
|
for (const header of headers) {
|
||||||
|
switch (header.type) {
|
||||||
|
case HeaderReferenceType.DEFAULT:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
default: header.header,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case HeaderReferenceType.FIRST:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
first: header.header,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case HeaderReferenceType.EVEN:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
even: header.header,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
default: header.header,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private groupFooters(footers: IDocumentFooter[], group: IHeaderFooterGroup<FooterWrapper> = {}): IHeaderFooterGroup<FooterWrapper> {
|
||||||
|
let newGroup = group;
|
||||||
|
|
||||||
|
for (const footer of footers) {
|
||||||
|
switch (footer.type) {
|
||||||
|
case FooterReferenceType.DEFAULT:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
default: footer.footer,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case FooterReferenceType.FIRST:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
first: footer.footer,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case FooterReferenceType.EVEN:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
even: footer.footer,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newGroup = {
|
||||||
|
...newGroup,
|
||||||
|
default: footer.footer,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newGroup;
|
||||||
|
}
|
||||||
|
|
||||||
public get Document(): Document {
|
public get Document(): Document {
|
||||||
return this.document;
|
return this.document;
|
||||||
}
|
}
|
||||||
@ -247,35 +378,19 @@ export class File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get Header(): HeaderWrapper {
|
public get Header(): HeaderWrapper {
|
||||||
return this.headerWrapper[0];
|
return this.headers[0].header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get Headers(): HeaderWrapper[] {
|
public get Headers(): HeaderWrapper[] {
|
||||||
return this.headerWrapper;
|
return this.headers.map((item) => item.header);
|
||||||
}
|
|
||||||
|
|
||||||
public HeaderByRefNumber(refId: number): HeaderWrapper {
|
|
||||||
const entry = this.headerWrapper.find((h) => h.Header.ReferenceId === refId);
|
|
||||||
if (entry) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new Error(`There is no header with given reference id ${refId}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get Footer(): FooterWrapper {
|
public get Footer(): FooterWrapper {
|
||||||
return this.footerWrapper[0];
|
return this.footers[0].footer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get Footers(): FooterWrapper[] {
|
public get Footers(): FooterWrapper[] {
|
||||||
return this.footerWrapper;
|
return this.footers.map((item) => item.footer);
|
||||||
}
|
|
||||||
|
|
||||||
public FooterByRefNumber(refId: number): FooterWrapper {
|
|
||||||
const entry = this.footerWrapper.find((h) => h.Footer.ReferenceId === refId);
|
|
||||||
if (entry) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
throw new Error(`There is no footer with given reference id ${refId}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get ContentTypes(): ContentTypes {
|
public get ContentTypes(): ContentTypes {
|
||||||
@ -293,10 +408,4 @@ export class File {
|
|||||||
public get Settings(): Settings {
|
public get Settings(): Settings {
|
||||||
return this.settings;
|
return this.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public verifyUpdateFields(): void {
|
|
||||||
if (this.document.getTablesOfContents().length) {
|
|
||||||
this.settings.addUpdateFields();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,23 @@
|
|||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
|
import { FooterReferenceType } from "./document";
|
||||||
import { Footer } from "./footer/footer";
|
import { Footer } from "./footer/footer";
|
||||||
import { Image, Media } from "./media";
|
import { Image, IMediaData, Media } from "./media";
|
||||||
import { ImageParagraph, Paragraph } from "./paragraph";
|
import { ImageParagraph, Paragraph } from "./paragraph";
|
||||||
import { Relationships } from "./relationships";
|
import { Relationships } from "./relationships";
|
||||||
import { Table } from "./table";
|
import { Table } from "./table";
|
||||||
|
|
||||||
|
export interface IDocumentFooter {
|
||||||
|
readonly footer: FooterWrapper;
|
||||||
|
readonly type: FooterReferenceType;
|
||||||
|
}
|
||||||
|
|
||||||
export class FooterWrapper {
|
export class FooterWrapper {
|
||||||
private readonly footer: Footer;
|
private readonly footer: Footer;
|
||||||
private readonly relationships: Relationships;
|
private readonly relationships: Relationships;
|
||||||
|
|
||||||
constructor(private readonly media: Media, referenceId: number) {
|
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
|
||||||
this.footer = new Footer(referenceId);
|
this.footer = new Footer(referenceId, initContent);
|
||||||
this.relationships = new Relationships();
|
this.relationships = new Relationships();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,17 +39,33 @@ export class FooterWrapper {
|
|||||||
return this.footer.createTable(rows, cols);
|
return this.footer.createTable(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addChildElement(childElement: XmlComponent | string): void {
|
public addChildElement(childElement: XmlComponent): void {
|
||||||
this.footer.addChildElement(childElement);
|
this.footer.addChildElement(childElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createImage(image: Buffer, width?: number, height?: number): void {
|
public addImageRelationship(image: Buffer, refId: number, width?: number, height?: number): IMediaData {
|
||||||
const mediaData = this.media.addMedia(image, this.relationships.RelationshipCount, width, height);
|
const mediaData = this.media.addMedia(image, refId, width, height);
|
||||||
this.relationships.createRelationship(
|
this.relationships.createRelationship(
|
||||||
mediaData.referenceId,
|
mediaData.referenceId,
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||||
`media/${mediaData.fileName}`,
|
`media/${mediaData.fileName}`,
|
||||||
);
|
);
|
||||||
|
return mediaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addHyperlinkRelationship(target: string, refId: number, targetMode?: "External" | undefined): void {
|
||||||
|
this.relationships.createRelationship(
|
||||||
|
refId,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
||||||
|
target,
|
||||||
|
targetMode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public createImage(image: Buffer | string | Uint8Array | ArrayBuffer, width?: number, height?: number): void {
|
||||||
|
// TODO
|
||||||
|
// tslint:disable-next-line:no-any
|
||||||
|
const mediaData = this.addImageRelationship(image as any, this.relationships.RelationshipCount, width, height);
|
||||||
this.addImage(new Image(new ImageParagraph(mediaData)));
|
this.addImage(new Image(new ImageParagraph(mediaData)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,4 +81,8 @@ export class FooterWrapper {
|
|||||||
public get Relationships(): Relationships {
|
public get Relationships(): Relationships {
|
||||||
return this.relationships;
|
return this.relationships;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get Media(): Media {
|
||||||
|
return this.media;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IFooterAttributesProperties {
|
export interface IFooterAttributesProperties {
|
||||||
wpc?: string;
|
readonly wpc?: string;
|
||||||
mc?: string;
|
readonly mc?: string;
|
||||||
o?: string;
|
readonly o?: string;
|
||||||
r?: string;
|
readonly r?: string;
|
||||||
m?: string;
|
readonly m?: string;
|
||||||
v?: string;
|
readonly v?: string;
|
||||||
wp14?: string;
|
readonly wp14?: string;
|
||||||
wp?: string;
|
readonly wp?: string;
|
||||||
w10?: string;
|
readonly w10?: string;
|
||||||
w?: string;
|
readonly w?: string;
|
||||||
w14?: string;
|
readonly w14?: string;
|
||||||
w15?: string;
|
readonly w15?: string;
|
||||||
wpg?: string;
|
readonly wpg?: string;
|
||||||
wpi?: string;
|
readonly wpi?: string;
|
||||||
wne?: string;
|
readonly wne?: string;
|
||||||
wps?: string;
|
readonly wps?: string;
|
||||||
cp?: string;
|
readonly cp?: string;
|
||||||
dc?: string;
|
readonly dc?: string;
|
||||||
dcterms?: string;
|
readonly dcterms?: string;
|
||||||
dcmitype?: string;
|
readonly dcmitype?: string;
|
||||||
xsi?: string;
|
readonly xsi?: string;
|
||||||
type?: string;
|
readonly type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FooterAttributes extends XmlAttributeComponent<IFooterAttributesProperties> {
|
export class FooterAttributes extends XmlAttributeComponent<IFooterAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
wpc: "xmlns:wpc",
|
wpc: "xmlns:wpc",
|
||||||
mc: "xmlns:mc",
|
mc: "xmlns:mc",
|
||||||
o: "xmlns:o",
|
o: "xmlns:o",
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// http://officeopenxml.com/WPfooters.php
|
// http://officeopenxml.com/WPfooters.php
|
||||||
import { XmlComponent } from "file/xml-components";
|
import { InitializableXmlComponent, XmlComponent } from "file/xml-components";
|
||||||
import { Paragraph } from "../paragraph";
|
import { Paragraph } from "../paragraph";
|
||||||
import { Table } from "../table";
|
import { Table } from "../table";
|
||||||
import { FooterAttributes } from "./footer-attributes";
|
import { FooterAttributes } from "./footer-attributes";
|
||||||
|
|
||||||
export class Footer extends XmlComponent {
|
export class Footer extends InitializableXmlComponent {
|
||||||
private readonly refId: number;
|
private readonly refId: number;
|
||||||
|
|
||||||
constructor(referenceNumber: number) {
|
constructor(referenceNumber: number, initContent?: XmlComponent) {
|
||||||
super("w:ftr");
|
super("w:ftr", initContent);
|
||||||
this.refId = referenceNumber;
|
this.refId = referenceNumber;
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new FooterAttributes({
|
new FooterAttributes({
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IFootnoteAttributesProperties {
|
export interface IFootnoteAttributesProperties {
|
||||||
type?: string;
|
readonly type?: string;
|
||||||
id: number;
|
readonly id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FootnoteAttributes extends XmlAttributeComponent<IFootnoteAttributesProperties> {
|
export class FootnoteAttributes extends XmlAttributeComponent<IFootnoteAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
type: "w:type",
|
type: "w:type",
|
||||||
id: "w:id",
|
id: "w:id",
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { expect } from "chai";
|
import { expect } from "chai";
|
||||||
import { Formatter } from "../../../export/formatter";
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
import { Footnote, FootnoteType } from "./footnote";
|
import { Footnote, FootnoteType } from "./footnote";
|
||||||
|
|
||||||
describe("Footnote", () => {
|
describe("Footnote", () => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
import { Paragraph } from "file/paragraph";
|
||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
import { Paragraph } from "../../paragraph";
|
|
||||||
import { FootnoteAttributes } from "./footnote-attributes";
|
import { FootnoteAttributes } from "./footnote-attributes";
|
||||||
import { FootnoteRefRun } from "./run/footnote-ref-run";
|
import { FootnoteRefRun } from "./run/footnote-ref-run";
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ import { Style } from "file/paragraph/run/style";
|
|||||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IFootNoteReferenceRunAttributesProperties {
|
export interface IFootNoteReferenceRunAttributesProperties {
|
||||||
id: number;
|
readonly id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FootNoteReferenceRunAttributes extends XmlAttributeComponent<IFootNoteReferenceRunAttributesProperties> {
|
export class FootNoteReferenceRunAttributes extends XmlAttributeComponent<IFootNoteReferenceRunAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
id: "w:id",
|
id: "w:id",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IFootnotesAttributesProperties {
|
export interface IFootnotesAttributesProperties {
|
||||||
wpc?: string;
|
readonly wpc?: string;
|
||||||
mc?: string;
|
readonly mc?: string;
|
||||||
o?: string;
|
readonly o?: string;
|
||||||
r?: string;
|
readonly r?: string;
|
||||||
m?: string;
|
readonly m?: string;
|
||||||
v?: string;
|
readonly v?: string;
|
||||||
wp14?: string;
|
readonly wp14?: string;
|
||||||
wp?: string;
|
readonly wp?: string;
|
||||||
w10?: string;
|
readonly w10?: string;
|
||||||
w?: string;
|
readonly w?: string;
|
||||||
w14?: string;
|
readonly w14?: string;
|
||||||
w15?: string;
|
readonly w15?: string;
|
||||||
wpg?: string;
|
readonly wpg?: string;
|
||||||
wpi?: string;
|
readonly wpi?: string;
|
||||||
wne?: string;
|
readonly wne?: string;
|
||||||
wps?: string;
|
readonly wps?: string;
|
||||||
Ignorable?: string;
|
readonly Ignorable?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FootnotesAttributes extends XmlAttributeComponent<IFootnotesAttributesProperties> {
|
export class FootnotesAttributes extends XmlAttributeComponent<IFootnotesAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
wpc: "xmlns:wpc",
|
wpc: "xmlns:wpc",
|
||||||
mc: "xmlns:mc",
|
mc: "xmlns:mc",
|
||||||
o: "xmlns:o",
|
o: "xmlns:o",
|
||||||
|
@ -6,12 +6,13 @@ import { SeperatorRun } from "./footnote/run/seperator-run";
|
|||||||
import { FootnotesAttributes } from "./footnotes-attributes";
|
import { FootnotesAttributes } from "./footnotes-attributes";
|
||||||
|
|
||||||
export class FootNotes extends XmlComponent {
|
export class FootNotes extends XmlComponent {
|
||||||
private counter: number;
|
// tslint:disable-next-line:readonly-keyword
|
||||||
|
private currentId: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super("w:footnotes");
|
super("w:footnotes");
|
||||||
|
|
||||||
this.counter = 1;
|
this.currentId = 1;
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new FootnotesAttributes({
|
new FootnotesAttributes({
|
||||||
@ -61,10 +62,10 @@ export class FootNotes extends XmlComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public createFootNote(paragraph: Paragraph): void {
|
public createFootNote(paragraph: Paragraph): void {
|
||||||
const footnote = new Footnote(this.counter);
|
const footnote = new Footnote(this.currentId);
|
||||||
footnote.addParagraph(paragraph);
|
footnote.addParagraph(paragraph);
|
||||||
this.root.push(footnote);
|
this.root.push(footnote);
|
||||||
|
|
||||||
this.counter++;
|
this.currentId++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/file/header-wrapper.spec.ts
Normal file
29
src/file/header-wrapper.spec.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
|
import { HeaderWrapper } from "./header-wrapper";
|
||||||
|
import { Media } from "./media";
|
||||||
|
import { Paragraph } from "./paragraph";
|
||||||
|
import { Table } from "./table";
|
||||||
|
|
||||||
|
describe("HeaderWrapper", () => {
|
||||||
|
describe("#addParagraph", () => {
|
||||||
|
it("should call the underlying header's addParagraph", () => {
|
||||||
|
const file = new HeaderWrapper(new Media(), 1);
|
||||||
|
const spy = sinon.spy(file.Header, "addParagraph");
|
||||||
|
file.addParagraph(new Paragraph());
|
||||||
|
|
||||||
|
expect(spy.called).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#addTable", () => {
|
||||||
|
it("should call the underlying header's addParagraph", () => {
|
||||||
|
const file = new HeaderWrapper(new Media(), 1);
|
||||||
|
const spy = sinon.spy(file.Header, "addTable");
|
||||||
|
file.addTable(new Table(1, 1));
|
||||||
|
|
||||||
|
expect(spy.called).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,16 +1,23 @@
|
|||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
|
import { HeaderReferenceType } from "./document";
|
||||||
import { Header } from "./header/header";
|
import { Header } from "./header/header";
|
||||||
import { Image, Media } from "./media";
|
import { Image, IMediaData, Media } from "./media";
|
||||||
import { ImageParagraph, Paragraph } from "./paragraph";
|
import { ImageParagraph, Paragraph } from "./paragraph";
|
||||||
import { Relationships } from "./relationships";
|
import { Relationships } from "./relationships";
|
||||||
import { Table } from "./table";
|
import { Table } from "./table";
|
||||||
|
|
||||||
|
export interface IDocumentHeader {
|
||||||
|
readonly header: HeaderWrapper;
|
||||||
|
readonly type: HeaderReferenceType;
|
||||||
|
}
|
||||||
|
|
||||||
export class HeaderWrapper {
|
export class HeaderWrapper {
|
||||||
private readonly header: Header;
|
private readonly header: Header;
|
||||||
private readonly relationships: Relationships;
|
private readonly relationships: Relationships;
|
||||||
|
|
||||||
constructor(private readonly media: Media, referenceId: number) {
|
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
|
||||||
this.header = new Header(referenceId);
|
this.header = new Header(referenceId, initContent);
|
||||||
this.relationships = new Relationships();
|
this.relationships = new Relationships();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,13 +43,29 @@ export class HeaderWrapper {
|
|||||||
this.header.addChildElement(childElement);
|
this.header.addChildElement(childElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createImage(image: Buffer, width?: number, height?: number): void {
|
public addImageRelationship(image: Buffer, refId: number, width?: number, height?: number): IMediaData {
|
||||||
const mediaData = this.media.addMedia(image, this.relationships.RelationshipCount, width, height);
|
const mediaData = this.media.addMedia(image, refId, width, height);
|
||||||
this.relationships.createRelationship(
|
this.relationships.createRelationship(
|
||||||
mediaData.referenceId,
|
mediaData.referenceId,
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||||
`media/${mediaData.fileName}`,
|
`media/${mediaData.fileName}`,
|
||||||
);
|
);
|
||||||
|
return mediaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addHyperlinkRelationship(target: string, refId: number, targetMode?: "External" | undefined): void {
|
||||||
|
this.relationships.createRelationship(
|
||||||
|
refId,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
||||||
|
target,
|
||||||
|
targetMode,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public createImage(image: Buffer | string | Uint8Array | ArrayBuffer, width?: number, height?: number): void {
|
||||||
|
// TODO
|
||||||
|
// tslint:disable-next-line:no-any
|
||||||
|
const mediaData = this.addImageRelationship(image as any, this.relationships.RelationshipCount, width, height);
|
||||||
this.addImage(new Image(new ImageParagraph(mediaData)));
|
this.addImage(new Image(new ImageParagraph(mediaData)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,4 +81,8 @@ export class HeaderWrapper {
|
|||||||
public get Relationships(): Relationships {
|
public get Relationships(): Relationships {
|
||||||
return this.relationships;
|
return this.relationships;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get Media(): Media {
|
||||||
|
return this.media;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,43 @@
|
|||||||
import { XmlAttributeComponent } from "file/xml-components";
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
|
||||||
export interface IHeaderAttributesProperties {
|
export interface IHeaderAttributesProperties {
|
||||||
wpc?: string;
|
readonly wpc?: string;
|
||||||
mc?: string;
|
readonly mc?: string;
|
||||||
o?: string;
|
readonly o?: string;
|
||||||
r?: string;
|
readonly r?: string;
|
||||||
m?: string;
|
readonly m?: string;
|
||||||
v?: string;
|
readonly v?: string;
|
||||||
wp14?: string;
|
readonly wp14?: string;
|
||||||
wp?: string;
|
readonly wp?: string;
|
||||||
w10?: string;
|
readonly w10?: string;
|
||||||
w?: string;
|
readonly w?: string;
|
||||||
w14?: string;
|
readonly w14?: string;
|
||||||
w15?: string;
|
readonly w15?: string;
|
||||||
wpg?: string;
|
readonly wpg?: string;
|
||||||
wpi?: string;
|
readonly wpi?: string;
|
||||||
wne?: string;
|
readonly wne?: string;
|
||||||
wps?: string;
|
readonly wps?: string;
|
||||||
cp?: string;
|
readonly cp?: string;
|
||||||
dc?: string;
|
readonly dc?: string;
|
||||||
dcterms?: string;
|
readonly dcterms?: string;
|
||||||
dcmitype?: string;
|
readonly dcmitype?: string;
|
||||||
xsi?: string;
|
readonly xsi?: string;
|
||||||
type?: string;
|
readonly type?: string;
|
||||||
|
readonly cx?: string;
|
||||||
|
readonly cx1?: string;
|
||||||
|
readonly cx2?: string;
|
||||||
|
readonly cx3?: string;
|
||||||
|
readonly cx4?: string;
|
||||||
|
readonly cx5?: string;
|
||||||
|
readonly cx6?: string;
|
||||||
|
readonly cx7?: string;
|
||||||
|
readonly cx8?: string;
|
||||||
|
readonly w16cid: string;
|
||||||
|
readonly w16se: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HeaderAttributes extends XmlAttributeComponent<IHeaderAttributesProperties> {
|
export class HeaderAttributes extends XmlAttributeComponent<IHeaderAttributesProperties> {
|
||||||
protected xmlKeys = {
|
protected readonly xmlKeys = {
|
||||||
wpc: "xmlns:wpc",
|
wpc: "xmlns:wpc",
|
||||||
mc: "xmlns:mc",
|
mc: "xmlns:mc",
|
||||||
o: "xmlns:o",
|
o: "xmlns:o",
|
||||||
@ -49,5 +60,16 @@ export class HeaderAttributes extends XmlAttributeComponent<IHeaderAttributesPro
|
|||||||
dcmitype: "xmlns:dcmitype",
|
dcmitype: "xmlns:dcmitype",
|
||||||
xsi: "xmlns:xsi",
|
xsi: "xmlns:xsi",
|
||||||
type: "xsi:type",
|
type: "xsi:type",
|
||||||
|
cx: "xmlns:cx",
|
||||||
|
cx1: "xmlns:cx1",
|
||||||
|
cx2: "xmlns:cx2",
|
||||||
|
cx3: "xmlns:cx3",
|
||||||
|
cx4: "xmlns:cx4",
|
||||||
|
cx5: "xmlns:cx5",
|
||||||
|
cx6: "xmlns:cx6",
|
||||||
|
cx7: "xmlns:cx7",
|
||||||
|
cx8: "xmlns:cx8",
|
||||||
|
w16cid: "xmlns:w16cid",
|
||||||
|
w16se: "xmlns:w16se",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
// http://officeopenxml.com/WPheaders.php
|
// http://officeopenxml.com/WPheaders.php
|
||||||
import { XmlComponent } from "file/xml-components";
|
import { InitializableXmlComponent, XmlComponent } from "file/xml-components";
|
||||||
import { Paragraph } from "../paragraph";
|
import { Paragraph } from "../paragraph";
|
||||||
import { Table } from "../table";
|
import { Table } from "../table";
|
||||||
import { HeaderAttributes } from "./header-attributes";
|
import { HeaderAttributes } from "./header-attributes";
|
||||||
|
|
||||||
export class Header extends XmlComponent {
|
export class Header extends InitializableXmlComponent {
|
||||||
private readonly refId: number;
|
private readonly refId: number;
|
||||||
|
|
||||||
constructor(referenceNumber: number) {
|
constructor(referenceNumber: number, initContent?: XmlComponent) {
|
||||||
super("w:hdr");
|
super("w:hdr", initContent);
|
||||||
|
|
||||||
this.refId = referenceNumber;
|
this.refId = referenceNumber;
|
||||||
|
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new HeaderAttributes({
|
new HeaderAttributes({
|
||||||
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
|
||||||
@ -29,6 +30,17 @@ export class Header extends XmlComponent {
|
|||||||
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
|
wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
|
||||||
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
|
wne: "http://schemas.microsoft.com/office/word/2006/wordml",
|
||||||
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
|
||||||
|
cx: "http://schemas.microsoft.com/office/drawing/2014/chartex",
|
||||||
|
cx1: "http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
|
||||||
|
cx2: "http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
|
||||||
|
cx3: "http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",
|
||||||
|
cx4: "http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",
|
||||||
|
cx5: "http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",
|
||||||
|
cx6: "http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",
|
||||||
|
cx7: "http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
|
||||||
|
cx8: "http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
|
||||||
|
w16cid: "http://schemas.microsoft.com/office/word/2016/wordml/cid",
|
||||||
|
w16se: "http://schemas.microsoft.com/office/word/2015/wordml/symex",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export * from "./paragraph";
|
export * from "./paragraph";
|
||||||
export * from "./table";
|
export * from "./table";
|
||||||
export * from "./file";
|
export * from "./file";
|
||||||
|
export * from "./file-properties";
|
||||||
export * from "./numbering";
|
export * from "./numbering";
|
||||||
export * from "./media";
|
export * from "./media";
|
||||||
export * from "./drawing";
|
export * from "./drawing";
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user