Support page numbers (#714)

* feat: add num pages

* fix: num pages

* rc1

* fix

* fix

* fix
main
bokuweb 2024-06-09 09:01:52 +09:00 committed by GitHub
parent ef068a6348
commit 2626b89b83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 665 additions and 461 deletions

View File

@ -3,16 +3,15 @@ use docx_rs::*;
pub fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./output/examples/header_with_page_num.docx");
let file = std::fs::File::create(path).unwrap();
let header = Header::new()
.add_page_num(
PageNum::new()
.wrap("none")
.v_anchor("text")
.h_anchor("margin")
.x_align("right")
.y(1),
)
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello")));
let header = Header::new().add_paragraph(
Paragraph::new()
.wrap("none")
.v_anchor("text")
.h_anchor("margin")
.x_align("right")
.add_run(Run::new().add_text("Hello"))
.add_page_num(PageNum::new()),
);
Docx::new()
.header(header)
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("World")))

View File

@ -0,0 +1,20 @@
use serde::Serialize;
use crate::documents::*;
#[derive(Serialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub struct InstrNUMPAGES {}
impl InstrNUMPAGES {
pub fn new() -> Self {
Self {}
}
}
impl BuildXML for InstrNUMPAGES {
fn build(&self) -> Vec<u8> {
let instr = "NUMPAGES".to_owned();
instr.into()
}
}

View File

