Compare commits
377 Commits
5.0.0-rc5
...
feat/parag
Author | SHA1 | Date | |
---|---|---|---|
5e87e4fb0b | |||
19fc900045 | |||
6bdd9b882a | |||
0d97d428fa | |||
a0b42d7bdb | |||
69ba312a96 | |||
a0c13214e6 | |||
4c8829df28 | |||
3ee3e95410 | |||
806deeaf78 | |||
feb121707d | |||
31c7f034ec | |||
30ab92652c | |||
0407548113 | |||
277845626c | |||
b2af8b970e | |||
542866e18b | |||
f54192809f | |||
f3ba62fd88 | |||
8d4a07302b | |||
d504231124 | |||
173b1e118c | |||
ffba276f0d | |||
b210608e56 | |||
74353104dc | |||
825136d1c9 | |||
b2fea471f1 | |||
e9adb8b0ed | |||
5d6bc039d0 | |||
27638063c8 | |||
f6a4d78ab7 | |||
4061e31400 | |||
74db67689f | |||
2213eb28cb | |||
d1b45d416b | |||
f72f7e7514 | |||
0165cfb3e5 | |||
ef747486c0 | |||
e0b2f59c2f | |||
82bdb301f9 | |||
c7ea26e422 | |||
34b2029efe | |||
37e610d2b3 | |||
4882235d20 | |||
1552ebde11 | |||
d263d0c8a5 | |||
610b2388bb | |||
bcb16cef9b | |||
0f3afd94f3 | |||
60eb686d05 | |||
7f5e43fba9 | |||
ed52ef358b | |||
214afab711 | |||
18a1677588 | |||
cae372e9ad | |||
ea5f9a48ab | |||
dcf755e756 | |||
d445c21ea1 | |||
6db0449ed0 | |||
ae37b1980f | |||
96f76906c4 | |||
19d9619785 | |||
5be195fd91 | |||
e36e9e1cf4 | |||
102d6aa55c | |||
daea8d2868 | |||
700a74fd4c | |||
32a84a5ad0 | |||
3c9f9474ce | |||
1e10686315 | |||
cae6405d9a | |||
a884ce94e5 | |||
065c17de74 | |||
09db2c528a | |||
2adfe532dd | |||
6cbe40cecb | |||
6b9467393e | |||
5125e77431 | |||
ab68ae0092 | |||
38079b6171 | |||
d584290f3d | |||
9b9baa9b4a | |||
c258310560 | |||
af0bf5ced5 | |||
57c480a6c6 | |||
25f7423533 | |||
0c068bb03b | |||
1822473abc | |||
93a7d607b2 | |||
d45213636c | |||
e196d9d917 | |||
cf88e50afd | |||
64e5814c31 | |||
37251c84f8 | |||
a576098639 | |||
2450fe83ce | |||
e1004440d2 | |||
491c7abd1c | |||
364ce6d856 | |||
ffb6b73bb7 | |||
6041c39a26 | |||
c54f0a52f6 | |||
6b87d9c038 | |||
1285304f97 | |||
58fae6b201 | |||
dc1f3aebe9 | |||
8a189161f2 | |||
6667595627 | |||
33befaab09 | |||
c91f135c28 | |||
08f9926e60 | |||
f323b293fb | |||
adc91929b0 | |||
c63cba5a0c | |||
7a48da440b | |||
05dda37b71 | |||
ee43585210 | |||
a6eb8e01df | |||
8c45c30753 | |||
d18cfbc26f | |||
f4af5f9e33 | |||
69adbbc1c1 | |||
4f6a9f734c | |||
8b78f2d200 | |||
26a3fa6946 | |||
f955a18936 | |||
ee1a7818b6 | |||
8e455f1097 | |||
827c46cf47 | |||
61cbee829d | |||
f0ad1e9194 | |||
bbd339f0e4 | |||
858af64dc3 | |||
01e34c1b28 | |||
41acb475a9 | |||
20978f8c24 | |||
265a3dbe21 | |||
627f5b4bf0 | |||
1538c1aaeb | |||
839661e5f8 | |||
fff6244597 | |||
b2280f64a1 | |||
21d53c41d0 | |||
6e94bbb5e5 | |||
7d655cd3f7 | |||
00821677c8 | |||
784de3e430 | |||
3213c4838d | |||
1b9bc8eb1d | |||
bf58d0b864 | |||
28ca8392ed | |||
5238c55bc2 | |||
901f10c387 | |||
defa22ffe5 | |||
84919c0cc0 | |||
1e8ca123b0 | |||
3ae7c6aedf | |||
6a3ed4bbf8 | |||
e632d323c9 | |||
d2b35ab8f2 | |||
e60f39df41 | |||
076431e04d | |||
75ab44403c | |||
e2d6097819 | |||
ab12ff1257 | |||
25a0212f4e | |||
a8993f14d6 | |||
1834cd86da | |||
437de27ed8 | |||
96f08482da | |||
edec2eca7a | |||
9202524d83 | |||
0461907533 | |||
445a2896d2 | |||
e2d8f1b6b1 | |||
7baa696a76 | |||
3f7ca6bbff | |||
36e1c5fe6a | |||
75a03f1576 | |||
437e83ab78 | |||
b8232f7a02 | |||
49eadb0efc | |||
40dc90e585 | |||
0de302d192 | |||
80bab95f6c | |||
ba3d551c9f | |||
d14fe31f97 | |||
057f41e355 | |||
8c9b61b37a | |||
11e54b3e2c | |||
fa7cb0bef1 | |||
3977c8ab3b | |||
e8f92efe05 | |||
994df8531b | |||
3cdf96ee0c | |||
e2f55d52e9 | |||
d6fa33035a | |||
f11bca728f | |||
596761d78d | |||
8a3c8d4664 | |||
fdfce79e87 | |||
88340aa336 | |||
d0f53fdd4b | |||
d657f61e11 | |||
20e6b98770 | |||
5ae824358c | |||
3ea106bd22 | |||
538264dec5 | |||
6bcd1c2c24 | |||
120c3a7bbe | |||
2654799822 | |||
6245635b86 | |||
b4f1c4dd6a | |||
25a7ce3742 | |||
08bc069cbf | |||
0ebdcc30ed | |||
3eca81d3f5 | |||
faefbae3a1 | |||
370fb098ac | |||
c73019d84c | |||
250a1de71e | |||
012963e90a | |||
632f3cd19b | |||
1c8cd325d7 | |||
7bcdaab2f2 | |||
5b58e520f9 | |||
78f6ea6c44 | |||
b5172e73f9 | |||
5cf534ad26 | |||
d53cdb0558 | |||
212adbbffb | |||
99ab2f0ef5 | |||
a8201b2658 | |||
f13e676c3b | |||
61b01836bc | |||
2ee918b845 | |||
e9579d75c4 | |||
97824f1bb5 | |||
884c134b25 | |||
4f3cb49076 | |||
152285ed5a | |||
49b7ac212d | |||
83450e6277 | |||
6d6155c742 | |||
f8da2c311b | |||
f6bcaef5b5 | |||
1a9e71bfa1 | |||
3591e11637 | |||
47533cf4e2 | |||
de03f19b46 | |||
d1472368f6 | |||
b83d2c388f | |||
ee5425bef7 | |||
3fdbca939e | |||
c68dc8c52a | |||
96471ecb45 | |||
a13f898ad3 | |||
b4cce534a5 | |||
e0698554ad | |||
1649d2a0fa | |||
9683e89159 | |||
2bece0bb61 | |||
deb6c42d86 | |||
2b0953bb19 | |||
d25d22508c | |||
6db37eb4fb | |||
af461f8418 | |||
8bdbd1de39 | |||
1bdc93ef59 | |||
c12101fbc6 | |||
d5ba6578b3 | |||
b37aefdc8d | |||
0be7c26798 | |||
bf1d10e893 | |||
7dfb016faa | |||
b2aeb2d83c | |||
8f4c78e2a8 | |||
bd1f5898a8 | |||
05a4ef1702 | |||
da9e6d6664 | |||
e9d3853d93 | |||
5a9d6120a5 | |||
e8410ff692 | |||
3427d220c7 | |||
643e3c2f84 | |||
9b40b5e55e | |||
a622c210ef | |||
9495f30e2d | |||
617af87065 | |||
9aab68a8f8 | |||
c1dd421b27 | |||
8eff6bd0cf | |||
8566c64eab | |||
afd468277e | |||
ca9c992237 | |||
c93b74661b | |||
08ff092638 | |||
2276572902 | |||
43ddeec6e1 | |||
9eaf04f4c7 | |||
c3c29bb119 | |||
ddb34e6a46 | |||
ef3055430b | |||
75cdae1473 | |||
860afe8f28 | |||
f685dbe0d1 | |||
50911fff57 | |||
a7064f4728 | |||
564e9600ea | |||
fcc4202598 | |||
bfbe59cb84 | |||
06abde2425 | |||
75c3c2f985 | |||
fefefdd473 | |||
db59474f1e | |||
1d5e806ff4 | |||
bf4885c7cf | |||
3b289be5ce | |||
2bb7e08ade | |||
b571a7550f | |||
721de30587 | |||
f16126e948 | |||
40d1a3a7c2 | |||
0d4c7a5fc0 | |||
5d401dfb27 | |||
a37c9d8f2f | |||
10ab3c70bf | |||
591b2f4e04 | |||
2536fbe752 | |||
33549d5ec3 | |||
720c6172e3 | |||
bbad2f5cde | |||
d2a0baa221 | |||
ad62f5459b | |||
dfb910defb | |||
04b6d8e54a | |||
d2dded860d | |||
38f2638ea0 | |||
2b874e3f69 | |||
b43ed12c84 | |||
59be381213 | |||
172c333357 | |||
c5eb3d5670 | |||
44b95f2f15 | |||
bd888219fc | |||
2842619196 | |||
b2de74a0e6 | |||
7aa4134e2b | |||
cc36ea7542 | |||
c11af71ed7 | |||
a9d4ebc898 | |||
d2f82052b4 | |||
f88a309d55 | |||
418adca9f3 | |||
993f8f81f7 | |||
99718784f1 | |||
59fc1ed632 | |||
cb74868247 | |||
bd6ae2c0dc | |||
60a599a550 | |||
4ac55a787e | |||
cb52a1ef42 | |||
7827d158d7 | |||
535f2d75b0 | |||
4f8d435e16 | |||
5ecdb48d43 | |||
a1b9be453b | |||
2502fe7f39 | |||
02487fbb22 | |||
2abff6991f | |||
49e85275c3 | |||
96efdf8b1a | |||
b52a4adaff | |||
a9fc40dad4 | |||
b609a17362 | |||
4b49fdbf8e | |||
fd52c8cf47 |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: dolanmiu
|
||||||
|
patreon: dolanmiu
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
104
.github/workflows/default.yml
vendored
Normal file
104
.github/workflows/default.yml
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
name: Default
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Build
|
||||||
|
run: npm run build
|
||||||
|
- name: Archive Production Artifact
|
||||||
|
uses: actions/upload-artifact@master
|
||||||
|
with:
|
||||||
|
name: build
|
||||||
|
path: build
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Test
|
||||||
|
run: npm run test.coverage
|
||||||
|
lint:
|
||||||
|
name: Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Lint
|
||||||
|
run: npm run lint
|
||||||
|
prettier:
|
||||||
|
name: Prettier
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Prettier
|
||||||
|
run: npm run style
|
||||||
|
demos:
|
||||||
|
name: Run Demos
|
||||||
|
needs: [build]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@master
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Download Artifact
|
||||||
|
uses: actions/download-artifact@master
|
||||||
|
with:
|
||||||
|
name: build
|
||||||
|
path: build
|
||||||
|
- name: Run demos
|
||||||
|
run: |
|
||||||
|
npm run ts-node -- ./demo/1-basic.ts
|
||||||
|
npm run ts-node -- ./demo/2-declaritive-styles.ts
|
||||||
|
npm run ts-node -- ./demo/3-numbering-and-bullet-points.ts
|
||||||
|
npm run ts-node -- ./demo/4-basic-table.ts
|
||||||
|
npm run ts-node -- ./demo/5-images.ts
|
||||||
|
npm run ts-node -- ./demo/6-page-borders.ts
|
||||||
|
npm run ts-node -- ./demo/7-landscape.ts
|
||||||
|
npm run ts-node -- ./demo/8-header-footer.ts
|
||||||
|
npm run ts-node -- ./demo/9-images-in-header-and-footer.ts
|
||||||
|
npm run ts-node -- ./demo/10-my-cv.ts
|
||||||
|
npm run ts-node -- ./demo/11-declaritive-styles-2.ts
|
||||||
|
npm run ts-node -- ./demo/12-scaling-images.ts
|
||||||
|
npm run ts-node -- ./demo/13-xml-styles.ts
|
||||||
|
npm run ts-node -- ./demo/14-page-numbers.ts
|
||||||
|
npm run ts-node -- ./demo/15-page-break-before.ts
|
||||||
|
npm run ts-node -- ./demo/16-multiple-sections.ts
|
||||||
|
npm run ts-node -- ./demo/17-footnotes.ts
|
||||||
|
npm run ts-node -- ./demo/18-image-from-buffer.ts
|
||||||
|
npm run ts-node -- ./demo/19-export-to-base64.ts
|
||||||
|
npm run ts-node -- ./demo/20-table-cell-borders.ts
|
||||||
|
npm run ts-node -- ./demo/21-bookmarks.ts
|
||||||
|
npm run ts-node -- ./demo/22-right-to-left-text.ts
|
||||||
|
npm run ts-node -- ./demo/23-base64-images.ts
|
||||||
|
npm run ts-node -- ./demo/24-images-to-table-cell.ts
|
||||||
|
npm run ts-node -- ./demo/26-paragraph-borders.ts
|
||||||
|
npm run ts-node -- ./demo/27-declaritive-styles-3.ts
|
||||||
|
npm run ts-node -- ./demo/28-table-of-contents.ts
|
||||||
|
npm run ts-node -- ./demo/29-numbered-lists.ts
|
||||||
|
npm run ts-node -- ./demo/30-template-document.ts
|
||||||
|
npm run ts-node -- ./demo/31-tables.ts
|
||||||
|
npm run ts-node -- ./demo/32-merge-and-shade-table-cells.ts
|
||||||
|
npm run ts-node -- ./demo/33-sequential-captions.ts
|
||||||
|
npm run ts-node -- ./demo/34-floating-tables.ts
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,7 +52,6 @@ docs/.nojekyll
|
|||||||
.idea
|
.idea
|
||||||
|
|
||||||
# Lock files
|
# Lock files
|
||||||
package-lock.json
|
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
# Documents
|
# Documents
|
||||||
|
11
.nycrc
11
.nycrc
@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"check-coverage": true,
|
"check-coverage": true,
|
||||||
"lines": 87.54,
|
"lines": 96.81,
|
||||||
"functions": 83.61,
|
"functions": 93.80,
|
||||||
"branches": 72.57,
|
"branches": 92.63,
|
||||||
"statements": 87.32,
|
"statements": 96.80,
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts"
|
"src/**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"src/**/*.spec.ts"
|
"src/**/*.spec.ts",
|
||||||
|
"src/import-dotx/import-dotx.ts"
|
||||||
],
|
],
|
||||||
"reporter": [
|
"reporter": [
|
||||||
"lcov",
|
"lcov",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- 9
|
- 10
|
||||||
install:
|
install:
|
||||||
- npm install
|
- npm install
|
||||||
- npm install -g codecov
|
- npm install -g codecov
|
||||||
@ -10,7 +10,7 @@ script:
|
|||||||
- npm run style
|
- npm run style
|
||||||
- npm run build
|
- npm run build
|
||||||
- npm run ts-node -- ./demo/1-basic.ts
|
- npm run ts-node -- ./demo/1-basic.ts
|
||||||
- npm run e2e "My Document.docx"
|
# - npm run e2e "My Document.docx"
|
||||||
- npm run ts-node -- ./demo/2-declaritive-styles.ts
|
- npm run ts-node -- ./demo/2-declaritive-styles.ts
|
||||||
- npm run ts-node -- ./demo/3-numbering-and-bullet-points.ts
|
- npm run ts-node -- ./demo/3-numbering-and-bullet-points.ts
|
||||||
- npm run ts-node -- ./demo/4-basic-table.ts
|
- npm run ts-node -- ./demo/4-basic-table.ts
|
||||||
@ -20,7 +20,7 @@ script:
|
|||||||
- npm run ts-node -- ./demo/8-header-footer.ts
|
- npm run ts-node -- ./demo/8-header-footer.ts
|
||||||
- npm run ts-node -- ./demo/9-images-in-header-and-footer.ts
|
- npm run ts-node -- ./demo/9-images-in-header-and-footer.ts
|
||||||
- npm run ts-node -- ./demo/10-my-cv.ts
|
- npm run ts-node -- ./demo/10-my-cv.ts
|
||||||
- npm run e2e "My Document.docx"
|
# - npm run e2e "My Document.docx"
|
||||||
- npm run ts-node -- ./demo/11-declaritive-styles-2.ts
|
- npm run ts-node -- ./demo/11-declaritive-styles-2.ts
|
||||||
- npm run ts-node -- ./demo/12-scaling-images.ts
|
- npm run ts-node -- ./demo/12-scaling-images.ts
|
||||||
- npm run ts-node -- ./demo/13-xml-styles.ts
|
- npm run ts-node -- ./demo/13-xml-styles.ts
|
||||||
@ -42,7 +42,7 @@ script:
|
|||||||
- npm run ts-node -- ./demo/29-numbered-lists.ts
|
- npm run ts-node -- ./demo/29-numbered-lists.ts
|
||||||
- npm run ts-node -- ./demo/30-template-document.ts
|
- npm run ts-node -- ./demo/30-template-document.ts
|
||||||
- npm run ts-node -- ./demo/31-tables.ts
|
- npm run ts-node -- ./demo/31-tables.ts
|
||||||
- npm run ts-node -- ./demo/32-merge-table-cells.ts
|
- npm run ts-node -- ./demo/32-merge-and-shade-table-cells.ts
|
||||||
# - npm run e2e "My Document.docx" // Need to fix
|
# - npm run e2e "My Document.docx" // Need to fix
|
||||||
- npm run ts-node -- ./demo/33-sequential-captions.ts
|
- npm run ts-node -- ./demo/33-sequential-captions.ts
|
||||||
- npm run ts-node -- ./demo/34-floating-tables.ts
|
- npm run ts-node -- ./demo/34-floating-tables.ts
|
||||||
|
27
README.md
27
README.md
@ -11,6 +11,7 @@
|
|||||||
[![NPM version][npm-image]][npm-url]
|
[![NPM version][npm-image]][npm-url]
|
||||||
[![Downloads per month][downloads-image]][downloads-url]
|
[![Downloads per month][downloads-image]][downloads-url]
|
||||||
[![Build Status][travis-image]][travis-url]
|
[![Build Status][travis-image]][travis-url]
|
||||||
|
[![GitHub Action Workflow Status][github-actions-workflow-image]][github-actions-workflow-url]
|
||||||
[![Dependency Status][daviddm-image]][daviddm-url]
|
[![Dependency Status][daviddm-image]][daviddm-url]
|
||||||
[![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]
|
||||||
@ -18,7 +19,7 @@
|
|||||||
[![codecov][codecov-image]][codecov-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/TCH0YzD.png" alt="drawing" width="800"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Demo
|
# Demo
|
||||||
@ -27,13 +28,22 @@
|
|||||||
|
|
||||||
Here are examples of `docx` being used with basic `HTML/JS` in a browser environment:
|
Here are examples of `docx` being used with basic `HTML/JS` in a browser environment:
|
||||||
|
|
||||||
* https://codepen.io/anon/pen/dqoVgQ
|
* https://codepen.io/dolanmiu/pen/RwNeObg
|
||||||
* https://jsfiddle.net/3xhezb5w/2
|
* https://jsfiddle.net/dolanmiu/kqxrj35u/1/
|
||||||
|
|
||||||
Here is an example of `docx` working in `Angular`:
|
Here is an example of `docx` working in `Angular`:
|
||||||
|
|
||||||
* https://stackblitz.com/edit/angular-afvxtz
|
* https://stackblitz.com/edit/angular-afvxtz
|
||||||
|
|
||||||
|
Here is an example of `docx` working in `React`:
|
||||||
|
|
||||||
|
* https://stackblitz.com/edit/react-ts-qq25sp
|
||||||
|
* https://stackblitz.com/edit/react-ts-qdqu7z (adding images to Word Document)
|
||||||
|
|
||||||
|
Here is an example of `docx` working in `Vue.js`:
|
||||||
|
|
||||||
|
* https://stackblitz.com/edit/vuejs-docx
|
||||||
|
|
||||||
## Node
|
## Node
|
||||||
|
|
||||||
Press `endpoint` on the `RunKit` website:
|
Press `endpoint` on the `RunKit` website:
|
||||||
@ -50,7 +60,7 @@ Press `endpoint` on the `RunKit` website:
|
|||||||
* https://runkit.com/dolanmiu/docx-demo8 - Header and Footer
|
* https://runkit.com/dolanmiu/docx-demo8 - Header and Footer
|
||||||
* https://runkit.com/dolanmiu/docx-demo10 - **My CV generated with docx**
|
* https://runkit.com/dolanmiu/docx-demo10 - **My CV generated with docx**
|
||||||
|
|
||||||
More [here](https://docx.js.org/#/examples) and [here](https://github.com/dolanmiu/docx/tree/master/demo)
|
More [here](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||||
|
|
||||||
# How to use & Documentation
|
# How to use & Documentation
|
||||||
|
|
||||||
@ -58,7 +68,7 @@ Please refer to the [documentation at https://docx.js.org/](https://docx.js.org/
|
|||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
Check the `examples` section in the [documentation](https://docx.js.org/#/examples) and the [demo folder](https://github.com/dolanmiu/docx/tree/master/demo) for examples.
|
Check the [demo folder](https://github.com/dolanmiu/docx/tree/master/demo) for examples.
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
@ -73,6 +83,11 @@ Read the contribution guidelines [here](https://docx.js.org/#/contribution-guide
|
|||||||
[<img src="https://i.imgur.com/suiH2zc.png" alt="drawing" height="50"/>](https://www.dabblewriter.com/)
|
[<img src="https://i.imgur.com/suiH2zc.png" alt="drawing" height="50"/>](https://www.dabblewriter.com/)
|
||||||
[<img src="https://i.imgur.com/1LjuK2M.png" alt="drawing" height="50"/>](https://turbopatent.com/)
|
[<img src="https://i.imgur.com/1LjuK2M.png" alt="drawing" height="50"/>](https://turbopatent.com/)
|
||||||
[<img src="https://i.imgur.com/dHMg0wF.gif" alt="drawing" height="50"/>](http://www.madisoncres.com/)
|
[<img src="https://i.imgur.com/dHMg0wF.gif" alt="drawing" height="50"/>](http://www.madisoncres.com/)
|
||||||
|
[<img src="https://i.imgur.com/QEZXU5b.png" alt="drawing" height="50"/>](https://www.beekast.com/)
|
||||||
|
[<img src="https://imgur.com/XVU6aoi.png" alt="drawing" height="50"/>](https://herraizsoto.com/)
|
||||||
|
[<img src="https://i.imgur.com/fn1xccG.png" alt="drawing" height="50"/>](http://www.ativer.com.br/)
|
||||||
|
[<img src="https://i.imgur.com/cmykN7c.png" alt="drawing"/>](https://www.arity.co/)
|
||||||
|
|
||||||
|
|
||||||
...and many more!
|
...and many more!
|
||||||
|
|
||||||
@ -89,6 +104,8 @@ Made with 💖
|
|||||||
[downloads-url]: https://npmjs.org/package/docx
|
[downloads-url]: https://npmjs.org/package/docx
|
||||||
[travis-image]: https://travis-ci.org/dolanmiu/docx.svg?branch=master
|
[travis-image]: https://travis-ci.org/dolanmiu/docx.svg?branch=master
|
||||||
[travis-url]: https://travis-ci.org/dolanmiu/docx
|
[travis-url]: https://travis-ci.org/dolanmiu/docx
|
||||||
|
[github-actions-workflow-image]: https://github.com/dolanmiu/docx/workflows/Default/badge.svg
|
||||||
|
[github-actions-workflow-url]: https://github.com/dolanmiu/docx/actions
|
||||||
[daviddm-image]: https://david-dm.org/dolanmiu/docx.svg?theme=shields.io
|
[daviddm-image]: https://david-dm.org/dolanmiu/docx.svg?theme=shields.io
|
||||||
[daviddm-url]: https://david-dm.org/dolanmiu/docx
|
[daviddm-url]: https://david-dm.org/dolanmiu/docx
|
||||||
[snky-image]: https://snyk.io/test/github/dolanmiu/docx/badge.svg
|
[snky-image]: https://snyk.io/test/github/dolanmiu/docx/badge.svg
|
||||||
|
@ -16,9 +16,9 @@ doc.addSection({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Github is the best",
|
text: "\tGithub is the best",
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Generate a CV
|
// Generate a CV
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TextRun } from "../build";
|
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "../build";
|
||||||
|
|
||||||
// tslint:disable:no-shadowed-variable
|
// tslint:disable:no-shadowed-variable
|
||||||
|
|
||||||
@ -226,18 +226,21 @@ class DocumentCreator {
|
|||||||
|
|
||||||
public createInstitutionHeader(institutionName: string, dateText: string): Paragraph {
|
public createInstitutionHeader(institutionName: string, dateText: string): Paragraph {
|
||||||
return new Paragraph({
|
return new Paragraph({
|
||||||
tabStop: {
|
tabStops: [
|
||||||
maxRight: {},
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
children: [
|
children: [
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: institutionName,
|
text: institutionName,
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: dateText,
|
text: `\t${dateText}`,
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,93 +1,164 @@
|
|||||||
// Setting styles with JavaScript configuration
|
// Setting styles with JavaScript configuration
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, Footer, HeadingLevel, Media, Packer, Paragraph, Table } from "../build";
|
import {
|
||||||
|
AlignmentType,
|
||||||
|
Document,
|
||||||
|
Footer,
|
||||||
|
HeadingLevel,
|
||||||
|
Media,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableRow,
|
||||||
|
TabStopPosition,
|
||||||
|
UnderlineType,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
doc.Styles.createParagraphStyle("Heading1", "Heading 1")
|
default: {
|
||||||
.basedOn("Normal")
|
heading1: {
|
||||||
.next("Normal")
|
run: {
|
||||||
.quickFormat()
|
font: "Calibri",
|
||||||
.font("Calibri")
|
size: 52,
|
||||||
.size(52)
|
bold: true,
|
||||||
.center()
|
color: "000000",
|
||||||
.bold()
|
underline: {
|
||||||
.color("000000")
|
type: UnderlineType.SINGLE,
|
||||||
.spacing({ line: 340 })
|
color: "000000",
|
||||||
.underline("single", "000000");
|
},
|
||||||
|
},
|
||||||
doc.Styles.createParagraphStyle("Heading2", "Heading 2")
|
paragraph: {
|
||||||
.basedOn("Normal")
|
alignment: AlignmentType.CENTER,
|
||||||
.next("Normal")
|
spacing: { line: 340 },
|
||||||
.font("Calibri")
|
},
|
||||||
.quickFormat()
|
},
|
||||||
.size(26)
|
heading2: {
|
||||||
.bold()
|
run: {
|
||||||
.spacing({ line: 340 });
|
font: "Calibri",
|
||||||
|
size: 26,
|
||||||
doc.Styles.createParagraphStyle("Heading3", "Heading 3")
|
bold: true,
|
||||||
.basedOn("Normal")
|
},
|
||||||
.next("Normal")
|
paragraph: {
|
||||||
.font("Calibri")
|
spacing: { line: 340 },
|
||||||
.quickFormat()
|
},
|
||||||
.size(26)
|
},
|
||||||
.bold()
|
heading3: {
|
||||||
.spacing({ line: 276 });
|
run: {
|
||||||
|
font: "Calibri",
|
||||||
doc.Styles.createParagraphStyle("Heading4", "Heading 4")
|
size: 26,
|
||||||
.basedOn("Normal")
|
bold: true,
|
||||||
.next("Normal")
|
},
|
||||||
.justified()
|
paragraph: {
|
||||||
.font("Calibri")
|
spacing: { line: 276 },
|
||||||
.size(26)
|
},
|
||||||
.bold();
|
},
|
||||||
|
heading4: {
|
||||||
doc.Styles.createParagraphStyle("normalPara", "Normal Para")
|
run: {
|
||||||
.basedOn("Normal")
|
font: "Calibri",
|
||||||
.next("Normal")
|
size: 26,
|
||||||
.font("Calibri")
|
bold: true,
|
||||||
.quickFormat()
|
},
|
||||||
.leftTabStop(453.543307087)
|
paragraph: {
|
||||||
.maxRightTabStop()
|
alignment: AlignmentType.JUSTIFIED,
|
||||||
.size(26)
|
},
|
||||||
.spacing({ line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 });
|
},
|
||||||
|
},
|
||||||
doc.Styles.createParagraphStyle("normalPara2", "Normal Para2")
|
paragraphStyles: [
|
||||||
.basedOn("Normal")
|
{
|
||||||
.next("Normal")
|
id: "normalPara",
|
||||||
.quickFormat()
|
name: "Normal Para",
|
||||||
.font("Calibri")
|
basedOn: "Normal",
|
||||||
.size(26)
|
next: "Normal",
|
||||||
.justified()
|
quickFormat: true,
|
||||||
.spacing({ line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 });
|
run: {
|
||||||
|
font: "Calibri",
|
||||||
doc.Styles.createParagraphStyle("aside", "Aside")
|
size: 26,
|
||||||
.basedOn("Normal")
|
bold: true,
|
||||||
.next("Normal")
|
},
|
||||||
.color("999999")
|
paragraph: {
|
||||||
.italics()
|
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||||
.indent({ left: 720 })
|
rightTabStop: TabStopPosition.MAX,
|
||||||
.spacing({ line: 276 });
|
leftTabStop: 453.543307087,
|
||||||
|
},
|
||||||
doc.Styles.createParagraphStyle("wellSpaced", "Well Spaced")
|
},
|
||||||
.basedOn("Normal")
|
{
|
||||||
.spacing({ line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 });
|
id: "normalPara2",
|
||||||
|
name: "Normal Para2",
|
||||||
doc.Styles.createParagraphStyle("ListParagraph", "List Paragraph")
|
basedOn: "Normal",
|
||||||
.quickFormat()
|
next: "Normal",
|
||||||
.basedOn("Normal");
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
font: "Calibri",
|
||||||
|
size: 26,
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
alignment: AlignmentType.JUSTIFIED,
|
||||||
|
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "aside",
|
||||||
|
name: "Aside",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
run: {
|
||||||
|
color: "999999",
|
||||||
|
italics: true,
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
spacing: { line: 276 },
|
||||||
|
indent: { left: 720 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "wellSpaced",
|
||||||
|
name: "Well Spaced",
|
||||||
|
basedOn: "Normal",
|
||||||
|
paragraph: {
|
||||||
|
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const image = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
const image = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 4,
|
rows: [
|
||||||
columns: 4,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Test cell 1.")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Test cell 2.")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Test cell 3.")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Test cell 4.")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
table
|
|
||||||
.getRow(0)
|
|
||||||
.getCell(0)
|
|
||||||
.add(new Paragraph("Pole No."));
|
|
||||||
|
|
||||||
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||||
const image2 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
const image2 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Page numbers
|
// Page numbers
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, Header, Packer, Paragraph, TextRun } from "../build";
|
import { AlignmentType, Document, Header, Packer, PageBreak, PageNumber, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
@ -11,7 +11,12 @@ doc.addSection({
|
|||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
alignment: AlignmentType.RIGHT,
|
alignment: AlignmentType.RIGHT,
|
||||||
children: [new TextRun("My Title "), new TextRun("Page ").pageNumber()],
|
children: [
|
||||||
|
new TextRun("My Title "),
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -19,15 +24,20 @@ doc.addSection({
|
|||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
alignment: AlignmentType.RIGHT,
|
alignment: AlignmentType.RIGHT,
|
||||||
children: [new TextRun("First Page Header "), new TextRun("Page ").pageNumber()],
|
children: [
|
||||||
|
new TextRun("First Page Header "),
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "First Page",
|
children: [new TextRun("First Page"), new PageBreak()],
|
||||||
}).pageBreak(),
|
}),
|
||||||
new Paragraph("Second Page"),
|
new Paragraph("Second Page"),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// Multiple sections and headers
|
// Multiple sections and headers
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Footer, Header, Packer, PageNumberFormat, PageOrientation, Paragraph, TextRun } from "../build";
|
import { Document, Footer, Header, Packer, PageNumber, PageNumberFormat, PageOrientation, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [new Paragraph("Hello World").pageBreak()],
|
children: [new Paragraph("Hello World")],
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
@ -53,7 +53,11 @@ doc.addSection({
|
|||||||
default: new Header({
|
default: new Header({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [new TextRun("Page number: ").pageNumber()],
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -69,7 +73,11 @@ doc.addSection({
|
|||||||
default: new Header({
|
default: new Header({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [new TextRun("Page number: ").pageNumber()],
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -90,7 +98,11 @@ doc.addSection({
|
|||||||
default: new Header({
|
default: new Header({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
children: [new TextRun("Page number: ").pageNumber()],
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
@ -1,16 +1,54 @@
|
|||||||
// Footnotes
|
// Footnotes
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph } from "../build";
|
import { Document, FootnoteReferenceRun, Packer, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
|
footnotes: [
|
||||||
doc.addSection({
|
new Paragraph("Foo"),
|
||||||
children: [new Paragraph("Hello World").referenceFootnote(1), new Paragraph("Hello World").referenceFootnote(2)],
|
new Paragraph("Test"),
|
||||||
|
new Paragraph("My amazing reference"),
|
||||||
|
new Paragraph("Foo1"),
|
||||||
|
new Paragraph("Test1"),
|
||||||
|
new Paragraph("My amazing reference1"),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.createFootnote(new Paragraph("Test"));
|
doc.addSection({
|
||||||
doc.createFootnote(new Paragraph("My amazing reference"));
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Hello", new FootnoteReferenceRun(1)],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
children: [" World!", new FootnoteReferenceRun(2)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World"), new FootnoteReferenceRun(3)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
children: ["Hello", new FootnoteReferenceRun(4)],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
children: [" World!", new FootnoteReferenceRun(5)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World"), new FootnoteReferenceRun(6)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
@ -15,9 +15,9 @@ doc.addSection({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Bar",
|
text: "\tBar",
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -1,55 +1,96 @@
|
|||||||
// Example on how to customise the look at feel using Styles
|
// Example on how to customise the look at feel using Styles
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, TextRun } from "../build";
|
import { AlignmentType, Document, HeadingLevel, Packer, Paragraph, TextRun, UnderlineType } from "../build";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
creator: "Clippy",
|
creator: "Clippy",
|
||||||
title: "Sample Document",
|
title: "Sample Document",
|
||||||
description: "A brief example of using docx",
|
description: "A brief example of using docx",
|
||||||
|
styles: {
|
||||||
|
default: {
|
||||||
|
heading1: {
|
||||||
|
run: {
|
||||||
|
size: 28,
|
||||||
|
bold: true,
|
||||||
|
italics: true,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
spacing: {
|
||||||
|
after: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
heading2: {
|
||||||
|
run: {
|
||||||
|
size: 26,
|
||||||
|
bold: true,
|
||||||
|
underline: {
|
||||||
|
type: UnderlineType.DOUBLE,
|
||||||
|
color: "FF0000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
spacing: {
|
||||||
|
before: 240,
|
||||||
|
after: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
listParagraph: {
|
||||||
|
run: {
|
||||||
|
color: '#FF0000'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: "aside",
|
||||||
|
name: "Aside",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
run: {
|
||||||
|
color: "999999",
|
||||||
|
italics: true,
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
indent: {
|
||||||
|
left: 720,
|
||||||
|
},
|
||||||
|
spacing: {
|
||||||
|
line: 276,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "wellSpaced",
|
||||||
|
name: "Well Spaced",
|
||||||
|
basedOn: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
paragraph: {
|
||||||
|
spacing: { line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
numbering: {
|
||||||
|
config: [
|
||||||
|
{
|
||||||
|
reference: "my-crazy-numbering",
|
||||||
|
levels: [
|
||||||
|
{
|
||||||
|
level: 0,
|
||||||
|
format: "lowerLetter",
|
||||||
|
text: "%1)",
|
||||||
|
alignment: AlignmentType.LEFT,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.Styles.createParagraphStyle("Heading1", "Heading 1")
|
|
||||||
.basedOn("Normal")
|
|
||||||
.next("Normal")
|
|
||||||
.quickFormat()
|
|
||||||
.size(28)
|
|
||||||
.bold()
|
|
||||||
.italics()
|
|
||||||
.spacing({ after: 120 });
|
|
||||||
|
|
||||||
doc.Styles.createParagraphStyle("Heading2", "Heading 2")
|
|
||||||
.basedOn("Normal")
|
|
||||||
.next("Normal")
|
|
||||||
.quickFormat()
|
|
||||||
.size(26)
|
|
||||||
.bold()
|
|
||||||
.underline("double", "FF0000")
|
|
||||||
.spacing({ before: 240, after: 120 });
|
|
||||||
|
|
||||||
doc.Styles.createParagraphStyle("aside", "Aside")
|
|
||||||
.basedOn("Normal")
|
|
||||||
.next("Normal")
|
|
||||||
.color("999999")
|
|
||||||
.italics()
|
|
||||||
.indent({ left: 720 })
|
|
||||||
.spacing({ line: 276 });
|
|
||||||
|
|
||||||
doc.Styles.createParagraphStyle("wellSpaced", "Well Spaced")
|
|
||||||
.basedOn("Normal")
|
|
||||||
.spacing({ line: 276, before: 20 * 72 * 0.1, after: 20 * 72 * 0.05 });
|
|
||||||
|
|
||||||
doc.Styles.createParagraphStyle("ListParagraph", "List Paragraph")
|
|
||||||
.quickFormat()
|
|
||||||
.basedOn("Normal");
|
|
||||||
|
|
||||||
const numberedAbstract = doc.Numbering.createAbstractNumbering();
|
|
||||||
numberedAbstract.createLevel(0, "lowerLetter", "%1)", "left");
|
|
||||||
|
|
||||||
const letterNumbering = doc.Numbering.createConcreteNumbering(numberedAbstract);
|
|
||||||
const letterNumbering5 = doc.Numbering.createConcreteNumbering(numberedAbstract);
|
|
||||||
letterNumbering5.overrideLevel(0, 5);
|
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
@ -64,32 +105,34 @@ doc.addSection({
|
|||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Option1",
|
text: "Option1",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: letterNumbering,
|
reference: "my-crazy-numbering",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Option5 -- override 2 to 5",
|
text: "Option5 -- override 2 to 5",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: letterNumbering,
|
reference: "my-crazy-numbering",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Option3",
|
text: "Option3",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: letterNumbering,
|
reference: "my-crazy-numbering",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({}).addRun(
|
new Paragraph({
|
||||||
|
children: [
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Some monospaced content",
|
text: "Some monospaced content",
|
||||||
font: {
|
font: {
|
||||||
name: "Monospace",
|
name: "Monospace",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
),
|
],
|
||||||
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "An aside, in light gray italics and indented",
|
text: "An aside, in light gray italics and indented",
|
||||||
style: "aside",
|
style: "aside",
|
||||||
@ -109,6 +152,10 @@ doc.addSection({
|
|||||||
text: "and then underlined ",
|
text: "and then underlined ",
|
||||||
underline: {},
|
underline: {},
|
||||||
}),
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "and then emphasis-mark ",
|
||||||
|
emphasisMark: {},
|
||||||
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "and back to normal.",
|
text: "and back to normal.",
|
||||||
}),
|
}),
|
||||||
|
@ -1,23 +1,102 @@
|
|||||||
// Add custom borders to table cell
|
// Add custom borders to table cell
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { BorderStyle, Document, Packer, Paragraph, Table } from "../build";
|
import { BorderStyle, Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 4,
|
rows: [
|
||||||
columns: 4,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
borders: {
|
||||||
|
top: {
|
||||||
|
style: BorderStyle.DASH_DOT_STROKED,
|
||||||
|
size: 3,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
style: BorderStyle.DOUBLE,
|
||||||
|
size: 3,
|
||||||
|
color: "blue",
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
style: BorderStyle.DASH_DOT_STROKED,
|
||||||
|
size: 3,
|
||||||
|
color: "green",
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
style: BorderStyle.DASH_DOT_STROKED,
|
||||||
|
size: 3,
|
||||||
|
color: "#ff8000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.addSection({ children: [table] });
|
doc.addSection({ children: [table] });
|
||||||
table
|
|
||||||
.getCell(2, 2)
|
|
||||||
.add(new Paragraph("Hello"))
|
|
||||||
.Borders.addTopBorder(BorderStyle.DASH_DOT_STROKED, 3, "red")
|
|
||||||
.addBottomBorder(BorderStyle.DOUBLE, 3, "blue")
|
|
||||||
.addStartBorder(BorderStyle.DOT_DOT_DASH, 3, "green")
|
|
||||||
.addEndBorder(BorderStyle.DOT_DOT_DASH, 3, "#ff8000");
|
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// This demo shows how to create bookmarks then link to them with internal hyperlinks
|
// This demo shows how to create bookmarks then link to them with internal hyperlinks
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph } from "../build";
|
import { Bookmark, Document, HeadingLevel, HyperlinkRef, HyperlinkType, Packer, PageBreak, Paragraph } from "../build";
|
||||||
|
|
||||||
const LOREM_IPSUM =
|
const LOREM_IPSUM =
|
||||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mi velit, convallis convallis scelerisque nec, faucibus nec leo. Phasellus at posuere mauris, tempus dignissim velit. Integer et tortor dolor. Duis auctor efficitur mattis. Vivamus ut metus accumsan tellus auctor sollicitudin venenatis et nibh. Cras quis massa ac metus fringilla venenatis. Proin rutrum mauris purus, ut suscipit magna consectetur id. Integer consectetur sollicitudin ante, vitae faucibus neque efficitur in. Praesent ultricies nibh lectus. Mauris pharetra id odio eget iaculis. Duis dictum, risus id pellentesque rutrum, lorem quam malesuada massa, quis ullamcorper turpis urna a diam. Cras vulputate metus vel massa porta ullamcorper. Etiam porta condimentum nulla nec tristique. Sed nulla urna, pharetra non tortor sed, sollicitudin molestie diam. Maecenas enim leo, feugiat eget vehicula id, sollicitudin vitae ante.";
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam mi velit, convallis convallis scelerisque nec, faucibus nec leo. Phasellus at posuere mauris, tempus dignissim velit. Integer et tortor dolor. Duis auctor efficitur mattis. Vivamus ut metus accumsan tellus auctor sollicitudin venenatis et nibh. Cras quis massa ac metus fringilla venenatis. Proin rutrum mauris purus, ut suscipit magna consectetur id. Integer consectetur sollicitudin ante, vitae faucibus neque efficitur in. Praesent ultricies nibh lectus. Mauris pharetra id odio eget iaculis. Duis dictum, risus id pellentesque rutrum, lorem quam malesuada massa, quis ullamcorper turpis urna a diam. Cras vulputate metus vel massa porta ullamcorper. Etiam porta condimentum nulla nec tristique. Sed nulla urna, pharetra non tortor sed, sollicitudin molestie diam. Maecenas enim leo, feugiat eget vehicula id, sollicitudin vitae ante.";
|
||||||
@ -10,23 +10,28 @@ const doc = new Document({
|
|||||||
creator: "Clippy",
|
creator: "Clippy",
|
||||||
title: "Sample Document",
|
title: "Sample Document",
|
||||||
description: "A brief example of using docx with bookmarks and internal hyperlinks",
|
description: "A brief example of using docx with bookmarks and internal hyperlinks",
|
||||||
|
hyperlinks: {
|
||||||
|
myAnchorId: {
|
||||||
|
text: "Hyperlink",
|
||||||
|
type: HyperlinkType.INTERNAL,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const anchorId = "anchorID";
|
|
||||||
|
|
||||||
// First create the bookmark
|
|
||||||
const bookmark = doc.createBookmark(anchorId, "Lorem Ipsum");
|
|
||||||
const hyperlink = doc.createInternalHyperLink(anchorId, `Click me!`);
|
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
heading: HeadingLevel.HEADING_1,
|
heading: HeadingLevel.HEADING_1,
|
||||||
}).addBookmark(bookmark),
|
children: [new Bookmark("myAnchorId", "Lorem Ipsum")],
|
||||||
|
}),
|
||||||
new Paragraph("\n"),
|
new Paragraph("\n"),
|
||||||
new Paragraph(LOREM_IPSUM),
|
new Paragraph(LOREM_IPSUM),
|
||||||
new Paragraph({}).pageBreak(),
|
new Paragraph({
|
||||||
new Paragraph({}).addHyperLink(hyperlink),
|
children: [new PageBreak()],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new HyperlinkRef("myAnchorId")],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,24 +1,85 @@
|
|||||||
// Add image to table cell
|
// Add image to table cell
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Media, Packer, Paragraph, Table } from "../build";
|
import { Document, Media, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
|
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 4,
|
rows: [
|
||||||
columns: 4,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(image)],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table],
|
||||||
});
|
});
|
||||||
|
|
||||||
table.getCell(2, 2).add(new Paragraph("Hello"));
|
|
||||||
|
|
||||||
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
|
||||||
table.getCell(1, 1).add(new Paragraph(image));
|
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
});
|
});
|
||||||
|
@ -1,28 +1,53 @@
|
|||||||
// Custom styles using JavaScript configuration
|
// Custom styles using JavaScript configuration
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph } from "../build";
|
import { Document, HeadingLevel, Packer, Paragraph, UnderlineType } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
// The first argument is an ID you use to apply the style to paragraphs
|
paragraphStyles: [
|
||||||
// The second argument is a human-friendly name to show in the UI
|
{
|
||||||
doc.Styles.createParagraphStyle("myWonkyStyle", "My Wonky Style")
|
id: "myWonkyStyle",
|
||||||
.basedOn("Normal")
|
name: "My Wonky Style",
|
||||||
.next("Normal")
|
basedOn: "Normal",
|
||||||
.color("990000")
|
next: "Normal",
|
||||||
.italics()
|
run: {
|
||||||
.indent({ left: 720 }) // 720 TWIP === 720 / 20 pt === .5 in
|
color: "990000",
|
||||||
.spacing({ line: 276 }); // 276 / 240 = 1.15x line spacing
|
italics: true,
|
||||||
|
},
|
||||||
doc.Styles.createParagraphStyle("Heading2", "Heading 2")
|
paragraph: {
|
||||||
.basedOn("Normal")
|
indent: {
|
||||||
.next("Normal")
|
left: 720,
|
||||||
.quickFormat()
|
},
|
||||||
.size(26) // 26 half-points === 13pt font
|
spacing: {
|
||||||
.bold()
|
line: 276,
|
||||||
.underline("double", "FF0000")
|
},
|
||||||
.spacing({ before: 240, after: 120 }); // TWIP for both
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "Heading2",
|
||||||
|
name: "Heading 2",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
bold: true,
|
||||||
|
size: 26,
|
||||||
|
underline: {
|
||||||
|
type: UnderlineType.DOUBLE,
|
||||||
|
color: "FF0000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
spacing: {
|
||||||
|
before: 240,
|
||||||
|
after: 120,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
|
@ -3,15 +3,23 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { File, HeadingLevel, Packer, Paragraph, StyleLevel, TableOfContents } from "../build";
|
import { File, HeadingLevel, Packer, Paragraph, StyleLevel, TableOfContents } from "../build";
|
||||||
|
|
||||||
const doc = new File();
|
const doc = new File({
|
||||||
|
styles: {
|
||||||
// The first argument is an ID you use to apply the style to paragraphs
|
paragraphStyles: [
|
||||||
// The second argument is a human-friendly name to show in the UI
|
{
|
||||||
doc.Styles.createParagraphStyle("MySpectacularStyle", "My Spectacular Style")
|
id: "MySpectacularStyle",
|
||||||
.basedOn("Heading1")
|
name: "My Spectacular Style",
|
||||||
.next("Heading1")
|
basedOn: "Heading1",
|
||||||
.color("990000")
|
next: "Heading1",
|
||||||
.italics();
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
italics: true,
|
||||||
|
color: "990000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// WordprocessingML docs for TableOfContents can be found here:
|
// WordprocessingML docs for TableOfContents can be found here:
|
||||||
// http://officeopenxml.com/WPtableOfContents.php
|
// http://officeopenxml.com/WPtableOfContents.php
|
||||||
|
@ -1,23 +1,53 @@
|
|||||||
// Numbered lists
|
// Numbered lists
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Numbering, Packer, Paragraph } from "../build";
|
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
|
numbering: {
|
||||||
const numbering = new Numbering();
|
config: [
|
||||||
|
{
|
||||||
const abstractNum = numbering.createAbstractNumbering();
|
levels: [
|
||||||
abstractNum.createLevel(0, "upperRoman", "%1", "start").indent({ left: 720, hanging: 260 });
|
{
|
||||||
|
level: 0,
|
||||||
const concrete = numbering.createConcreteNumbering(abstractNum);
|
format: "upperRoman",
|
||||||
|
text: "%1",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 720, hanging: 260 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
reference: "my-crazy-reference",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
levels: [
|
||||||
|
{
|
||||||
|
level: 0,
|
||||||
|
format: "decimal",
|
||||||
|
text: "%1",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 720, hanging: 260 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
reference: "my-number-numbering-reference",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "line with contextual spacing",
|
text: "line with contextual spacing",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-reference",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
contextualSpacing: true,
|
contextualSpacing: true,
|
||||||
@ -28,7 +58,7 @@ doc.addSection({
|
|||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "line with contextual spacing",
|
text: "line with contextual spacing",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-reference",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
contextualSpacing: true,
|
contextualSpacing: true,
|
||||||
@ -39,7 +69,7 @@ doc.addSection({
|
|||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "line without contextual spacing",
|
text: "line without contextual spacing",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-reference",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
contextualSpacing: false,
|
contextualSpacing: false,
|
||||||
@ -50,7 +80,7 @@ doc.addSection({
|
|||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "line without contextual spacing",
|
text: "line without contextual spacing",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-reference",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
contextualSpacing: false,
|
contextualSpacing: false,
|
||||||
@ -58,6 +88,27 @@ doc.addSection({
|
|||||||
before: 200,
|
before: 200,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "Step 1 - Add sugar",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-number-numbering-reference",
|
||||||
|
level: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "Step 2 - Add wheat",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-number-numbering-reference",
|
||||||
|
level: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "Step 3 - Put in oven",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-number-numbering-reference",
|
||||||
|
level: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,46 +1,91 @@
|
|||||||
// Numbering and bullet points example
|
// Numbering and bullet points example
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Numbering, Packer, Paragraph } from "../build";
|
import { AlignmentType, Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
|
numbering: {
|
||||||
const numbering = new Numbering();
|
config: [
|
||||||
|
{
|
||||||
const abstractNum = numbering.createAbstractNumbering();
|
reference: "my-crazy-numbering",
|
||||||
abstractNum.createLevel(0, "upperRoman", "%1", "start").indent({ left: 720, hanging: 260 });
|
levels: [
|
||||||
abstractNum.createLevel(1, "decimal", "%2.", "start").indent({ left: 1440, hanging: 980 });
|
{
|
||||||
abstractNum.createLevel(2, "lowerLetter", "%3)", "start").indent({ left: 14402160, hanging: 1700 });
|
level: 0,
|
||||||
|
format: "upperRoman",
|
||||||
const concrete = numbering.createConcreteNumbering(abstractNum);
|
text: "%1",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 720, hanging: 260 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
format: "decimal",
|
||||||
|
text: "%2.",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 1440, hanging: 980 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 2,
|
||||||
|
format: "lowerLetter",
|
||||||
|
text: "%3)",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 2160, hanging: 1700 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
format: "upperLetter",
|
||||||
|
text: "%4)",
|
||||||
|
alignment: AlignmentType.START,
|
||||||
|
style: {
|
||||||
|
paragraph: {
|
||||||
|
indent: { left: 2880, hanging: 2420 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Hey you",
|
text: "Hey you",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-numbering",
|
||||||
level: 0,
|
level: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "What's up fam",
|
text: "What's up fam",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-numbering",
|
||||||
level: 1,
|
level: 1,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Hello World 2",
|
text: "Hello World 2",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-numbering",
|
||||||
level: 1,
|
level: 1,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Yeah boi",
|
text: "Yeah boi",
|
||||||
numbering: {
|
numbering: {
|
||||||
num: concrete,
|
reference: "my-crazy-numbering",
|
||||||
level: 2,
|
level: 2,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -68,6 +113,27 @@ doc.addSection({
|
|||||||
level: 3,
|
level: 3,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "101 MSXFM",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-crazy-numbering",
|
||||||
|
level: 3,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "back to level 1",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-crazy-numbering",
|
||||||
|
level: 1,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "back to level 0",
|
||||||
|
numbering: {
|
||||||
|
reference: "my-crazy-numbering",
|
||||||
|
level: 0,
|
||||||
|
},
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,27 +1,71 @@
|
|||||||
// Example of how you would create a table and add data to it
|
// 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 from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, Table, VerticalAlign } from "../build";
|
import { Document, HeadingLevel, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign, TextDirection } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 2,
|
rows: [
|
||||||
columns: 2,
|
new TableRow({
|
||||||
});
|
children: [
|
||||||
|
new TableCell({
|
||||||
table
|
children: [new Paragraph({}), new Paragraph({})],
|
||||||
.getCell(1, 1)
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
.add(new Paragraph("This text should be in the middle of the cell"))
|
}),
|
||||||
.setVerticalAlign(VerticalAlign.CENTER);
|
new TableCell({
|
||||||
|
children: [new Paragraph({}), new Paragraph({})],
|
||||||
table.getCell(1, 0).add(
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph({ text: "bottom to top" }), new Paragraph({})],
|
||||||
|
textDirection: TextDirection.BOTTOM_TO_TOP_LEFT_TO_RIGHT,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph({ text: "top to bottom" }), new Paragraph({})],
|
||||||
|
textDirection: TextDirection.TOP_TO_BOTTOM_RIGHT_TO_LEFT,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text:
|
text:
|
||||||
"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",
|
"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",
|
||||||
heading: HeadingLevel.HEADING_1,
|
heading: HeadingLevel.HEADING_1,
|
||||||
}),
|
}),
|
||||||
);
|
],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "This text should be in the middle of the cell",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "Text above should be vertical from bottom to top",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "Text above should be vertical from top to bottom",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table],
|
||||||
|
397
demo/32-merge-and-shade-table-cells.ts
Normal file
397
demo/32-merge-and-shade-table-cells.ts
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
// Example of how you would merge cells together (Rows and Columns) and apply shading
|
||||||
|
// Also includes an example on how to center tables
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { AlignmentType, BorderStyle, Document, HeadingLevel, Packer, Paragraph, ShadingType, Table, TableCell, TableRow, WidthType } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const table = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const table2 = new Table({
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("World")],
|
||||||
|
margins: {
|
||||||
|
top: 1000,
|
||||||
|
bottom: 1000,
|
||||||
|
left: 1000,
|
||||||
|
right: 1000,
|
||||||
|
},
|
||||||
|
columnSpan: 3,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.AUTO,
|
||||||
|
},
|
||||||
|
columnWidths: [1000, 1000, 1000],
|
||||||
|
});
|
||||||
|
|
||||||
|
const table3 = new Table({
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Foo")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("v")],
|
||||||
|
columnSpan: 3,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Bar1")],
|
||||||
|
shading: {
|
||||||
|
fill: "b79c2f",
|
||||||
|
val: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Bar2")],
|
||||||
|
shading: {
|
||||||
|
fill: "42c5f4",
|
||||||
|
val: ShadingType.PERCENT_95,
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Bar3")],
|
||||||
|
shading: {
|
||||||
|
fill: "880aa8",
|
||||||
|
val: ShadingType.PERCENT_10,
|
||||||
|
color: "e2df0b",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Bar4")],
|
||||||
|
shading: {
|
||||||
|
fill: "FF0000",
|
||||||
|
val: ShadingType.CLEAR,
|
||||||
|
color: "auto",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 7000,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
},
|
||||||
|
margins: {
|
||||||
|
top: 400,
|
||||||
|
bottom: 400,
|
||||||
|
right: 400,
|
||||||
|
left: 400,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const table4 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,0")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,1")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const table5 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,1")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,2")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,1")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const borders = {
|
||||||
|
top: {
|
||||||
|
style: BorderStyle.DASH_SMALL_GAP,
|
||||||
|
size: 1,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
style: BorderStyle.DASH_SMALL_GAP,
|
||||||
|
size: 1,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
style: BorderStyle.DASH_SMALL_GAP,
|
||||||
|
size: 1,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
style: BorderStyle.DASH_SMALL_GAP,
|
||||||
|
size: 1,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const table6 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
borders,
|
||||||
|
children: [new Paragraph("0,0")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
borders,
|
||||||
|
children: [new Paragraph("0,1")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
borders,
|
||||||
|
children: [new Paragraph("1,1")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
borders,
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const table7 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,2")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,3")],
|
||||||
|
rowSpan: 3,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,0")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,2")],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,3")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const table8 = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("1,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,2")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,3")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("1,4")], rowSpan: 4, borders }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("2,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("2,2")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("2,3")], rowSpan: 3 }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("3,1")] }),
|
||||||
|
new TableCell({ children: [new Paragraph("3,2")], rowSpan: 2 }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({ children: [new Paragraph("4,1")] }),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
width: {
|
||||||
|
size: 100,
|
||||||
|
type: WidthType.PERCENTAGE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
table,
|
||||||
|
new Paragraph({
|
||||||
|
text: "Another table",
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
}),
|
||||||
|
table2,
|
||||||
|
new Paragraph({
|
||||||
|
text: "Another table",
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
}),
|
||||||
|
table3,
|
||||||
|
new Paragraph("Merging columns 1"),
|
||||||
|
table4,
|
||||||
|
new Paragraph("Merging columns 2"),
|
||||||
|
table5,
|
||||||
|
new Paragraph("Merging columns 3"),
|
||||||
|
table6,
|
||||||
|
new Paragraph("Merging columns 4"),
|
||||||
|
table7,
|
||||||
|
new Paragraph("Merging columns 5"),
|
||||||
|
table8,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
@ -1,113 +0,0 @@
|
|||||||
// Example of how you would merge cells together
|
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
|
||||||
import * as fs from "fs";
|
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, ShadingType, Table, WidthType } from "../build";
|
|
||||||
|
|
||||||
const doc = new Document();
|
|
||||||
|
|
||||||
const table = new Table({
|
|
||||||
rows: 2,
|
|
||||||
columns: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
table.getCell(0, 0).add(new Paragraph("Hello"));
|
|
||||||
table.getRow(0).mergeCells(0, 1);
|
|
||||||
|
|
||||||
const table2 = new Table({
|
|
||||||
rows: 2,
|
|
||||||
columns: 3,
|
|
||||||
width: 100,
|
|
||||||
widthUnitType: WidthType.AUTO,
|
|
||||||
columnWidths: [1000, 1000, 1000],
|
|
||||||
});
|
|
||||||
|
|
||||||
table2
|
|
||||||
.getCell(0, 0)
|
|
||||||
.add(new Paragraph("World"))
|
|
||||||
.setMargins({
|
|
||||||
top: 1000,
|
|
||||||
bottom: 1000,
|
|
||||||
left: 1000,
|
|
||||||
right: 1000,
|
|
||||||
});
|
|
||||||
table.getRow(0).mergeCells(0, 2);
|
|
||||||
|
|
||||||
const table3 = new Table({
|
|
||||||
rows: 2,
|
|
||||||
columns: 4,
|
|
||||||
width: 7000,
|
|
||||||
widthUnitType: WidthType.DXA,
|
|
||||||
margins: {
|
|
||||||
top: 400,
|
|
||||||
bottom: 400,
|
|
||||||
right: 400,
|
|
||||||
left: 400,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
table3.getCell(0, 0).add(new Paragraph("Foo"));
|
|
||||||
table3.getCell(0, 1).add(new Paragraph("v"));
|
|
||||||
|
|
||||||
table3
|
|
||||||
.getCell(1, 0)
|
|
||||||
.add(new Paragraph("Bar1"))
|
|
||||||
.setShading({
|
|
||||||
fill: "b79c2f",
|
|
||||||
val: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
|
||||||
color: "auto",
|
|
||||||
});
|
|
||||||
table3
|
|
||||||
.getCell(1, 1)
|
|
||||||
.add(new Paragraph("Bar2"))
|
|
||||||
.setShading({
|
|
||||||
fill: "42c5f4",
|
|
||||||
val: ShadingType.PERCENT_95,
|
|
||||||
color: "auto",
|
|
||||||
});
|
|
||||||
table3
|
|
||||||
.getCell(1, 2)
|
|
||||||
.add(new Paragraph("Bar3"))
|
|
||||||
.setShading({
|
|
||||||
fill: "880aa8",
|
|
||||||
val: ShadingType.PERCENT_10,
|
|
||||||
color: "e2df0b",
|
|
||||||
});
|
|
||||||
table3
|
|
||||||
.getCell(1, 3)
|
|
||||||
.add(new Paragraph("Bar4"))
|
|
||||||
.setShading({
|
|
||||||
fill: "FF0000",
|
|
||||||
val: ShadingType.CLEAR,
|
|
||||||
color: "auto",
|
|
||||||
});
|
|
||||||
|
|
||||||
table3.getRow(0).mergeCells(0, 3);
|
|
||||||
|
|
||||||
const table4 = new Table({
|
|
||||||
rows: 2,
|
|
||||||
columns: 2,
|
|
||||||
width: 100,
|
|
||||||
widthUnitType: WidthType.PERCENTAGE,
|
|
||||||
});
|
|
||||||
|
|
||||||
doc.addSection({
|
|
||||||
children: [
|
|
||||||
table,
|
|
||||||
new Paragraph({
|
|
||||||
text: "Another table",
|
|
||||||
heading: HeadingLevel.HEADING_2,
|
|
||||||
}),
|
|
||||||
table2,
|
|
||||||
new Paragraph({
|
|
||||||
text: "Another table",
|
|
||||||
heading: HeadingLevel.HEADING_2,
|
|
||||||
}),
|
|
||||||
table3,
|
|
||||||
new Paragraph("hi"),
|
|
||||||
table4,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
|
||||||
});
|
|
@ -1,28 +1,44 @@
|
|||||||
// Sequential Captions
|
// Sequential Captions
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, TextRun } from "../build";
|
import { Document, Packer, Paragraph, SequentialIdentifier, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph("Hello World 1->")
|
new Paragraph({
|
||||||
.addSequentialIdentifier("Caption")
|
children: [
|
||||||
.addRun(new TextRun(" text after sequencial caption 2->"))
|
new TextRun("Hello World 1->"),
|
||||||
.addSequentialIdentifier("Caption"),
|
new SequentialIdentifier("Caption"),
|
||||||
new Paragraph("Hello World 1->")
|
new TextRun(" text after sequencial caption 2->"),
|
||||||
.addSequentialIdentifier("Label")
|
new SequentialIdentifier("Caption"),
|
||||||
.addRun(new TextRun(" text after sequencial caption 2->"))
|
],
|
||||||
.addSequentialIdentifier("Label"),
|
}),
|
||||||
new Paragraph("Hello World 1->")
|
new Paragraph({
|
||||||
.addSequentialIdentifier("Another")
|
children: [
|
||||||
.addRun(new TextRun(" text after sequencial caption 3->"))
|
new TextRun("Hello World 1->"),
|
||||||
.addSequentialIdentifier("Label"),
|
new SequentialIdentifier("Label"),
|
||||||
new Paragraph("Hello World 2->")
|
new TextRun(" text after sequencial caption 2->"),
|
||||||
.addSequentialIdentifier("Another")
|
new SequentialIdentifier("Label"),
|
||||||
.addRun(new TextRun(" text after sequencial caption 4->"))
|
],
|
||||||
.addSequentialIdentifier("Label"),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World 1->"),
|
||||||
|
new SequentialIdentifier("Another"),
|
||||||
|
new TextRun(" text after sequencial caption 3->"),
|
||||||
|
new SequentialIdentifier("Label"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World 2->"),
|
||||||
|
new SequentialIdentifier("Another"),
|
||||||
|
new TextRun(" text after sequencial caption 4->"),
|
||||||
|
new SequentialIdentifier("Label"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,35 +3,56 @@
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {
|
import {
|
||||||
Document,
|
Document,
|
||||||
|
OverlapType,
|
||||||
Packer,
|
Packer,
|
||||||
Paragraph,
|
Paragraph,
|
||||||
RelativeHorizontalPosition,
|
RelativeHorizontalPosition,
|
||||||
RelativeVerticalPosition,
|
RelativeVerticalPosition,
|
||||||
Table,
|
Table,
|
||||||
TableAnchorType,
|
TableAnchorType,
|
||||||
|
TableCell,
|
||||||
TableLayoutType,
|
TableLayoutType,
|
||||||
|
TableRow,
|
||||||
WidthType,
|
WidthType,
|
||||||
} from "../build";
|
} from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 2,
|
rows: [
|
||||||
columns: 2,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
float: {
|
float: {
|
||||||
horizontalAnchor: TableAnchorType.MARGIN,
|
horizontalAnchor: TableAnchorType.MARGIN,
|
||||||
verticalAnchor: TableAnchorType.MARGIN,
|
verticalAnchor: TableAnchorType.MARGIN,
|
||||||
relativeHorizontalPosition: RelativeHorizontalPosition.RIGHT,
|
relativeHorizontalPosition: RelativeHorizontalPosition.RIGHT,
|
||||||
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
|
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
|
||||||
|
overlap: OverlapType.NEVER,
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
size: 4535,
|
||||||
|
type: WidthType.DXA,
|
||||||
},
|
},
|
||||||
width: 4535,
|
|
||||||
widthUnitType: WidthType.DXA,
|
|
||||||
layout: TableLayoutType.FIXED,
|
layout: TableLayoutType.FIXED,
|
||||||
});
|
});
|
||||||
|
|
||||||
table.getCell(0, 0).add(new Paragraph("Hello"));
|
|
||||||
table.getRow(0).mergeCells(0, 1);
|
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table],
|
||||||
});
|
});
|
||||||
|
@ -1,15 +1,34 @@
|
|||||||
// Example on how to add hyperlinks to websites
|
// Example on how to add hyperlinks to websites
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph } from "../build";
|
import { Document, HyperlinkRef, HyperlinkType, Packer, Paragraph, Media } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document({
|
||||||
const paragraph = new Paragraph({});
|
hyperlinks: {
|
||||||
const link = doc.createHyperlink("http://www.example.com", "Hyperlink");
|
myCoolLink: {
|
||||||
|
link: "http://www.example.com",
|
||||||
|
text: "Hyperlink",
|
||||||
|
type: HyperlinkType.EXTERNAL,
|
||||||
|
},
|
||||||
|
myOtherLink: {
|
||||||
|
link: "http://www.google.com",
|
||||||
|
text: "Google Link",
|
||||||
|
type: HyperlinkType.EXTERNAL,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
|
|
||||||
paragraph.addHyperLink(link);
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [paragraph],
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [new HyperlinkRef("myCoolLink")],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [image1, new HyperlinkRef("myOtherLink")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
@ -1,16 +1,61 @@
|
|||||||
// Add image to table cell
|
// Add image to table cell in a header and body
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Header, Media, Packer, Paragraph, Table } from "../build";
|
import { Document, Header, Media, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
const image = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 2,
|
rows: [
|
||||||
columns: 2,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(image)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
table.getCell(1, 1).add(new Paragraph(image));
|
|
||||||
|
|
||||||
// Adding same table in the body and in the header
|
// Adding same table in the body and in the header
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Example how to display page numbers
|
// Example how to display page numbers
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { AlignmentType, Document, Footer, Header, Packer, PageNumberFormat, Paragraph, TextRun } from "../build";
|
import { AlignmentType, Document, Footer, Header, Packer, PageBreak, PageNumber, PageNumberFormat, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
const doc = new Document({});
|
const doc = new Document({});
|
||||||
|
|
||||||
@ -9,9 +9,17 @@ doc.addSection({
|
|||||||
headers: {
|
headers: {
|
||||||
default: new Header({
|
default: new Header({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph("Foo Bar corp. ")
|
new Paragraph({
|
||||||
.addRun(new TextRun("Page Number ").pageNumber())
|
children: [
|
||||||
.addRun(new TextRun(" to ").numberOfTotalPages()),
|
new TextRun("Foo Bar corp. "),
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page Number ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
children: [" to ", PageNumber.TOTAL_PAGES],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@ -19,11 +27,17 @@ doc.addSection({
|
|||||||
default: new Footer({
|
default: new Footer({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
text: "Foo Bar corp. ",
|
|
||||||
alignment: AlignmentType.CENTER,
|
alignment: AlignmentType.CENTER,
|
||||||
})
|
children: [
|
||||||
.addRun(new TextRun("Page Number: ").pageNumber())
|
new TextRun("Foo Bar corp. "),
|
||||||
.addRun(new TextRun(" to ").numberOfTotalPages()),
|
new TextRun({
|
||||||
|
children: ["Page Number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
children: [" to ", PageNumber.TOTAL_PAGES],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@ -32,11 +46,21 @@ doc.addSection({
|
|||||||
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
new Paragraph("Hello World 1").pageBreak(),
|
new Paragraph({
|
||||||
new Paragraph("Hello World 2").pageBreak(),
|
children: [new TextRun("Hello World 1"), new PageBreak()],
|
||||||
new Paragraph("Hello World 3").pageBreak(),
|
}),
|
||||||
new Paragraph("Hello World 4").pageBreak(),
|
new Paragraph({
|
||||||
new Paragraph("Hello World 5").pageBreak(),
|
children: [new TextRun("Hello World 2"), new PageBreak()],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World 3"), new PageBreak()],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World 4"), new PageBreak()],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Hello World 5"), new PageBreak()],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,17 +1,35 @@
|
|||||||
// Example of how you would create a table and add data to it
|
// 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 from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, Table } from "../build";
|
import { Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 4,
|
rows: [
|
||||||
columns: 4,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("World")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
table.getCell(2, 2).add(new Paragraph("Hello"));
|
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table],
|
||||||
});
|
});
|
||||||
|
@ -1,52 +1,259 @@
|
|||||||
// Multiple cells merging in the same table
|
// Multiple cells merging in the same table - Rows and Columns
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, Table } from "../build";
|
import { Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 13,
|
rows: [
|
||||||
columns: 6,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,1")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("0,4")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,0")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,2")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,4")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,1")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,4")],
|
||||||
|
columnSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,2")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,4")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,0")],
|
||||||
|
columnSpan: 5,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
let row = 0;
|
const table2 = new Table({
|
||||||
table.getCell(row, 0).add(new Paragraph("0,0"));
|
rows: [
|
||||||
table.getCell(row, 1).add(new Paragraph("0,1"));
|
new TableRow({
|
||||||
table.getCell(row, 3).add(new Paragraph("0,3"));
|
children: [
|
||||||
table.getCell(row, 4).add(new Paragraph("0,4"));
|
new TableCell({
|
||||||
table.getRow(row).mergeCells(4, 5);
|
children: [new Paragraph("0,0")],
|
||||||
table.getRow(row).mergeCells(1, 2);
|
}),
|
||||||
row = 1;
|
new TableCell({
|
||||||
table.getCell(row, 0).add(new Paragraph("1,0"));
|
children: [new Paragraph("0,1")],
|
||||||
table.getCell(row, 2).add(new Paragraph("1,2"));
|
rowSpan: 2,
|
||||||
table.getCell(row, 4).add(new Paragraph("1,4"));
|
}),
|
||||||
table.getRow(row).mergeCells(4, 5);
|
new TableCell({
|
||||||
table.getRow(row).mergeCells(2, 3);
|
children: [new Paragraph("0,2")],
|
||||||
table.getRow(row).mergeCells(0, 1);
|
}),
|
||||||
|
new TableCell({
|
||||||
row = 2;
|
children: [new Paragraph("0,3")],
|
||||||
table.getCell(row, 0).add(new Paragraph("2,0"));
|
}),
|
||||||
table.getCell(row, 1).add(new Paragraph("2,1"));
|
new TableCell({
|
||||||
table.getCell(row, 2).add(new Paragraph("2,2"));
|
children: [new Paragraph("0,4")],
|
||||||
table.getCell(row, 3).add(new Paragraph("2,3"));
|
}),
|
||||||
table.getCell(row, 4).add(new Paragraph("2,4"));
|
new TableCell({
|
||||||
table.getRow(row).mergeCells(4, 5);
|
children: [new Paragraph("0,5")],
|
||||||
table.getRow(row).mergeCells(1, 2);
|
}),
|
||||||
row = 3;
|
],
|
||||||
table.getCell(row, 0).add(new Paragraph("3,0"));
|
}),
|
||||||
table.getCell(row, 1).add(new Paragraph("3,1"));
|
new TableRow({
|
||||||
table.getCell(row, 2).add(new Paragraph("3,2"));
|
children: [
|
||||||
table.getCell(row, 3).add(new Paragraph("3,3"));
|
new TableCell({
|
||||||
table.getCell(row, 4).add(new Paragraph("3,4"));
|
children: [new Paragraph("1,0")],
|
||||||
table.getCell(row, 5).add(new Paragraph("3,5"));
|
}),
|
||||||
row = 4;
|
new TableCell({
|
||||||
table.getCell(row, 0).add(new Paragraph("4,0"));
|
children: [new Paragraph("1,2")],
|
||||||
table.getCell(row, 5).add(new Paragraph("4,5"));
|
}),
|
||||||
table.getRow(row).mergeCells(0, 4);
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,4")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("1,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,2")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,4")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("2,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,2")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,4")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("3,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,0")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,1")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,2")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,3")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,4")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("4,5")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table, new Paragraph(""), table2],
|
||||||
});
|
});
|
||||||
|
|
||||||
Packer.toBuffer(doc).then((buffer) => {
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
@ -1,18 +1,80 @@
|
|||||||
// Add image to table cell
|
// Add image to table cell
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, Table } from "../build";
|
import { Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
const doc = new Document();
|
const doc = new Document();
|
||||||
|
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 4,
|
rows: [
|
||||||
columns: 4,
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
rowSpan: 2,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
table.getCell(2, 2).add(new Paragraph("Hello"));
|
|
||||||
table.getColumn(3).mergeCells(1, 2);
|
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [table],
|
children: [table],
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@ const doc = new Document();
|
|||||||
doc.addSection({
|
doc.addSection({
|
||||||
properties: {
|
properties: {
|
||||||
column: {
|
column: {
|
||||||
width: 708,
|
space: 708,
|
||||||
count: 2,
|
count: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -23,7 +23,7 @@ doc.addSection({
|
|||||||
doc.addSection({
|
doc.addSection({
|
||||||
properties: {
|
properties: {
|
||||||
column: {
|
column: {
|
||||||
width: 708,
|
space: 708,
|
||||||
count: 3,
|
count: 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -28,6 +28,18 @@ doc.addSection({
|
|||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
shading: {
|
||||||
|
type: ShadingType.DIAGONAL_CROSS,
|
||||||
|
color: "00FFFF",
|
||||||
|
fill: "FF0000",
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Hello World for entire paragraph",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
67
demo/47-number-of-total-pages-section.ts
Normal file
67
demo/47-number-of-total-pages-section.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Multiple sections with total number of pages in each section
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { AlignmentType, Document, Footer, Header, Packer, PageBreak, PageNumber, PageNumberFormat, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const header = new Header({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Header on another page"),
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
children: [" to ", PageNumber.TOTAL_PAGES_IN_SECTION],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const footer = new Footer({
|
||||||
|
children: [new Paragraph("Foo Bar corp. ")],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
headers: {
|
||||||
|
default: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
pageNumberStart: 1,
|
||||||
|
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Section 1"), new PageBreak(), new TextRun("Section 1"), new PageBreak()],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
headers: {
|
||||||
|
default: header,
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: footer,
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
pageNumberStart: 1,
|
||||||
|
pageNumberFormatType: PageNumberFormat.DECIMAL,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [new TextRun("Section 2"), new PageBreak(), new TextRun("Section 2"), new PageBreak()],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
31
demo/48-vertical-align.ts
Normal file
31
demo/48-vertical-align.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Example of making content of section vertically aligned
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, Packer, Paragraph, SectionVerticalAlignValue, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
properties: {
|
||||||
|
verticalAlign: SectionVerticalAlignValue.CENTER,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World"),
|
||||||
|
new TextRun({
|
||||||
|
text: "Foo Bar",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "\tGithub is the best",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
37
demo/49-table-borders.ts
Normal file
37
demo/49-table-borders.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Add custom borders to the table itself
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { BorderStyle, Document, Packer, Paragraph, Table, TableCell, TableRow } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const table = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("World")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({ children: [table] });
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
61
demo/50-readme-demo.ts
Normal file
61
demo/50-readme-demo.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Simple example to add text to a document
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, HeadingLevel, Media, Packer, Paragraph, Table, TableCell, TableRow, VerticalAlign } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
const image1 = Media.addImage(doc, fs.readFileSync("./demo/images/image1.jpeg"));
|
||||||
|
const image2 = Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"));
|
||||||
|
|
||||||
|
const table = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(image1)],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "Hello",
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "World",
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph(image1)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "Hello World",
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
}),
|
||||||
|
table,
|
||||||
|
new Paragraph(image2),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
37
demo/51-character-styles.ts
Normal file
37
demo/51-character-styles.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Custom character styles using JavaScript configuration
|
||||||
|
// 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({
|
||||||
|
styles: {
|
||||||
|
characterStyles: [
|
||||||
|
{
|
||||||
|
id: "myRedStyle",
|
||||||
|
name: "My Wonky Style",
|
||||||
|
basedOn: "Normal",
|
||||||
|
run: {
|
||||||
|
color: "990000",
|
||||||
|
italics: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "Foo bar",
|
||||||
|
style: "myRedStyle",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
37
demo/52-japanese.ts
Normal file
37
demo/52-japanese.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Japanese text - Need to use a Japanese font
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, HeadingLevel, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: "Normal",
|
||||||
|
name: "Normal",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
font: "MS Gothic",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "KFCを食べるのが好き",
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "こんにちは",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
55
demo/53-chinese.ts
Normal file
55
demo/53-chinese.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Chinese text - Chinese text need to use a Chinese font. And ascii text need to use a ascii font.
|
||||||
|
// Different from the `52-japanese.ts`.
|
||||||
|
// `52-japanese.ts` will set all characters to use Japanese font.
|
||||||
|
// `53-chinese.ts` will set Chinese characters to use Chinese font, and set ascii characters to use ascii font.
|
||||||
|
|
||||||
|
// Note that if the OS have not install `KaiTi` font, this demo doesn't work.
|
||||||
|
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Document, HeadingLevel, Packer, Paragraph, TextRun } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
styles: {
|
||||||
|
paragraphStyles: [
|
||||||
|
{
|
||||||
|
id: "Normal",
|
||||||
|
name: "Normal",
|
||||||
|
basedOn: "Normal",
|
||||||
|
next: "Normal",
|
||||||
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
font: {
|
||||||
|
ascii: "Times",
|
||||||
|
eastAsia: "KaiTi",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
text: "中文和英文 Chinese and English",
|
||||||
|
heading: HeadingLevel.HEADING_1,
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
text: "中文和英文 Chinese and English",
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun({
|
||||||
|
text: "中文和英文 Chinese and English",
|
||||||
|
font: { eastAsia: "SimSun" }, // set eastAsia to "SimSun".
|
||||||
|
// The ascii characters will use the default font ("Times") specified in paragraphStyles
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
145
demo/54-track-revisions.ts
Normal file
145
demo/54-track-revisions.ts
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Track Revisions aka. "Track Changes"
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {
|
||||||
|
AlignmentType,
|
||||||
|
DeletedTextRun,
|
||||||
|
Document,
|
||||||
|
Footer,
|
||||||
|
FootnoteReferenceRun,
|
||||||
|
InsertedTextRun,
|
||||||
|
Packer,
|
||||||
|
PageNumber,
|
||||||
|
Paragraph,
|
||||||
|
ShadingType,
|
||||||
|
TextRun,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
|
/*
|
||||||
|
For reference, see
|
||||||
|
- https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.insertedrun
|
||||||
|
- https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.deletedrun
|
||||||
|
|
||||||
|
The method `addTrackRevisions()` adds an element `<w:trackRevisions />` to the `settings.xml` file. This specifies that the application shall track *new* revisions made to the existing document.
|
||||||
|
See also https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.trackrevisions
|
||||||
|
|
||||||
|
Note that this setting enables to track *new changes* after teh file is generated, so this example will still show inserted and deleted text runs when you remove it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
footnotes: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a footnote"),
|
||||||
|
new DeletedTextRun({
|
||||||
|
text: " with some extra text which was deleted",
|
||||||
|
id: 0,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:05:00Z",
|
||||||
|
}),
|
||||||
|
new InsertedTextRun({
|
||||||
|
text: " and new content",
|
||||||
|
id: 1,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:05:00Z",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
features: {
|
||||||
|
trackRevisions: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a simple demo "),
|
||||||
|
new TextRun({
|
||||||
|
text: "on how to ",
|
||||||
|
}),
|
||||||
|
new InsertedTextRun({
|
||||||
|
text: "mark a text as an insertion ",
|
||||||
|
id: 0,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
}),
|
||||||
|
new DeletedTextRun({
|
||||||
|
text: "or a deletion.",
|
||||||
|
id: 1,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
paragraph,
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a demo "),
|
||||||
|
new DeletedTextRun({
|
||||||
|
text: "in order",
|
||||||
|
color: "red",
|
||||||
|
bold: true,
|
||||||
|
size: 24,
|
||||||
|
font: {
|
||||||
|
name: "Garamond",
|
||||||
|
},
|
||||||
|
shading: {
|
||||||
|
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||||
|
color: "00FFFF",
|
||||||
|
fill: "FF0000",
|
||||||
|
},
|
||||||
|
id: 2,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
}).break(),
|
||||||
|
new InsertedTextRun({
|
||||||
|
text: "to show how to ",
|
||||||
|
bold: false,
|
||||||
|
id: 3,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:05:00Z",
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
bold: true,
|
||||||
|
children: ["\tuse Inserted and Deleted TextRuns.", new FootnoteReferenceRun(1)],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
footers: {
|
||||||
|
default: new Footer({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
children: [
|
||||||
|
new TextRun("Awesome LLC"),
|
||||||
|
new TextRun({
|
||||||
|
children: ["Page Number: ", PageNumber.CURRENT],
|
||||||
|
}),
|
||||||
|
new DeletedTextRun({
|
||||||
|
children: [" to ", PageNumber.TOTAL_PAGES],
|
||||||
|
id: 4,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:05:00Z",
|
||||||
|
}),
|
||||||
|
new InsertedTextRun({
|
||||||
|
children: [" from ", PageNumber.TOTAL_PAGES],
|
||||||
|
bold: true,
|
||||||
|
id: 5,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:05:00Z",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
294
demo/55-math.ts
Normal file
294
demo/55-math.ts
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
// Simple example to add text to a document
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {
|
||||||
|
Document,
|
||||||
|
Math,
|
||||||
|
MathAngledBrackets,
|
||||||
|
MathCurlyBrackets,
|
||||||
|
MathFraction,
|
||||||
|
MathFunction,
|
||||||
|
MathPreSubSuperScript,
|
||||||
|
MathRadical,
|
||||||
|
MathRoundBrackets,
|
||||||
|
MathRun,
|
||||||
|
MathSquareBrackets,
|
||||||
|
MathSubScript,
|
||||||
|
MathSubSuperScript,
|
||||||
|
MathSum,
|
||||||
|
MathSuperScript,
|
||||||
|
Packer,
|
||||||
|
Paragraph,
|
||||||
|
TextRun,
|
||||||
|
} from "../build";
|
||||||
|
|
||||||
|
const doc = new Document();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathRun("2+2"),
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("hi")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "Foo Bar",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [
|
||||||
|
new MathRun("1"),
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSum({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
}),
|
||||||
|
new MathSum({
|
||||||
|
children: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("e")],
|
||||||
|
superScript: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("i")],
|
||||||
|
}),
|
||||||
|
new MathSum({
|
||||||
|
children: [
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("i")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("i")],
|
||||||
|
superScript: [new MathRun("10")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
superScript: [new MathRun("hello")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSubScript({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
subScript: [new MathRun("hello")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSubScript({
|
||||||
|
children: [new MathRun("x")],
|
||||||
|
subScript: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("y")],
|
||||||
|
superScript: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSubSuperScript({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
superScript: [new MathRun("hello")],
|
||||||
|
subScript: [new MathRun("world")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathPreSubSuperScript({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
superScript: [new MathRun("hello")],
|
||||||
|
subScript: [new MathRun("world")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSubScript({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("4")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathSubScript({
|
||||||
|
children: [
|
||||||
|
new MathRadical({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
degree: [new MathRun("4")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("x")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("4")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathFunction({
|
||||||
|
name: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("cos")],
|
||||||
|
superScript: [new MathRun("-1")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
children: [new MathRun("100")],
|
||||||
|
}),
|
||||||
|
new MathRun("×"),
|
||||||
|
new MathFunction({
|
||||||
|
name: [new MathRun("sin")],
|
||||||
|
children: [new MathRun("360")],
|
||||||
|
}),
|
||||||
|
new MathRun("= x"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathRoundBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new MathSquareBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new MathCurlyBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new MathAngledBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("4")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
denominator: [new MathRun("2a")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
33
demo/56-background-color.ts
Normal file
33
demo/56-background-color.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Change background colour of whole document
|
||||||
|
// 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({
|
||||||
|
background: {
|
||||||
|
color: "C45911",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World"),
|
||||||
|
new TextRun({
|
||||||
|
text: "Foo Bar",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "\tGithub is the best",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
31
demo/57-paragraph-run-styles.ts
Normal file
31
demo/57-paragraph-run-styles.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Add Run styles across the whole Paragraph
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
children: [
|
||||||
|
new Paragraph({
|
||||||
|
runStyle: {
|
||||||
|
size: 100,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new TextRun("Hello World"),
|
||||||
|
new TextRun({
|
||||||
|
text: "Foo Bar",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
new TextRun({
|
||||||
|
text: "\tGithub is the best",
|
||||||
|
bold: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
@ -21,9 +21,9 @@ doc.addSection({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Github is the best",
|
text: "\tGithub is the best",
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new Paragraph({
|
new Paragraph({
|
||||||
|
@ -12,21 +12,21 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function generate() {
|
function generate() {
|
||||||
const doc = new Document();
|
const doc = new docx.Document();
|
||||||
|
|
||||||
doc.addSection({
|
doc.addSection({
|
||||||
children: [
|
children: [
|
||||||
new Paragraph({
|
new docx.Paragraph({
|
||||||
children: [
|
children: [
|
||||||
new TextRun("Hello World"),
|
new docx.TextRun("Hello World"),
|
||||||
new TextRun({
|
new docx.TextRun({
|
||||||
text: "Foo Bar",
|
text: "Foo Bar",
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new docx.TextRun({
|
||||||
text: "Github is the best",
|
text: "\tGithub is the best",
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Packer.toBlob(doc).then((blob) => {
|
docx.Packer.toBlob(doc).then((blob) => {
|
||||||
console.log(blob);
|
console.log(blob);
|
||||||
saveAs(blob, "example.docx");
|
saveAs(blob, "example.docx");
|
||||||
console.log("Document created successfully");
|
console.log("Document created successfully");
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
<p align="center">
|
|
||||||
<img alt="clippy the assistant" src="https://i.imgur.com/37uBGhO.gif">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
Easily generate .docx files with JS/TS. Works for Node and on the Browser. :100:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Welcome
|
# Welcome
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@ -50,9 +40,9 @@ doc.addSection({
|
|||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
new TextRun({
|
new TextRun({
|
||||||
text: "Github is the best",
|
text: "\tGithub is the best",
|
||||||
bold: true,
|
bold: true,
|
||||||
}).tab(),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
@ -63,17 +53,11 @@ Packer.toBuffer(doc).then((buffer) => {
|
|||||||
fs.writeFileSync("My Document.docx", buffer);
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Done! A file called 'My First Document.docx' will be in your file system.
|
// Done! A file called 'My Document.docx' will be in your file system.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Honoured Mentions
|
|
||||||
|
|
||||||
[@felipeochoa](https://github.com/felipeochoa)
|
|
||||||
|
|
||||||
[@h4buli](https://github.com/h4buli)
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="clippy the assistant" src="http://i60.tinypic.com/339pvtt.png">
|
<img alt="clippy the assistant" src="./clippy.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
10
docs/_coverpage.md
Normal file
10
docs/_coverpage.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<img src="https://i.imgur.com/37uBGhO.gif" alt="drawing" style="width:200px;"/>
|
||||||
|
|
||||||
|
> Easily generate .docx files with JS/TS. Works for Node and on the Browser. :100:
|
||||||
|
|
||||||
|
- Simple, declarative API
|
||||||
|
- 50+ usage examples
|
||||||
|
- Battle tested, mature, 95%+ coverage
|
||||||
|
|
||||||
|
[GitHub](https://github.com/dolanmiu/docx)
|
||||||
|
[Get Started](#Welcome)
|
@ -1,6 +1,6 @@
|
|||||||
* [Getting Started](/)
|
* [Getting Started](/)
|
||||||
|
|
||||||
* [Examples](examples.md)
|
* [Examples](https://github.com/dolanmiu/docx/tree/master/demo)
|
||||||
|
|
||||||
* API
|
* API
|
||||||
|
|
||||||
@ -20,6 +20,8 @@
|
|||||||
* [Tab Stops](usage/tab-stops.md)
|
* [Tab Stops](usage/tab-stops.md)
|
||||||
* [Table of Contents](usage/table-of-contents.md)
|
* [Table of Contents](usage/table-of-contents.md)
|
||||||
* [Page Numbers](usage/page-numbers.md)
|
* [Page Numbers](usage/page-numbers.md)
|
||||||
|
* [Change Tracking](usage/change-tracking.md)
|
||||||
|
* [Math](usage/math.md)
|
||||||
* Styling
|
* Styling
|
||||||
* [Styling with JS](usage/styling-with-js.md)
|
* [Styling with JS](usage/styling-with-js.md)
|
||||||
* [Styling with XML](usage/styling-with-xml.md)
|
* [Styling with XML](usage/styling-with-xml.md)
|
||||||
@ -28,4 +30,3 @@
|
|||||||
* [Packers](usage/packers.md)
|
* [Packers](usage/packers.md)
|
||||||
|
|
||||||
* [Contribution Guidelines](contribution-guidelines.md)
|
* [Contribution Guidelines](contribution-guidelines.md)
|
||||||
|
|
||||||
|
BIN
docs/clippy.png
Normal file
BIN
docs/clippy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
docs/clippy.psd
Normal file
BIN
docs/clippy.psd
Normal file
Binary file not shown.
@ -1,25 +1,23 @@
|
|||||||
# Contribution Guidelines
|
# Contribution Guidelines
|
||||||
|
|
||||||
* Include documentation reference(s) at the top of each file:
|
- Include documentation reference(s) at the top of each file:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// http://officeopenxml.com/WPdocument.php
|
// http://officeopenxml.com/WPdocument.php
|
||||||
```
|
```
|
||||||
|
|
||||||
* Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
|
- Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
|
||||||
|
|
||||||
* Follow the `TSLint` rules
|
- Follow the `TSLint` rules
|
||||||
|
|
||||||
## Always think about the user
|
## Always think about the user
|
||||||
|
|
||||||
The number one pillar for contribution to `docx` is to **ALWAYS** think about how the user will use `docx`.
|
|
||||||
|
|
||||||
Put yourself in their position, and imagine how they would feel about your feature you wrote.
|
Put yourself in their position, and imagine how they would feel about your feature you wrote.
|
||||||
|
|
||||||
1. Is it easy to use?
|
1. Is it easy to use?
|
||||||
2. Has it been documented well?
|
2. Has it been documented well?
|
||||||
3. Is it intuitive?
|
3. Is it intuitive?
|
||||||
4. Is it consistent with the rest of the API?
|
4. Is it declarative?
|
||||||
5. Is it fun to use?
|
5. Is it fun to use?
|
||||||
|
|
||||||
## Good Commit Names
|
## Good Commit Names
|
||||||
@ -27,6 +25,7 @@ Put yourself in their position, and imagine how they would feel about your featu
|
|||||||
Please write good commit messages when making a commit: https://chris.beams.io/posts/git-commit/
|
Please write good commit messages when making a commit: https://chris.beams.io/posts/git-commit/
|
||||||
|
|
||||||
**Do not:**
|
**Do not:**
|
||||||
|
|
||||||
```
|
```
|
||||||
c // What?
|
c // What?
|
||||||
rtl // Adding acryonyms without explaining anything else is not helpful
|
rtl // Adding acryonyms without explaining anything else is not helpful
|
||||||
@ -35,34 +34,6 @@ demo updated // Getting better, but capitalize the first letter
|
|||||||
Unesesary coment removed // Make sure to use correct spelling
|
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 of the outside API accept primitives, 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 for the end user, no need for:
|
|
||||||
```ts
|
|
||||||
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 `new` up the object, and inject it in like so:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
public float(tableFloatProperties: TableFloatProperties): Table
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
table.float(new TableFloatProperties(...));
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
**Do**
|
||||||
|
|
||||||
`ITableFloatOptions` is an interface for a JSON of primitives. The end user would need to pass in a json object and not need to worry about the internals:
|
`ITableFloatOptions` is an interface for a JSON of primitives. The end user would need to pass in a json object and not need to worry about the internals:
|
||||||
@ -71,31 +42,29 @@ This is so that:
|
|||||||
public float(tableFloatOptions: ITableFloatOptions): Table
|
public float(tableFloatOptions: ITableFloatOptions): Table
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Delcariative API
|
||||||
|
|
||||||
|
Make sure the API is declarative, so no _method calling_ or _mutation_. This is a design decision, consistent with the rest of the project. There are benefits to delcariative code over other styles of code, explained here: https://dzone.com/articles/why-declarative-coding-makes-you-a-better-programm
|
||||||
|
|
||||||
|
**Do not:**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
table.float({...});
|
const paragraph = doc.createParagraph();
|
||||||
|
const text = paragraph.createText();
|
||||||
|
text.contents = "Hello World";
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add vs Create
|
**Do**
|
||||||
|
|
||||||
This is just a guideline, and the rules can sometimes be broken.
|
```ts
|
||||||
|
doc.addSection({
|
||||||
* Use `create` if the method `new`'s up an element inside:
|
children: [
|
||||||
|
new Paragraph({
|
||||||
```ts
|
children: [new TextRun("Hello World")],
|
||||||
public createParagraph() {
|
}),
|
||||||
const paragraph = new Paragraph();
|
],
|
||||||
this.root.push(paragraph);
|
});
|
||||||
}
|
```
|
||||||
```
|
|
||||||
|
|
||||||
* Use `add` if you add the element into the method as a parameter.
|
|
||||||
*Note:* This may look like its breaking the previous guideline, but it has semantically different meanings. The previous one is using data to construct an object, whereas this one is simply adding elements into the document:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
public add(paragraph: Paragraph) {
|
|
||||||
this.root.push(paragraph);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getters and Setters
|
## Getters and Setters
|
||||||
|
|
||||||
@ -107,7 +76,7 @@ public get Level() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
There is no performance advantage by doing this. It means we don't need to prefix all private variables with the ugly `_`:
|
This is the convention of this project. There is no performance advantage by doing this. It means we don't need to prefix all private variables with `_`:
|
||||||
|
|
||||||
**Do not:**
|
**Do not:**
|
||||||
|
|
||||||
@ -121,30 +90,6 @@ private get _level: string;
|
|||||||
private get level: string;
|
private get level: string;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Temporal Methods
|
|
||||||
|
|
||||||
Some methods are `non-temporal`, which means regardless of when you call the method, it will have the same affect on the document. For example, setting the width of a table at the end of the document will have the same effect as setting the width at the start:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
table.setWidth(1000); // now removed as of version 5.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
Whereas some methods are `temporal`, which means depending on the time-frame they are called, it would produce a difference result. For example, moving `createParagraph()` around your code will physically alter the document.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
doc.createParagraph("hello");
|
|
||||||
```
|
|
||||||
|
|
||||||
If a method is `non-temporal`, put it in the objects `constructor`. For example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const table = new Table(width: number);
|
|
||||||
```
|
|
||||||
|
|
||||||
`Non-temporal` methods are usually methods which can only be used one time and one time only. For example, `.float()`. It does not make sense to call `.float()` again if its already floating.
|
|
||||||
|
|
||||||
I am not sure what the real term is, but this will do.
|
|
||||||
|
|
||||||
## Interfaces over type alias
|
## Interfaces over type alias
|
||||||
|
|
||||||
Do not use `type`, but rather use `Interfaces`. `type` cannot be extended, and a class cannot implement it.
|
Do not use `type`, but rather use `Interfaces`. `type` cannot be extended, and a class cannot implement it.
|
||||||
@ -152,14 +97,14 @@ Do not use `type`, but rather use `Interfaces`. `type` cannot be extended, and a
|
|||||||
> "In general, use what you want ( type alias / interface ) just be consistent"
|
> "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"
|
> "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
|
> - 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
|
`Interface` is generally preferred over `type`: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
|
||||||
|
|
||||||
**Do not:**
|
**Do not:**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
type RelationshipFileInfo = { id: number, target: string };
|
type RelationshipFileInfo = { id: number; target: string };
|
||||||
```
|
```
|
||||||
|
|
||||||
**Do:**
|
**Do:**
|
||||||
@ -193,26 +138,26 @@ enum WeaponType = {
|
|||||||
|
|
||||||
## Spell correctly, in full and in American English
|
## Spell correctly, in 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:**
|
**Do not:**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
readdy // misspelling
|
readdy; // misspelling
|
||||||
perm // abbreviation
|
perm; // abbreviation
|
||||||
conf // abbreviation
|
conf; // abbreviation
|
||||||
cnty // abbreviation
|
cnty; // abbreviation
|
||||||
relationFile // abbreviation
|
relationFile; // abbreviation
|
||||||
colour // U.K. English
|
colour; // U.K. English
|
||||||
```
|
```
|
||||||
|
|
||||||
**Do:**
|
**Do:**
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
ready
|
ready;
|
||||||
permission
|
permission;
|
||||||
config
|
config;
|
||||||
country
|
country;
|
||||||
relationshipFile
|
relationshipFile;
|
||||||
color
|
color;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keep files small (within reason)
|
## Keep files small (within reason)
|
||||||
|
219
docs/examples.md
219
docs/examples.md
@ -1,219 +0,0 @@
|
|||||||
# Examples
|
|
||||||
|
|
||||||
> All examples can run independently and can be found in the `/demo` folder of the project
|
|
||||||
|
|
||||||
All the examples below can be ran locally, to do so, run the following command:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run demo
|
|
||||||
```
|
|
||||||
|
|
||||||
This command will run the `demo selector app` in the `/demo` folder. It will prompt you to select a demo number, which will run a demo from that folder.
|
|
||||||
|
|
||||||
## Simple
|
|
||||||
|
|
||||||
A simple hello world of the `docx` library:
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo1.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo1.ts_
|
|
||||||
|
|
||||||
## Styles
|
|
||||||
|
|
||||||
### Styling with JS
|
|
||||||
|
|
||||||
This example shows how to customise the look and feel of a document using JS configuration
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo2.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo2.ts_
|
|
||||||
|
|
||||||
### Styling with XML
|
|
||||||
|
|
||||||
This example shows how to customise the look and feel of a document using XML configuration
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo13.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo13.ts_
|
|
||||||
|
|
||||||
## Numbering
|
|
||||||
|
|
||||||
This example shows many levels of numbering
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo3.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo3.ts_
|
|
||||||
|
|
||||||
## Table
|
|
||||||
|
|
||||||
Example of simple table
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo4.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo4.ts_
|
|
||||||
|
|
||||||
### Styling table borders
|
|
||||||
|
|
||||||
Styling the borders of a table
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo20.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo20.ts_
|
|
||||||
|
|
||||||
## Images
|
|
||||||
|
|
||||||
### Add image to the document
|
|
||||||
|
|
||||||
Importing Images from file system path
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo5.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo5.ts_
|
|
||||||
|
|
||||||
### Add images to header and footer
|
|
||||||
|
|
||||||
Example showing how to add image to headers and footers
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo9.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo9.ts_
|
|
||||||
|
|
||||||
### Scaling images
|
|
||||||
|
|
||||||
Example showing how to scale images
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo12.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo12.ts_
|
|
||||||
|
|
||||||
### Add Image to media before adding to document
|
|
||||||
|
|
||||||
This is the best way to add an image to a document because you can add the same image in two locations without increasing document size by re-using the same image
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo23.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo23.ts_
|
|
||||||
|
|
||||||
### Add image to table
|
|
||||||
|
|
||||||
As before, to add an image to a table, you would need to add it to the `Media` object first
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo24.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo24.ts_
|
|
||||||
|
|
||||||
### Images using Base64 URI
|
|
||||||
|
|
||||||
If you want to use a Base64 image instead
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo18.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo18.ts_
|
|
||||||
|
|
||||||
## Margins
|
|
||||||
|
|
||||||
Example showing how to set custom margins
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo6.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo6.ts_
|
|
||||||
|
|
||||||
## Orientation
|
|
||||||
|
|
||||||
Example showing how to set the document to `landscape` or `portrait`
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo7.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo7.ts_
|
|
||||||
|
|
||||||
## Headers & Footers
|
|
||||||
|
|
||||||
Example showing how to add headers and footers
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo8.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo8.ts_
|
|
||||||
|
|
||||||
## Multiple headers and footers
|
|
||||||
|
|
||||||
Check out `Sections` for this feature
|
|
||||||
|
|
||||||
## Page Breaks
|
|
||||||
|
|
||||||
### Normal page breaks
|
|
||||||
|
|
||||||
Example showing how to page break
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo14.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo14.ts_
|
|
||||||
|
|
||||||
### Page break before
|
|
||||||
|
|
||||||
Example showing how to page break before like in Word
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo15.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo15.ts_
|
|
||||||
|
|
||||||
## Sections
|
|
||||||
|
|
||||||
Example of how sections work. Sections allow multiple headers and footers, and `landscape`/`portrait` inside the same document.
|
|
||||||
Also you can have different page number formats and starts for different sections.
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo16.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo16.ts_
|
|
||||||
|
|
||||||
## Footnotes
|
|
||||||
|
|
||||||
Example of how to add footnotes. Good for references
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo17.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo17.ts_
|
|
||||||
|
|
||||||
## Packers
|
|
||||||
|
|
||||||
## Buffer output
|
|
||||||
|
|
||||||
Example showing how to use the Buffer packer and then write that buffer to the file system
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo19.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo19.ts_
|
|
||||||
|
|
||||||
|
|
||||||
## Bookmarks
|
|
||||||
|
|
||||||
Example showing how to make bookmarks to make internal hyperlinks within the document
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo21.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo21.ts_
|
|
||||||
|
|
||||||
## Bidirectional text
|
|
||||||
|
|
||||||
Example showing how to use bidirectional text for certain languages such as Hebrew
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo22.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo22.ts_
|
|
||||||
|
|
||||||
## Showcase
|
|
||||||
|
|
||||||
### My CV
|
|
||||||
|
|
||||||
Example showing how to add headers and footers
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo10.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo10.ts_
|
|
||||||
|
|
||||||
### Style and Images
|
|
||||||
|
|
||||||
This example shows how to customise the look and feel of a document and add images
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo11.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo11.ts_
|
|
BIN
docs/images/math-example.png
Normal file
BIN
docs/images/math-example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -1,31 +1,36 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
<head>
|
<meta charset="UTF-8" />
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>docx - Generate .docx documents with JavaScript</title>
|
<title>docx - Generate .docx documents with JavaScript</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||||
<meta name="description" content="Generate .docx documents with JavaScript">
|
<meta name="description" content="Generate .docx documents with JavaScript" />
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
|
||||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
<link
|
||||||
</head>
|
rel="stylesheet"
|
||||||
|
href="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/style.min.css"
|
||||||
|
title="docsify-darklight-theme"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script>
|
<script>
|
||||||
window.$docsify = {
|
window.$docsify = {
|
||||||
name: 'docx',
|
name: "docx",
|
||||||
repo: 'https://github.com/dolanmiu/docx',
|
repo: "https://github.com/dolanmiu/docx",
|
||||||
loadSidebar: true,
|
loadSidebar: true,
|
||||||
subMaxLevel: 2,
|
subMaxLevel: 2,
|
||||||
search: 'auto',
|
search: "auto",
|
||||||
}
|
coverpage: true,
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
||||||
<script src="https://unpkg.com/docsify-copy-code@2"></script>
|
<script src="https://unpkg.com/docsify-copy-code@2"></script>
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||||
<script src="//unpkg.com/prismjs/components/prism-typescript.min.js"></script>
|
<script src="//unpkg.com/prismjs/components/prism-typescript.min.js"></script>
|
||||||
</body>
|
<script src="//cdn.jsdelivr.net/npm/docsify-darklight-theme@latest/dist/index.min.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -5,17 +5,16 @@
|
|||||||
To make a bullet point, simply make a paragraph into a bullet point:
|
To make a bullet point, simply make a paragraph into a bullet point:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const text = new docx.TextRun("Bullet points");
|
const text = new TextRun("Bullet points");
|
||||||
const paragraph = new docx.Paragraph(text).bullet();
|
const paragraph = new Paragraph({
|
||||||
|
text: "Bullet points",
|
||||||
const text2 = new docx.TextRun("Are awesome");
|
bullet: {
|
||||||
const paragraph2 = new docx.Paragraph(text2).bullet();
|
level: 0, // How deep you want the bullet to me
|
||||||
|
},
|
||||||
doc.add(paragraph);
|
});
|
||||||
doc.add(paragraph2);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### This will produce:
|
### This will produce:
|
||||||
|
|
||||||
* Bullet points
|
- Bullet points
|
||||||
* Are awesome
|
- Are awesome
|
||||||
|
61
docs/usage/change-tracking.md
Normal file
61
docs/usage/change-tracking.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Change Tracking
|
||||||
|
|
||||||
|
> Instead of adding a `TextRun` into a `Paragraph`, you can also add an `InsertedTextRun` or `DeletedTextRun` where you need to supply an `id`, `author` and `date` for the change.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Paragraph, TextRun, InsertedTextRun, DeletedTextRun } from "docx";
|
||||||
|
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a simple demo "),
|
||||||
|
new TextRun({
|
||||||
|
text: "on how to "
|
||||||
|
}),
|
||||||
|
new InsertedTextRun({
|
||||||
|
text: "mark a text as an insertion ",
|
||||||
|
id: 0,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
}),
|
||||||
|
new DeletedTextRun({
|
||||||
|
text: "or a deletion.",
|
||||||
|
id: 1,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
})
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that for a `InsertedTextRun` and `DeletedTextRun`, it is not possible to simply call it with only a text as in `new TextRun("some text")`, since the additonal fields for change tracking need to be provided. Similar to a normal `TextRun` you can add additional text properties.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Paragraph, TextRun, InsertedTextRun, DeletedTextRun } from "docx";
|
||||||
|
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a simple demo"),
|
||||||
|
new DeletedTextRun({
|
||||||
|
text: "with a deletion.",
|
||||||
|
color: "red",
|
||||||
|
bold: true,
|
||||||
|
size: 24,
|
||||||
|
id: 0,
|
||||||
|
author: "Firstname Lastname",
|
||||||
|
date: "2020-10-06T09:00:00Z",
|
||||||
|
})
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
In addtion to marking text as inserted or deleted, change tracking can also be added via the document settings. This will enable new changes to be tracked as well.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Document } from "docx";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
features: {
|
||||||
|
trackRevisions: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
@ -30,6 +30,24 @@ const doc = new docx.Document({
|
|||||||
* keywords
|
* keywords
|
||||||
* lastModifiedBy
|
* lastModifiedBy
|
||||||
* revision
|
* revision
|
||||||
|
* externalStyles
|
||||||
|
* styles
|
||||||
|
* numbering
|
||||||
|
* footnotes
|
||||||
|
* hyperlinks
|
||||||
|
* background
|
||||||
|
|
||||||
|
### Change background color of Document
|
||||||
|
|
||||||
|
Set the hex value in the document like so:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const doc = new docx.Document({
|
||||||
|
background: {
|
||||||
|
color: "C45911",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
You can mix and match whatever properties you want, or provide no properties.
|
You can mix and match whatever properties you want, or provide no properties.
|
||||||
|
|
||||||
|
@ -2,52 +2,46 @@
|
|||||||
|
|
||||||
!> Headers and Footers requires an understanding of [Sections](usage/sections.md).
|
!> Headers and Footers requires an understanding of [Sections](usage/sections.md).
|
||||||
|
|
||||||
|
Every Section has a sections which you can define its Headers and Footers:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
doc.addSection({
|
||||||
|
headers: {
|
||||||
|
default: new Header({ // The standard default header
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
first: new Header({ // The first header
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
even: new Header({ // The header on every other page
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
footers: {
|
||||||
|
default: new Footer({ // The standard default footer
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
first: new Footer({ // The first footer
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
even: new Footer({ // The footer on every other page
|
||||||
|
children: [],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want more head
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
Creating Headers and footers is simple. Access the `Header` and `Footer` by doing so like this:
|
Example showing basic header and footer
|
||||||
|
|
||||||
```ts
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/8-header-footer.ts ':include')
|
||||||
doc.Header;
|
|
||||||
doc.Footer;
|
|
||||||
```
|
|
||||||
|
|
||||||
You can call the same methods as you would with a `File`:
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/8-header-footer.ts_
|
||||||
|
|
||||||
```ts
|
|
||||||
doc.Header.createParagraph("Header text");
|
|
||||||
doc.Footer.createParagraph("Footer text");
|
|
||||||
```
|
|
||||||
|
|
||||||
Even add images:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
doc.Header.createImage([BUFFER_OF_YOUR_IMAGE]);
|
|
||||||
doc.Footer.createImage([BUFFER_OF_YOUR_IMAGE]);
|
|
||||||
```
|
|
||||||
|
|
||||||
Refer to [`demo8.ts`](https://github.com/dolanmiu/docx/blob/master/demo/demo8.ts) for more information.
|
|
||||||
|
|
||||||
## Multiple Headers and Footers
|
## Multiple Headers and Footers
|
||||||
|
|
||||||
Also all the supported section properties are implemented according to: http://officeopenxml.com/WPsection.php
|
More headers and footers can be accomplished by creating more `Section`. New headers and footers can be set per `Section`
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const header = this.document.createHeader();
|
|
||||||
const footer = this.document.createFooter();
|
|
||||||
|
|
||||||
// Add new section with another header and footer
|
|
||||||
doc.addSection({
|
|
||||||
headers: {
|
|
||||||
default: header
|
|
||||||
},
|
|
||||||
footers: {
|
|
||||||
default: footer
|
|
||||||
},
|
|
||||||
pageNumberStart: 1,
|
|
||||||
pageNumberFormatType: docx.PageNumberFormat.DECIMAL,
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,22 +227,22 @@ Media.addImage(doc, fs.readFileSync("./demo/images/pizza.gif"), 200, 200, {
|
|||||||
|
|
||||||
Importing Images from file system path
|
Importing Images from file system path
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo5.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/5-images.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo5.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/5-images.ts_
|
||||||
|
|
||||||
### Add images to header and footer
|
### Add images to header and footer
|
||||||
|
|
||||||
Example showing how to add image to headers and footers
|
Example showing how to add image to headers and footers
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo9.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/9-images-in-header-and-footer.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo9.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/9-images-in-header-and-footer.ts_
|
||||||
|
|
||||||
### Floating images
|
### Floating images
|
||||||
|
|
||||||
Example showing how to float images on top of text and optimally give a `margin`
|
Example showing how to float images on top of text and optimally give a `margin`
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo38.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/38-text-wrapping.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo38.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/38-text-wrapping.ts_
|
||||||
|
265
docs/usage/math.md
Normal file
265
docs/usage/math.md
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
# Math
|
||||||
|
|
||||||
|
!> Math requires an understanding of [Sections](usage/sections.md) and [Paragraphs](usage/paragraph.md).
|
||||||
|
|
||||||
|
## Intro
|
||||||
|
|
||||||
|
1. To add math, create a `Math` object
|
||||||
|
2. Add `MathComponents` inside `Math`
|
||||||
|
3. `MathComponents` can have nested `MathComponents` inside. e.g. A fraction where the numerator is a square root, and the demoninator as another fraction. More on `MathComponents` below
|
||||||
|
4. Make sure to add the `Math` object inside a `Paragraph`
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathRun("2+2"),
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("hi")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
This will produce:
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img alt="clippy the assistant" src="images/math-example.png" width="200">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Math Components
|
||||||
|
|
||||||
|
`MathComponents` are the unit sized building blocks of an equation in `docx`. A `MathComponent` takes in more nested `MathComponents` until you reach `MathRun`, which has no children. `MathRun` is similar to a [TextRun](usage/text.md).
|
||||||
|
|
||||||
|
### Math Run
|
||||||
|
|
||||||
|
`MathRun` is the most basic `MathComponent`.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathRun("2+2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathRun("hello");
|
||||||
|
```
|
||||||
|
|
||||||
|
An example of it being used inside `Math`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathRun("2"),
|
||||||
|
new MathRun("+"),
|
||||||
|
new MathRun("2"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Math Fraction
|
||||||
|
|
||||||
|
`MathFractions` require a `numerator` and a `demoninator`, which are both a list of `MathComponents`
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [
|
||||||
|
new MathRun("1"),
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
An example of it being used inside `Math`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new Math({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
new MathText("+"),
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
new MathText("= 1"),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sum
|
||||||
|
|
||||||
|
A `MathComponent` for `Σ`. It can take a `superScript` and/or `subScript` as arguments to add `MathComponents` (usually limits) on the top and bottom
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSum({
|
||||||
|
children: [new MathRun("i")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSum({
|
||||||
|
children: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("e")],
|
||||||
|
superScript: [new MathRun("2")],
|
||||||
|
})
|
||||||
|
],
|
||||||
|
subScript: [new MathRun("i")],
|
||||||
|
superScript: [new MathRun("10")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Radicals
|
||||||
|
|
||||||
|
A `MathComponent` for the `√` symbol. Examples include, square root, cube root etc. There is an optional `degree` parameter to specify the number of times the radicand is multiplied by itself. For example, `3` for cube root.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathRadical({
|
||||||
|
children: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
Cube root example:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathRadical({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
new MathRun('+ 1'),
|
||||||
|
],
|
||||||
|
degree: [new MathRun("3")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Super Script
|
||||||
|
|
||||||
|
`MathSuperScripts` are the little numbers written to the top right of numbers or variables. It means the exponent or power if written by itself with the number or variable.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("x")],
|
||||||
|
superScript: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
An example with cosine:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("cos")],
|
||||||
|
superScript: [new MathRun("-1")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sub Script
|
||||||
|
|
||||||
|
`MathSubScripts` are similar to `MathSuperScripts`, except the little number is written below.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSubScript({
|
||||||
|
children: [new MathRun("F")],
|
||||||
|
subScript: [new MathRun("n-1")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sub-Super Script
|
||||||
|
|
||||||
|
`MathSubSuperScripts` are a combination of both `MathSuperScript` and `MathSubScript`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSubSuperScript({
|
||||||
|
children: [new MathRun("test")],
|
||||||
|
superScript: [new MathRun("hello")],
|
||||||
|
subScript: [new MathRun("world")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Function
|
||||||
|
|
||||||
|
`MathFunctions` are a way of describing what happens to an input variable, in order to get the output result. It takes a `name` parameter to specify the name of the function.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathFunction({
|
||||||
|
name: [
|
||||||
|
new MathSuperScript({
|
||||||
|
children: [new MathRun("cos")],
|
||||||
|
superScript: [new MathRun("-1")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
children: [new MathRun("100")],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
### Brackets
|
||||||
|
|
||||||
|
#### Square brackets
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathSquareBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Round brackets
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathRoundBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Curly brackets
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathCurlyBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Angled brackets
|
||||||
|
|
||||||
|
```ts
|
||||||
|
new MathAngledBrackets({
|
||||||
|
children: [
|
||||||
|
new MathFraction({
|
||||||
|
numerator: [new MathRun("1")],
|
||||||
|
denominator: [new MathRun("2")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
```
|
@ -86,11 +86,3 @@ topLevelP.setNumbering(concrete, 0);
|
|||||||
subP.setNumbering(concrete, 1);
|
subP.setNumbering(concrete, 1);
|
||||||
subSubP.setNumbering(concrete, 2);
|
subSubP.setNumbering(concrete, 2);
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, you need to let your exporter know about your numbering
|
|
||||||
styles when you're ready to render the document:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const packer = new Packer(doc, undefined, undefined, numbering);
|
|
||||||
packer.pack(myOutput);
|
|
||||||
```
|
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
> Packers are the way in which `docx` turns your code into `.docx` format. It is completely decoupled from the `docx.Document`.
|
> Packers are the way in which `docx` turns your code into `.docx` format. It is completely decoupled from the `docx.Document`.
|
||||||
|
|
||||||
Packers in `version 4` and above are now one single `Packer`. It works in both a node and browser environment (Angular etc). Now, the packer returns a `Buffer`, `Blob` or `base64 string`. It is up to you to take that and persist it with node's `fs`, send it down as a downloadable file, or anything else you wish. As of version 4, this library will not have options to export to PDF.
|
Packers works in both a node and browser environment (Angular etc). Now, the packer returns a `Buffer`, `Blob` or `base64 string`. It is up to you to take that and persist it with node's `fs`, send it down as a downloadable file, or anything else you wish. As of `version 4+`, this library will not have options to export to PDF.
|
||||||
|
|
||||||
## Version 5
|
|
||||||
|
|
||||||
Packers in `version 5` and above are now static methods on `Packer`.
|
|
||||||
|
|
||||||
### Export as Buffer
|
### Export as Buffer
|
||||||
|
|
||||||
@ -36,117 +32,3 @@ Packer.toBlob(doc).then((blob) => {
|
|||||||
saveAs(blob, "example.docx");
|
saveAs(blob, "example.docx");
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Version 4
|
|
||||||
|
|
||||||
The `Packer` in `version 4` requires an instance of `Packer`, so be sure to `new` it.
|
|
||||||
|
|
||||||
### Export as Buffer
|
|
||||||
|
|
||||||
This will return a NodeJS `Buffer`. If this is used in the browser, it will return a `UInt8Array` instead.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const packer = new docx.Packer();
|
|
||||||
|
|
||||||
packer.toBuffer(doc).then((buffer) => {
|
|
||||||
fs.writeFileSync("My Document.docx", buffer);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export as a `base64` string
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const packer = new docx.Packer();
|
|
||||||
|
|
||||||
packer.toBase64String(doc).then((string) => {
|
|
||||||
console.log(string);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export as Blob
|
|
||||||
|
|
||||||
This is useful if you want to send it as an downloadable in a browser environment.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const packer = new docx.Packer();
|
|
||||||
|
|
||||||
packer.toBlob(doc).then((blob) => {
|
|
||||||
// saveAs from FileSaver will download the file
|
|
||||||
saveAs(blob, "example.docx");
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Version 3 and below
|
|
||||||
|
|
||||||
### File System Packer
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const docx = require("docx");
|
|
||||||
|
|
||||||
const doc = new docx.Document();
|
|
||||||
const exporter = new docx.LocalPacker(doc);
|
|
||||||
exporter.pack("My Document");
|
|
||||||
// Word Document is in file system
|
|
||||||
```
|
|
||||||
|
|
||||||
### Buffer Packer
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const docx = require("docx");
|
|
||||||
|
|
||||||
const doc = new docx.Document();
|
|
||||||
const exporter = new docx.BufferPacker(doc);
|
|
||||||
const buffer = exporter.pack();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Stream Packer
|
|
||||||
|
|
||||||
Creates a `node` `Readable` stream
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const docx = require("docx");
|
|
||||||
|
|
||||||
const doc = new docx.Document();
|
|
||||||
const exporter = new docx.StreamPacker(doc);
|
|
||||||
const stream = exporter.pack();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Express Packer
|
|
||||||
|
|
||||||
The old express packer is now deprecated and may disappear soon, so you should upgrade.
|
|
||||||
|
|
||||||
The reason for this is because it means this project needs to know about and use `express`, which for a Word document generator, does not sound right. Seperation of concerns.
|
|
||||||
|
|
||||||
It will still be usable (for now), but it is ill advised.
|
|
||||||
|
|
||||||
I used the express exporter in my [website](http://www.dolan.bio).
|
|
||||||
|
|
||||||
The recommended way is to use the `StreamPacker` and handle the `express` magic outside of the library:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const docx = require("docx");
|
|
||||||
|
|
||||||
const doc = new docx.Document();
|
|
||||||
const exporter = new docx.StreamPacker(doc);
|
|
||||||
|
|
||||||
const stream = exporter.pack();
|
|
||||||
|
|
||||||
// Express' response object
|
|
||||||
res.attachment("yourfile.xlsx");
|
|
||||||
stream.pipe(res);
|
|
||||||
```
|
|
||||||
|
|
||||||
where `res` is the response object obtained through the Express router. It is that simple. The file will begin downloading in the browser.
|
|
||||||
|
|
||||||
### PDF Exporting
|
|
||||||
|
|
||||||
You can export your word document as a PDF file like so:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const exporter = new docx.LocalPacker(doc);
|
|
||||||
exporter.packPdf("My Document");
|
|
||||||
|
|
||||||
// Express
|
|
||||||
const exporter = new docx.ExpressPacker(doc, res);
|
|
||||||
exporter.packPdf("My Document");
|
|
||||||
```
|
|
||||||
|
@ -61,6 +61,6 @@ doc.Header.createParagraph().addRun(new TextRun("Page ").pageNumber()).addRun(ne
|
|||||||
|
|
||||||
Adding page numbers to Header and Footer
|
Adding page numbers to Header and Footer
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo39.ts ':include')
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/39-page-numbers.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo39.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/39-page-numbers.ts_
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> Everything (text, images, graphs etc) in OpenXML is organised in paragraphs.
|
> Everything (text, images, graphs etc) in OpenXML is organised in paragraphs.
|
||||||
|
|
||||||
!> Paragraphs requires an understanding of [Sections](usage/sections.md).
|
!> Paragraphs requires an understanding of [Sections](sections.md).
|
||||||
|
|
||||||
You can create `Paragraphs` in the following ways:
|
You can create `Paragraphs` in the following ways:
|
||||||
|
|
||||||
@ -16,11 +16,11 @@ const paragraph = new Paragraph("Short hand Hello World");
|
|||||||
|
|
||||||
### Children Method
|
### Children Method
|
||||||
|
|
||||||
This method is useful for adding different `text` with different styles or adding `images` inline.
|
This method is useful for adding different [text](text.md) with different styles, [symbols](symbols.md), or adding [images](images.md) inline.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const paragraph = new Paragraph({
|
const paragraph = new Paragraph({
|
||||||
children: [new TextRun("Lorem Ipsum Foo Bar"), new TextRun("Hello World")],
|
children: [new TextRun("Lorem Ipsum Foo Bar"), new TextRun("Hello World"), new SymbolRun("F071")],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ doc.addSection({
|
|||||||
This is the list of options for a paragraph. A detailed explanation is below:
|
This is the list of options for a paragraph. A detailed explanation is below:
|
||||||
|
|
||||||
| Property | Type | Mandatory? | Possible Values |
|
| Property | Type | Mandatory? | Possible Values |
|
||||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
|
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
|
||||||
| [text](#text) | `string` | Optional | |
|
| [text](#text) | `string` | Optional | |
|
||||||
| [heading](#heading) | `HeadingLevel` | Optional | `HEADING_1`, `HEADING_2`, `HEADING_3`, `HEADING_4`, `HEADING_5`, `HEADING_6`, `TITLE` |
|
| [heading](#heading) | `HeadingLevel` | Optional | `HEADING_1`, `HEADING_2`, `HEADING_3`, `HEADING_4`, `HEADING_5`, `HEADING_6`, `TITLE` |
|
||||||
| [border](#border) | `IBorderOptions` | Optional | `top`, `bottom`, `left`, `right`. Each of these are of type IBorderPropertyOptions. Click here for Example |
|
| [border](#border) | `IBorderOptions` | Optional | `top`, `bottom`, `left`, `right`. Each of these are of type IBorderPropertyOptions. Click here for Example |
|
||||||
@ -76,7 +76,7 @@ This is the list of options for a paragraph. A detailed explanation is below:
|
|||||||
| style | `string` | Optional | |
|
| style | `string` | Optional | |
|
||||||
| tabStop | `{ left?: ITabStopOptions; right?: ITabStopOptions; maxRight?: { leader: LeaderType; }; center?: ITabStopOptions }` | Optional | |
|
| tabStop | `{ left?: ITabStopOptions; right?: ITabStopOptions; maxRight?: { leader: LeaderType; }; center?: ITabStopOptions }` | Optional | |
|
||||||
| bullet | `{ level: number }` | Optional | |
|
| bullet | `{ level: number }` | Optional | |
|
||||||
| numbering | `{ num: Num; level: number; custom?: boolean }` | Optional | |
|
| numbering | `{ num: ConcreteNumbering; level: number; custom?: boolean }` | Optional | |
|
||||||
|
|
||||||
## Text
|
## Text
|
||||||
|
|
||||||
@ -142,6 +142,21 @@ const paragraph = new Paragraph({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Shading
|
||||||
|
|
||||||
|
Add color to an entire paragraph block
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
text: "shading",
|
||||||
|
shading: {
|
||||||
|
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||||
|
color: "00FFFF",
|
||||||
|
fill: "FF0000",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
## Spacing
|
## Spacing
|
||||||
|
|
||||||
Adding spacing between paragraphs
|
Adding spacing between paragraphs
|
||||||
@ -244,10 +259,12 @@ The above example will create a heading with a page break directly under it.
|
|||||||
|
|
||||||
## Page Break
|
## Page Break
|
||||||
|
|
||||||
To move to a new page (insert a page break), simply add `.pageBreak()` on a paragraph:
|
To move to a new page (insert a page break):
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const paragraph = new docx.Paragraph("Amazing Heading").pageBreak();
|
const paragraph = new docx.Paragraph({
|
||||||
|
children: [new TextRun("Amazing Heading"), new PageBreak()],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
The above example will create a heading and start a new page immediately afterwards.
|
The above example will create a heading and start a new page immediately afterwards.
|
||||||
@ -265,7 +282,7 @@ const paragraph = new Paragraph({
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Example: https://github.com/dolanmiu/docx/blob/master/demo/demo15.ts
|
Example: https://github.com/dolanmiu/docx/blob/master/demo/15-page-break-before.ts
|
||||||
|
|
||||||
## Page break control
|
## Page break control
|
||||||
|
|
||||||
|
@ -3,112 +3,148 @@
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const para = new Paragraph("To whom it may concern:").heading2().center();
|
const para = new Paragraph({
|
||||||
|
text: "To whom it may concern:",
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
|
|
||||||
const name = new TextRun("Name:")
|
const name = new TextRun({
|
||||||
.bold()
|
text: "Name:",
|
||||||
.font("Calibri")
|
bold: true,
|
||||||
.allCaps();
|
font: "Calibri",
|
||||||
|
allCaps: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Available methods
|
## Available Options
|
||||||
|
|
||||||
* For run formatting:
|
### Run formatting
|
||||||
* `.bold()`, `.italics()`, `.smallCaps()`, `.allCaps()`, `.strike()`, `.doubleStrike()`, `.subScript()`, `.superScript()`: Set the formatting property to true
|
|
||||||
* `.underline(style="single", color=null)`: Set the underline style and color
|
|
||||||
* `.color(color)`: Set the text color, using 6 hex characters for RRGGBB (no leading `#`)
|
|
||||||
* `.size(halfPts)`: Set the font size, measured in half-points
|
|
||||||
* `.font(name)`: Set the run's font
|
|
||||||
* `.style(name)`: Apply a named run style
|
|
||||||
* `.characterSpacing(value)`: Set the character spacing adjustment (in TWIPs)
|
|
||||||
* For paragraph formatting:
|
|
||||||
* `.heading1()`, `.heading2()`, `.heading3()`, `.heading4()`, `.heading5()`, `.title()`: apply the appropriate style to the paragraph
|
|
||||||
* `.left()`, `.center()`, `.right()`, `.justified()`: set the paragraph's alignment
|
|
||||||
* `.thematicBreak()`, `.pageBreak()`: Insert a thick rule or a page break beneath the paragraph
|
|
||||||
* `.leftTabStop(position)`: Add a left tab stop (measured in TWIPs from the left)
|
|
||||||
* `.maxRightTabStop()`: Add a right tab stop at the far right
|
|
||||||
* `.bullet()`: Use the default bullet style
|
|
||||||
* `.setNumbering(numbering, indentLevel)`: Use a custom numbering format for the paragraph
|
|
||||||
* `.style(name)`: Apply a named paragraph style
|
|
||||||
* `.indent(start, hanging=0)`: Set the paragraph's indent level (in TWIPs)
|
|
||||||
* `.spacing({before=0, after=0, line=0})`: Set the line and before/after on the paragraph. Before/after is measured in TWIPs, line is measured in 240ths of a line
|
|
||||||
|
|
||||||
Paragraph styles have all the run formatting methods, except `style()`, and `.left()`, `.center()`, `.right()`, `.justified()`, `.thematicBreak()`, `.leftTabStop(position)`, `.maxRightTabStop()`, `.indent(start, hanging=0)`, and `.spacing({before=0, after=0, line=0})` methods.
|
- `bold`, `italics`, `smallCaps`, `allCaps`, `strike`, `doubleStrike`, `subScript`, `superScript`: Set the formatting property to true
|
||||||
|
- `underline({type="single", color=null})`: Set the underline style and color
|
||||||
|
- `emphasisMark({type="dot"})`: Set the emphasis mark style
|
||||||
|
- `color(color)`: Set the text color, using 6 hex characters for RRGGBB (no leading `#`)
|
||||||
|
- `size(halfPts)`: Set the font size, measured in half-points
|
||||||
|
- `font(name)` or `font({ascii, cs, eastAsia, hAnsi, hint})`: Set the run's font
|
||||||
|
- `style(name)`: Apply a named run style
|
||||||
|
- `characterSpacing(value)`: Set the character spacing adjustment (in TWIPs)
|
||||||
|
|
||||||
|
### Paragraph formatting
|
||||||
|
|
||||||
|
- `heading1`, `heading2`, `heading3`, `heading4`, `heading5`, `title`: apply the appropriate style to the paragraph
|
||||||
|
- `left`, `center`, `right`, `justified`: set the paragraph's alignment
|
||||||
|
- `thematicBreak`, `pageBreak`: Insert a thick rule or a page break beneath the paragraph
|
||||||
|
- `leftTabStop(position)`: Add a left tab stop (measured in TWIPs from the left)
|
||||||
|
- `maxRightTabStop`: Add a right tab stop at the far right
|
||||||
|
- `bullet`: Use the default bullet style
|
||||||
|
- `setNumbering(numbering, indentLevel)`: Use a custom numbering format for the paragraph
|
||||||
|
- `style(name)`: Apply a named paragraph style
|
||||||
|
- `indent(start, hanging=0)`: Set the paragraph's indent level (in TWIPs)
|
||||||
|
- `spacing({before=0, after=0, line=0})`: Set the line and before/after on the paragraph. Before/after is measured in TWIPs, line is measured in 240ths of a line
|
||||||
|
|
||||||
|
Paragraph styles have all the run formatting methods, except `style()`, and `left()`, `center()`, `right()`, `justified()`, `thematicBreak()`, `leftTabStop(position)`, `maxRightTabStop()`, `indent(start, hanging=0)`, and `spacing({before=0, after=0, line=0})` methods.
|
||||||
|
|
||||||
## Detailed guide
|
## Detailed guide
|
||||||
|
|
||||||
There are 4 items in DOCX that can be styled:
|
There are 4 items in `docx` that can be styled:
|
||||||
|
|
||||||
* Characters: Attributes that can change within a paragraph. e.g., bold, italics, etc.
|
- Characters: Attributes that can change within a paragraph. e.g., bold, italics, etc.
|
||||||
* Paragraphs: Attributes like indent, text alignment, line spacing, etc.
|
- Paragraphs: Attributes like indent, text alignment, line spacing, etc.
|
||||||
* Tables: Border styles, table formats, etc.
|
- Tables: Border styles, table formats, etc.
|
||||||
* List items: These are the numbers and bullets that are automatically inserted
|
- List items: These are the numbers and bullets that are automatically inserted
|
||||||
|
|
||||||
There are a few different ways of styling this content in DOCX, which somewhat resemble the HTML/CSS approach. In order of greatest to lowest priority:
|
There are a few different ways of styling this content in `docx`, which somewhat resemble the HTML/CSS approach. In order of greatest to lowest priority:
|
||||||
|
|
||||||
1. Direct formatting (AKA inline formatting)
|
1. Direct formatting (inline formatting)
|
||||||
2. Centrally defined styles (similar to external CSS)
|
2. Declaritive Styles (similar to external CSS)
|
||||||
3. Document defaults (similar to a `*` rule in CSS)
|
3. Document defaults (similar to a `*` rule in CSS)
|
||||||
|
|
||||||
Unlike CSS, less specific rules don't _necessarily_ override parent rules. The rules are a bit wonky, but if you're interested, see the [advanced formatting section](#Advanced formatting).
|
Unlike CSS, less specific rules don't _necessarily_ override parent rules. The rules are a bit wonky, but if you're interested, see the [advanced formatting section](#Advanced formatting).
|
||||||
|
|
||||||
### Direct formatting (AKA inline formatting)
|
### Direct formatting (inline formatting)
|
||||||
|
|
||||||
This is the type of formatting that your uncle uses when he types out documents: _N ... a ... m ... e ... :_ Then he grabs the mouse, highlights _Name:_ and moves over to the **B** for bold. This manner of formatting results in markup that is similar to writing `<span style="bold: true">Name:</span>` if you were typing out HTML. DOCX (the format) allows you to specify this for any of the four types of items. `docx` (the library) only supports this type of formatting for paragraphs and characters, using a _fluent_ api. Thus you could do:
|
This is the type of formatting that your uncle uses when he types out documents: _N ... a ... m ... e ... :_ Then he grabs the mouse, highlights _Name:_ and moves over to the **B** for bold. This manner of formatting results in markup that is similar to writing `<span style="bold: true">Name:</span>` if you were typing out HTML. `docx` (the format) allows you to specify this for any of the four types of items. `docx` (the library) only supports this type of formatting for paragraphs and characters, using a _fluent_ api. Thus you could do:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const name = new TextRun("Name:")
|
const name = new TextRun({
|
||||||
.bold()
|
text: "Name:",
|
||||||
.font("Calibri")
|
bold: true,
|
||||||
.allCaps();
|
font: "Calibri",
|
||||||
|
allCaps: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Or for paragraph formatting:
|
Or for paragraph formatting:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const para = new Paragraph("To whom it may concern:").heading2().center();
|
const para = new Paragraph({
|
||||||
|
text: "To whom it may concern:",
|
||||||
|
heading: HeadingLevel.HEADING_2,
|
||||||
|
alignment: AlignmentType.CENTER,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Centrally defined styles (similar to external CSS)
|
### Declaritive Styles (similar to external CSS)
|
||||||
|
|
||||||
DOCX files contain a styles section separate from the main content, much like how HTML includes CSS files. Unlike CSS, DOCX distinguishes between styles meant for tables (which show up in the table formatting toolbar), styles for lists (which show up under bullets and numbering), and styles for runs and paragraphs, which show up as dropdowns offering standard styles, like "Heading 1", "Caption", or any custom styles defined in that document. <!-- TODO: add pictures of the panes -->. `docx` allows you to define these styles using a fluent interface as well.
|
`docx` files contain a styles section separate from the main content, much like how HTML includes CSS files. Unlike CSS, `docx` distinguishes between styles meant for tables (which show up in the table formatting toolbar), styles for lists (which show up under bullets and numbering), and styles for runs and paragraphs, which show up as dropdowns offering standard styles, like "Heading 1", "Caption", or any custom styles defined in that document. <!-- TODO: add pictures of the panes -->. `docx` allows you to define these styles using a fluent interface as well.
|
||||||
|
|
||||||
There are three parts to using custom styles with `docx`:
|
To add styles, define your custom styles in the `document`:
|
||||||
|
|
||||||
1. Create a container object for the style definitions:
|
```ts
|
||||||
```ts
|
// The first argument is an ID you use to apply the style to paragraphs
|
||||||
const myStyles = new docx.Styles();
|
// The second argument is a human-friendly name to show in the UI
|
||||||
```
|
const doc = new Document({
|
||||||
2. Define your custom styles, similar to the way you would format a paragraph or run
|
creator: "Clippy",
|
||||||
|
title: "Sample Document",
|
||||||
```ts
|
description: "A brief example of using docx",
|
||||||
// The first argument is an ID you use to apply the style to paragraphs
|
styles: {
|
||||||
// The second argument is a human-friendly name to show in the UI
|
paragraphStyles: [
|
||||||
myStyles
|
{
|
||||||
.createParagraphStyle("myWonkyStyle", "My Wonky Style")
|
id: "myWonkyStyle",
|
||||||
.basedOn("Normal")
|
name: "My Wonky Style",
|
||||||
.next("Normal")
|
basedOn: "Normal",
|
||||||
.color("999999")
|
next: "Normal",
|
||||||
.italics()
|
quickFormat: true,
|
||||||
.indent(720) // 720 TWIP === 720 / 20 pt === .5 in
|
run: {
|
||||||
.spacing({ line: 276 }); // 276 / 240 = 1.15x line spacing
|
italics: true,
|
||||||
|
color: "999999",
|
||||||
myStyles
|
},
|
||||||
.createParagraphStyle("Heading2", "Heading 2")
|
paragraph: {
|
||||||
.basedOn("Normal")
|
spacing: {
|
||||||
.next("Normal")
|
line: 276,
|
||||||
.quickFormat()
|
},
|
||||||
.size(26) // 26 half-points === 13pt font
|
indent: {
|
||||||
.bold()
|
left: 720,
|
||||||
.underline("double", "FF0000")
|
},
|
||||||
.spacing({ before: 240, after: 120 }); // TWIP for both
|
},
|
||||||
```
|
},
|
||||||
|
{
|
||||||
3. When you generate your document, make sure to pass the `styles` container to the `Packer`:
|
id: "Heading2",
|
||||||
|
name: "Heading 2",
|
||||||
```ts
|
basedOn: "Normal",
|
||||||
Packer.pack(myOutStream);
|
next: "Normal",
|
||||||
```
|
quickFormat: true,
|
||||||
|
run: {
|
||||||
|
size: 26
|
||||||
|
bold: true,
|
||||||
|
color: "999999",
|
||||||
|
{
|
||||||
|
type: UnderlineType.DOUBLE,
|
||||||
|
color: "FF0000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paragraph: {
|
||||||
|
spacing: {
|
||||||
|
before: 240,
|
||||||
|
after: 120
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
**Note**: If you are using the `.headingX` or `.title` methods of paragraphs, you must make sure to define `HeadingX` or `Title` styles for these. Otherwise they'll show up unstyled :(. If you are using the `.bullet` or `.setNumbering` methods, you need to define a `ListParagraph` style or the numbers may not show up.
|
**Note**: If you are using the `.headingX` or `.title` methods of paragraphs, you must make sure to define `HeadingX` or `Title` styles for these. Otherwise they'll show up unstyled :(. If you are using the `.bullet` or `.setNumbering` methods, you need to define a `ListParagraph` style or the numbers may not show up.
|
||||||
|
|
||||||
@ -144,19 +180,29 @@ To determine the value of a styling property, you must first identify whether it
|
|||||||
|
|
||||||
The following properties are treated in a special manner; they're called toggle properties:
|
The following properties are treated in a special manner; they're called toggle properties:
|
||||||
|
|
||||||
* Bold
|
- Bold
|
||||||
* All caps
|
- All caps
|
||||||
* Small caps
|
- Small caps
|
||||||
* Italics
|
- Italics
|
||||||
* Single strike-through
|
- Single strike-through
|
||||||
* Hidden
|
- Hidden
|
||||||
* Imprint
|
- Imprint
|
||||||
* Emboss
|
- Emboss
|
||||||
* Character outline
|
- Character outline
|
||||||
* Character shadow
|
- Character shadow
|
||||||
|
|
||||||
For these properties, the rules state the following conflict resolution in case the property is specified at multiple points for the same item:
|
For these properties, the rules state the following conflict resolution in case the property is specified at multiple points for the same item:
|
||||||
|
|
||||||
* Direct formatting trumps all if specified (either true or false)
|
- Direct formatting trumps all if specified (either true or false)
|
||||||
* Otherwise, if the property is true in document defaults, the property is set to true
|
- Otherwise, if the property is true in document defaults, the property is set to true
|
||||||
* Otherwise, the property's value is an XOR of its effective table, paragraph, and character values. (So specifying bold `true` on a table style and a paragraph style would result in non-bold text if a paragraph inside the table had that style)
|
- Otherwise, the property's value is an XOR of its effective table, paragraph, and character values. (So specifying bold `true` on a table style and a paragraph style would result in non-bold text if a paragraph inside the table had that style)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Declaritive styles
|
||||||
|
|
||||||
|
Importing Images from file system path
|
||||||
|
|
||||||
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/2-declaritive-styles.ts ':include')
|
||||||
|
|
||||||
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/2-declaritive-styles.ts_
|
||||||
|
@ -44,4 +44,4 @@ doc.add(paragraph);
|
|||||||
doc.createParagraph("Some normal text");
|
doc.createParagraph("Some normal text");
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: https://github.com/dolanmiu/docx/blob/master/demo/demo13.ts
|
Example: https://github.com/dolanmiu/docx/blob/master/demo/13-xml-styles.ts
|
||||||
|
53
docs/usage/symbols.md
Normal file
53
docs/usage/symbols.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# Symbol Runs
|
||||||
|
|
||||||
|
!> SymbolRuns require an understanding of [Paragraphs](paragraph.md).
|
||||||
|
|
||||||
|
You can add multiple `symbol runs` in `Paragraphs` along with [text runs](text.md) using the Paragraph's `children` property.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Paragraph, TextRun, SymbolRun } from "docx";
|
||||||
|
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
children: [
|
||||||
|
new TextRun("This is a checkbox: "),
|
||||||
|
new SymbolRun("F071")
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Specifying symbol font
|
||||||
|
|
||||||
|
By default symbol runs will use the `Wingdings` font. To switch fonts, pass an object instead of a string to the `SymbolRun` constructor and specify `char` and `symbolfont` properties:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const symbol = new SymbolRun({
|
||||||
|
char: "F071",
|
||||||
|
symbolfont: "Arial",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example symbols
|
||||||
|
|
||||||
|
Symbols are specified by their hexidecimal code. Ref http://officeopenxml.com/WPtextSpecialContent-symbol.php. Below are some examples.
|
||||||
|
|
||||||
|
- `F071`: empty checkbox
|
||||||
|
- `F043`: thumbs up
|
||||||
|
- `F04A`: smile
|
||||||
|
- `F04C`: frown
|
||||||
|
- `F022`: scissors
|
||||||
|
- `F0F0`: right arrow
|
||||||
|
- `F0FE`: checked box
|
||||||
|
|
||||||
|
## Typographical Emphasis
|
||||||
|
|
||||||
|
Symbol runs can have their display modified just like text runs. For example, they can be bolded and italicized:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const symbol = new SymbolRun({
|
||||||
|
char: "F071",
|
||||||
|
bold: true,
|
||||||
|
italics: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [text run](text.md) documentation for more info.
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> Tab stops are useful, if you are unclear of what they are, [here is a link explaining](https://en.wikipedia.org/wiki/Tab_stop). It enables side by side text which is nicely laid out without the need for tables, or constantly pressing space bar.
|
> Tab stops are useful, if you are unclear of what they are, [here is a link explaining](https://en.wikipedia.org/wiki/Tab_stop). It enables side by side text which is nicely laid out without the need for tables, or constantly pressing space bar.
|
||||||
|
|
||||||
!> **Note**: At the moment, the unit of measurement for a tab stop is counter intuitive for a human. It is using OpenXMLs own measuring system. For example, 2268 roughly translates to 3cm. Therefore in the future, I may consider changing it to percentages or even cm.
|
!> **Note**: The unit of measurement for a tab stop is in [DXA](https://stackoverflow.com/questions/14360183/default-wordml-unit-measurement-pixel-or-point-or-inches)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -11,44 +11,111 @@ Simply call the relevant methods on the paragraph listed below. Then just add a
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const paragraph = new docx.Paragraph().maxRightTabStop();
|
const paragraph = new Paragraph({
|
||||||
const leftText = new docx.TextRun("Hey everyone").bold();
|
children: [new TextRun("Hey everyone").bold(), new TextRun(\t"11th November 1999")],
|
||||||
const rightText = new docx.TextRun("11th November 2015").tab();
|
tabStops: [
|
||||||
paragraph.addRun(leftText);
|
{
|
||||||
paragraph.addRun(rightText);
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
The example above will create a left aligned text, and a right aligned text on the same line. The laymans approach to this problem would be to either use text boxes or tables. YUK!
|
|
||||||
|
The example above will create a left aligned text, and a right aligned text on the same line. The laymans approach to this problem would be to either use text boxes or tables. Not ideal!
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const paragraph = new docx.Paragraph();
|
const paragraph = new Paragraph({
|
||||||
paragraph.maxRightTabStop();
|
children: [new TextRun("Second tab stop here I come!")],
|
||||||
paragraph.leftTabStop(1000);
|
tabStops: [
|
||||||
const text = new docx.TextRun("Second tab stop here I come!").tab().tab();
|
{
|
||||||
paragraph.addRun(text);
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: TabStopType.LEFT,
|
||||||
|
position: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
The above shows the use of two tab stops, and how to select/use it.
|
The above shows the use of two tab stops, and how to select/use it.
|
||||||
|
|
||||||
## Left Tab Stop
|
You can add multiple tab stops of the same `type` too.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
paragraph.leftTabStop(2268);
|
const paragraph = new Paragraph({
|
||||||
|
children: [new TextRun("Multiple tab stops!")],
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: 1000,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Left Tab Stop
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.LEFT,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
2268 is the distance from the left side.
|
2268 is the distance from the left side.
|
||||||
|
|
||||||
## Center Tab Stop
|
## Center Tab Stop
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
paragraph.centerTabStop(2268);
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.CENTER,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
2268 is the distance from the center.
|
||||||
|
|
||||||
## Right Tab Stop
|
## Right Tab Stop
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
paragraph.rightTabStop(2268);
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: 2268,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
2268 is the distance from the left side.
|
|
||||||
|
2268 is the distance fro0oum the left side.
|
||||||
|
|
||||||
## Max Right Tab Stop
|
## Max Right Tab Stop
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
paragraph.maxRightTabStop();
|
const paragraph = new Paragraph({
|
||||||
|
tabStops: [
|
||||||
|
{
|
||||||
|
type: TabStopType.RIGHT,
|
||||||
|
position: TabStopPosition.MAX,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create a tab stop on the very edge of the right hand side. Handy for right aligning and left aligning text on the same line.
|
This will create a tab stop on the very edge of the right hand side. Handy for right aligning and left aligning text on the same line.
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
You can generate table of contents with `docx`. More information can be found [here](http://officeopenxml.com/WPtableOfContents.php).
|
You can generate table of contents with `docx`. More information can be found [here](http://officeopenxml.com/WPtableOfContents.php).
|
||||||
|
|
||||||
>Tables of Contents are fields and, by design, it's content is only generated or updated by Word. We can't do it programatically.
|
> Tables of Contents are fields and, by design, it's content is only generated or updated by Word. We can't do it programatically.
|
||||||
>This is why, when you open a the file, Word you will prompt the message "This document contains fields that may refer to other files. Do you want to update the fields in this document?".
|
> This is why, when you open a the file, Word you will prompt the message "This document contains fields that may refer to other files. Do you want to update the fields in this document?".
|
||||||
>You have say yes to Word generate the content of all table of contents.
|
> You have say yes to Word generate the content of all table of contents.
|
||||||
|
|
||||||
The complete documentation can be found [here](https://www.ecma-international.org/publications/standards/Ecma-376.htm) (at Part 1, Page 1251).
|
The complete documentation can be found [here](https://www.ecma-international.org/publications/standards/Ecma-376.htm) (at Part 1, Page 1251).
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ All you need to do is create a `TableOfContents` object and assign it to the doc
|
|||||||
const toc = new TableOfContents("Summary", {
|
const toc = new TableOfContents("Summary", {
|
||||||
hyperlink: true,
|
hyperlink: true,
|
||||||
headingStyleRange: "1-5",
|
headingStyleRange: "1-5",
|
||||||
stylesWithLevels: [new StyleLevel("MySpectacularStyle", 1)]
|
stylesWithLevels: [new StyleLevel("MySpectacularStyle", 1)],
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.addTableOfContents(toc);
|
doc.addTableOfContents(toc);
|
||||||
@ -27,50 +27,26 @@ doc.addTableOfContents(toc);
|
|||||||
Here is the list of all options that you can use to generate your tables of contents:
|
Here is the list of all options that you can use to generate your tables of contents:
|
||||||
|
|
||||||
| Option | Type | TOC Field Switch | Description |
|
| Option | Type | TOC Field Switch | Description |
|
||||||
| --- | --- | --- | --- |
|
| ------------------------------- | ------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|captionLabel|string|`\a`|Includes captioned items, but omits caption labels and numbers. The identifier designated by `text` in this switch's field-argument corresponds to the caption label. Use ``\c`` to build a table of captions with labels and numbers.|
|
| captionLabel | string | `\a` | Includes captioned items, but omits caption labels and numbers. The identifier designated by `text` in this switch's field-argument corresponds to the caption label. Use `\c` to build a table of captions with labels and numbers. |
|
||||||
|entriesFromBookmark|string|`\b`|Includes entries only from the portion of the document marked by the bookmark named by `text` in this switch's field-argument.|
|
| entriesFromBookmark | string | `\b` | Includes entries only from the portion of the document marked by the bookmark named by `text` in this switch's field-argument. |
|
||||||
|captionLabelIncludingNumbers|string|`\c`|Includes figures, tables, charts, and other items that are numbered by a SEQ field (§17.16.5.56). The sequence identifier designated by `text` in this switch's field-argument, which corresponds to the caption label, shall match the identifier in the corresponding SEQ field.|
|
| captionLabelIncludingNumbers | string | `\c` | Includes figures, tables, charts, and other items that are numbered by a SEQ field (§17.16.5.56). The sequence identifier designated by `text` in this switch's field-argument, which corresponds to the caption label, shall match the identifier in the corresponding SEQ field. |
|
||||||
|sequenceAndPageNumbersSeparator|string|`\d`|When used with `\s`, the `text` in this switch's field-argument defines the separator between sequence and page numbers. The default separator is a hyphen (-).|
|
| sequenceAndPageNumbersSeparator | string | `\d` | When used with `\s`, the `text` in this switch's field-argument defines the separator between sequence and page numbers. The default separator is a hyphen (-). |
|
||||||
|tcFieldIdentifier|string|`\f`|Includes only those TC fields whose identifier exactly matches the `text` in this switch's field-argument (which is typically a letter).|
|
| tcFieldIdentifier | string | `\f` | Includes only those TC fields whose identifier exactly matches the `text` in this switch's field-argument (which is typically a letter). |
|
||||||
|hyperlink|boolean|`\h`|Makes the table of contents entries hyperlinks.|
|
| hyperlink | boolean | `\h` | Makes the table of contents entries hyperlinks. |
|
||||||
|tcFieldLevelRange|string|`\l`|Includes TC fields that assign entries to one of the levels specified by `text` in this switch's field-argument as a range having the form startLevel-endLevel, where startLevel and endLevel are integers, and startLevel has a value equal-to or less-than endLevel. TC fields that assign entries to lower levels are skipped.|
|
| tcFieldLevelRange | string | `\l` | Includes TC fields that assign entries to one of the levels specified by `text` in this switch's field-argument as a range having the form startLevel-endLevel, where startLevel and endLevel are integers, and startLevel has a value equal-to or less-than endLevel. TC fields that assign entries to lower levels are skipped. |
|
||||||
|pageNumbersEntryLevelsRange|string|`\n`|Without field-argument, omits page numbers from the table of contents. Page numbers are omitted from all levels unless a range of entry levels is specified by `text` in this switch's field-argument. A range is specified as for `\l`.|
|
| pageNumbersEntryLevelsRange | string | `\n` | Without field-argument, omits page numbers from the table of contents. Page numbers are omitted from all levels unless a range of entry levels is specified by `text` in this switch's field-argument. A range is specified as for `\l`. |
|
||||||
|headingStyleRange|string|`\o`|Uses paragraphs formatted with all or the specified range of builtin heading styles. Headings in a style range are specified by `text` in this switch's field-argument using the notation specified as for `\l`, where each integer corresponds to the style with a style ID of HeadingX (e.g. 1 corresponds to Heading1). If no heading range is specified, all heading levels used in the document are listed.|
|
| headingStyleRange | string | `\o` | Uses paragraphs formatted with all or the specified range of builtin heading styles. Headings in a style range are specified by `text` in this switch's field-argument using the notation specified as for `\l`, where each integer corresponds to the style with a style ID of HeadingX (e.g. 1 corresponds to Heading1). If no heading range is specified, all heading levels used in the document are listed. |
|
||||||
|entryAndPageNumberSeparator|string|`\p`|`text` in this switch's field-argument specifies a sequence of characters that separate an entry and its page number. The default is a tab with leader dots.|
|
| entryAndPageNumberSeparator | string | `\p` | `text` in this switch's field-argument specifies a sequence of characters that separate an entry and its page number. The default is a tab with leader dots. |
|
||||||
|seqFieldIdentifierForPrefix|string|`\s`|For entries numbered with a SEQ field (§17.16.5.56), adds a prefix to the page number. The prefix depends on the type of entry. `text` in this switch's field-argument shall match the identifier in the SEQ field.|
|
| seqFieldIdentifierForPrefix | string | `\s` | For entries numbered with a SEQ field (§17.16.5.56), adds a prefix to the page number. The prefix depends on the type of entry. `text` in this switch's field-argument shall match the identifier in the SEQ field. |
|
||||||
|stylesWithLevels|StyleLevel[]|`\t`| Uses paragraphs formatted with styles other than the built-in heading styles. `text` in this switch's field-argument specifies those styles as a set of comma-separated doublets, with each doublet being a comma-separated set of style name and table of content level. `\t` can be combined with `\o`.|
|
| stylesWithLevels | StyleLevel[] | `\t` | Uses paragraphs formatted with styles other than the built-in heading styles. `text` in this switch's field-argument specifies those styles as a set of comma-separated doublets, with each doublet being a comma-separated set of style name and table of content level. `\t` can be combined with `\o`. |
|
||||||
|useAppliedParagraphOutlineLevel|boolean|`\u`|Uses the applied paragraph outline level.|
|
| useAppliedParagraphOutlineLevel | boolean | `\u` | Uses the applied paragraph outline level. |
|
||||||
|preserveTabInEntries|boolean|`\w`|Preserves tab entries within table entries.|
|
| preserveTabInEntries | boolean | `\w` | Preserves tab entries within table entries. |
|
||||||
|preserveNewLineInEntries|boolean|`\x`|Preserves newline characters within table entries.|
|
| preserveNewLineInEntries | boolean | `\x` | Preserves newline characters within table entries. |
|
||||||
|hideTabAndPageNumbersInWebView|boolean|`\z`|Hides tab leader and page numbers in web page view (§17.18.102).|
|
| hideTabAndPageNumbersInWebView | boolean | `\z` | Hides tab leader and page numbers in web page view (§17.18.102). |
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
```ts
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/28-table-of-contents.ts ':include')
|
||||||
// Let's define the options for generate a TOC for heading 1-5 and MySpectacularStyle,
|
|
||||||
// making the entries be hyperlinks for the paragraph
|
|
||||||
const toc = new TableOfContents("Summary", {
|
|
||||||
hyperlink: true,
|
|
||||||
headingStyleRange: "1-5",
|
|
||||||
stylesWithLevels: [new StyleLevel("MySpectacularStyle", 1)]
|
|
||||||
});
|
|
||||||
|
|
||||||
doc.addTableOfContents(toc);
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/28-table-of-contents.ts_
|
||||||
|
|
||||||
doc.add(new Paragraph("Header #1").heading1().pageBreakBefore());
|
|
||||||
doc.add(new Paragraph("I'm a little text, very nicely written.'"));
|
|
||||||
|
|
||||||
doc.add(new Paragraph("Header #2").heading1().pageBreakBefore());
|
|
||||||
doc.add(new Paragraph("I'm another text very nicely written.'"));
|
|
||||||
doc.add(new Paragraph("Header #2.1").heading2());
|
|
||||||
doc.add(new Paragraph("I'm another text very nicely written.'"));
|
|
||||||
|
|
||||||
doc.add(new Paragraph("My Spectacular Style #1").style("MySpectacularStyle").pageBreakBefore());
|
|
||||||
```
|
|
||||||
|
|
||||||
### Complete example
|
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo28.ts ':include')
|
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo28.ts_
|
|
||||||
|
@ -1,306 +1,387 @@
|
|||||||
# Tables
|
# Tables
|
||||||
|
|
||||||
You can create tables with `docx`. More information can be found [here](http://officeopenxml.com/WPtable.php).
|
!> Paragraphs requires an understanding of [Sections](usage/sections.md).
|
||||||
|
|
||||||
## Create Table
|
## Intro
|
||||||
|
|
||||||
To create a table, simply create one with `new Table()`, then add it to the document: `doc.add()`.
|
* `Tables` contain a list of `Rows`
|
||||||
|
* `Rows` contain a list of `TableCells`
|
||||||
|
* `TableCells` contain a list of `Parahraphs` and/or `Tables`. You can add `Tables` as tables can be nested inside each other
|
||||||
|
|
||||||
```ts
|
Create a simple table like so:
|
||||||
const table = doc.add(new Table({
|
|
||||||
rows: [NUMBER OF ROWS],
|
|
||||||
columns: [NUMBER OF COLUMNS]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, you can create a table object directly, and then add it in the `document`
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const table = new Table(4, 4);
|
|
||||||
doc.add(table);
|
|
||||||
```
|
|
||||||
|
|
||||||
The snippet below creates a table of 2 rows and 4 columns.
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const table = new Table({
|
const table = new Table({
|
||||||
rows: 2,
|
rows: [Array of `TableRow`s]
|
||||||
columns: 4,
|
|
||||||
});
|
});
|
||||||
doc.add(table);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rows and Columns
|
Then add the table in the `section`
|
||||||
|
|
||||||
You can get a row or a column from a table like so, where `index` is a number:
|
|
||||||
|
|
||||||
### Get Row
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const row = doc.getRow(index);
|
doc.addSection({
|
||||||
|
children: [table],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
With this, you can merge a row by using the `mergeCells()` method, where `startIndex` is the row number you want to merge from, and `endIndex` is where you want it to merge to:
|
## Table
|
||||||
|
|
||||||
|
### Set Width
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
row.mergeCells(startIndex, endIndex);
|
const table = new Table({
|
||||||
|
...,
|
||||||
|
width: {
|
||||||
|
size: [TABLE_WIDTH],
|
||||||
|
type: WidthType,
|
||||||
|
}
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
You can get a cell from a `row` by using the `getCell()` method, where `index` is the row index:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
row.getCell(index);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get Column
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const column = doc.getColumn(index);
|
|
||||||
```
|
|
||||||
|
|
||||||
Again, you can merge a row by using the `mergeCells()` method, where `startIndex` is the row number you want to merge from, and `endIndex` is where you want it to merge to:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
column.mergeCells(startIndex, endIndex);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can get a cell from a `column` by using the `getCell()` method, where `index` is the column index:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
column.getCell(index);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Cells
|
|
||||||
|
|
||||||
To access the cell, use the `getCell()` method.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const cell = table.getCell([ROW INDEX], [COLUMN INDEX]);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also get a cell from a `column` or a `row` with `getCell()`, mentioned previously.
|
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const cell = table.getCell(0, 2);
|
|
||||||
|
|
||||||
const cell = row.getCell(0);
|
const table = new Table({
|
||||||
|
...,
|
||||||
|
width: {
|
||||||
|
size: 4535,
|
||||||
|
type: WidthType.DXA,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
const cell = column.getCell(2);
|
## Table Row
|
||||||
|
|
||||||
|
A table consists of multiple `table rows`. Table rows have a list of `children` which accepts a list of `table cells` explained below. You can create a simple `table row` like so:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const tableRow = new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("hello")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Or preferably, add the tableRow directly into the `table` without declaring a variable:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const table = new Table({
|
||||||
|
rows: [
|
||||||
|
new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("hello")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
Here is a list of options you can add to the `table row`:
|
||||||
|
|
||||||
|
| Property | Type | Notes |
|
||||||
|
| ----------- | ------------------------------------- | -------- |
|
||||||
|
| children | `Array<TableCell>` | Required |
|
||||||
|
| cantSplit | `boolean` | Optional |
|
||||||
|
| tableHeader | `boolean` | Optional |
|
||||||
|
| height | `{ height: number, rule: HeightRule }` | Optional |
|
||||||
|
|
||||||
|
### Repeat row
|
||||||
|
|
||||||
|
If a table is paginated on multiple pages, it is possible to repeat a row at the top of each new page by setting `tableHeader` to `true`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const row = new TableRow({
|
||||||
|
...,
|
||||||
|
tableHeader: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pagination
|
||||||
|
|
||||||
|
#### Prevent row pagination
|
||||||
|
|
||||||
|
To prevent breaking contents of a row across multiple pages, call `cantSplit`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const row = new Row({
|
||||||
|
...,
|
||||||
|
cantSplit: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Table Cells
|
||||||
|
|
||||||
|
Cells need to be added in the `table row`, you can create a table cell like:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const tableCell = new TableCell({
|
||||||
|
children: [new Paragraph("hello")],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Or preferably, add the tableRow directly into the `table row` without declaring a variable:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const tableRow = new TableRow({
|
||||||
|
children: [
|
||||||
|
new TableCell({
|
||||||
|
children: [new Paragraph("hello")],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Property | Type | Notes |
|
||||||
|
| ------------- | ----------------------------------- | ----------------------------------------------------------- |
|
||||||
|
| children | `Array<Paragraph | Table>` | Required. You can nest tables by adding a table into a cell |
|
||||||
|
| shading | `ITableShadingAttributesProperties` | Optional |
|
||||||
|
| margins | `ITableCellMarginOptions` | Optional |
|
||||||
|
| verticalAlign | `VerticalAlign` | Optional |
|
||||||
|
| columnSpan | `number` | Optional |
|
||||||
|
| rowSpan | `number` | Optional |
|
||||||
|
| borders | `BorderOptions` | Optional |
|
||||||
|
| width | `{ size: number type: WidthType }` | Optional |
|
||||||
|
|
||||||
|
#### Border Options
|
||||||
|
|
||||||
|
| Property | Type | Notes |
|
||||||
|
| -------- | ----------------------------------------------------- | -------- |
|
||||||
|
| top | `{ style: BorderStyle, size: number, color: string }` | Optional |
|
||||||
|
| bottom | `{ style: BorderStyle, size: number, color: string }` | Optional |
|
||||||
|
| left | `{ style: BorderStyle, size: number, color: string }` | Optional |
|
||||||
|
| right | `{ style: BorderStyle, size: number, color: string }` | Optional |
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
|
borders: {
|
||||||
|
top: {
|
||||||
|
style: BorderStyle.DASH_DOT_STROKED,
|
||||||
|
size: 1,
|
||||||
|
color: "red",
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
style: BorderStyle.THICK_THIN_MEDIUM_GAP,
|
||||||
|
size: 5,
|
||||||
|
color: "889900",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Google DOCS
|
||||||
|
|
||||||
|
Google DOCS does not support start and end borders, instead they use left and right borders. So to set left and right borders for Google DOCS you should use:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
|
borders: {
|
||||||
|
top: {
|
||||||
|
style: BorderStyle.DOT_DOT_DASH,
|
||||||
|
size: 3,
|
||||||
|
color: "green",
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
style: BorderStyle.DOT_DOT_DASH,
|
||||||
|
size: 3,
|
||||||
|
color: "ff8000",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add paragraph to a cell
|
### Add paragraph to a cell
|
||||||
|
|
||||||
Once you have got the cell, you can add data to it with the `add()` method.
|
Once you have got the cell, you can add data to it:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
cell.add(new Paragraph("Hello"));
|
const cell = new TableCell({
|
||||||
|
children: [new Paragraph("Hello")],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Set width of a cell
|
### Set width of a cell
|
||||||
|
|
||||||
You can specify the width of a cell using:
|
You can specify the width of a cell using:
|
||||||
|
|
||||||
`cell.Properties.setWidth(width, format)`
|
```ts
|
||||||
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
|
width: {
|
||||||
|
size: number,
|
||||||
|
type: WidthType,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
format can be:
|
`WidthType` values can be:
|
||||||
|
|
||||||
- WidthType.AUTO
|
| Property | Notes |
|
||||||
- WidthType.DXA: value is in twentieths of a point
|
| -------- | --------------------------------- |
|
||||||
- WidthType.NIL: is considered as zero
|
| AUTO | |
|
||||||
- WidthType.PCT: percent of table width
|
| DXA | value is in twentieths of a point |
|
||||||
|
| NIL | is considered as zero |
|
||||||
|
| PCT | percent of table width |
|
||||||
|
|
||||||
### Example
|
#### Example
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
cell.Properties.setWidth(100, WidthType.DXA);
|
cell.Properties.setWidth(100, WidthType.DXA);
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
### Nested Tables
|
||||||
cell.Properties.setWidth("50%", WidthType.PCT);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Borders
|
To have a table within a table, simply add it in the `children` block of a `table cell`:
|
||||||
|
|
||||||
BorderStyle can be imported from `docx`. Size determines the thickness. HTML color can be a hex code or alias such as `red`.
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
cell.Borders.addTopBorder([BorderStyle], [SIZE], [HTML COLOR]);
|
const cell = new TableCell({
|
||||||
|
children: [new Table(...)],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
### Vertical Align
|
||||||
cell.Borders.addBottomBorder([BorderStyle], [SIZE], [HTML COLOR]);
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
cell.Borders.addStartBorder([[BorderStyle]], [SIZE], [HTML COLOR]);
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
cell.Borders.addEndBorder([BorderStyle], [SIZE], [HTML COLOR]);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { BorderStyle } from "docx";
|
|
||||||
|
|
||||||
cell.Borders.addStartBorder(BorderStyle.DOT_DOT_DASH, 3, "green");
|
|
||||||
cell.Borders.addEndBorder(BorderStyle.DOT_DOT_DASH, 3, "#ff8000");
|
|
||||||
```
|
|
||||||
|
|
||||||
### Google DOCS
|
|
||||||
|
|
||||||
Google DOCS does not support start and end borders, instead they use left and right borders. So to set left and right borders for Google DOCS you should use:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { BorderStyle } from "docx";
|
|
||||||
|
|
||||||
cell.Borders.addLeftBorder(BorderStyle.DOT_DOT_DASH, 3, "green");
|
|
||||||
cell.Borders.addRightBorder(BorderStyle.DOT_DOT_DASH, 3, "#ff8000");
|
|
||||||
```
|
|
||||||
|
|
||||||
## Set Width
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { WidthType } from "docx";
|
|
||||||
|
|
||||||
table.setWidth([WIDTH], [OPTIONAL WidthType. Defaults to DXA]);
|
|
||||||
```
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
table.setWidth(4535, WidthType.DXA);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Vertical Align
|
|
||||||
|
|
||||||
Sets the vertical alignment of the contents of the cell
|
Sets the vertical alignment of the contents of the cell
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { VerticalAlign } from "docx";
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
cell.setVerticalAlign([VerticalAlign TYPE]);
|
verticalAlign: VerticalAlign,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`VerticalAlign` values can be:
|
||||||
|
|
||||||
|
| Property | Notes |
|
||||||
|
| -------- | ------------------------------------------ |
|
||||||
|
| BOTTOM | Align the contents on the bottom |
|
||||||
|
| CENTER | Align the contents on the center |
|
||||||
|
| TOP | Align the contents on the top. The default |
|
||||||
|
|
||||||
For example, to center align a cell:
|
For example, to center align a cell:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
cell.setVerticalAlign(VerticalAlign.CENTER);
|
const cell = new TableCell({
|
||||||
|
verticalAlign: VerticalAlign.CENTER,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rows
|
## Merging cells together
|
||||||
|
|
||||||
To get a row, use the `getRow` method on a `table`. There are a handful of methods which you can apply to a row which will be explained below.
|
### Row Merge
|
||||||
|
|
||||||
|
When cell rows are merged, it counts as multiple rows, so be sure to remove excess cells. It is similar to how HTML's `rowspan` works.
|
||||||
|
https://www.w3schools.com/tags/att_td_rowspan.asp
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
table.getRow([ROW INDEX]);
|
const cell = new TableCell({
|
||||||
```
|
...,
|
||||||
|
rowSpan: [NUMBER_OF_CELLS_TO_MERGE],
|
||||||
## Merge cells together
|
});
|
||||||
|
|
||||||
### Merging on a row
|
|
||||||
|
|
||||||
First obtain the row, and call `mergeCells()`. The first argument is where the merge should start. The second argument is where the merge should end.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
table.getRow(0).mergeCells([FROM INDEX], [TO INDEX]);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
This will merge 3 cells together starting from index `0`:
|
The example will merge three rows together.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
table.getRow(0).mergeCells(0, 2);
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
|
rowSpan: 3,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Merging on a column
|
### Column Merge
|
||||||
|
|
||||||
It has not been implemented yet, but it will follow a similar structure as merging a row.
|
When cell columns are merged, it counts as multiple columns, so be sure to remove excess cells. It is similar to how HTML's `colspan` works.
|
||||||
|
https://www.w3schools.com/tags/att_td_colspan.asp
|
||||||
## Nested Tables
|
|
||||||
|
|
||||||
To have a table within a table
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
cell.add(new Table(1, 1));
|
const cell = new TableCell({
|
||||||
|
...,
|
||||||
|
columnSpan: [NUMBER_OF_CELLS_TO_MERGE],
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pagination
|
#### Example
|
||||||
|
|
||||||
###Prevent row pagination
|
The example will merge three columns together.
|
||||||
To prevent breaking contents of a row across multiple pages, call `cantSplit()`:
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
table.getRow(0).setCantSplit();
|
const cell = new TableCell({
|
||||||
```
|
...,
|
||||||
|
columnSpan: 3,
|
||||||
###Repeat row
|
});
|
||||||
If a table is paginated on multiple pages, it is possible to repeat a row at the top of each new page calling `setTableHeader()`:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
table.getRow(0).setTableHeader();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo4.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/4-basic-table.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo4.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/4-basic-table.ts_
|
||||||
|
|
||||||
### Custom borders
|
### Custom borders
|
||||||
|
|
||||||
Example showing how to add colourful borders to tables
|
Example showing how to add colourful borders to tables
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo20.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/20-table-cell-borders.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo20.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/20-table-cell-borders.ts_
|
||||||
|
|
||||||
### Adding images
|
### Adding images
|
||||||
|
|
||||||
Example showing how to add images to tables
|
Example showing how to add images to tables
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo24.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/24-images-to-table-cell.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo24.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/24-images-to-table-cell.ts_
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo36.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/36-image-to-table-cell.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo36.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/36-image-to-table-cell.ts_
|
||||||
|
|
||||||
### Alignment of text in a cell
|
### Alignment of text in a cell
|
||||||
|
|
||||||
Example showing how align text in a table cell
|
Example showing how align text in a table cell
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo31.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/31-tables.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo31.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/31-tables.ts_
|
||||||
|
|
||||||
### Merging rows
|
### Shading
|
||||||
|
|
||||||
Example showing merging of `rows`
|
Example showing merging of columns and rows and shading
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo32.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/32-merge-and-shade-table-cells.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo32.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/32-merge-and-shade-table-cells.ts_
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo41.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/41-merge-table-cells-2.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo41.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/41-merge-table-cells-2.ts_
|
||||||
|
|
||||||
### Merging columns
|
### Merging columns
|
||||||
|
|
||||||
Example showing merging of `columns`
|
Example showing merging of columns and rows
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo43.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/43-images-to-table-cell-2.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo43.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/43-images-to-table-cell-2.ts_
|
||||||
|
|
||||||
### Floating tables
|
### Floating tables
|
||||||
|
|
||||||
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/demo34.ts ":include")
|
[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/34-floating-tables.ts ':include')
|
||||||
|
|
||||||
_Source: https://github.com/dolanmiu/docx/blob/master/demo/demo34.ts_
|
_Source: https://github.com/dolanmiu/docx/blob/master/demo/34-floating-tables.ts_
|
||||||
|
@ -68,40 +68,87 @@ const text = new TextRun({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Emphasis Mark
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const text = new TextRun({
|
||||||
|
text: "and then emphasis mark",
|
||||||
|
emphasisMark: {},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shading and Highlighting
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const text = new TextRun({
|
||||||
|
text: "shading",
|
||||||
|
shading: {
|
||||||
|
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
|
||||||
|
color: "00FFFF",
|
||||||
|
fill: "FF0000",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const text = new TextRun({
|
||||||
|
text: "highlighting",
|
||||||
|
highlight: "yellow",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### Strike through
|
### Strike through
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.strike();
|
const text = new TextRun({
|
||||||
|
text: "strike",
|
||||||
|
strike: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Double strike through
|
### Double strike through
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.doubleStrike();
|
const text = new TextRun({
|
||||||
|
text: "doubleStrike",
|
||||||
|
doubleStrike: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Superscript
|
### Superscript
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.superScript();
|
const text = new TextRun({
|
||||||
|
text: "superScript",
|
||||||
|
superScript: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Subscript
|
### Subscript
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.subScript();
|
const text = new TextRun({
|
||||||
|
text: "subScript",
|
||||||
|
subScript: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### All Capitals
|
### All Capitals
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.allCaps();
|
const text = new TextRun({
|
||||||
|
text: "allCaps",
|
||||||
|
allCaps: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Small Capitals
|
### Small Capitals
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.smallCaps();
|
const text = new TextRun({
|
||||||
|
text: "smallCaps",
|
||||||
|
smallCaps: true,
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Break
|
## Break
|
||||||
@ -109,13 +156,8 @@ text.smallCaps();
|
|||||||
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
Sometimes you would want to put text underneath another line of text but inside the same paragraph.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
text.break();
|
const text = new TextRun({
|
||||||
```
|
text: "break",
|
||||||
|
break: true,
|
||||||
## Chaining
|
});
|
||||||
|
|
||||||
What if you want to create a paragraph which is **_bold_** and **_italic_**?
|
|
||||||
|
|
||||||
```ts
|
|
||||||
paragraph.bold().italics();
|
|
||||||
```
|
```
|
||||||
|
9218
package-lock.json
generated
Normal file
9218
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
package.json
31
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "docx",
|
"name": "docx",
|
||||||
"version": "5.0.0-rc5",
|
"version": "5.4.1",
|
||||||
"description": "Generate .docx documents with JavaScript (formerly Office-Clippy)",
|
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"pretest": "rimraf ./build",
|
"pretest": "rimraf ./build",
|
||||||
@ -50,7 +50,9 @@
|
|||||||
"types": "./build/index.d.ts",
|
"types": "./build/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/jszip": "^3.1.4",
|
"@types/jszip": "^3.1.4",
|
||||||
|
"@types/node": "^14.0.5",
|
||||||
"jszip": "^3.1.5",
|
"jszip": "^3.1.5",
|
||||||
|
"shortid": "^2.2.15",
|
||||||
"xml": "^1.0.1",
|
"xml": "^1.0.1",
|
||||||
"xml-js": "^1.6.8"
|
"xml-js": "^1.6.8"
|
||||||
},
|
},
|
||||||
@ -62,9 +64,10 @@
|
|||||||
"homepage": "https://github.com/dolanmiu/docx#readme",
|
"homepage": "https://github.com/dolanmiu/docx#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^3.4.35",
|
"@types/chai": "^3.4.35",
|
||||||
"@types/mocha": "^2.2.39",
|
"@types/mocha": "^8.0.0",
|
||||||
"@types/request-promise": "^4.1.42",
|
"@types/request-promise": "^4.1.42",
|
||||||
"@types/sinon": "^4.3.1",
|
"@types/shortid": "0.0.29",
|
||||||
|
"@types/sinon": "^9.0.4",
|
||||||
"@types/webpack": "^4.4.24",
|
"@types/webpack": "^4.4.24",
|
||||||
"awesome-typescript-loader": "^3.4.1",
|
"awesome-typescript-loader": "^3.4.1",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
@ -74,24 +77,24 @@
|
|||||||
"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",
|
"nyc": "^15.1.0",
|
||||||
"pre-commit": "^1.2.2",
|
"pre-commit": "^1.2.2",
|
||||||
"prettier": "^1.15.2",
|
"prettier": "^2.1.2",
|
||||||
"prompt": "^1.0.0",
|
"prompt": "^1.0.0",
|
||||||
"replace-in-file": "^3.1.0",
|
"replace-in-file": "^3.1.0",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"rimraf": "^2.5.2",
|
"rimraf": "^3.0.2",
|
||||||
"shelljs": "^0.7.7",
|
"shelljs": "^0.8.4",
|
||||||
"sinon": "^5.0.7",
|
"sinon": "^9.0.2",
|
||||||
"ts-node": "^7.0.1",
|
"ts-node": "^9.0.0",
|
||||||
"tslint": "^5.11.0",
|
"tslint": "^6.1.3",
|
||||||
"tslint-immutable": "^4.9.0",
|
"tslint-immutable": "^6.0.1",
|
||||||
"typedoc": "^0.11.1",
|
"typedoc": "^0.16.11",
|
||||||
"typescript": "2.9.2",
|
"typescript": "2.9.2",
|
||||||
"webpack": "^3.10.0"
|
"webpack": "^3.10.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { assert, expect } from "chai";
|
import { assert, expect } from "chai";
|
||||||
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
import { Formatter } from "export/formatter";
|
import { Formatter } from "export/formatter";
|
||||||
import * as file from "file";
|
import { Paragraph, TextRun } from "file";
|
||||||
import { CoreProperties } from "file/core-properties";
|
import { CoreProperties } from "file/core-properties";
|
||||||
import { Attributes } from "file/xml-components";
|
import { Attributes } from "file/xml-components";
|
||||||
|
|
||||||
@ -14,28 +15,65 @@ describe("Formatter", () => {
|
|||||||
|
|
||||||
describe("#format()", () => {
|
describe("#format()", () => {
|
||||||
it("should format simple paragraph", () => {
|
it("should format simple paragraph", () => {
|
||||||
const paragraph = new file.Paragraph("");
|
const paragraph = new Paragraph("");
|
||||||
const newJson = formatter.format(paragraph);
|
const newJson = formatter.format(paragraph);
|
||||||
assert.isDefined(newJson["w:p"]);
|
assert.isDefined(newJson["w:p"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should remove xmlKeys", () => {
|
it("should remove xmlKeys", () => {
|
||||||
const paragraph = new file.Paragraph("");
|
const paragraph = new Paragraph("");
|
||||||
const newJson = formatter.format(paragraph);
|
const newJson = formatter.format(paragraph);
|
||||||
const stringifiedJson = JSON.stringify(newJson);
|
const stringifiedJson = JSON.stringify(newJson);
|
||||||
assert(stringifiedJson.indexOf("xmlKeys") < 0);
|
assert(stringifiedJson.indexOf("xmlKeys") < 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should format simple paragraph with bold text", () => {
|
it("should format simple paragraph with bold text", () => {
|
||||||
const paragraph = new file.Paragraph("");
|
const paragraph = new Paragraph({
|
||||||
paragraph.addRun(
|
children: [
|
||||||
new file.TextRun({
|
new TextRun({
|
||||||
text: "test",
|
text: "test",
|
||||||
bold: true,
|
bold: true,
|
||||||
}),
|
}),
|
||||||
);
|
],
|
||||||
const newJson = formatter.format(paragraph);
|
});
|
||||||
assert.isDefined(newJson["w:p"][1]["w:r"][0]["w:rPr"][0]["w:b"]._attr["w:val"]);
|
|
||||||
|
const tree = formatter.format(paragraph);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:p": [
|
||||||
|
{
|
||||||
|
"w:r": [
|
||||||
|
{
|
||||||
|
"w:rPr": [
|
||||||
|
{
|
||||||
|
"w:b": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:bCs": {
|
||||||
|
_attr: {
|
||||||
|
"w:val": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"w:t": [
|
||||||
|
{
|
||||||
|
_attr: {
|
||||||
|
"xml:space": "preserve",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"test",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should format attributes (rsidSect)", () => {
|
it("should format attributes (rsidSect)", () => {
|
||||||
@ -63,7 +101,7 @@ describe("Formatter", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should should change 'p' tag into 'w:p' tag", () => {
|
it("should should change 'p' tag into 'w:p' tag", () => {
|
||||||
const paragraph = new file.Paragraph("");
|
const paragraph = new Paragraph("");
|
||||||
const newJson = formatter.format(paragraph);
|
const newJson = formatter.format(paragraph);
|
||||||
assert.isDefined(newJson["w:p"]);
|
assert.isDefined(newJson["w:p"]);
|
||||||
});
|
});
|
||||||
@ -76,5 +114,13 @@ describe("Formatter", () => {
|
|||||||
const newJson = formatter.format(properties);
|
const newJson = formatter.format(properties);
|
||||||
assert.isDefined(newJson["cp:coreProperties"]);
|
assert.isDefined(newJson["cp:coreProperties"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should call the prep method only once", () => {
|
||||||
|
const paragraph = new Paragraph("");
|
||||||
|
const spy = sinon.spy(paragraph, "prepForXml");
|
||||||
|
|
||||||
|
formatter.format(paragraph);
|
||||||
|
expect(spy.calledOnce).to.equal(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
|
import { BaseXmlComponent, IXmlableObject } from "file/xml-components";
|
||||||
|
import { File } from "../file";
|
||||||
|
|
||||||
export class Formatter {
|
export class Formatter {
|
||||||
public format(input: BaseXmlComponent): IXmlableObject {
|
public format(input: BaseXmlComponent, file?: File): IXmlableObject {
|
||||||
const output = input.prepForXml();
|
const output = input.prepForXml(file);
|
||||||
|
|
||||||
if (output) {
|
if (output) {
|
||||||
return output;
|
return output;
|
||||||
|
@ -5,7 +5,7 @@ export class ImageReplacer {
|
|||||||
let currentXmlData = xmlData;
|
let currentXmlData = xmlData;
|
||||||
|
|
||||||
mediaData.forEach((image, i) => {
|
mediaData.forEach((image, i) => {
|
||||||
currentXmlData = currentXmlData.replace(`{${image.fileName}}`, (offset + i).toString());
|
currentXmlData = currentXmlData.replace(new RegExp(`{${image.fileName}}`, "g"), (offset + i).toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
return currentXmlData;
|
return currentXmlData;
|
||||||
|
@ -1,7 +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 * as sinon from "sinon";
|
||||||
|
|
||||||
import { File, Footer, Header } from "file";
|
import { File, Footer, Header, Paragraph } from "file";
|
||||||
|
|
||||||
import { Compiler } from "./next-compiler";
|
import { Compiler } from "./next-compiler";
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ describe("Compiler", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("#compile()", () => {
|
describe("#compile()", () => {
|
||||||
it("should pack all the content", async function() {
|
it("should pack all the content", async function () {
|
||||||
this.timeout(99999999);
|
this.timeout(99999999);
|
||||||
const zipFile = compiler.compile(file);
|
const zipFile = compiler.compile(file);
|
||||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||||
@ -34,7 +35,7 @@ describe("Compiler", () => {
|
|||||||
expect(fileNames).to.include("_rels/.rels");
|
expect(fileNames).to.include("_rels/.rels");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should pack all additional headers and footers", async function() {
|
it("should pack all additional headers and footers", async function () {
|
||||||
file.addSection({
|
file.addSection({
|
||||||
headers: {
|
headers: {
|
||||||
default: new Header(),
|
default: new Header(),
|
||||||
@ -72,5 +73,22 @@ describe("Compiler", () => {
|
|||||||
expect(fileNames).to.include("word/footer2.xml");
|
expect(fileNames).to.include("word/footer2.xml");
|
||||||
expect(fileNames).to.include("word/_rels/footer2.xml.rels");
|
expect(fileNames).to.include("word/_rels/footer2.xml.rels");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should call the format method X times equalling X files to be formatted", () => {
|
||||||
|
// This test is required because before, there was a case where Document was formatted twice, which was inefficient
|
||||||
|
// This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
|
||||||
|
const paragraph = new Paragraph("");
|
||||||
|
const doc = new File();
|
||||||
|
|
||||||
|
doc.addSection({
|
||||||
|
properties: {},
|
||||||
|
children: [paragraph],
|
||||||
|
});
|
||||||
|
// tslint:disable-next-line: no-string-literal
|
||||||
|
const spy = sinon.spy(compiler["formatter"], "format");
|
||||||
|
|
||||||
|
compiler.compile(file);
|
||||||
|
expect(spy.callCount).to.equal(10);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,7 @@ import * as xml from "xml";
|
|||||||
import { File } from "file";
|
import { File } from "file";
|
||||||
import { Formatter } from "../formatter";
|
import { Formatter } from "../formatter";
|
||||||
import { ImageReplacer } from "./image-replacer";
|
import { ImageReplacer } from "./image-replacer";
|
||||||
|
import { NumberingReplacer } from "./numbering-replacer";
|
||||||
|
|
||||||
interface IXmlifyedFile {
|
interface IXmlifyedFile {
|
||||||
readonly data: string;
|
readonly data: string;
|
||||||
@ -30,10 +31,12 @@ interface IXmlifyedFileMapping {
|
|||||||
export class Compiler {
|
export class Compiler {
|
||||||
private readonly formatter: Formatter;
|
private readonly formatter: Formatter;
|
||||||
private readonly imageReplacer: ImageReplacer;
|
private readonly imageReplacer: ImageReplacer;
|
||||||
|
private readonly numberingReplacer: NumberingReplacer;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.formatter = new Formatter();
|
this.formatter = new Formatter();
|
||||||
this.imageReplacer = new ImageReplacer();
|
this.imageReplacer = new ImageReplacer();
|
||||||
|
this.numberingReplacer = new NumberingReplacer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public compile(file: File, prettifyXml?: boolean): JSZip {
|
public compile(file: File, prettifyXml?: boolean): JSZip {
|
||||||
@ -68,13 +71,13 @@ export class Compiler {
|
|||||||
file.verifyUpdateFields();
|
file.verifyUpdateFields();
|
||||||
const documentRelationshipCount = file.DocumentRelationships.RelationshipCount + 1;
|
const documentRelationshipCount = file.DocumentRelationships.RelationshipCount + 1;
|
||||||
|
|
||||||
|
const documentXmlData = xml(this.formatter.format(file.Document, file), prettify);
|
||||||
|
const documentMediaDatas = this.imageReplacer.getMediaData(documentXmlData, file.Media);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Relationships: {
|
Relationships: {
|
||||||
data: (() => {
|
data: (() => {
|
||||||
const xmlData = xml(this.formatter.format(file.Document), prettify);
|
documentMediaDatas.forEach((mediaData, i) => {
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
|
||||||
|
|
||||||
mediaDatas.forEach((mediaData, i) => {
|
|
||||||
file.DocumentRelationships.createRelationship(
|
file.DocumentRelationships.createRelationship(
|
||||||
documentRelationshipCount + i,
|
documentRelationshipCount + i,
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||||
@ -82,26 +85,25 @@ export class Compiler {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return xml(this.formatter.format(file.DocumentRelationships), prettify);
|
return xml(this.formatter.format(file.DocumentRelationships, file), prettify);
|
||||||
})(),
|
})(),
|
||||||
path: "word/_rels/document.xml.rels",
|
path: "word/_rels/document.xml.rels",
|
||||||
},
|
},
|
||||||
Document: {
|
Document: {
|
||||||
data: (() => {
|
data: (() => {
|
||||||
const tempXmlData = xml(this.formatter.format(file.Document), prettify);
|
const xmlData = this.imageReplacer.replace(documentXmlData, documentMediaDatas, documentRelationshipCount);
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
|
const referenedXmlData = this.numberingReplacer.replace(xmlData, file.Numbering.ConcreteNumbering);
|
||||||
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, documentRelationshipCount);
|
|
||||||
|
|
||||||
return xmlData;
|
return referenedXmlData;
|
||||||
})(),
|
})(),
|
||||||
path: "word/document.xml",
|
path: "word/document.xml",
|
||||||
},
|
},
|
||||||
Styles: {
|
Styles: {
|
||||||
data: xml(this.formatter.format(file.Styles), prettify),
|
data: xml(this.formatter.format(file.Styles, file), prettify),
|
||||||
path: "word/styles.xml",
|
path: "word/styles.xml",
|
||||||
},
|
},
|
||||||
Properties: {
|
Properties: {
|
||||||
data: xml(this.formatter.format(file.CoreProperties), {
|
data: xml(this.formatter.format(file.CoreProperties, file), {
|
||||||
declaration: {
|
declaration: {
|
||||||
standalone: "yes",
|
standalone: "yes",
|
||||||
encoding: "UTF-8",
|
encoding: "UTF-8",
|
||||||
@ -110,15 +112,15 @@ export class Compiler {
|
|||||||
path: "docProps/core.xml",
|
path: "docProps/core.xml",
|
||||||
},
|
},
|
||||||
Numbering: {
|
Numbering: {
|
||||||
data: xml(this.formatter.format(file.Numbering), prettify),
|
data: xml(this.formatter.format(file.Numbering, file), prettify),
|
||||||
path: "word/numbering.xml",
|
path: "word/numbering.xml",
|
||||||
},
|
},
|
||||||
FileRelationships: {
|
FileRelationships: {
|
||||||
data: xml(this.formatter.format(file.FileRelationships), prettify),
|
data: xml(this.formatter.format(file.FileRelationships, file), prettify),
|
||||||
path: "_rels/.rels",
|
path: "_rels/.rels",
|
||||||
},
|
},
|
||||||
HeaderRelationships: file.Headers.map((headerWrapper, index) => {
|
HeaderRelationships: file.Headers.map((headerWrapper, index) => {
|
||||||
const xmlData = xml(this.formatter.format(headerWrapper.Header), prettify);
|
const xmlData = xml(this.formatter.format(headerWrapper.Header, file), prettify);
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
||||||
|
|
||||||
mediaDatas.forEach((mediaData, i) => {
|
mediaDatas.forEach((mediaData, i) => {
|
||||||
@ -130,12 +132,12 @@ export class Compiler {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: xml(this.formatter.format(headerWrapper.Relationships), prettify),
|
data: xml(this.formatter.format(headerWrapper.Relationships, file), prettify),
|
||||||
path: `word/_rels/header${index + 1}.xml.rels`,
|
path: `word/_rels/header${index + 1}.xml.rels`,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
FooterRelationships: file.Footers.map((footerWrapper, index) => {
|
FooterRelationships: file.Footers.map((footerWrapper, index) => {
|
||||||
const xmlData = xml(this.formatter.format(footerWrapper.Footer), prettify);
|
const xmlData = xml(this.formatter.format(footerWrapper.Footer, file), prettify);
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
const mediaDatas = this.imageReplacer.getMediaData(xmlData, file.Media);
|
||||||
|
|
||||||
mediaDatas.forEach((mediaData, i) => {
|
mediaDatas.forEach((mediaData, i) => {
|
||||||
@ -147,12 +149,12 @@ export class Compiler {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: xml(this.formatter.format(footerWrapper.Relationships), prettify),
|
data: xml(this.formatter.format(footerWrapper.Relationships, file), prettify),
|
||||||
path: `word/_rels/footer${index + 1}.xml.rels`,
|
path: `word/_rels/footer${index + 1}.xml.rels`,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
Headers: file.Headers.map((headerWrapper, index) => {
|
Headers: file.Headers.map((headerWrapper, index) => {
|
||||||
const tempXmlData = xml(this.formatter.format(headerWrapper.Header), prettify);
|
const tempXmlData = xml(this.formatter.format(headerWrapper.Header, file), prettify);
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
|
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
|
||||||
// TODO: 0 needs to be changed when headers get relationships of their own
|
// TODO: 0 needs to be changed when headers get relationships of their own
|
||||||
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);
|
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);
|
||||||
@ -163,7 +165,7 @@ export class Compiler {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
Footers: file.Footers.map((footerWrapper, index) => {
|
Footers: file.Footers.map((footerWrapper, index) => {
|
||||||
const tempXmlData = xml(this.formatter.format(footerWrapper.Footer), prettify);
|
const tempXmlData = xml(this.formatter.format(footerWrapper.Footer, file), prettify);
|
||||||
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
|
const mediaDatas = this.imageReplacer.getMediaData(tempXmlData, file.Media);
|
||||||
// TODO: 0 needs to be changed when headers get relationships of their own
|
// TODO: 0 needs to be changed when headers get relationships of their own
|
||||||
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);
|
const xmlData = this.imageReplacer.replace(tempXmlData, mediaDatas, 0);
|
||||||
@ -174,19 +176,19 @@ export class Compiler {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
ContentTypes: {
|
ContentTypes: {
|
||||||
data: xml(this.formatter.format(file.ContentTypes), prettify),
|
data: xml(this.formatter.format(file.ContentTypes, file), prettify),
|
||||||
path: "[Content_Types].xml",
|
path: "[Content_Types].xml",
|
||||||
},
|
},
|
||||||
AppProperties: {
|
AppProperties: {
|
||||||
data: xml(this.formatter.format(file.AppProperties), prettify),
|
data: xml(this.formatter.format(file.AppProperties, file), prettify),
|
||||||
path: "docProps/app.xml",
|
path: "docProps/app.xml",
|
||||||
},
|
},
|
||||||
FootNotes: {
|
FootNotes: {
|
||||||
data: xml(this.formatter.format(file.FootNotes), prettify),
|
data: xml(this.formatter.format(file.FootNotes, file), prettify),
|
||||||
path: "word/footnotes.xml",
|
path: "word/footnotes.xml",
|
||||||
},
|
},
|
||||||
Settings: {
|
Settings: {
|
||||||
data: xml(this.formatter.format(file.Settings), prettify),
|
data: xml(this.formatter.format(file.Settings, file), prettify),
|
||||||
path: "word/settings.xml",
|
path: "word/settings.xml",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
17
src/export/packer/numbering-replacer.ts
Normal file
17
src/export/packer/numbering-replacer.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { ConcreteNumbering } from "file";
|
||||||
|
|
||||||
|
export class NumberingReplacer {
|
||||||
|
public replace(xmlData: string, concreteNumberings: ConcreteNumbering[]): string {
|
||||||
|
let currentXmlData = xmlData;
|
||||||
|
|
||||||
|
for (const concreteNumbering of concreteNumberings) {
|
||||||
|
if (!concreteNumbering.reference) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentXmlData = currentXmlData.replace(new RegExp(`{${concreteNumbering.reference}}`, "g"), concreteNumbering.id.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentXmlData;
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ describe("Packer", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("#toBuffer()", () => {
|
describe("#toBuffer()", () => {
|
||||||
it("should create a standard docx file", async function() {
|
it("should create a standard docx file", async function () {
|
||||||
this.timeout(99999999);
|
this.timeout(99999999);
|
||||||
const buffer = await Packer.toBuffer(file);
|
const buffer = await Packer.toBuffer(file);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ describe("Packer", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("#toBase64String()", () => {
|
describe("#toBase64String()", () => {
|
||||||
it("should create a standard docx file", async function() {
|
it("should create a standard docx file", async function () {
|
||||||
this.timeout(99999999);
|
this.timeout(99999999);
|
||||||
const str = await Packer.toBase64String(file);
|
const str = await Packer.toBase64String(file);
|
||||||
|
|
||||||
|
@ -4,30 +4,33 @@ import { Compiler } from "./next-compiler";
|
|||||||
export class Packer {
|
export class Packer {
|
||||||
public static async toBuffer(file: File, prettify?: boolean): Promise<Buffer> {
|
public static async toBuffer(file: File, prettify?: boolean): Promise<Buffer> {
|
||||||
const zip = this.compiler.compile(file, prettify);
|
const zip = this.compiler.compile(file, prettify);
|
||||||
const zipData = (await zip.generateAsync({
|
const zipData = await zip.generateAsync({
|
||||||
type: "nodebuffer",
|
type: "nodebuffer",
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
})) as Buffer;
|
compression: "DEFLATE",
|
||||||
|
});
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async toBase64String(file: File, prettify?: boolean): Promise<string> {
|
public static async toBase64String(file: File, prettify?: boolean): Promise<string> {
|
||||||
const zip = this.compiler.compile(file, prettify);
|
const zip = this.compiler.compile(file, prettify);
|
||||||
const zipData = (await zip.generateAsync({
|
const zipData = await zip.generateAsync({
|
||||||
type: "base64",
|
type: "base64",
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
})) as string;
|
compression: "DEFLATE",
|
||||||
|
});
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async toBlob(file: File, prettify?: boolean): Promise<Blob> {
|
public static async toBlob(file: File, prettify?: boolean): Promise<Blob> {
|
||||||
const zip = this.compiler.compile(file, prettify);
|
const zip = this.compiler.compile(file, prettify);
|
||||||
const zipData = (await zip.generateAsync({
|
const zipData = await zip.generateAsync({
|
||||||
type: "blob",
|
type: "blob",
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
})) as Blob;
|
compression: "DEFLATE",
|
||||||
|
});
|
||||||
|
|
||||||
return zipData;
|
return zipData;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,23 @@
|
|||||||
import { XmlComponent } from "file/xml-components";
|
import { XmlComponent } from "file/xml-components";
|
||||||
|
import { IDocumentBackgroundOptions } from "../document";
|
||||||
|
|
||||||
import { DocumentAttributes } from "../document/document-attributes";
|
import { DocumentAttributes } from "../document/document-attributes";
|
||||||
|
import { INumberingOptions } from "../numbering";
|
||||||
|
import { HyperlinkType, Paragraph } from "../paragraph";
|
||||||
|
import { IStylesOptions } from "../styles";
|
||||||
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 IInternalHyperlinkDefinition {
|
||||||
|
readonly text: string;
|
||||||
|
readonly type: HyperlinkType.INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IExternalHyperlinkDefinition {
|
||||||
|
readonly link: string;
|
||||||
|
readonly text: string;
|
||||||
|
readonly type: HyperlinkType.EXTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPropertiesOptions {
|
export interface IPropertiesOptions {
|
||||||
readonly title?: string;
|
readonly title?: string;
|
||||||
readonly subject?: string;
|
readonly subject?: string;
|
||||||
@ -11,6 +27,16 @@ export interface IPropertiesOptions {
|
|||||||
readonly lastModifiedBy?: string;
|
readonly lastModifiedBy?: string;
|
||||||
readonly revision?: string;
|
readonly revision?: string;
|
||||||
readonly externalStyles?: string;
|
readonly externalStyles?: string;
|
||||||
|
readonly styles?: IStylesOptions;
|
||||||
|
readonly numbering?: INumberingOptions;
|
||||||
|
readonly footnotes?: Paragraph[];
|
||||||
|
readonly hyperlinks?: {
|
||||||
|
readonly [key: string]: IInternalHyperlinkDefinition | IExternalHyperlinkDefinition;
|
||||||
|
};
|
||||||
|
readonly background?: IDocumentBackgroundOptions;
|
||||||
|
readonly features?: {
|
||||||
|
readonly trackRevisions?: boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CoreProperties extends XmlComponent {
|
export class CoreProperties extends XmlComponent {
|
||||||
|
@ -22,9 +22,6 @@ describe("Body", () => {
|
|||||||
|
|
||||||
expect(tree).to.deep.equal({
|
expect(tree).to.deep.equal({
|
||||||
"w:body": [
|
"w:body": [
|
||||||
{
|
|
||||||
"w:p": {},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"w:sectPr": [
|
"w:sectPr": [
|
||||||
{ "w:pgSz": { _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } } },
|
{ "w:pgSz": { _attr: { "w:w": 10000, "w:h": 10000, "w:orient": "portrait" } } },
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { IXmlableObject, XmlComponent } from "file/xml-components";
|
import { IXmlableObject, XmlComponent } from "file/xml-components";
|
||||||
import { Paragraph, ParagraphProperties, TableOfContents } from "../..";
|
import { Paragraph, ParagraphProperties, TableOfContents } from "../..";
|
||||||
|
import { File } from "../../../file";
|
||||||
import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties";
|
import { SectionProperties, SectionPropertiesOptions } from "./section-properties/section-properties";
|
||||||
|
|
||||||
export class Body extends XmlComponent {
|
export class Body extends XmlComponent {
|
||||||
@ -24,12 +25,13 @@ export class Body extends XmlComponent {
|
|||||||
this.sections.push(new SectionProperties(options));
|
this.sections.push(new SectionProperties(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepForXml(): IXmlableObject | undefined {
|
public prepForXml(file?: File): IXmlableObject | undefined {
|
||||||
if (this.sections.length === 1) {
|
if (this.sections.length === 1) {
|
||||||
|
this.root.splice(0, 1);
|
||||||
this.root.push(this.sections.pop() as SectionProperties);
|
this.root.push(this.sections.pop() as SectionProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.prepForXml();
|
return super.prepForXml(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public push(component: XmlComponent): void {
|
public push(component: XmlComponent): void {
|
||||||
@ -43,7 +45,7 @@ export class Body extends XmlComponent {
|
|||||||
private createSectionParagraph(section: SectionProperties): Paragraph {
|
private createSectionParagraph(section: SectionProperties): Paragraph {
|
||||||
const paragraph = new Paragraph({});
|
const paragraph = new Paragraph({});
|
||||||
const properties = new ParagraphProperties({});
|
const properties = new ParagraphProperties({});
|
||||||
properties.addChildElement(section);
|
properties.push(section);
|
||||||
paragraph.addChildElement(properties);
|
paragraph.addChildElement(properties);
|
||||||
return paragraph;
|
return paragraph;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
import { FooterReference } from "./footer-reference";
|
||||||
|
import { FooterReferenceType } from "./footer-reference-attributes";
|
||||||
|
|
||||||
|
describe("footerReference", () => {
|
||||||
|
it("should create", () => {
|
||||||
|
const footer = new FooterReference({
|
||||||
|
footerType: FooterReferenceType.DEFAULT,
|
||||||
|
footerId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(footer);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:footerReference": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"w:type": "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create without a footer type", () => {
|
||||||
|
const footer = new FooterReference({
|
||||||
|
footerId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(footer);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:footerReference": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"w:type": "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,42 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
import { HeaderReference } from "./header-reference";
|
||||||
|
import { HeaderReferenceType } from "./header-reference-attributes";
|
||||||
|
|
||||||
|
describe("HeaderReference", () => {
|
||||||
|
it("should create", () => {
|
||||||
|
const footer = new HeaderReference({
|
||||||
|
headerType: HeaderReferenceType.DEFAULT,
|
||||||
|
headerId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(footer);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:headerReference": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"w:type": "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create without a header type", () => {
|
||||||
|
const footer = new HeaderReference({
|
||||||
|
headerId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tree = new Formatter().format(footer);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:headerReference": {
|
||||||
|
_attr: {
|
||||||
|
"r:id": "rId1",
|
||||||
|
"w:type": "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -5,3 +5,4 @@ export * from "./page-size";
|
|||||||
export * from "./page-number";
|
export * from "./page-number";
|
||||||
export * from "./page-border";
|
export * from "./page-border";
|
||||||
export * from "./line-number";
|
export * from "./line-number";
|
||||||
|
export * from "./vertical-align";
|
||||||
|
@ -14,6 +14,7 @@ export enum PageNumberFormat {
|
|||||||
ORDINAL_TEXT = "ordinalText",
|
ORDINAL_TEXT = "ordinalText",
|
||||||
UPPER_LETTER = "upperLetter",
|
UPPER_LETTER = "upperLetter",
|
||||||
UPPER_ROMAN = "upperRoman",
|
UPPER_ROMAN = "upperRoman",
|
||||||
|
DECIMAL_FULL_WIDTH = "decimalFullWidth",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPageNumberTypeAttributes {
|
export interface IPageNumberTypeAttributes {
|
||||||
|
@ -8,6 +8,7 @@ import { Media } from "file/media";
|
|||||||
import { PageBorderOffsetFrom } from "./page-border";
|
import { PageBorderOffsetFrom } from "./page-border";
|
||||||
import { PageNumberFormat } from "./page-number";
|
import { PageNumberFormat } from "./page-number";
|
||||||
import { SectionProperties } from "./section-properties";
|
import { SectionProperties } from "./section-properties";
|
||||||
|
import { SectionVerticalAlignValue } from "./vertical-align";
|
||||||
|
|
||||||
describe("SectionProperties", () => {
|
describe("SectionProperties", () => {
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -38,6 +39,8 @@ describe("SectionProperties", () => {
|
|||||||
},
|
},
|
||||||
pageNumberStart: 10,
|
pageNumberStart: 10,
|
||||||
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,
|
pageNumberFormatType: PageNumberFormat.CARDINAL_TEXT,
|
||||||
|
titlePage: true,
|
||||||
|
verticalAlign: SectionVerticalAlignValue.TOP,
|
||||||
});
|
});
|
||||||
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"]);
|
||||||
|
@ -18,6 +18,7 @@ import { IPageNumberTypeAttributes, 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";
|
import { TitlePage } from "./title-page/title-page";
|
||||||
|
import { ISectionVerticalAlignAttributes, SectionVerticalAlign } from "./vertical-align";
|
||||||
|
|
||||||
export interface IHeaderFooterGroup<T> {
|
export interface IHeaderFooterGroup<T> {
|
||||||
readonly default?: T;
|
readonly default?: T;
|
||||||
@ -45,7 +46,8 @@ export type SectionPropertiesOptions = IPageSizeAttributes &
|
|||||||
IPageNumberTypeAttributes &
|
IPageNumberTypeAttributes &
|
||||||
ILineNumberAttributes &
|
ILineNumberAttributes &
|
||||||
IPageBordersOptions &
|
IPageBordersOptions &
|
||||||
ITitlePageOptions & {
|
ITitlePageOptions &
|
||||||
|
ISectionVerticalAlignAttributes & {
|
||||||
readonly column?: {
|
readonly column?: {
|
||||||
readonly space?: number;
|
readonly space?: number;
|
||||||
readonly count?: number;
|
readonly count?: number;
|
||||||
@ -87,6 +89,7 @@ export class SectionProperties extends XmlComponent {
|
|||||||
pageBorderBottom,
|
pageBorderBottom,
|
||||||
pageBorderLeft,
|
pageBorderLeft,
|
||||||
titlePage = false,
|
titlePage = false,
|
||||||
|
verticalAlign,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
@ -121,6 +124,10 @@ export class SectionProperties extends XmlComponent {
|
|||||||
if (titlePage) {
|
if (titlePage) {
|
||||||
this.root.push(new TitlePage());
|
this.root.push(new TitlePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verticalAlign) {
|
||||||
|
this.root.push(new SectionVerticalAlign(verticalAlign));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private addHeaders(headers?: IHeaderFooterGroup<HeaderWrapper>): void {
|
private addHeaders(headers?: IHeaderFooterGroup<HeaderWrapper>): void {
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
export * from "./vertical-align";
|
||||||
|
export * from "./vertical-align-attributes";
|
@ -0,0 +1,12 @@
|
|||||||
|
import { XmlAttributeComponent } from "file/xml-components";
|
||||||
|
import { SectionVerticalAlignValue } from "./vertical-align";
|
||||||
|
|
||||||
|
export interface ISectionVerticalAlignAttributes {
|
||||||
|
readonly verticalAlign?: SectionVerticalAlignValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SectionVerticalAlignAttributes extends XmlAttributeComponent<ISectionVerticalAlignAttributes> {
|
||||||
|
protected readonly xmlKeys = {
|
||||||
|
verticalAlign: "w:val",
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
// http://officeopenxml.com/WPsection.php
|
||||||
|
|
||||||
|
import { XmlComponent } from "file/xml-components";
|
||||||
|
import { SectionVerticalAlignAttributes } from "./vertical-align-attributes";
|
||||||
|
|
||||||
|
export enum SectionVerticalAlignValue {
|
||||||
|
BOTH = "both",
|
||||||
|
BOTTOM = "bottom",
|
||||||
|
CENTER = "center",
|
||||||
|
TOP = "top",
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SectionVerticalAlign extends XmlComponent {
|
||||||
|
constructor(value: SectionVerticalAlignValue) {
|
||||||
|
super("w:vAlign");
|
||||||
|
this.root.push(new SectionVerticalAlignAttributes({ verticalAlign: value }));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
|
import { DocumentBackground } from "./document-background";
|
||||||
|
|
||||||
|
describe("DocumentBackground", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create a DocumentBackground with no options and set color to auto", () => {
|
||||||
|
const documentBackground = new DocumentBackground({});
|
||||||
|
const tree = new Formatter().format(documentBackground);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:background": {
|
||||||
|
_attr: {
|
||||||
|
"w:color": "FFFFFF",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a DocumentBackground with no options and set color to value", () => {
|
||||||
|
const documentBackground = new DocumentBackground({ color: "ffff00" });
|
||||||
|
const tree = new Formatter().format(documentBackground);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:background": {
|
||||||
|
_attr: {
|
||||||
|
"w:color": "ffff00",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create a DocumentBackground with no options and set other values", () => {
|
||||||
|
const documentBackground = new DocumentBackground({
|
||||||
|
color: "ffff00",
|
||||||
|
themeColor: "test",
|
||||||
|
themeShade: "test",
|
||||||
|
themeTint: "test",
|
||||||
|
});
|
||||||
|
const tree = new Formatter().format(documentBackground);
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:background": {
|
||||||
|
_attr: {
|
||||||
|
"w:color": "ffff00",
|
||||||
|
"w:themeColor": "test",
|
||||||
|
"w:themeShade": "test",
|
||||||
|
"w:themeTint": "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
39
src/file/document/document-background/document-background.ts
Normal file
39
src/file/document/document-background/document-background.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// http://officeopenxml.com/WPdocument.php
|
||||||
|
// http://www.datypic.com/sc/ooxml/e-w_background-1.html
|
||||||
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
|
export class DocumentBackgroundAttributes extends XmlAttributeComponent<{
|
||||||
|
readonly color: string;
|
||||||
|
readonly themeColor?: string;
|
||||||
|
readonly themeShade?: string;
|
||||||
|
readonly themeTint?: string;
|
||||||
|
}> {
|
||||||
|
protected readonly xmlKeys = {
|
||||||
|
color: "w:color",
|
||||||
|
themeColor: "w:themeColor",
|
||||||
|
themeShade: "w:themeShade",
|
||||||
|
themeTint: "w:themeTint",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDocumentBackgroundOptions {
|
||||||
|
readonly color?: string;
|
||||||
|
readonly themeColor?: string;
|
||||||
|
readonly themeShade?: string;
|
||||||
|
readonly themeTint?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DocumentBackground extends XmlComponent {
|
||||||
|
constructor(options: IDocumentBackgroundOptions) {
|
||||||
|
super("w:background");
|
||||||
|
|
||||||
|
this.root.push(
|
||||||
|
new DocumentBackgroundAttributes({
|
||||||
|
color: options.color ? options.color : "FFFFFF",
|
||||||
|
themeColor: options.themeColor,
|
||||||
|
themeShade: options.themeShade,
|
||||||
|
themeTint: options.themeTint,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
src/file/document/document-background/index.ts
Normal file
1
src/file/document/document-background/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./document-background";
|
@ -8,7 +8,7 @@ describe("Document", () => {
|
|||||||
let document: Document;
|
let document: Document;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
document = new Document();
|
document = new Document({ background: {} });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#constructor()", () => {
|
describe("#constructor()", () => {
|
||||||
@ -38,6 +38,13 @@ describe("Document", () => {
|
|||||||
"mc:Ignorable": "w14 w15 wp14",
|
"mc:Ignorable": "w14 w15 wp14",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"w:background": {
|
||||||
|
_attr: {
|
||||||
|
"w:color": "FFFFFF",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{ "w:body": {} },
|
{ "w:body": {} },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user