feat: Support top level bookmark (#133)
parent
e143a80216
commit
5dcd4d73ae
|
@ -0,0 +1,13 @@
|
|||
use docx_rs::*;
|
||||
|
||||
pub fn main() -> Result<(), DocxError> {
|
||||
let path = std::path::Path::new("./output/bookmark.docx");
|
||||
let file = std::fs::File::create(&path).unwrap();
|
||||
Docx::new()
|
||||
.add_bookmark_start(1, "hello")
|
||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello")))
|
||||
.add_bookmark_end(1)
|
||||
.build()
|
||||
.pack(file)?;
|
||||
Ok(())
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use serde::ser::{SerializeStruct, Serializer};
|
||||
use serde::Serialize;
|
||||
|
||||
use super::{Paragraph, SectionProperty, Table};
|
||||
use super::*;
|
||||
use crate::documents::BuildXML;
|
||||
use crate::xml_builder::*;
|
||||
|
||||
|
@ -17,6 +17,8 @@ pub struct Document {
|
|||
pub enum DocumentChild {
|
||||
Paragraph(Paragraph),
|
||||
Table(Table),
|
||||
BookmarkStart(BookmarkStart),
|
||||
BookmarkEnd(BookmarkEnd),
|
||||
}
|
||||
|
||||
impl Serialize for DocumentChild {
|
||||
|
@ -37,6 +39,18 @@ impl Serialize for DocumentChild {
|
|||
t.serialize_field("data", c)?;
|
||||
t.end()
|
||||
}
|
||||
DocumentChild::BookmarkStart(ref c) => {
|
||||
let mut t = serializer.serialize_struct("BookmarkStart", 2)?;
|
||||
t.serialize_field("type", "bookmarkStart")?;
|
||||
t.serialize_field("data", c)?;
|
||||
t.end()
|
||||
}
|
||||
DocumentChild::BookmarkEnd(ref c) => {
|
||||
let mut t = serializer.serialize_struct("BookmarkEnd", 2)?;
|
||||
t.serialize_field("type", "bookmarkEnd")?;
|
||||
t.serialize_field("data", c)?;
|
||||
t.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +85,18 @@ impl Document {
|
|||
self.children.push(DocumentChild::Table(t));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_start(mut self, id: usize, name: impl Into<String>) -> Self {
|
||||
self.children
|
||||
.push(DocumentChild::BookmarkStart(BookmarkStart::new(id, name)));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_end(mut self, id: usize) -> Self {
|
||||
self.children
|
||||
.push(DocumentChild::BookmarkEnd(BookmarkEnd::new(id)));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildXML for Document {
|
||||
|
@ -83,6 +109,8 @@ impl BuildXML for Document {
|
|||
match c {
|
||||
DocumentChild::Paragraph(p) => b = b.add_child(p),
|
||||
DocumentChild::Table(t) => b = b.add_child(t),
|
||||
DocumentChild::BookmarkStart(s) => b = b.add_child(s),
|
||||
DocumentChild::BookmarkEnd(e) => b = b.add_child(e),
|
||||
}
|
||||
}
|
||||
b.add_child(&self.section_property).close().close().build()
|
||||
|
|
|
@ -112,6 +112,7 @@ impl Docx {
|
|||
self.document_rels.has_numberings = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.document = d;
|
||||
|
@ -138,6 +139,16 @@ impl Docx {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_start(mut self, id: usize, name: impl Into<String>) -> Docx {
|
||||
self.document = self.document.add_bookmark_start(id, name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_end(mut self, id: usize) -> Docx {
|
||||
self.document = self.document.add_bookmark_end(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_table(mut self, t: Table) -> Docx {
|
||||
if t.has_numbering {
|
||||
// If this document has numbering, set numberings.xml to document_rels.
|
||||
|
@ -247,6 +258,7 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,6 +317,7 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// If this document has comments, set comments.xml to document_rels.
|
||||
|
@ -371,6 +384,7 @@ impl Docx {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
(image_ids, images)
|
||||
|
|
|
@ -2,6 +2,7 @@ import { saveAs } from "file-saver";
|
|||
|
||||
import("../js").then((w) => {
|
||||
const buf = new w.Docx()
|
||||
.addBookmarkStart(0, "Hello")
|
||||
.addParagraph(
|
||||
new w.Paragraph()
|
||||
.addRun(new w.Run().addText("Hello "))
|
||||
|
@ -29,6 +30,7 @@ import("../js").then((w) => {
|
|||
)
|
||||
.addCommentEnd(new w.CommentEnd(2))
|
||||
)
|
||||
.addBookmarkEnd(0)
|
||||
.docId("12345678-1234-1234-1234-1234567890AB")
|
||||
.build();
|
||||
saveAs(new Blob([buf]), "hello.docx");
|
||||
|
|
|
@ -48,7 +48,7 @@ const convertBorderType = (t: BorderType) => {
|
|||
};
|
||||
|
||||
export class Docx {
|
||||
children: (Paragraph | Table)[] = [];
|
||||
children: (Paragraph | Table | BookmarkStart | BookmarkEnd)[] = [];
|
||||
hasNumberings = false;
|
||||
abstractNumberings: AbstractNumbering[] = [];
|
||||
numberings: Numbering[] = [];
|
||||
|
@ -62,6 +62,16 @@ export class Docx {
|
|||
return this;
|
||||
}
|
||||
|
||||
addBookmarkStart(id: number, name: string) {
|
||||
this.children.push(new BookmarkStart(id, name));
|
||||
return this;
|
||||
}
|
||||
|
||||
addBookmarkEnd(id: number) {
|
||||
this.children.push(new BookmarkEnd(id));
|
||||
return this;
|
||||
}
|
||||
|
||||
addTable(t: Table) {
|
||||
if (t.hasNumberings) {
|
||||
this.hasNumberings = true;
|
||||
|
@ -452,6 +462,10 @@ export class Docx {
|
|||
} else if (child instanceof Table) {
|
||||
let t = this.buildTable(child);
|
||||
docx = docx.add_table(t);
|
||||
} else if (child instanceof BookmarkStart) {
|
||||
docx = docx.add_bookmark_start(child.id, child.name);
|
||||
} else if (child instanceof BookmarkEnd) {
|
||||
docx = docx.add_bookmark_end(child.id);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -18,6 +18,16 @@ impl Docx {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_start(mut self, id: usize, name: &str) -> Self {
|
||||
self.0 = self.0.add_bookmark_start(id, name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_bookmark_end(mut self, id: usize) -> Docx {
|
||||
self.0 = self.0.add_bookmark_end(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_table(mut self, t: Table) -> Docx {
|
||||
self.0.document = self.0.document.add_table(t.take());
|
||||
self
|
||||
|
|
Loading…
Reference in New Issue