@ -9,6 +9,7 @@ pub enum InstrText {
TOC(InstrToC),
TC(InstrTC),
PAGE(InstrPAGE),
NUMPAGES(InstrNUMPAGES),
PAGEREF(InstrPAGEREF),
HYPERLINK(InstrHyperlink),
Unsupported(String),
@ -21,6 +22,7 @@ impl BuildXML for Box<InstrText> {
InstrText::TC(tc) => tc.build(),
InstrText::PAGEREF(page_ref) => page_ref.build(),
InstrText::PAGE(page) => page.build(),
InstrText::NUMPAGES(page) => page.build(),
InstrText::HYPERLINK(_link) => todo!(),
InstrText::Unsupported(s) => s.as_bytes().to_vec(),
};
@ -62,6 +64,12 @@ impl Serialize for InstrText {
t.serialize_field("data", s)?;
t.end()
}
InstrText::NUMPAGES(ref s) => {
let mut t = serializer.serialize_struct("NUMPAGES", 2)?;
t.serialize_field("type", "numPages")?;
t.serialize_field("data", s)?;
t.end()
}
InstrText::HYPERLINK(ref s) => {
let mut t = serializer.serialize_struct("HYPERLINK", 2)?;
t.serialize_field("type", "hyperlink")?;

View File

@ -40,6 +40,7 @@ mod indent;
mod indent_level;
mod insert;
mod instr_hyperlink;
mod instr_num_pages;
mod instr_page;
mod instr_pageref;
mod instr_tc;
@ -59,6 +60,7 @@ mod link;
mod mc_fallback;
mod name;
mod next;
mod num_pages;
mod number_format;
mod numbering;
mod numbering_id;
@ -172,6 +174,7 @@ pub use indent::*;
pub use indent_level::*;
pub use insert::*;
pub use instr_hyperlink::*;
pub use instr_num_pages::*;
pub use instr_page::*;
pub use instr_pageref::*;
pub use instr_tc::*;
@ -191,6 +194,7 @@ pub use link::*;
pub use mc_fallback::*;
pub use name::*;
pub use next::*;
pub use num_pages::*;
pub use number_format::*;
pub use numbering::*;
pub use numbering_id::*;

View File

@ -0,0 +1,66 @@
use serde::Serialize;
use crate::documents::*;
use crate::types::*;
use crate::xml_builder::*;
#[derive(Serialize, Debug, Clone, PartialEq)]
pub struct NumPages {
pub instr: InstrNUMPAGES,
}
impl Default for NumPages {
fn default() -> Self {
Self {
instr: InstrNUMPAGES {},
}
}
}
impl NumPages {
pub fn new() -> Self {
Self::default()
}
fn inner_build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
let r = Run::new()
.add_field_char(FieldCharType::Begin, false)
.add_instr_text(InstrText::NUMPAGES(self.instr.clone()))
.add_field_char(FieldCharType::Separate, false)
.add_text("1")
.add_field_char(FieldCharType::End, false);
b.add_child(&r).build()
}
}
impl BuildXML for NumPages {
fn build(&self) -> Vec<u8> {
self.inner_build()
}
}
impl BuildXML for Box<NumPages> {
fn build(&self) -> Vec<u8> {
self.inner_build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_num_pages() {
let b = NumPages::new().build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:r><w:rPr /><w:fldChar w:fldCharType="begin" w:dirty="false" /><w:instrText>NUMPAGES</w:instrText><w:fldChar w:fldCharType="separate" w:dirty="false" /><w:t xml:space="preserve">1</w:t><w:fldChar w:fldCharType="end" w:dirty="false" /></w:r>"#
);
}
}

View File

@ -7,18 +7,12 @@ use crate::xml_builder::*;
#[derive(Serialize, Debug, Clone, PartialEq)]
pub struct PageNum {
pub instr: InstrPAGE,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_property: Option<FrameProperty>,
#[serde(skip_serializing_if = "Option::is_none")]
pub paragraph_property: Option<ParagraphProperty>,
}
impl Default for PageNum {
fn default() -> Self {
Self {
instr: InstrPAGE {},
frame_property: None,
paragraph_property: None,
}
}
}
@ -28,140 +22,16 @@ impl PageNum {
Self::default()
}
pub fn wrap(mut self, wrap: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
wrap: Some(wrap.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn v_anchor(mut self, anchor: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
v_anchor: Some(anchor.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn h_anchor(mut self, anchor: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
h_anchor: Some(anchor.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn h_rule(mut self, r: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
h_rule: Some(r.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn x_align(mut self, align: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
x_align: Some(align.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn y_align(mut self, align: impl Into<String>) -> Self {
self.frame_property = Some(FrameProperty {
y_align: Some(align.into()),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.frame_property = Some(FrameProperty {
h_space: Some(x),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.frame_property = Some(FrameProperty {
v_space: Some(x),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn x(mut self, x: i32) -> Self {
self.frame_property = Some(FrameProperty {
x: Some(x),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn y(mut self, y: i32) -> Self {
self.frame_property = Some(FrameProperty {
y: Some(y),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn width(mut self, n: u32) -> Self {
self.frame_property = Some(FrameProperty {
w: Some(n),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn height(mut self, n: u32) -> Self {
self.frame_property = Some(FrameProperty {
h: Some(n),
..self.frame_property.unwrap_or_default()
});
self
}
pub fn align(mut self, alignment_type: AlignmentType) -> Self {
self.paragraph_property = Some(
self.paragraph_property
.unwrap_or_default()
.align(alignment_type),
);
self
}
fn inner_build(&self) -> Vec<u8> {
let p = StructuredDataTagProperty::new();
let mut b = XMLBuilder::new();
let b = XMLBuilder::new();
let r = Run::new()
.add_field_char(FieldCharType::Begin, false)
.add_instr_text(InstrText::PAGE(self.instr.clone()))
.add_field_char(FieldCharType::Separate, false)
.add_text("1")
.add_field_char(FieldCharType::End, false);
b = b
.open_structured_tag()
.add_child(&p)
.open_structured_tag_content();
let mut p = Paragraph::new().add_run(
Run::new()
.add_field_char(FieldCharType::Begin, false)
.add_instr_text(InstrText::PAGE(self.instr.clone()))
.add_field_char(FieldCharType::Separate, false)
.add_text("1")
.add_field_char(FieldCharType::End, false),
);
if let Some(ref pr) = self.paragraph_property {
p.property = pr.clone();
}
if let Some(ref f) = self.frame_property {
p.property.frame_property = Some(f.clone());
}
b = b.add_child(&p);
b = b.close().close();
b.build()
b.add_child(&r).build()
}
}
@ -190,18 +60,7 @@ mod tests {
let b = PageNum::new().build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:sdt><w:sdtPr><w:rPr /></w:sdtPr><w:sdtContent><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType="begin" w:dirty="false" /><w:instrText>PAGE</w:instrText><w:fldChar w:fldCharType="separate" w:dirty="false" /><w:t xml:space="preserve">1</w:t><w:fldChar w:fldCharType="end" w:dirty="false" /></w:r></w:p></w:sdtContent>
</w:sdt>"#
);
}
#[test]
fn test_page_with_wrap() {
let b = PageNum::new().wrap("none").x_align("left").build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:sdt><w:sdtPr><w:rPr /></w:sdtPr><w:sdtContent><w:p w14:paraId="12345678"><w:pPr><w:rPr /><w:framePr w:wrap="none" w:xAlign="left" /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType="begin" w:dirty="false" /><w:instrText>PAGE</w:instrText><w:fldChar w:fldCharType="separate" w:dirty="false" /><w:t xml:space="preserve">1</w:t><w:fldChar w:fldCharType="end" w:dirty="false" /></w:r></w:p></w:sdtContent>
</w:sdt>"#
r#"<w:r><w:rPr /><w:fldChar w:fldCharType="begin" w:dirty="false" /><w:instrText>PAGE</w:instrText><w:fldChar w:fldCharType="separate" w:dirty="false" /><w:t xml:space="preserve">1</w:t><w:fldChar w:fldCharType="end" w:dirty="false" /></w:r>"#
);
}
}

View File

@ -37,6 +37,8 @@ pub enum ParagraphChild {
CommentStart(Box<CommentRangeStart>),
CommentEnd(CommentRangeEnd),
StructuredDataTag(Box<StructuredDataTag>),
PageNum(Box<PageNum>),
NumPages(Box<NumPages>),
}
impl BuildXML for ParagraphChild {
@ -51,6 +53,8 @@ impl BuildXML for ParagraphChild {
ParagraphChild::CommentStart(v) => v.build(),
ParagraphChild::CommentEnd(v) => v.build(),
ParagraphChild::StructuredDataTag(v) => v.build(),
ParagraphChild::PageNum(v) => v.build(),
ParagraphChild::NumPages(v) => v.build(),
}
}
}
@ -115,6 +119,18 @@ impl Serialize for ParagraphChild {
t.serialize_field("data", r)?;
t.end()
}
ParagraphChild::PageNum(ref r) => {
let mut t = serializer.serialize_struct("PageNum", 2)?;
t.serialize_field("type", "pageNum")?;
t.serialize_field("data", r)?;
t.end()
}
ParagraphChild::NumPages(ref r) => {
let mut t = serializer.serialize_struct("NumPages", 2)?;
t.serialize_field("type", "numPages")?;
t.serialize_field("data", r)?;
t.end()
}
}
}
}
@ -357,6 +373,113 @@ impl Paragraph {
}
s
}
pub fn add_page_num(mut self, p: PageNum) -> Self {
self.children.push(ParagraphChild::PageNum(Box::new(p)));
self
}
pub fn add_num_pages(mut self, p: NumPages) -> Self {
self.children.push(ParagraphChild::NumPages(Box::new(p)));
self
}
// frameProperty
pub fn wrap(mut self, wrap: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
wrap: Some(wrap.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn v_anchor(mut self, anchor: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
v_anchor: Some(anchor.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn h_anchor(mut self, anchor: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
h_anchor: Some(anchor.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn h_rule(mut self, r: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
h_rule: Some(r.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn x_align(mut self, align: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
x_align: Some(align.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn y_align(mut self, align: impl Into<String>) -> Self {
self.property.frame_property = Some(FrameProperty {
y_align: Some(align.into()),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.property.frame_property = Some(FrameProperty {
h_space: Some(x),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.property.frame_property = Some(FrameProperty {
v_space: Some(x),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_x(mut self, x: i32) -> Self {
self.property.frame_property = Some(FrameProperty {
x: Some(x),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_y(mut self, y: i32) -> Self {
self.property.frame_property = Some(FrameProperty {
y: Some(y),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_width(mut self, n: u32) -> Self {
self.property.frame_property = Some(FrameProperty {
w: Some(n),
..self.property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_height(mut self, n: u32) -> Self {
self.property.frame_property = Some(FrameProperty {
h: Some(n),
..self.property.frame_property.unwrap_or_default()
});
self
}
}
impl BuildXML for Paragraph {

View File

@ -215,6 +215,103 @@ impl Style {
self.table_cell_property = p;
self
}
// frameProperty
pub fn wrap(mut self, wrap: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
wrap: Some(wrap.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn v_anchor(mut self, anchor: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
v_anchor: Some(anchor.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn h_anchor(mut self, anchor: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
h_anchor: Some(anchor.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn h_rule(mut self, r: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
h_rule: Some(r.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn x_align(mut self, align: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
x_align: Some(align.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn y_align(mut self, align: impl Into<String>) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
y_align: Some(align.into()),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
h_space: Some(x),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
v_space: Some(x),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_x(mut self, x: i32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
x: Some(x),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_y(mut self, y: i32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
y: Some(y),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_width(mut self, n: u32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
w: Some(n),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
pub fn frame_height(mut self, n: u32) -> Self {
self.paragraph_property.frame_property = Some(FrameProperty {
h: Some(n),
..self.paragraph_property.frame_property.unwrap_or_default()
});
self
}
}
impl BuildXML for Style {

View File

@ -33,11 +33,6 @@ impl Footer {
self
}
pub fn add_page_num(mut self, p: PageNum) -> Self {
self.children.push(FooterChild::PageNum(Box::new(p)));
self
}
/// reader only
pub(crate) fn add_structured_data_tag(mut self, t: StructuredDataTag) -> Self {
if t.has_numbering {
@ -53,7 +48,6 @@ impl Footer {
pub enum FooterChild {
Paragraph(Box<Paragraph>),
Table(Box<Table>),
PageNum(Box<PageNum>),
StructuredDataTag(Box<StructuredDataTag>),
}
@ -75,12 +69,6 @@ impl Serialize for FooterChild {
t.serialize_field("data", c)?;
t.end()
}
FooterChild::PageNum(ref r) => {
let mut t = serializer.serialize_struct("PageNum", 2)?;
t.serialize_field("type", "pageNum")?;
t.serialize_field("data", r)?;
t.end()
}
FooterChild::StructuredDataTag(ref r) => {
let mut t = serializer.serialize_struct("StructuredDataTag", 2)?;
t.serialize_field("type", "structuredDataTag")?;
@ -100,7 +88,6 @@ impl BuildXML for Footer {
match c {
FooterChild::Paragraph(p) => b = b.add_child(p),
FooterChild::Table(t) => b = b.add_child(t),
FooterChild::PageNum(p) => b = b.add_child(p),
FooterChild::StructuredDataTag(t) => b = b.add_child(t),
}
}

View File

@ -33,11 +33,6 @@ impl Header {
self
}
pub fn add_page_num(mut self, p: PageNum) -> Self {
self.children.push(HeaderChild::PageNum(Box::new(p)));
self
}
/// reader only
pub(crate) fn add_structured_data_tag(mut self, t: StructuredDataTag) -> Self {
if t.has_numbering {
@ -53,7 +48,6 @@ impl Header {
pub enum HeaderChild {
Paragraph(Box<Paragraph>),
Table(Box<Table>),
PageNum(Box<PageNum>),
StructuredDataTag(Box<StructuredDataTag>),
}
@ -75,12 +69,6 @@ impl Serialize for HeaderChild {
t.serialize_field("data", c)?;
t.end()
}
HeaderChild::PageNum(ref r) => {
let mut t = serializer.serialize_struct("PageNum", 2)?;
t.serialize_field("type", "pageNum")?;
t.serialize_field("data", r)?;
t.end()
}
HeaderChild::StructuredDataTag(ref r) => {
let mut t = serializer.serialize_struct("StructuredDataTag", 2)?;
t.serialize_field("type", "structuredDataTag")?;
@ -100,7 +88,6 @@ impl BuildXML for Header {
match c {
HeaderChild::Paragraph(p) => b = b.add_child(p),
HeaderChild::Table(t) => b = b.add_child(t),
HeaderChild::PageNum(p) => b = b.add_child(p),
HeaderChild::StructuredDataTag(t) => b = b.add_child(t),
}
}

View File

@ -925,7 +925,6 @@ impl Docx {
Some("header"),
);
}
HeaderChild::PageNum(_) => {}
HeaderChild::StructuredDataTag(tag) => {
for child in tag.children.iter_mut() {
if let StructuredDataTagChild::Paragraph(paragraph) = child {
@ -971,7 +970,6 @@ impl Docx {
Some("header"),
);
}
HeaderChild::PageNum(_) => {}
HeaderChild::StructuredDataTag(tag) => {
for child in tag.children.iter_mut() {
if let StructuredDataTagChild::Paragraph(paragraph) = child {
@ -1017,7 +1015,6 @@ impl Docx {
Some("header"),
);
}
HeaderChild::PageNum(_) => {}
HeaderChild::StructuredDataTag(tag) => {
for child in tag.children.iter_mut() {
if let StructuredDataTagChild::Paragraph(paragraph) = child {
@ -1062,7 +1059,6 @@ impl Docx {
Some("footer"),
);
}
FooterChild::PageNum(_) => {}
FooterChild::Table(table) => {
collect_images_from_table(
table,
@ -1108,7 +1104,6 @@ impl Docx {
Some("footer"),
);
}
FooterChild::PageNum(_) => {}
FooterChild::Table(table) => {
collect_images_from_table(
table,
@ -1154,7 +1149,6 @@ impl Docx {
Some("footer"),
);
}
FooterChild::PageNum(_) => {}
FooterChild::Table(table) => {
collect_images_from_table(
table,

View File

@ -11,6 +11,8 @@ import { Hyperlink, convertHyperlinkType } from "./hyperlink";
import { setParagraphProperty } from "./paragraph-property";
import * as wasm from "./pkg";
import { PageNum } from "./page-num";
import { NumPages } from "./num-pages";
type Child = Paragraph | Table | Comment | Hyperlink;
@ -64,6 +66,10 @@ function buildParagraph(child: Paragraph) {
paragraph = paragraph.add_comment_start(comment as wasm.Comment);
} else if (child instanceof CommentEnd) {
paragraph = paragraph.add_comment_end(child.id);
} else if (child instanceof PageNum) {
paragraph = paragraph.add_page_num(wasm.createPageNum());
} else if (child instanceof NumPages) {
paragraph = paragraph.add_num_pages(wasm.createNumPages());
}
});

View File

@ -1,10 +1,9 @@
import { PageNum } from "./page-num";
import { Paragraph } from "./paragraph";
import { Table } from "./table";
export class Footer {
hasNumberings = false;
children: (Paragraph | Table | PageNum)[] = [];
children: (Paragraph | Table)[] = [];
addParagraph(p: Paragraph) {
if (p.hasNumberings) {
@ -21,9 +20,4 @@ export class Footer {
this.children.push(t);
return this;
}
addPageNum(p: PageNum) {
this.children.push(p);
return this;
}
}

View File

@ -1,10 +1,9 @@
import { PageNum } from "./page-num";
import { Paragraph } from "./paragraph";
import { Table } from "./table";
export class Header {
hasNumberings = false;
children: (Paragraph | Table | PageNum)[] = [];
children: (Paragraph | Table)[] = [];
addParagraph(p: Paragraph) {
if (p.hasNumberings) {
@ -21,9 +20,4 @@ export class Header {
this.children.push(t);
return this;
}
addPageNum(p: PageNum) {
this.children.push(p);
return this;
}
}

View File

@ -424,9 +424,6 @@ export class Docx {
header = header.add_paragraph(build(c));
} else if (c instanceof Table) {
header = header.add_table(c.build());
} else {
const p = c.build();
header = header.add_page_num(p);
}
});
docx = docx.header(header);
@ -439,9 +436,6 @@ export class Docx {
header = header.add_paragraph(build(c));
} else if (c instanceof Table) {
header = header.add_table(c.build());
} else {
const p = c.build();
header = header.add_page_num(p);
}
});
docx = docx.first_header(header);
@ -454,9 +448,6 @@ export class Docx {
header = header.add_paragraph(build(c));
} else if (c instanceof Table) {
header = header.add_table(c.build());
} else {
const p = c.build();
header = header.add_page_num(p);
}
});
docx = docx.even_header(header);
@ -469,9 +460,6 @@ export class Docx {
footer = footer.add_paragraph(build(c));
} else if (c instanceof Table) {
footer = footer.add_table(c.build());
} else {
const p = c.build();
footer = footer.add_page_num(p);
}
});
docx = docx.footer(footer);
@ -484,9 +472,6 @@ export class Docx {
footer = footer.add_paragraph(build(c));
} else if (c instanceof Table) {
footer = footer.add_table(c.build());
} else {
const p = c.build();
footer = footer.add_page_num(p);
}
});
docx = docx.first_footer(footer);
@ -499,9 +484,6 @@ export class Docx {
footer = footer.add_paragraph(build(c));
} else if (c instanceof Table) {
footer = footer.add_table(c.build());
} else {
const p = c.build();
footer = footer.add_page_num(p);
}
});
docx = docx.even_footer(footer);
@ -687,5 +669,6 @@ export * from "./json";
export * from "./webextension";
export * from "./header";
export * from "./page-num";
export * from "./num-pages";
export * from "./footer";
export * from "./image";

View File

@ -0,0 +1,7 @@
import * as wasm from "./pkg/docx_wasm";
export class NumPages {
build() {
return wasm.createNumPages();
}
}

View File

@ -1,153 +1,8 @@
import {
AlignmentType,
ParagraphProperty,
createDefaultParagraphProperty,
createParagraphAlignment,
} from "./paragraph-property";
import * as wasm from "./pkg/docx_wasm";
export type FrameProperty = {
h?: number;
hRule?: string;
hAnchor?: string;
hSpace?: number;
vAnchor?: string;
vSpace?: number;
w?: number;
wrap?: string;
x?: number;
xAlign?: string;
y?: number;
yAlign?: string;
};
export class PageNum {
frameProperty: FrameProperty | null = null;
paragraphProperty: ParagraphProperty | null = null;
height(h: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.h = h;
return this;
}
hRule(r: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.hRule = r;
return this;
}
hAnchor(a: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.hAnchor = a;
return this;
}
hSpace(s: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.hSpace = s;
return this;
}
vAnchor(a: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.vAnchor = a;
return this;
}
vSpace(s: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.vSpace = s;
return this;
}
width(w: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.w = w;
return this;
}
wrap(w: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.wrap = w;
return this;
}
x(x: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.x = x;
return this;
}
xAlign(a: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.xAlign = a;
return this;
}
y(y: number) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.y = y;
return this;
}
yAlign(y: string) {
this.frameProperty = { ...this.frameProperty };
this.frameProperty.yAlign = y;
return this;
}
align(align: AlignmentType) {
this.paragraphProperty = {
...createDefaultParagraphProperty(),
align,
};
return this;
}
build() {
let pageNum = wasm.createPageNum();
if (this.frameProperty?.h != null) {
pageNum = pageNum.height(this.frameProperty.h);
}
if (this.frameProperty?.hRule != null) {
pageNum = pageNum.h_rule(this.frameProperty.hRule);
}
if (this.frameProperty?.hAnchor != null) {
pageNum = pageNum.h_anchor(this.frameProperty.hAnchor);
}
if (this.frameProperty?.hSpace != null) {
pageNum = pageNum.h_space(this.frameProperty.hSpace);
}
if (this.frameProperty?.vAnchor != null) {
pageNum = pageNum.v_anchor(this.frameProperty.vAnchor);
}
if (this.frameProperty?.vSpace != null) {
pageNum = pageNum.v_space(this.frameProperty.vSpace);
}
if (this.frameProperty?.w != null) {
pageNum = pageNum.width(this.frameProperty.w);
}
if (this.frameProperty?.wrap != null) {
pageNum = pageNum.wrap(this.frameProperty.wrap);
}
if (this.frameProperty?.x != null) {
pageNum = pageNum.x(this.frameProperty.x);
}
if (this.frameProperty?.xAlign != null) {
pageNum = pageNum.x_align(this.frameProperty.xAlign);
}
if (this.frameProperty?.y != null) {
pageNum = pageNum.y(this.frameProperty.y);
}
if (this.frameProperty?.yAlign != null) {
pageNum = pageNum.y_align(this.frameProperty.yAlign);
}
if (this.paragraphProperty?.align != null) {
const align = createParagraphAlignment(this.paragraphProperty.align);
if (align) {
pageNum = pageNum.align(align);
}
}
const pageNum = wasm.createPageNum();
return pageNum;
}
}

View File

@ -11,6 +11,21 @@ export type SpecialIndentKind = "firstLine" | "hanging";
export type LineSpacingType = "atLeast" | "auto" | "exact";
export type FrameProperty = {
h?: number;
hRule?: string;
hAnchor?: string;
hSpace?: number;
vAnchor?: string;
vSpace?: number;
w?: number;
wrap?: string;
x?: number;
xAlign?: string;
y?: number;
yAlign?: string;
};
export class LineSpacing {
_before?: number;
_after?: number;
@ -69,6 +84,7 @@ export type ParagraphProperty = {
outlineLvl?: number | null;
adjustRightInd?: number;
tabs?: Tab[];
frameProperty?: FrameProperty;
};
export const createDefaultParagraphProperty = (): ParagraphProperty => {
@ -395,5 +411,44 @@ export const setParagraphProperty = <T extends wasm.Paragraph | wasm.Style>(
}
}
if (property.frameProperty) {
if (property.frameProperty?.h != null) {
target = target.frame_height(property.frameProperty.h) as T;
}
if (property.frameProperty?.hRule != null) {
target = target.h_rule(property.frameProperty.hRule) as T;
}
if (property.frameProperty?.hAnchor != null) {
target = target.h_anchor(property.frameProperty.hAnchor) as T;
}
if (property.frameProperty?.hSpace != null) {
target = target.h_space(property.frameProperty.hSpace) as T;
}
if (property.frameProperty?.vAnchor != null) {
target = target.v_anchor(property.frameProperty.vAnchor) as T;
}
if (property.frameProperty?.vSpace != null) {
target = target.v_space(property.frameProperty.vSpace) as T;
}
if (property.frameProperty?.w != null) {
target = target.frame_width(property.frameProperty.w) as T;
}
if (property.frameProperty?.wrap != null) {
target = target.wrap(property.frameProperty.wrap) as T;
}
if (property.frameProperty?.x != null) {
target = target.frame_x(property.frameProperty.x) as T;
}
if (property.frameProperty?.xAlign != null) {
target = target.x_align(property.frameProperty.xAlign) as T;
}
if (property.frameProperty?.y != null) {
target = target.frame_y(property.frameProperty.y) as T;
}
if (property.frameProperty?.yAlign != null) {
target = target.y_align(property.frameProperty.yAlign) as T;
}
}
return target;
};

View File

@ -17,6 +17,8 @@ import { Hyperlink } from "./hyperlink";
import { TextAlignmentType } from "./json/bindings/TextAlignmentType";
import { TabValueType } from "./json/bindings/TabValueType";
import { TabLeaderType } from "./json/bindings/TabLeaderType";
import { NumPages } from "./num-pages";
import { PageNum } from "./page-num";
export type ParagraphChild =
| Run
@ -26,7 +28,9 @@ export type ParagraphChild =
| BookmarkStart
| BookmarkEnd
| Comment
| CommentEnd;
| CommentEnd
| NumPages
| PageNum;
export class Paragraph {
hasNumberings = false;
@ -73,6 +77,16 @@ export class Paragraph {
return this;
}
addPageNum() {
this.children.push(new PageNum());
return this;
}
addNumPages() {
this.children.push(new NumPages());
return this;
}
tabs(
tabs: {
val: TabValueType | null;
@ -195,4 +209,76 @@ export class Paragraph {
this.property.paragraphPropertyChange = propertyChange;
return this;
}
// frameProperty
frameHeight(h: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.h = h;
return this;
}
hRule(r: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.hRule = r;
return this;
}
hAnchor(a: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.hAnchor = a;
return this;
}
hSpace(s: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.hSpace = s;
return this;
}
vAnchor(a: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.vAnchor = a;
return this;
}
vSpace(s: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.vSpace = s;
return this;
}
frameWidth(w: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.w = w;
return this;
}
wrap(w: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.wrap = w;
return this;
}
frameX(x: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.x = x;
return this;
}
xAlign(a: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.xAlign = a;
return this;
}
frameY(y: number) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.y = y;
return this;
}
yAlign(y: string) {
this.property.frameProperty = { ...this.property.frameProperty };
this.property.frameProperty.yAlign = y;
return this;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "docx-wasm",
"version": "0.4.17",
"version": "0.4.18-rc2",
"main": "dist/node/index.js",
"browser": "dist/web/index.js",
"author": "bokuweb <bokuweb12@gmail.com>",

View File

@ -27,9 +27,4 @@ impl Footer {
self.0 = self.0.add_table(t.take());
self
}
pub fn add_page_num(mut self, t: PageNum) -> Self {
self.0 = self.0.add_page_num(t.take());
self
}
}

View File

@ -27,9 +27,4 @@ impl Header {
self.0 = self.0.add_table(t.take());
self
}
pub fn add_page_num(mut self, t: PageNum) -> Self {
self.0 = self.0.add_page_num(t.take());
self
}
}

View File

@ -10,6 +10,7 @@ mod insert;
mod level;
mod level_override;
mod line_spacing;
mod num_pages;
mod numbering;
mod page_margin;
mod page_num;
@ -41,6 +42,7 @@ pub use insert::*;
pub use level::*;
pub use level_override::*;
pub use line_spacing::*;
pub use num_pages::*;
pub use numbering::*;
pub use page_margin::*;
pub use page_num::*;

View File

@ -0,0 +1,16 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct NumPages(docx_rs::NumPages);
#[wasm_bindgen(js_name = createNumPages)]
pub fn create_num_pages() -> NumPages {
NumPages(docx_rs::NumPages::new())
}
impl NumPages {
pub fn take(self) -> docx_rs::NumPages {
self.0
}
}

View File

@ -14,77 +14,3 @@ impl PageNum {
self.0
}
}
#[wasm_bindgen]
impl PageNum {
pub fn wrap(mut self, wrap: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().wrap(wrap));
self
}
pub fn v_anchor(mut self, anchor: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().v_anchor(anchor));
self
}
pub fn h_anchor(mut self, anchor: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().h_anchor(anchor));
self
}
pub fn h_rule(mut self, r: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().h_rule(r));
self
}
pub fn x_align(mut self, align: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().x_align(align));
self
}
pub fn y_align(mut self, align: &str) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().y_align(align));
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().h_space(x));
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().v_space(x));
self
}
pub fn x(mut self, x: i32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().x(x));
self
}
pub fn y(mut self, y: i32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().y(y));
self
}
pub fn width(mut self, n: u32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().width(n));
self
}
pub fn height(mut self, n: u32) -> Self {
self.0.frame_property = Some(self.0.frame_property.unwrap_or_default().height(n));
self
}
// TODO: add other pPr fields
pub fn align(mut self, alignment_type: docx_rs::AlignmentType) -> Self {
self.0.paragraph_property = Some(
self.0
.paragraph_property
.unwrap_or_default()
.align(alignment_type),
);
self
}
}

View File

@ -247,6 +247,77 @@ impl Paragraph {
self.0.property = self.0.property.paragraph_property_change(p.take());
self
}
pub fn add_page_num(mut self, p: PageNum) -> Self {
self.0 = self.0.add_page_num(p.take());
self
}
pub fn add_num_pages(mut self, p: NumPages) -> Self {
self.0 = self.0.add_num_pages(p.take());
self
}
// frame property
pub fn wrap(mut self, wrap: &str) -> Self {
self.0 = self.0.wrap(wrap);
self
}
pub fn v_anchor(mut self, anchor: &str) -> Self {
self.0 = self.0.v_anchor(anchor);
self
}
pub fn h_anchor(mut self, anchor: &str) -> Self {
self.0 = self.0.h_anchor(anchor);
self
}
pub fn h_rule(mut self, r: &str) -> Self {
self.0 = self.0.h_rule(r);
self
}
pub fn x_align(mut self, align: &str) -> Self {
self.0 = self.0.x_align(align);
self
}
pub fn y_align(mut self, align: &str) -> Self {
self.0 = self.0.y_align(align);
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.0 = self.0.h_space(x);
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.0 = self.0.v_space(x);
self
}
pub fn frame_x(mut self, x: i32) -> Self {
self.0 = self.0.frame_x(x);
self
}
pub fn frame_y(mut self, y: i32) -> Self {
self.0 = self.0.frame_y(y);
self
}
pub fn frame_width(mut self, n: u32) -> Self {
self.0 = self.0.frame_width(n);
self
}
pub fn frame_height(mut self, n: u32) -> Self {
self.0 = self.0.frame_height(n);
self
}
}
impl Paragraph {

View File

@ -245,6 +245,67 @@ impl Style {
self.0.table_property = self.0.table_property.layout(t);
self
}
// frame property
pub fn wrap(mut self, wrap: &str) -> Self {
self.0 = self.0.wrap(wrap);
self
}
pub fn v_anchor(mut self, anchor: &str) -> Self {
self.0 = self.0.v_anchor(anchor);
self
}
pub fn h_anchor(mut self, anchor: &str) -> Self {
self.0 = self.0.h_anchor(anchor);
self
}
pub fn h_rule(mut self, r: &str) -> Self {
self.0 = self.0.h_rule(r);
self
}
pub fn x_align(mut self, align: &str) -> Self {
self.0 = self.0.x_align(align);
self
}
pub fn y_align(mut self, align: &str) -> Self {
self.0 = self.0.y_align(align);
self
}
pub fn h_space(mut self, x: i32) -> Self {
self.0 = self.0.h_space(x);
self
}
pub fn v_space(mut self, x: i32) -> Self {
self.0 = self.0.v_space(x);
self
}
pub fn frame_x(mut self, x: i32) -> Self {
self.0 = self.0.frame_x(x);
self
}
pub fn frame_y(mut self, y: i32) -> Self {
self.0 = self.0.frame_y(y);
self
}
pub fn frame_width(mut self, n: u32) -> Self {
self.0 = self.0.frame_width(n);
self
}
pub fn frame_height(mut self, n: u32) -> Self {
self.0 = self.0.frame_height(n);
self
}
}
impl Style {

View File

@ -171637,10 +171637,20 @@ exports[`writer should write pageNum in header 1`] = `
exports[`writer should write pageNum in header 2`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
<w:document xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" xmlns:w15=\\"http://schemas.microsoft.com/office/word/2012/wordml\\" mc:Ignorable=\\"w14 wp14\\">
<w:body><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello world!!</w:t></w:r></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:cols w:space=\\"425\\" w:num=\\"1\\" /><w:headerReference w:type=\\"default\\" r:id=\\"rIdHeader1\\" /></w:sectPr></w:body>
<w:body><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /><w:jc w:val=\\"center\\" /></w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello world!! </w:t></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGE</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r><w:r><w:rPr /><w:t xml:space=\\"preserve\\"> / </w:t></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>NUMPAGES</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:cols w:space=\\"425\\" w:num=\\"1\\" /><w:headerReference w:type=\\"default\\" r:id=\\"rIdHeader1\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write pageNum in header 3`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
<w:hdr xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" mc:Ignorable=\\"w14 wp14\\"><w:p w14:paraId=\\"00000002\\"><w:pPr><w:rPr /><w:jc w:val=\\"center\\" /></w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello world!! </w:t></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGE</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r><w:r><w:rPr /><w:t xml:space=\\"preserve\\"> / </w:t></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>NUMPAGES</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p></w:hdr>"
`;
exports[`writer should write pageNum in header 4`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\" />"
`;
exports[`writer should write paragraph delete 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">

View File

@ -1045,16 +1045,20 @@ describe("writer", () => {
});
test("should write pageNum in header", () => {
const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!"));
const page = new w.PageNum().align('center');
const header = new w.Header().addParagraph(p).addPageNum(page);
const p = new w.Paragraph()
.addRun(new w.Run().addText("Hello world!! "))
.addPageNum()
.addRun(new w.Run().addText(" / "))
.addNumPages()
.align("center");
const header = new w.Header().addParagraph(p);
const buffer = new w.Docx().header(header).addParagraph(p).build();
writeFileSync("../output/js/header_in_page_num.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
if (e.entryName.match(/document.xml|header/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}